Version 1.10.0-dev.0.0

svn merge -r 44223:44706 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@44707 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/.gitignore b/.gitignore
index 917e10a..65d9dea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,6 +44,9 @@
 # Compiled python binaries
 *.pyc
 
+# pydev project file.
+.pydevproject
+
 # From the Mac OS X Finder
 .DS_Store
 
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index eddcbb8..502038c 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -8,7 +8,6 @@
 \newcommand{\code}[1]{{\sf #1}}
 \title{Dart Programming Language  Specification \\
 {\large Version 1.9}}
-%\author{The Dart Team}
 
 % For information about Location Markers (and in particular the
 % commands \LMHash and \LMLabel), see the long comment at the
@@ -40,8 +39,6 @@
 \LMHash{}
 A conforming implementation is permitted to provide additional APIs, but not additional syntax.
 
-% A claim of conformance with this Ecma Standard shall specify?
-
 \section{Normative References}
 \LMLabel{ecmaNormativeReferences}
 
@@ -1003,6 +1000,8 @@
 \LMHash{}
 It is a static warning if the return type of the user-declared operator \code{[]=} is explicitly declared and not \VOID{}.
 
+% add rationale: return in []= methods will have no effect, a the expression always returns its second argument (the RHS of the assignment, for consistency with assignment in general). So it's best to enforce this by declaring the method to be void, even though the expression that uses it returns an object with the type of the RHS, as described in \ref{assignment}.
+
 
 \subsection{Getters} 
 \LMLabel{getters}
@@ -3090,7 +3089,33 @@
 The static type of a function literal of the form 
 
 $(T_1$ $a_1, \ldots, T_n$ $a_n, [T_{n+1}$ $x_{n+1} = d_1, \ldots,  T_{n+k}$ $x_{n+k} = d_k])$ \ASYNC{} $=> e$
-is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarrow Future<T_0>$, where $T_0$ is the static type of $e$. 
+is $(T_1 \ldots, T_n, [T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}]) \rightarrow Future<flatten(T_0)>$, where $T_0$ is the static type of $e$ and  $flatten(T)$ is defined as follows:
+
+ If $T = Future<S>$ then $flatten(T) = flatten(S)$. 
+ 
+ Otherwise if $T <: Future$ then let $S$ be a type such that $T << Future<S>$ and for all $R$, if $T << Future<R>$ then $S << R$.  
+
+\rationale{
+This ensures that $Future<S>$ is the most specific instantiation of \cd{Future} that is a super type of $T$.
+}
+
+Then $flatten(T) =  S$.  
+
+In any other circumstance, $flatten(T) = T$.
+
+
+
+\rationale{
+We collapse multiple layers of futures into one. If $e$ evaluates to a future $f$, the future will not invoke its \code{then()} callback until f completes to a non-future value, and so the result of an await is never a future, and the result of an async function will never have type \code{Future$<X>$} where $X$ itself is an invocation of \code{Future}. 
+
+The  exception to that would be a type $X$ that extended or implemented \code{Future}. In that case, only one unwrapping takes place. As an example of why this is done, consider
+
+\cd{\CLASS{} C$<$T$>$  \IMPLEMENTS{}  Future$<$C$<$C$<$T$>>>$ \ldots }
+
+Here, a naive definition of $flatten$ diverges; there is not even a fixed point. A more sophisticated definition of $flatten$ is possible, but the existing rule deals with most realistic examples while remaining relatively simple to understand.
+
+}
+
 
 \LMHash{}
 The static type of a function literal of the form 
@@ -3105,7 +3130,7 @@
 
 $(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots,  T_{n+k}$ $x_{n+k} : d_k\})$ \ASYNC{}  $=> e$
 
-is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow Future<T_0>$, where $T_0$ is the static type of $e$. 
+is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow Future<flatten(T_0)>$, where $T_0$ is the static type of $e$. 
 
 \LMHash{}
 The static type of a function literal of the form  
@@ -3521,7 +3546,7 @@
 }
 
 \LMHash{}
-When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()} on it, execution of the body of $f$ will begin. When $f$ terminates, $j$ is positioned after its last element, so that its current value is \NULL{} and the current call to \code{moveNext()} on $j$ returns false, as will all further calls.
+When iteration over the iterable is started, by getting an iterator $j$ from the iterable and calling \code{moveNext()}, execution of the body of $f$ will begin. When $f$ terminates, $j$ is positioned after its last element, so that its current value is \NULL{} and the current call to \code{moveNext()} on $j$ returns false, as will all further calls.
 
 Each iterator starts a separate computation. If the \SYNC* function is impure, the sequence of values yielded by each iterator may differ. 
 
@@ -3779,7 +3804,7 @@
 
 \LMHash{}
 If the method lookup has failed, then let $g$ be the result of looking up getter (\ref{getterAndSetterLookup}) $m$ in $v_o$ with respect to $L$. 
-f $v_o$ is an instance of \code{Type} but $o$ is not a constant type literal, then if $g$ is a getter that forwards to a static getter, getter lookup fails.
+If $v_o$ is an instance of \code{Type} but $o$ is not a constant type literal, then if $g$ is a getter that forwards to a static getter, getter lookup fails.
 If the getter lookup succeeded, let $v_g$ be the value of the getter invocation $o.m$. Then the value of $i$ is the result of invoking 
 the static method \code{Function.apply()} with arguments $v.g, [o_1, \ldots , o_n], \{x_{n+1}: o_{n+1}, \ldots , x_{n+k}: o_{n+k}\}$.
 
@@ -4596,12 +4621,7 @@
 }
 
 \LMHash{}
-Let $flatten(T) = flatten(S)$ if $T = Future<S>$, and $T$ otherwise. The static type of $a$ is $flatten(T)$ where $T$ is the static type of $e$.
-
-\rationale{
-We collapse multiple layers of futures into one. If $e$ evaluates to a future $f$, the future will not invoke its \code{then()} callback until f completes to a non-future value, and so the result of an await is never a future, and the result of an async function will never have type \code{Future$<X>$} where $X$ itself is an invocation of \code{Future}. 
-}
-
+The static type of $a$ is $flatten(T)$ (the $flatten$ function is defined in section \ref{functionExpressions}) where $T$ is the static type of $e$.
 
 
      
@@ -5739,7 +5759,7 @@
 Let $T$ be the static type of $e$ and let $f$ be the immediately enclosing function.  
 
 \LMHash{}
-It is a static type warning if the body of $f$ is marked \ASYNC{} and the type \code{Future$<$flatten(T)$>$} (\ref{awaitExpressions}) may not be assigned to the declared return type of $f$.   Otherwise, it is a static type warning if $T$ may not be assigned to the declared return type of $f$. 
+It is a static type warning if the body of $f$ is marked \ASYNC{} and the type \code{Future$<$flatten(T)$>$} (\ref{functionExpressions}) may not be assigned to the declared return type of $f$.    Otherwise, it is a static type warning if $T$ may not be assigned to the declared return type of $f$. 
 
 \LMHash{}
 Let $S$ be the runtime type of $o$. In checked mode:
@@ -5911,10 +5931,18 @@
 }
 
 \LMHash{}
+Otherwise, if the enclosing function $m$ is marked \ASYNC* (\ref{functions}) then the enclosing function may suspend.
+
+\rationale {
+If a \YIELD{} occurred inside an infinite loop and the enclosing function never suspended, there might not be an opportunity for consumers of the  enclosing stream to run and access the data in the stream.  The stream might then accumulate an unbounded number of elements. Such a situation is untenable. Therefore, we allow the enclosing function to be suspended when a new value is added to its associated stream. However, it is not essential (and in fact, can be quite costly) to suspend the function on every \YIELD{}. The implementation is free to decide how often to suspend the enclosing function. The only requirement is that consumers are not blocked indefinitely.
+}
+
+
+\LMHash{}
 If the enclosing function $m$ is marked \SYNC* (\ref{functions}) then:
 \begin{itemize}
 \item
-Execution of the function $m$ immediately enclosing $s$ is suspended until the method \code{moveNext()} is invoked upon the iterator used to initiate the current invocation of $m$. 
+Execution of the function $m$ immediately enclosing $s$ is suspended until the nullary method \code{moveNext()} is invoked upon the iterator used to initiate the current invocation of $m$. 
 \item
 The current call to \code{moveNext()} returns \TRUE.
 \end{itemize}
@@ -5945,27 +5973,39 @@
 \end{grammar}
 
 \LMHash{}
-Execution of a statement s of the form \code{\YIELD* $e$;}  proceeds as follows:
+Execution of a statement $s$ of the form \code{\YIELD* $e$;}  proceeds as follows:
 
 \LMHash{}
-First, the expression $e$ is evaluated to an object $o$. If the immediately enclosing function $m$ is synchronous, then it is a dynamic error if the class of $o$ does not implement \code{Iterable}.  If $m$ asynchronous, then it is a dynamic error if the class of $o$ does not implement \code{Stream}. Next, for each element $x$ of $o$:
-\begin{itemize}
-\item
-If $m$ is marked \ASYNC* (\ref{functions}) and the stream $u$ associated with $m$ has been paused,  then execution of $m$ is suspended until $u$ is resumed or canceled.
-\item
- $x$ is added to the iterable or stream associated with $m$ in the order it appears in $o$.  
- \item
-If $m$ is marked \ASYNC* and the stream $u$ associated with $m$ has been canceled, then let $c$ be the \FINALLY{} clause (\ref{try}) of the innermost enclosing try-finally statement, if any. If $c$ is defined,  let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. If $h$ is undefined, the immediately enclosing function terminates.
-\end{itemize}
+First, the expression $e$ is evaluated to an object $o$. 
 
 \LMHash{}
-If the enclosing function is marked \SYNC* (\ref{functions}) then:
-\begin{itemize}
-\item
-Execution of the function $m$ immediately enclosing $s$ is suspended until the method \code{moveNext()} is invoked upon the iterator used to initiate the current invocation of $m$. 
+If the immediately enclosing function $m$ is marked \SYNC* (\ref{functions}), then:
+\begin{enumerate}
+\item It is a dynamic error if the class of $o$ does not implement \code{Iterable}.  Otherwise
+\item The method \cd{iterator} is invoked upon $o$ returning an object $i$. 
+\item \label{moveNext} The \cd{moveNext} method of $i$ is invoked on it with no arguments. If \cd{moveNext} returns \FALSE{} execution of $s$ is complete. Otherwise
+\item The getter \cd{current} is invoked on $i$. If the invocation raises an exception $ex$, execution of $s$ throws $ex$. Otherwise, the result $x$ of the getter invocation is added to the iterable associated with $m$.
+Execution of the function $m$ immediately enclosing $s$ is suspended until the nullary method \code{moveNext()} is invoked upon the iterator used to initiate the current invocation of $m$, at which point execution of $s$ continues at \ref{moveNext}. 
 \item
 The current call to \code{moveNext()} returns \TRUE.
+\end{enumerate}
+
+\LMHash{}
+If $m$ is marked \ASYNC* (\ref{functions}), then:
+\begin{itemize}
+\item  It is a dynamic error if the class of $o$ does not implement \code{Stream}. Otherwise
+\item For each element $x$ of $o$:
+\begin{itemize}
+\item
+If the stream $u$ associated with $m$ has been paused,  then execution of $m$ is suspended until $u$ is resumed or canceled.
+ \item
+If the stream $u$ associated with $m$ has been canceled, then let $c$ be the \FINALLY{} clause (\ref{try}) of the innermost enclosing try-finally statement, if any. If $c$ is defined,  let $h$ be the handler induced by $c$. If $h$ is defined, control is transferred to $h$. If $h$ is undefined, the immediately enclosing function terminates.
+\item
+Otherwise,  $x$ is added to the stream associated with $m$ in the order it appears in $o$.  The function $m$ may suspend.
 \end{itemize}
+\item If the stream $o$ is done, execution of $s$ is complete. 
+\end{itemize}
+
 
 \LMHash{}
 It is a compile-time error if a yield-each statement appears in a function that is not a generator function.
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 5585838..f0dac74 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -43,7 +43,7 @@
 </style></head>
   <body>
     <h1>Analysis Server API Specification</h1>
-    <h1 style="color:#999999">Version 1.3.0</h1>
+    <h1 style="color:#999999">Version 1.5.0</h1>
     <p>
       This document contains a specification of the API provided by the
       analysis server.  The API in this document is currently under
@@ -227,7 +227,7 @@
       
       
       
-    <h3>Requests</h3><dl><dt class="request">server.getVersion</dt><dd><div class="box"><pre>request: {
+    <h3>Requests</h3><dl><dt class="request"><a name="request_server.getVersion">server.getVersion</a> (<a href="#request_server.getVersion">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "server.getVersion"
 }</pre><br><pre>response: {
@@ -242,7 +242,7 @@
       <h4>Returns</h4><dl><dt class="field"><b><i>version ( String )</i></b></dt><dd>
             
             <p>The version number of the analysis server.</p>
-          </dd></dl></dd><dt class="request">server.shutdown</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_server.shutdown">server.shutdown</a> (<a href="#request_server.shutdown">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "server.shutdown"
 }</pre><br><pre>response: {
@@ -257,7 +257,7 @@
           further responses or notifications will be sent after the
           response to this request has been sent.
         </p>
-      </dd><dt class="request">server.setSubscriptions</dt><dd><div class="box"><pre>request: {
+      </dd><dt class="request"><a name="request_server.setSubscriptions">server.setSubscriptions</a> (<a href="#request_server.setSubscriptions">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "server.setSubscriptions"
   "params": {
@@ -280,7 +280,7 @@
       <h4>Parameters</h4><dl><dt class="field"><b><i>subscriptions ( List&lt;<a href="#type_ServerService">ServerService</a>&gt; )</i></b></dt><dd>
             
             <p>A list of the services being subscribed to.</p>
-          </dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification">server.connected</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification"><a name="notification_server.connected">server.connected</a> (<a href="#notification_server.connected">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "server.connected"
   "params": {
     "<b>version</b>": String
@@ -300,7 +300,7 @@
       <h4>Parameters</h4><dl><dt class="field"><b><i>version ( String )</i></b></dt><dd>
             
             <p>The version number of the analysis server.</p>
-          </dd></dl></dd><dt class="notification">server.error</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd><dt class="notification"><a name="notification_server.error">server.error</a> (<a href="#notification_server.error">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "server.error"
   "params": {
     "<b>isFatal</b>": bool
@@ -340,7 +340,7 @@
               The stack trace associated with the generation of the
               error, used for debugging the server.
             </p>
-          </dd></dl></dd><dt class="notification">server.status</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd><dt class="notification"><a name="notification_server.status">server.status</a> (<a href="#notification_server.status">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "server.status"
   "params": {
     "<b>analysis</b>": <span style="color:#999999">optional</span> <a href="#type_AnalysisStatus">AnalysisStatus</a>
@@ -397,7 +397,7 @@
       
       
       
-    <h3>Requests</h3><dl><dt class="request">analysis.getErrors</dt><dd><div class="box"><pre>request: {
+    <h3>Requests</h3><dl><dt class="request"><a name="request_analysis.getErrors">analysis.getErrors</a> (<a href="#request_analysis.getErrors">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "analysis.getErrors"
   "params": {
@@ -449,7 +449,7 @@
             <p>
               The errors associated with the file.
             </p>
-          </dd></dl></dd><dt class="request">analysis.getHover</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_analysis.getHover">analysis.getHover</a> (<a href="#request_analysis.getHover">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "analysis.getHover"
   "params": {
@@ -491,7 +491,7 @@
               in multiple contexts in conflicting ways (such as a
               part that is included in multiple libraries).
             </p>
-          </dd></dl></dd><dt class="request">analysis.getLibraryDependencies</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_analysis.getLibraryDependencies">analysis.getLibraryDependencies</a> (<a href="#request_analysis.getLibraryDependencies">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "analysis.getLibraryDependencies"
 }</pre><br><pre>response: {
@@ -520,7 +520,7 @@
                 package names to source directories for use in client-side
                 package URI resolution.
               </p>
-            </dd></dl></dd><dt class="request">analysis.getNavigation</dt><dd><div class="box"><pre>request: {
+            </dd></dl></dd><dt class="request"><a name="request_analysis.getNavigation">analysis.getNavigation</a> (<a href="#request_analysis.getNavigation">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "analysis.getNavigation"
   "params": {
@@ -592,7 +592,7 @@
               A list of the navigation regions within the requested region of
               the file.
             </p>
-          </dd></dl></dd><dt class="request">analysis.reanalyze</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_analysis.reanalyze">analysis.reanalyze</a> (<a href="#request_analysis.reanalyze">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "analysis.reanalyze"
   "params": {
@@ -621,7 +621,7 @@
             <p>
               A list of the analysis roots that are to be re-analyzed.
             </p>
-          </dd></dl></dd><dt class="request">analysis.setAnalysisRoots</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_analysis.setAnalysisRoots">analysis.setAnalysisRoots</a> (<a href="#request_analysis.setAnalysisRoots">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "analysis.setAnalysisRoots"
   "params": {
@@ -698,7 +698,7 @@
               or the empty map is specified, that indicates that the
               normal pubspec.yaml mechanism should always be used.
             </p>
-          </dd></dl></dd><dt class="request">analysis.setPriorityFiles</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_analysis.setPriorityFiles">analysis.setPriorityFiles</a> (<a href="#request_analysis.setPriorityFiles">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "analysis.setPriorityFiles"
   "params": {
@@ -739,7 +739,7 @@
             <p>
               The files that are to be a priority for analysis.
             </p>
-          </dd></dl></dd><dt class="request">analysis.setSubscriptions</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_analysis.setSubscriptions">analysis.setSubscriptions</a> (<a href="#request_analysis.setSubscriptions">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "analysis.setSubscriptions"
   "params": {
@@ -789,7 +789,7 @@
               A table mapping services to a list of the files being
               subscribed to the service.
             </p>
-          </dd></dl></dd><dt class="request">analysis.updateContent</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_analysis.updateContent">analysis.updateContent</a> (<a href="#request_analysis.updateContent">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "analysis.updateContent"
   "params": {
@@ -819,7 +819,7 @@
               A table mapping the files whose content has changed to a
               description of the content change.
             </p>
-          </dd></dl><h4>Returns</h4><dl></dl></dd><dt class="request">analysis.updateOptions</dt><dd><div class="box"><pre>request: {
+          </dd></dl><h4>Returns</h4><dl></dl></dd><dt class="request"><a name="request_analysis.updateOptions">analysis.updateOptions</a> (<a href="#request_analysis.updateOptions">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "analysis.updateOptions"
   "params": {
@@ -842,7 +842,7 @@
             <p>
               The options that are to be used to control analysis.
             </p>
-          </dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification">analysis.errors</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification"><a name="notification_analysis.errors">analysis.errors</a> (<a href="#notification_analysis.errors">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "analysis.errors"
   "params": {
     "<b>file</b>": <a href="#type_FilePath">FilePath</a>
@@ -869,7 +869,7 @@
             <p>
               The errors contained in the file.
             </p>
-          </dd></dl></dd><dt class="notification">analysis.flushResults</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd><dt class="notification"><a name="notification_analysis.flushResults">analysis.flushResults</a> (<a href="#notification_analysis.flushResults">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "analysis.flushResults"
   "params": {
     "<b>files</b>": List&lt;<a href="#type_FilePath">FilePath</a>&gt;
@@ -898,7 +898,7 @@
             <p>
               The files that are no longer being analyzed.
             </p>
-          </dd></dl></dd><dt class="notification">analysis.folding</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd><dt class="notification"><a name="notification_analysis.folding">analysis.folding</a> (<a href="#notification_analysis.folding">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "analysis.folding"
   "params": {
     "<b>file</b>": <a href="#type_FilePath">FilePath</a>
@@ -929,7 +929,7 @@
             <p>
               The folding regions contained in the file.
             </p>
-          </dd></dl></dd><dt class="notification">analysis.highlights</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd><dt class="notification"><a name="notification_analysis.highlights">analysis.highlights</a> (<a href="#notification_analysis.highlights">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "analysis.highlights"
   "params": {
     "<b>file</b>": <a href="#type_FilePath">FilePath</a>
@@ -961,7 +961,7 @@
               other highlight regions if there is more than one
               meaning associated with a particular region.
             </p>
-          </dd></dl></dd><dt class="notification">analysis.invalidate</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd><dt class="notification"><a name="notification_analysis.invalidate">analysis.invalidate</a> (<a href="#notification_analysis.invalidate">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "analysis.invalidate"
   "params": {
     "<b>file</b>": <a href="#type_FilePath">FilePath</a>
@@ -1002,7 +1002,7 @@
               the invalidated region in order to update it so that it doesn't
               need to be re-requested.
             </p>
-          </dd></dl></dd><dt class="notification">analysis.navigation</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd><dt class="notification"><a name="notification_analysis.navigation">analysis.navigation</a> (<a href="#notification_analysis.navigation">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "analysis.navigation"
   "params": {
     "<b>file</b>": <a href="#type_FilePath">FilePath</a>
@@ -1054,7 +1054,7 @@
               They are referenced by <tt>NavigationTarget</tt>s by their
               index in this array.
             </p>
-          </dd></dl></dd><dt class="notification">analysis.occurrences</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd><dt class="notification"><a name="notification_analysis.occurrences">analysis.occurrences</a> (<a href="#notification_analysis.occurrences">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "analysis.occurrences"
   "params": {
     "<b>file</b>": <a href="#type_FilePath">FilePath</a>
@@ -1083,7 +1083,7 @@
               The occurrences of references to elements within the
               file.
             </p>
-          </dd></dl></dd><dt class="notification">analysis.outline</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd><dt class="notification"><a name="notification_analysis.outline">analysis.outline</a> (<a href="#notification_analysis.outline">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "analysis.outline"
   "params": {
     "<b>file</b>": <a href="#type_FilePath">FilePath</a>
@@ -1110,7 +1110,7 @@
             <p>
               The outline associated with the file.
             </p>
-          </dd></dl></dd><dt class="notification">analysis.overrides</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd><dt class="notification"><a name="notification_analysis.overrides">analysis.overrides</a> (<a href="#notification_analysis.overrides">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "analysis.overrides"
   "params": {
     "<b>file</b>": <a href="#type_FilePath">FilePath</a>
@@ -1145,7 +1145,7 @@
       </p>
       
       
-    <h3>Requests</h3><dl><dt class="request">completion.getSuggestions</dt><dd><div class="box"><pre>request: {
+    <h3>Requests</h3><dl><dt class="request"><a name="request_completion.getSuggestions">completion.getSuggestions</a> (<a href="#request_completion.getSuggestions">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "completion.getSuggestions"
   "params": {
@@ -1183,7 +1183,7 @@
               The identifier used to associate results with this
               completion request.
             </p>
-          </dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification">completion.results</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification"><a name="notification_completion.results">completion.results</a> (<a href="#notification_completion.results">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "completion.results"
   "params": {
     "<b>id</b>": <a href="#type_CompletionId">CompletionId</a>
@@ -1251,7 +1251,7 @@
       
       
       
-    <h3>Requests</h3><dl><dt class="request">search.findElementReferences</dt><dd><div class="box"><pre>request: {
+    <h3>Requests</h3><dl><dt class="request"><a name="request_search.findElementReferences">search.findElementReferences</a> (<a href="#request_search.findElementReferences">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "search.findElementReferences"
   "params": {
@@ -1318,7 +1318,7 @@
               If no element was found at the given location, this
               field will be absent.
             </p>
-          </dd></dl></dd><dt class="request">search.findMemberDeclarations</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_search.findMemberDeclarations">search.findMemberDeclarations</a> (<a href="#request_search.findMemberDeclarations">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "search.findMemberDeclarations"
   "params": {
@@ -1353,7 +1353,7 @@
               The identifier used to associate results with this
               search request.
             </p>
-          </dd></dl></dd><dt class="request">search.findMemberReferences</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_search.findMemberReferences">search.findMemberReferences</a> (<a href="#request_search.findMemberReferences">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "search.findMemberReferences"
   "params": {
@@ -1390,7 +1390,7 @@
               The identifier used to associate results with this
               search request.
             </p>
-          </dd></dl></dd><dt class="request">search.findTopLevelDeclarations</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_search.findTopLevelDeclarations">search.findTopLevelDeclarations</a> (<a href="#request_search.findTopLevelDeclarations">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "search.findTopLevelDeclarations"
   "params": {
@@ -1427,7 +1427,7 @@
               The identifier used to associate results with this
               search request.
             </p>
-          </dd></dl></dd><dt class="request">search.getTypeHierarchy</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_search.getTypeHierarchy">search.getTypeHierarchy</a> (<a href="#request_search.getTypeHierarchy">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "search.getTypeHierarchy"
   "params": {
@@ -1474,7 +1474,7 @@
               not been sufficiently analyzed to allow a type hierarchy
               to be produced.
             </p>
-          </dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification">search.results</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification"><a name="notification_search.results">search.results</a> (<a href="#notification_search.results">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "search.results"
   "params": {
     "<b>id</b>": <a href="#type_SearchId">SearchId</a>
@@ -1518,7 +1518,7 @@
       
       
       
-    <h3>Requests</h3><dl><dt class="request">edit.format</dt><dd><div class="box"><pre>request: {
+    <h3>Requests</h3><dl><dt class="request"><a name="request_edit.format">edit.format</a> (<a href="#request_edit.format">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "edit.format"
   "params": {
@@ -1585,7 +1585,7 @@
             <p>
               The length of the selection after formatting the code.
             </p>
-          </dd></dl></dd><dt class="request">edit.getAssists</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_edit.getAssists">edit.getAssists</a> (<a href="#request_edit.getAssists">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "edit.getAssists"
   "params": {
@@ -1631,7 +1631,7 @@
             <p>
               The assists that are available at the given location.
             </p>
-          </dd></dl></dd><dt class="request">edit.getAvailableRefactorings</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_edit.getAvailableRefactorings">edit.getAvailableRefactorings</a> (<a href="#request_edit.getAvailableRefactorings">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "edit.getAvailableRefactorings"
   "params": {
@@ -1676,7 +1676,7 @@
               The kinds of refactorings that are valid for the given
               selection.
             </p>
-          </dd></dl></dd><dt class="request">edit.getFixes</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_edit.getFixes">edit.getFixes</a> (<a href="#request_edit.getFixes">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "edit.getFixes"
   "params": {
@@ -1713,7 +1713,7 @@
             <p>
               The fixes that are available for the errors at the given offset.
             </p>
-          </dd></dl></dd><dt class="request">edit.getRefactoring</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_edit.getRefactoring">edit.getRefactoring</a> (<a href="#request_edit.getRefactoring">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "edit.getRefactoring"
   "params": {
@@ -1837,7 +1837,7 @@
               will be omitted if the change field is omitted or if there are no
               potential edits for the refactoring.
             </p>
-          </dd></dl></dd><dt class="request">edit.sortMembers</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_edit.sortMembers">edit.sortMembers</a> (<a href="#request_edit.sortMembers">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "edit.sortMembers"
   "params": {
@@ -1887,7 +1887,7 @@
       
       
       
-    <h3>Requests</h3><dl><dt class="request">execution.createContext</dt><dd><div class="box"><pre>request: {
+    <h3>Requests</h3><dl><dt class="request"><a name="request_execution.createContext">execution.createContext</a> (<a href="#request_execution.createContext">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "execution.createContext"
   "params": {
@@ -1920,7 +1920,7 @@
               The identifier used to refer to the execution context that was
               created.
             </p>
-          </dd></dl></dd><dt class="request">execution.deleteContext</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_execution.deleteContext">execution.deleteContext</a> (<a href="#request_execution.deleteContext">#</a>)</dt><dd><div class="box"><pre>request: {
   "<b>id</b>": String
   "method": "execution.deleteContext"
   "params": {
@@ -1941,7 +1941,7 @@
             <p>
               The identifier of the execution context that is to be deleted.
             </p>
-          </dd></dl></dd><dt class="request">execution.mapUri</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_execution.mapUri">execution.mapUri</a> (<a href="#request_execution.mapUri">#</a>)</dt><dd><div class="box"><pre>request: {
   "<b>id</b>": String
   "method": "execution.mapUri"
   "params": {
@@ -2015,7 +2015,7 @@
               The URI to which the file path was mapped. This field is omitted
               if the file field was not given in the request.
             </p>
-          </dd></dl></dd><dt class="request">execution.setSubscriptions</dt><dd><div class="box"><pre>request: {
+          </dd></dl></dd><dt class="request"><a name="request_execution.setSubscriptions">execution.setSubscriptions</a> (<a href="#request_execution.setSubscriptions">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "execution.setSubscriptions"
   "params": {
@@ -2040,7 +2040,7 @@
             <p>
               A list of the services being subscribed to.
             </p>
-          </dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification">execution.launchData</dt><dd><div class="box"><pre>notification: {
+          </dd></dl></dd></dl><h3>Notifications</h3><dl><dt class="notification"><a name="notification_execution.launchData">execution.launchData</a> (<a href="#notification_execution.launchData">#</a>)</dt><dd><div class="box"><pre>notification: {
   "event": "execution.launchData"
   "params": {
     "<b>file</b>": <a href="#type_FilePath">FilePath</a>
@@ -2528,6 +2528,12 @@
               element does not have a declared return type, this field
               will contain an empty string.
             </p>
+          </dd><dt class="field"><b><i>typeParameters ( <span style="color:#999999">optional</span> String )</i></b></dt><dd>
+            
+            <p>
+              The type parameter list for the element. If the element doesn't
+              have type parameters, this field will not be defined.
+            </p>
           </dd></dl></dd><dt class="typeDefinition"><a name="type_ElementKind">ElementKind: String</a></dt><dd>
         <p>
           An enumeration of the kinds of elements.
@@ -2656,6 +2662,13 @@
               element, or if the element is declared inside an HTML
               file.
             </p>
+          </dd><dt class="field"><b><i>containingClassDescription ( <span style="color:#999999">optional</span> String )</i></b></dt><dd>
+            
+            <p>
+              A human-readable description of the class declaring the element
+              being referenced. This data is omitted if there is no referenced
+              element, or if the element is not a class member.
+            </p>
           </dd><dt class="field"><b><i>dartdoc ( <span style="color:#999999">optional</span> String )</i></b></dt><dd>
             
             <p>
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index f699bdc..bad954c 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -20,6 +20,7 @@
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/plugin/plugin.dart';
 import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
@@ -65,7 +66,7 @@
    * The version of the analysis server. The value should be replaced
    * automatically during the build.
    */
-  static final String VERSION = '1.3.0';
+  static final String VERSION = '1.5.0';
 
   /**
    * The number of milliseconds to perform operations before inserting
@@ -234,6 +235,11 @@
   final ContentCache overlayState = new ContentCache();
 
   /**
+   * The plugins that are defined outside the analysis_server package.
+   */
+  List<Plugin> userDefinedPlugins;
+
+  /**
    * Initialize a newly created server to receive requests from and send
    * responses to the given [channel].
    *
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 2c98c84..0491336 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -168,7 +168,7 @@
       Element enclosingElement = element.enclosingElement;
       if (enclosingElement is ClassElement && enclosingElement.isEnum) {
         type = HighlightRegionType.ENUM_CONSTANT;
-      } else if ((element as FieldElement).isStatic) {
+      } else if (element.isStatic) {
         type = HighlightRegionType.FIELD_STATIC;
       } else {
         type = HighlightRegionType.FIELD;
diff --git a/pkg/analysis_server/lib/src/computer/computer_hover.dart b/pkg/analysis_server/lib/src/computer/computer_hover.dart
index 9cc2f41..aad7ca3 100644
--- a/pkg/analysis_server/lib/src/computer/computer_hover.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_hover.dart
@@ -95,7 +95,13 @@
         // description
         hover.elementDescription = element.toString();
         hover.elementKind = element.kind.displayName;
-        // library
+        // containing class
+        ClassElement containingClass =
+            element.getAncestor((e) => e is ClassElement);
+        if (containingClass != null) {
+          hover.containingClassDescription = containingClass.toString();
+        }
+        // containing library
         LibraryElement library = element.library;
         if (library != null) {
           hover.containingLibraryName = library.name;
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index c8351df..81e9b50 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -138,11 +138,10 @@
     // unit or class member
     if (parent is CompilationUnit) {
       firstOffset = 0;
-      siblings = (parent as CompilationUnit).declarations;
+      siblings = parent.declarations;
     } else if (parent is ClassDeclaration) {
-      ClassDeclaration classDeclaration = parent as ClassDeclaration;
-      firstOffset = classDeclaration.leftBracket.end;
-      siblings = classDeclaration.members;
+      firstOffset = parent.leftBracket.end;
+      siblings = parent.members;
     } else {
       int offset = node.offset;
       return new _SourceRegion(offset, endOffset - offset);
@@ -157,30 +156,31 @@
     return new _SourceRegion(prevSiblingEnd, endOffset - prevSiblingEnd);
   }
 
-  Outline _newClassOutline(
-      ClassDeclaration classDeclaration, List<Outline> classContents) {
-    SimpleIdentifier nameNode = classDeclaration.name;
+  Outline _newClassOutline(ClassDeclaration node, List<Outline> classContents) {
+    SimpleIdentifier nameNode = node.name;
     String name = nameNode.name;
-    _SourceRegion sourceRegion = _getSourceRegion(classDeclaration);
+    _SourceRegion sourceRegion = _getSourceRegion(node);
     Element element = new Element(ElementKind.CLASS, name, Element.makeFlags(
             isPrivate: Identifier.isPrivateName(name),
-            isDeprecated: _isDeprecated(classDeclaration),
-            isAbstract: classDeclaration.isAbstract),
-        location: _getLocationNode(nameNode));
+            isDeprecated: _isDeprecated(node),
+            isAbstract: node.isAbstract),
+        location: _getLocationNode(nameNode),
+        typeParameters: _getTypeParametersStr(node.typeParameters));
     return new Outline(element, sourceRegion.offset, sourceRegion.length,
         children: nullIfEmpty(classContents));
   }
 
-  Outline _newClassTypeAlias(ClassTypeAlias alias) {
-    SimpleIdentifier nameNode = alias.name;
+  Outline _newClassTypeAlias(ClassTypeAlias node) {
+    SimpleIdentifier nameNode = node.name;
     String name = nameNode.name;
-    _SourceRegion sourceRegion = _getSourceRegion(alias);
+    _SourceRegion sourceRegion = _getSourceRegion(node);
     Element element = new Element(ElementKind.CLASS_TYPE_ALIAS, name, Element
             .makeFlags(
                 isPrivate: Identifier.isPrivateName(name),
-                isDeprecated: _isDeprecated(alias),
-                isAbstract: alias.isAbstract),
-        location: _getLocationNode(nameNode));
+                isDeprecated: _isDeprecated(node),
+                isAbstract: node.isAbstract),
+        location: _getLocationNode(nameNode),
+        typeParameters: _getTypeParametersStr(node.typeParameters));
     return new Outline(element, sourceRegion.offset, sourceRegion.length);
   }
 
@@ -268,21 +268,22 @@
     return outline;
   }
 
-  Outline _newFunctionTypeAliasOutline(FunctionTypeAlias alias) {
-    TypeName returnType = alias.returnType;
-    SimpleIdentifier nameNode = alias.name;
+  Outline _newFunctionTypeAliasOutline(FunctionTypeAlias node) {
+    TypeName returnType = node.returnType;
+    SimpleIdentifier nameNode = node.name;
     String name = nameNode.name;
-    _SourceRegion sourceRegion = _getSourceRegion(alias);
-    FormalParameterList parameters = alias.parameters;
+    _SourceRegion sourceRegion = _getSourceRegion(node);
+    FormalParameterList parameters = node.parameters;
     String parametersStr = parameters != null ? parameters.toSource() : '';
     String returnTypeStr = returnType != null ? returnType.toSource() : '';
     Element element = new Element(ElementKind.FUNCTION_TYPE_ALIAS, name, Element
             .makeFlags(
                 isPrivate: Identifier.isPrivateName(name),
-                isDeprecated: _isDeprecated(alias)),
+                isDeprecated: _isDeprecated(node)),
         location: _getLocationNode(nameNode),
         parameters: parametersStr,
-        returnType: returnTypeStr);
+        returnType: returnTypeStr,
+        typeParameters: _getTypeParametersStr(node.typeParameters));
     return new Outline(element, sourceRegion.offset, sourceRegion.length);
   }
 
@@ -325,6 +326,13 @@
         children: nullIfEmpty(unitContents));
   }
 
+  static String _getTypeParametersStr(TypeParameterList parameters) {
+    if (parameters == null) {
+      return null;
+    }
+    return parameters.toSource();
+  }
+
   Outline _newVariableOutline(String typeName, ElementKind kind,
       VariableDeclaration variable, bool isStatic) {
     SimpleIdentifier nameNode = variable.name;
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index d715b6b..058662c 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -18,7 +18,6 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:path/path.dart' as pathos;
 import 'package:watcher/watcher.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
 
 /**
  * The name of `packages` folders.
@@ -134,7 +133,7 @@
         }
       }
     }
-    return flushedFiles.toList(growable:false);
+    return flushedFiles.toList(growable: false);
   }
 
   /**
@@ -286,7 +285,7 @@
     List<Resource> children;
     try {
       children = folder.getChildren();
-    } on FileSystemException catch (exception) {
+    } on FileSystemException {
       // The folder no longer exists, or cannot be read, to there's nothing to
       // do.
       return;
@@ -656,9 +655,6 @@
     if (context == null) {
       return source;
     }
-    if (context.sourceFactory == null) {
-      return null;
-    }
     Uri uri = context.sourceFactory.restoreUri(source);
     return file.createSource(uri);
   }
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index 08ff54e..59d70af 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -154,10 +154,7 @@
     ServerPerformanceStatistics.executionNotifications.makeCurrentWhile(() {
       Source source = notice.source;
       String filePath = source.fullName;
-      if (!_isInAnalysisRoot(filePath)) {
-        return;
-      }
-      AnalysisContext context = server.getAnalysisContext(filePath);
+      AnalysisContext context = server.getContainingContext(filePath);
       if (context == null) {
         return;
       }
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index edf92e7..9d4c7df 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -491,7 +491,7 @@
       engine.AnalysisContext context = contextSource.context;
       Source source = contextSource.source;
       refactoring = new MoveFileRefactoring(
-          server.resourceProvider.pathContext, searchEngine, context, source);
+          server.resourceProvider, searchEngine, context, source, file);
     }
     if (kind == RefactoringKind.RENAME) {
       List<AstNode> nodes = server.getNodesAtOffset(file, offset);
diff --git a/pkg/analysis_server/lib/src/generated_protocol.dart b/pkg/analysis_server/lib/src/generated_protocol.dart
index 844635f..bbd7572 100644
--- a/pkg/analysis_server/lib/src/generated_protocol.dart
+++ b/pkg/analysis_server/lib/src/generated_protocol.dart
@@ -6432,6 +6432,7 @@
  *   "flags": int
  *   "parameters": optional String
  *   "returnType": optional String
+ *   "typeParameters": optional String
  * }
  */
 class Element implements HasToJson {
@@ -6497,7 +6498,13 @@
    */
   String returnType;
 
-  Element(this.kind, this.name, this.flags, {this.location, this.parameters, this.returnType});
+  /**
+   * The type parameter list for the element. If the element doesn't have type
+   * parameters, this field will not be defined.
+   */
+  String typeParameters;
+
+  Element(this.kind, this.name, this.flags, {this.location, this.parameters, this.returnType, this.typeParameters});
 
   factory Element.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
     if (json == null) {
@@ -6534,7 +6541,11 @@
       if (json.containsKey("returnType")) {
         returnType = jsonDecoder._decodeString(jsonPath + ".returnType", json["returnType"]);
       }
-      return new Element(kind, name, flags, location: location, parameters: parameters, returnType: returnType);
+      String typeParameters;
+      if (json.containsKey("typeParameters")) {
+        typeParameters = jsonDecoder._decodeString(jsonPath + ".typeParameters", json["typeParameters"]);
+      }
+      return new Element(kind, name, flags, location: location, parameters: parameters, returnType: returnType, typeParameters: typeParameters);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "Element");
     }
@@ -6561,6 +6572,9 @@
     if (returnType != null) {
       result["returnType"] = returnType;
     }
+    if (typeParameters != null) {
+      result["typeParameters"] = typeParameters;
+    }
     return result;
   }
 
@@ -6575,7 +6589,8 @@
           location == other.location &&
           flags == other.flags &&
           parameters == other.parameters &&
-          returnType == other.returnType;
+          returnType == other.returnType &&
+          typeParameters == other.typeParameters;
     }
     return false;
   }
@@ -6589,6 +6604,7 @@
     hash = _JenkinsSmiHash.combine(hash, flags.hashCode);
     hash = _JenkinsSmiHash.combine(hash, parameters.hashCode);
     hash = _JenkinsSmiHash.combine(hash, returnType.hashCode);
+    hash = _JenkinsSmiHash.combine(hash, typeParameters.hashCode);
     return _JenkinsSmiHash.finish(hash);
   }
 }
@@ -7392,6 +7408,7 @@
  *   "length": int
  *   "containingLibraryPath": optional String
  *   "containingLibraryName": optional String
+ *   "containingClassDescription": optional String
  *   "dartdoc": optional String
  *   "elementDescription": optional String
  *   "elementKind": optional String
@@ -7428,6 +7445,13 @@
   String containingLibraryName;
 
   /**
+   * A human-readable description of the class declaring the element being
+   * referenced. This data is omitted if there is no referenced element, or if
+   * the element is not a class member.
+   */
+  String containingClassDescription;
+
+  /**
    * The dartdoc associated with the referenced element. Other than the removal
    * of the comment delimiters, including leading asterisks in the case of a
    * block comment, the dartdoc is unprocessed markdown. This data is omitted
@@ -7468,7 +7492,7 @@
    */
   String staticType;
 
-  HoverInformation(this.offset, this.length, {this.containingLibraryPath, this.containingLibraryName, this.dartdoc, this.elementDescription, this.elementKind, this.parameter, this.propagatedType, this.staticType});
+  HoverInformation(this.offset, this.length, {this.containingLibraryPath, this.containingLibraryName, this.containingClassDescription, this.dartdoc, this.elementDescription, this.elementKind, this.parameter, this.propagatedType, this.staticType});
 
   factory HoverInformation.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
     if (json == null) {
@@ -7495,6 +7519,10 @@
       if (json.containsKey("containingLibraryName")) {
         containingLibraryName = jsonDecoder._decodeString(jsonPath + ".containingLibraryName", json["containingLibraryName"]);
       }
+      String containingClassDescription;
+      if (json.containsKey("containingClassDescription")) {
+        containingClassDescription = jsonDecoder._decodeString(jsonPath + ".containingClassDescription", json["containingClassDescription"]);
+      }
       String dartdoc;
       if (json.containsKey("dartdoc")) {
         dartdoc = jsonDecoder._decodeString(jsonPath + ".dartdoc", json["dartdoc"]);
@@ -7519,7 +7547,7 @@
       if (json.containsKey("staticType")) {
         staticType = jsonDecoder._decodeString(jsonPath + ".staticType", json["staticType"]);
       }
-      return new HoverInformation(offset, length, containingLibraryPath: containingLibraryPath, containingLibraryName: containingLibraryName, dartdoc: dartdoc, elementDescription: elementDescription, elementKind: elementKind, parameter: parameter, propagatedType: propagatedType, staticType: staticType);
+      return new HoverInformation(offset, length, containingLibraryPath: containingLibraryPath, containingLibraryName: containingLibraryName, containingClassDescription: containingClassDescription, dartdoc: dartdoc, elementDescription: elementDescription, elementKind: elementKind, parameter: parameter, propagatedType: propagatedType, staticType: staticType);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "HoverInformation");
     }
@@ -7535,6 +7563,9 @@
     if (containingLibraryName != null) {
       result["containingLibraryName"] = containingLibraryName;
     }
+    if (containingClassDescription != null) {
+      result["containingClassDescription"] = containingClassDescription;
+    }
     if (dartdoc != null) {
       result["dartdoc"] = dartdoc;
     }
@@ -7566,6 +7597,7 @@
           length == other.length &&
           containingLibraryPath == other.containingLibraryPath &&
           containingLibraryName == other.containingLibraryName &&
+          containingClassDescription == other.containingClassDescription &&
           dartdoc == other.dartdoc &&
           elementDescription == other.elementDescription &&
           elementKind == other.elementKind &&
@@ -7583,6 +7615,7 @@
     hash = _JenkinsSmiHash.combine(hash, length.hashCode);
     hash = _JenkinsSmiHash.combine(hash, containingLibraryPath.hashCode);
     hash = _JenkinsSmiHash.combine(hash, containingLibraryName.hashCode);
+    hash = _JenkinsSmiHash.combine(hash, containingClassDescription.hashCode);
     hash = _JenkinsSmiHash.combine(hash, dartdoc.hashCode);
     hash = _JenkinsSmiHash.combine(hash, elementDescription.hashCode);
     hash = _JenkinsSmiHash.combine(hash, elementKind.hashCode);
diff --git a/pkg/analysis_server/lib/src/get_handler.dart b/pkg/analysis_server/lib/src/get_handler.dart
index d4f6a7a..fffe9ad 100644
--- a/pkg/analysis_server/lib/src/get_handler.dart
+++ b/pkg/analysis_server/lib/src/get_handler.dart
@@ -10,6 +10,7 @@
 import 'dart:io';
 import 'dart:math';
 
+import 'package:analyzer/plugin/plugin.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_completion.dart';
 import 'package:analysis_server/src/domain_execution.dart';
@@ -402,8 +403,8 @@
 
     List<Folder> allContexts = <Folder>[];
     Map<Folder, SourceEntry> entryMap = new HashMap<Folder, SourceEntry>();
-    analysisServer.folderMap.forEach(
-        (Folder folder, AnalysisContextImpl context) {
+    analysisServer.folderMap
+        .forEach((Folder folder, AnalysisContextImpl context) {
       Source source = context.sourceFactory.forUri(sourceUri);
       if (source != null) {
         SourceEntry entry = context.getReadableSourceEntryOrNull(source);
@@ -459,8 +460,8 @@
         };
 
         buffer.write('<h3>Library Independent</h3>');
-        _writeDescriptorTable(buffer,
-            entry.descriptors, entry.getState, entry.getValue, linkParameters);
+        _writeDescriptorTable(buffer, entry.descriptors, entry.getState,
+            entry.getValue, linkParameters);
         if (entry is DartEntry) {
           for (Source librarySource in entry.containingLibraries) {
             String libraryName = HTML_ESCAPE.convert(librarySource.fullName);
@@ -575,8 +576,8 @@
               : 0;
           buffer.write('<h4>Startup</h4>');
           buffer.write('<table>');
-          _writeRow(
-              buffer, [requestCount, 'requests'], classes: ["right", null]);
+          _writeRow(buffer, [requestCount, 'requests'],
+              classes: ["right", null]);
           _writeRow(buffer, [averageLatency, 'ms average latency'],
               classes: ["right", null]);
           _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
@@ -605,8 +606,8 @@
               : 0;
           buffer.write('<h4>Current</h4>');
           buffer.write('<table>');
-          _writeRow(
-              buffer, [requestCount, 'requests'], classes: ["right", null]);
+          _writeRow(buffer, [requestCount, 'requests'],
+              classes: ["right", null]);
           _writeRow(buffer, [averageLatency, 'ms average latency'],
               classes: ["right", null]);
           _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
@@ -712,9 +713,8 @@
     }
 
     _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Context', [
-        'Context: $contextFilter'
-      ], (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Context',
+          ['Context: $contextFilter'], (StringBuffer buffer) {
         List headerRowText = ['Context'];
         headerRowText.addAll(CacheState.values);
         buffer.write('<h3>Summary</h3>');
@@ -833,14 +833,13 @@
       Map<List<String>, List<InspectLocation>> relations =
           await index.findElementsByName(name);
       _writeResponse(request, (StringBuffer buffer) {
-        _writePage(buffer, 'Analysis Server - Index Elements', [
-          'Name: $name'
-        ], (StringBuffer buffer) {
+        _writePage(buffer, 'Analysis Server - Index Elements', ['Name: $name'],
+            (StringBuffer buffer) {
           buffer.write('<table border="1">');
           _writeRow(buffer, ['Element', 'Relationship', 'Location'],
               header: true);
-          relations.forEach(
-              (List<String> elementPath, List<InspectLocation> relations) {
+          relations.forEach((List<String> elementPath,
+              List<InspectLocation> relations) {
             String elementLocation = elementPath.join(' ');
             relations.forEach((InspectLocation location) {
               var relString = location.relationship.identifier;
@@ -912,6 +911,7 @@
           _writeAnalysisStatus(buffer);
           _writeEditStatus(buffer);
           _writeExecutionStatus(buffer);
+          _writePluginStatus(buffer);
           _writeRecentOutput(buffer);
         }
       });
@@ -1007,6 +1007,8 @@
       _writeOption(
           buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
       _writeOption(buffer, 'Cache size', options.cacheSize);
+      _writeOption(
+          buffer, 'Enable strict call checks', options.enableStrictCallChecks);
       _writeOption(buffer, 'Generate hints', options.hint);
       _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
       _writeOption(buffer, 'Generate errors in implicit files',
@@ -1016,8 +1018,8 @@
       _writeOption(buffer, 'Incremental resolution', options.incremental);
       _writeOption(buffer, 'Incremental resolution with API changes',
           options.incrementalApi);
-      _writeOption(
-          buffer, 'Preserve comments', options.preserveComments, last: true);
+      _writeOption(buffer, 'Preserve comments', options.preserveComments,
+          last: true);
       buffer.write('</p>');
       int freq = AnalysisServer.performOperationDelayFreqency;
       String delay = freq > 0 ? '1 ms every $freq ms' : 'off';
@@ -1313,6 +1315,26 @@
    * Write the recent output section (on the main status page) to the given
    * [buffer] object.
    */
+  void _writePluginStatus(StringBuffer buffer) {
+    void writePlugin(Plugin plugin) {
+      buffer.write(_server.serverPlugin.uniqueIdentifier);
+      buffer.write(' (');
+      buffer.write(_server.serverPlugin.runtimeType);
+      buffer.write(')<br>');
+    }
+    buffer.write('<h3>Plugin Status</h3><p>');
+    writePlugin(AnalysisEngine.instance.enginePlugin);
+    writePlugin(_server.serverPlugin);
+    for (Plugin plugin in _server.analysisServer.userDefinedPlugins) {
+      writePlugin(plugin);
+    }
+    buffer.write('<p>');
+  }
+
+  /**
+   * Write the recent output section (on the main status page) to the given
+   * [buffer] object.
+   */
   void _writeRecentOutput(StringBuffer buffer) {
     buffer.write('<h3>Recent Output</h3>');
     String output = HTML_ESCAPE.convert(_printBuffer.join('\n'));
diff --git a/pkg/analysis_server/lib/src/plugin/server_plugin.dart b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
index faeecc4..b74fb7f 100644
--- a/pkg/analysis_server/lib/src/plugin/server_plugin.dart
+++ b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
@@ -4,7 +4,6 @@
 
 library analysis_server.src.plugin.server_plugin;
 
-import 'package:analysis_server/plugin/plugin.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
 import 'package:analysis_server/src/domain_completion.dart';
@@ -13,12 +12,11 @@
 import 'package:analysis_server/src/edit/edit_domain.dart';
 import 'package:analysis_server/src/protocol.dart';
 import 'package:analysis_server/src/search/search_domain.dart';
+import 'package:analyzer/plugin/plugin.dart';
 
 /**
  * A function that will create a request handler that can be used by the given
  * [server].
- *
- * TODO(brianwilkerson) Move this into 'protocol.dart'.
  */
 typedef RequestHandler RequestHandlerFactory(AnalysisServer server);
 
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 7618308..f5c5806 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -84,6 +84,7 @@
  */
 Element newElement_fromEngine(engine.Element element) {
   String name = element.displayName;
+  String elementTypeParameters = _getTypeParametersString(element);
   String elementParameters = _getParametersString(element);
   String elementReturnType = _getReturnTypeString(element);
   return new Element(newElementKind_fromEngine(element.kind), name, Element
@@ -95,6 +96,7 @@
               isFinal: _isFinal(element),
               isStatic: _isStatic(element)),
       location: newLocation_fromElement(element),
+      typeParameters: elementTypeParameters,
       parameters: elementParameters,
       returnType: elementReturnType);
 }
@@ -351,6 +353,19 @@
   }
 }
 
+String _getTypeParametersString(engine.Element element) {
+  List<engine.TypeParameterElement> typeParameters;
+  if (element is engine.ClassElement) {
+    typeParameters = element.typeParameters;
+  } else if (element is engine.FunctionTypeAliasElement) {
+    typeParameters = element.typeParameters;
+  }
+  if (typeParameters == null || typeParameters.isEmpty) {
+    return null;
+  }
+  return '<${typeParameters.join(', ')}>';
+}
+
 bool _isAbstract(engine.Element element) {
   // TODO(scheglov) add isAbstract to Element API
   if (element is engine.ClassElement) {
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index c09c6c9..bc7c17b 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -8,9 +8,7 @@
 import 'dart:io';
 import 'dart:math';
 
-import 'package:analysis_server/plugin/plugin.dart';
 import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/plugin/plugin_impl.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/server/http_server.dart';
 import 'package:analysis_server/src/server/stdio_server.dart';
@@ -19,12 +17,14 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/file_instrumentation.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/options.dart';
+import 'package:analyzer/plugin/plugin.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/incremental_logger.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/sdk_io.dart';
-import 'package:analyzer/options.dart';
+import 'package:analyzer/src/plugin/plugin_impl.dart';
 import 'package:args/args.dart';
 
 /**
@@ -262,6 +262,7 @@
     //
     ServerPlugin serverPlugin = new ServerPlugin();
     List<Plugin> plugins = <Plugin>[];
+    plugins.add(AnalysisEngine.instance.enginePlugin);
     plugins.add(serverPlugin);
     plugins.addAll(_userDefinedPlugins);
     ExtensionManager manager = new ExtensionManager();
@@ -271,6 +272,7 @@
         analysisServerOptions, defaultSdk, service, serverPlugin);
     httpServer = new HttpAnalysisServer(socketServer);
     stdioServer = new StdioAnalysisServer(socketServer);
+    socketServer.userDefinedPlugins = _userDefinedPlugins;
 
     if (serve_http) {
       httpServer.serveHttp(port);
diff --git a/pkg/analysis_server/lib/src/services/completion/local_computer.dart b/pkg/analysis_server/lib/src/services/completion/local_computer.dart
index 028b116..5602d81 100644
--- a/pkg/analysis_server/lib/src/services/completion/local_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/local_computer.dart
@@ -429,6 +429,11 @@
   final DartCompletionRequest request;
   final OpType optype;
 
+  /**
+   * The simple identifier that is being completed, or `null` if none.
+   */
+  SimpleIdentifier targetId;
+
   _LocalVisitor(this.request, int offset, this.optype) : super(offset);
 
   @override
@@ -626,6 +631,13 @@
     }
   }
 
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    // Record the visited identifier so as not to suggest it
+    targetId = node;
+    return super.visitSimpleIdentifier(node);
+  }
+
   void _addParameterInfo(
       CompletionSuggestion suggestion, FormalParameterList parameters) {
     var paramList = parameters.parameters;
@@ -664,7 +676,7 @@
 
   CompletionSuggestion _addSuggestion(SimpleIdentifier id, TypeName returnType,
       bool isDeprecated, int defaultRelevance, {ClassDeclaration classDecl}) {
-    if (id != null) {
+    if (id != null && !identical(id, targetId)) {
       String completion = id.name;
       if (completion != null && completion.length > 0 && completion != '_') {
         CompletionSuggestion suggestion = new CompletionSuggestion(
diff --git a/pkg/analysis_server/lib/src/services/completion/optype.dart b/pkg/analysis_server/lib/src/services/completion/optype.dart
index 72c6e22..83ef718 100644
--- a/pkg/analysis_server/lib/src/services/completion/optype.dart
+++ b/pkg/analysis_server/lib/src/services/completion/optype.dart
@@ -139,22 +139,6 @@
   @override
   void visitBinaryExpression(BinaryExpression node) {
     if (identical(entity, node.rightOperand)) {
-      // An empty type argument list is parsed as a binary expression
-      // `C<>` is parsed as `C < `
-      Object entity = this.entity;
-      if (entity is SimpleIdentifier && entity.isSynthetic) {
-        Token operator = node.operator;
-        if (operator != null && operator.lexeme == '<') {
-          Token next = entity.token.next;
-          if (next is StringToken && next.lexeme.length == 0) {
-            next = next.next;
-          }
-          if (next != null && next.lexeme == '>') {
-            optype.includeTypeNameSuggestions = true;
-            return;
-          }
-        }
-      }
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
@@ -336,6 +320,12 @@
   }
 
   @override
+  void visitFunctionExpression(FunctionExpression node) {}
+
+  @override
+  void visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {}
+
+  @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
     if (identical(entity, node.returnType) ||
         identical(entity, node.name) && node.returnType == null) {
@@ -448,6 +438,12 @@
   }
 
   @override
+  void visitPostfixExpression(PostfixExpression node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
   void visitPrefixedIdentifier(PrefixedIdentifier node) {
     if (identical(entity, node.identifier)) {
       optype.includeInvocationSuggestions = true;
@@ -512,6 +508,12 @@
   }
 
   @override
+  void visitThrowExpression(ThrowExpression node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
   void visitTypeArgumentList(TypeArgumentList node) {
     NodeList<TypeName> arguments = node.arguments;
     for (TypeName typeName in arguments) {
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 5054644..f71a98f 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -51,6 +51,8 @@
       'CONVERT_INTO_BLOCK_BODY', 30, "Convert into block body");
   static const CONVERT_INTO_EXPRESSION_BODY = const AssistKind(
       'CONVERT_INTO_EXPRESSION_BODY', 30, "Convert into expression body");
+  static const CONVERT_INTO_FOR_INDEX = const AssistKind(
+      'CONVERT_INTO_FOR_INDEX', 30, "Convert into for-index loop");
   static const CONVERT_INTO_IS_NOT =
       const AssistKind('CONVERT_INTO_IS_NOT', 30, "Convert into is!");
   static const CONVERT_INTO_IS_NOT_EMPTY = const AssistKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 525a198..63287c4 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -81,6 +81,7 @@
     _addProposal_assignToLocalVariable();
     _addProposal_convertToBlockFunctionBody();
     _addProposal_convertToExpressionFunctionBody();
+    _addProposal_convertToForIndexLoop();
     _addProposal_convertToIsNot_onIs();
     _addProposal_convertToIsNot_onNot();
     _addProposal_convertToIsNotEmpty();
@@ -203,6 +204,11 @@
       _coverageMarker();
       return;
     }
+    // type source might be null, if the type is private
+    if (typeSource == null) {
+      _coverageMarker();
+      return;
+    }
     // add edit
     Token keyword = declaredIdentifier.keyword;
     if (keyword is KeywordToken && keyword.keyword == Keyword.VAR) {
@@ -215,6 +221,49 @@
     _addAssist(AssistKind.ADD_TYPE_ANNOTATION, []);
   }
 
+  void _addProposal_addTypeAnnotation_SimpleFormalParameter() {
+    AstNode node = this.node;
+    // should be the name of a simple parameter
+    if (node is! SimpleIdentifier || node.parent is! SimpleFormalParameter) {
+      _coverageMarker();
+      return;
+    }
+    SimpleIdentifier name = node;
+    SimpleFormalParameter parameter = node.parent;
+    // the parameter should not have a type
+    if (parameter.type != null) {
+      _coverageMarker();
+      return;
+    }
+    // prepare propagated type
+    DartType type = name.propagatedType;
+    // TODO(scheglov) If the parameter is in a method declaration, and if the
+    // method overrides a method that has a type for the corresponding
+    // parameter, it would be nice to copy down the type from the overridden
+    // method.
+    if (type is! InterfaceType) {
+      _coverageMarker();
+      return;
+    }
+    // prepare type source
+    String typeSource;
+    {
+      _configureTargetLocation(node);
+      Set<LibraryElement> librariesToImport = new Set<LibraryElement>();
+      typeSource = utils.getTypeSource(type, librariesToImport);
+      addLibraryImports(change, unitLibraryElement, librariesToImport);
+    }
+    // type source might be null, if the type is private
+    if (typeSource == null) {
+      _coverageMarker();
+      return;
+    }
+    // add edit
+    _addInsertEdit(name.offset, '$typeSource ');
+    // add proposal
+    _addAssist(AssistKind.ADD_TYPE_ANNOTATION, []);
+  }
+
   void _addProposal_addTypeAnnotation_VariableDeclaration() {
     AstNode node = this.node;
     // check if "var v = 42;^"
@@ -258,6 +307,11 @@
       _coverageMarker();
       return;
     }
+    // type source might be null, if the type is private
+    if (typeSource == null) {
+      _coverageMarker();
+      return;
+    }
     // add edit
     Token keyword = declarationList.keyword;
     if (keyword is KeywordToken && keyword.keyword == Keyword.VAR) {
@@ -270,44 +324,6 @@
     _addAssist(AssistKind.ADD_TYPE_ANNOTATION, []);
   }
 
-  void _addProposal_addTypeAnnotation_SimpleFormalParameter() {
-    AstNode node = this.node;
-    // should be the name of a simple parameter
-    if (node is! SimpleIdentifier || node.parent is! SimpleFormalParameter) {
-      _coverageMarker();
-      return;
-    }
-    SimpleIdentifier name = node;
-    SimpleFormalParameter parameter = node.parent;
-    // the parameter should not have a type
-    if (parameter.type != null) {
-      _coverageMarker();
-      return;
-    }
-    // prepare propagated type
-    DartType type = name.propagatedType;
-    // TODO(scheglov) If the parameter is in a method declaration, and if the
-    // method overrides a method that has a type for the corresponding
-    // parameter, it would be nice to copy down the type from the overridden
-    // method.
-    if (type is! InterfaceType) {
-      _coverageMarker();
-      return;
-    }
-    // prepare type source
-    String typeSource;
-    {
-      _configureTargetLocation(node);
-      Set<LibraryElement> librariesToImport = new Set<LibraryElement>();
-      typeSource = utils.getTypeSource(type, librariesToImport);
-      addLibraryImports(change, unitLibraryElement, librariesToImport);
-    }
-    // add edit
-    _addInsertEdit(name.offset, '$typeSource ');
-    // add proposal
-    _addAssist(AssistKind.ADD_TYPE_ANNOTATION, []);
-  }
-
   void _addProposal_assignToLocalVariable() {
     // prepare enclosing ExpressionStatement
     Statement statement = node.getAncestor((node) => node is Statement);
@@ -424,6 +440,81 @@
     _addAssist(AssistKind.CONVERT_INTO_EXPRESSION_BODY, []);
   }
 
+  void _addProposal_convertToForIndexLoop() {
+    // find enclosing ForEachStatement
+    ForEachStatement forEachStatement =
+        node.getAncestor((n) => n is ForEachStatement);
+    if (forEachStatement == null) {
+      _coverageMarker();
+      return;
+    }
+    if (selectionOffset < forEachStatement.offset ||
+        forEachStatement.rightParenthesis.end < selectionOffset) {
+      _coverageMarker();
+      return;
+    }
+    // loop should declare variable
+    DeclaredIdentifier loopVariable = forEachStatement.loopVariable;
+    if (loopVariable == null) {
+      _coverageMarker();
+      return;
+    }
+    // iterable should be VariableElement
+    String listName;
+    Expression iterable = forEachStatement.iterable;
+    if (iterable is SimpleIdentifier &&
+        iterable.staticElement is VariableElement) {
+      listName = iterable.name;
+    } else {
+      _coverageMarker();
+      return;
+    }
+    // iterable should be List
+    {
+      DartType iterableType = iterable.bestType;
+      InterfaceType listType = context.typeProvider.listType;
+      if (iterableType is! InterfaceType ||
+          iterableType.element != listType.element) {
+        _coverageMarker();
+        return;
+      }
+    }
+    // body should be Block
+    if (forEachStatement.body is! Block) {
+      _coverageMarker();
+      return;
+    }
+    Block body = forEachStatement.body;
+    // prepare a name for the index variable
+    String indexName;
+    {
+      Set<String> conflicts =
+          utils.findPossibleLocalVariableConflicts(forEachStatement.offset);
+      if (!conflicts.contains('i')) {
+        indexName = 'i';
+      } else if (!conflicts.contains('j')) {
+        indexName = 'j';
+      } else if (!conflicts.contains('k')) {
+        indexName = 'k';
+      } else {
+        _coverageMarker();
+        return;
+      }
+    }
+    // prepare environment
+    String prefix = utils.getNodePrefix(forEachStatement);
+    String indent = utils.getIndent(1);
+    int firstBlockLine = utils.getLineContentEnd(body.leftBracket.end);
+    // add change
+    _addReplaceEdit(
+        rangeStartEnd(forEachStatement, forEachStatement.rightParenthesis),
+        'for (int $indexName = 0; $indexName < $listName.length; $indexName++)');
+    _addInsertEdit(firstBlockLine,
+        '$prefix$indent$loopVariable = $listName[$indexName];$eol');
+    // add proposal
+    _addAssist(AssistKind.CONVERT_INTO_FOR_INDEX, []);
+  }
+
   void _addProposal_convertToIsNot_onIs() {
     // may be child of "is"
     AstNode node = this.node;
@@ -711,10 +802,19 @@
       _coverageMarker();
       return;
     }
+    // prepare location
+    int offset;
+    String statementPrefix;
+    if (isExpression.notOperator == null) {
+      offset = targetBlock.leftBracket.end;
+      statementPrefix = indent;
+    } else {
+      offset = targetBlock.rightBracket.end;
+      statementPrefix = '';
+    }
     // prepare source
-    int offset = targetBlock.leftBracket.end;
     SourceBuilder builder = new SourceBuilder(file, offset);
-    builder.append(eol + prefix + indent);
+    builder.append(eol + prefix + statementPrefix);
     builder.append(castTypeCode);
     // prepare excluded names
     Set<String> excluded = new Set<String>();
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 0bca27d..beb3367 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -44,6 +44,8 @@
 class FixKind {
   static const ADD_ASYNC =
       const FixKind('ADD_ASYNC', 50, "Add 'async' modifier");
+  static const ADD_FIELD_FORMAL_PARAMETERS = const FixKind(
+      'ADD_FIELD_FORMAL_PARAMETERS', 30, "Add final field formal parameters");
   static const ADD_PACKAGE_DEPENDENCY = const FixKind(
       'ADD_PACKAGE_DEPENDENCY', 50, "Add dependency on package '{0}'");
   static const ADD_SUPER_CONSTRUCTOR_INVOCATION = const FixKind(
@@ -56,6 +58,9 @@
       const FixKind('CREATE_CLASS', 50, "Create class '{0}'");
   static const CREATE_CONSTRUCTOR =
       const FixKind('CREATE_CONSTRUCTOR', 50, "Create constructor '{0}'");
+  static const CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS = const FixKind(
+      'CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS', 50,
+      "Create constructor for final fields");
   static const CREATE_CONSTRUCTOR_SUPER = const FixKind(
       'CREATE_CONSTRUCTOR_SUPER', 50, "Create constructor to call {0}");
   static const CREATE_FIELD =
@@ -94,6 +99,10 @@
       "Remove parentheses in getter invocation");
   static const REMOVE_UNNECASSARY_CAST =
       const FixKind('REMOVE_UNNECASSARY_CAST', 50, "Remove unnecessary cast");
+  static const REMOVE_UNUSED_CATCH_CLAUSE = const FixKind(
+      'REMOVE_UNUSED_CATCH', 50, "Remove unused 'catch' clause");
+  static const REMOVE_UNUSED_CATCH_STACK = const FixKind(
+      'REMOVE_UNUSED_CATCH_STACK', 50, "Remove unused stack trace variable");
   static const REMOVE_UNUSED_IMPORT =
       const FixKind('REMOVE_UNUSED_IMPORT', 50, "Remove unused import");
   static const REPLACE_BOOLEAN_WITH_BOOL = const FixKind(
@@ -102,6 +111,9 @@
       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(
+      'REPLACE_RETURN_TYPE_FUTURE', 50,
+      "Return 'Future' from 'async' function");
   static const USE_CONST = const FixKind('USE_CONST', 50, "Change to constant");
   static const USE_EFFECTIVE_INTEGER_DIVISION = const FixKind(
       'USE_EFFECTIVE_INTEGER_DIVISION', 50,
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 17944cd..0ff70e6 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -35,7 +35,7 @@
 /**
  * A predicate is a one-argument function that returns a boolean value.
  */
-typedef bool Predicate<E>(E argument);
+typedef bool ElementPredicate(Element argument);
 
 /**
  * The computer for Dart fixes.
@@ -134,6 +134,7 @@
     }
     if (errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST) {
       _addFix_createImportUri();
+      _addFix_createPartUri();
       _addFix_replaceImportUri();
     }
     if (errorCode == HintCode.DIVISION_OPTIMIZATION) {
@@ -145,9 +146,24 @@
     if (errorCode == HintCode.TYPE_CHECK_IS_NULL) {
       _addFix_isNull();
     }
+    if (errorCode == HintCode.UNDEFINED_GETTER) {
+      _addFix_undefinedClassAccessor_useSimilar();
+      _addFix_createField();
+      _addFix_createGetter();
+    }
+    if (errorCode == HintCode.UNDEFINED_SETTER) {
+      _addFix_undefinedClassAccessor_useSimilar();
+      _addFix_createField();
+    }
     if (errorCode == HintCode.UNNECESSARY_CAST) {
       _addFix_removeUnnecessaryCast();
     }
+    if (errorCode == HintCode.UNUSED_CATCH_CLAUSE) {
+      _addFix_removeUnusedCatchClause();
+    }
+    if (errorCode == HintCode.UNUSED_CATCH_STACK) {
+      _addFix_removeUnusedCatchStack();
+    }
     if (errorCode == HintCode.UNUSED_IMPORT) {
       _addFix_removeUnusedImport();
     }
@@ -198,9 +214,19 @@
       _addFix_createClass();
       _addFix_undefinedClass_useSimilar();
     }
+    if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED) {
+      _addFix_createConstructor_forUninitializedFinalFields();
+    }
+    if (errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 ||
+        errorCode == StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 ||
+        errorCode ==
+            StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS) {
+      _addFix_updateConstructor_forUninitializedFinalFields();
+    }
     if (errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER) {
       bool isAsync = _addFix_addAsync();
       if (!isAsync) {
+        _addFix_undefinedClassAccessor_useSimilar();
         _addFix_createField();
         _addFix_createGetter();
         _addFix_createFunction_forFunctionType();
@@ -209,6 +235,9 @@
         _addFix_createLocalVariable();
       }
     }
+    if (errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE) {
+      _addFix_illegalAsyncReturnType();
+    }
     if (errorCode == StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER) {
       _addFix_useStaticAccess_method();
       _addFix_useStaticAccess_property();
@@ -226,6 +255,7 @@
       _addFix_undefinedFunction_create();
     }
     if (errorCode == StaticTypeWarningCode.UNDEFINED_GETTER) {
+      _addFix_undefinedClassAccessor_useSimilar();
       _addFix_createField();
       _addFix_createGetter();
       _addFix_createFunction_forFunctionType();
@@ -238,6 +268,7 @@
       _addFix_undefinedFunction_create();
     }
     if (errorCode == StaticTypeWarningCode.UNDEFINED_SETTER) {
+      _addFix_undefinedClassAccessor_useSimilar();
       _addFix_createField();
     }
     // done
@@ -335,6 +366,49 @@
     }
   }
 
+  /**
+   * Here we handle cases when there are no constructors in a class, and the
+   * class has uninitialized final fields.
+   */
+  void _addFix_createConstructor_forUninitializedFinalFields() {
+    if (node is! SimpleIdentifier || node.parent is! VariableDeclaration) {
+      return;
+    }
+    ClassDeclaration classDeclaration =
+        node.getAncestor((node) => node is ClassDeclaration);
+    // prepare names of uninitialized final fields
+    List<String> fieldNames = <String>[];
+    for (ClassMember member in classDeclaration.members) {
+      if (member is FieldDeclaration) {
+        VariableDeclarationList variableList = member.fields;
+        if (variableList.isFinal) {
+          fieldNames.addAll(variableList.variables
+              .where((v) => v.initializer == null)
+              .map((v) => v.name.name));
+        }
+      }
+    }
+    // prepare location for a new constructor
+    _ConstructorLocation targetLocation =
+        _prepareNewConstructorLocation(classDeclaration);
+    // build constructor source
+    SourceBuilder sb = new SourceBuilder(file, targetLocation.offset);
+    {
+      String indent = '  ';
+      sb.append(targetLocation.prefix);
+      sb.append(indent);
+      sb.append(classDeclaration.name.name);
+      sb.append('(');
+      sb.append(fieldNames.map((name) => 'this.$name').join(', '));
+      sb.append(');');
+      sb.append(targetLocation.suffix);
+    }
+    // insert source
+    _insertBuilder(sb, unitElement);
+    // add proposal
+    _addFix(FixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS, []);
+  }
+
   void _addFix_createConstructor_insteadOfSyntheticDefault() {
     TypeName typeName = null;
     ConstructorName constructorName = null;
@@ -1013,6 +1087,39 @@
     _addFix(FixKind.CREATE_NO_SUCH_METHOD, []);
   }
 
+  void _addFix_createPartUri() {
+    if (node is SimpleStringLiteral && node.parent is PartDirective) {
+      PartDirective partDirective = node.parent;
+      Source source = partDirective.source;
+      if (source != null) {
+        String file = source.fullName;
+        String libName = unitLibraryElement.name;
+        SourceEdit edit = new SourceEdit(0, 0, 'part of $libName;$eol$eol');
+        change.addEdit(file, -1, edit);
+        doSourceChange_addSourceEdit(change, context, source, edit);
+        _addFix(FixKind.CREATE_FILE, [file]);
+      }
+    }
+  }
+
+  void _addFix_illegalAsyncReturnType() {
+    InterfaceType futureType = context.typeProvider.futureType;
+    String futureTypeCode = utils.getTypeSource(futureType, librariesToImport);
+    // prepare the existing type
+    TypeName typeName = node.getAncestor((n) => n is TypeName);
+    String nodeCode = utils.getNodeText(typeName);
+    // wrap the existing type with Future
+    String returnTypeCode;
+    if (nodeCode == 'void') {
+      returnTypeCode = futureTypeCode;
+    } else {
+      returnTypeCode = '$futureTypeCode<$nodeCode>';
+    }
+    _addReplaceEdit(rf.rangeNode(typeName), returnTypeCode);
+    // add proposal
+    _addFix(FixKind.REPLACE_RETURN_TYPE_FUTURE, []);
+  }
+
   void _addFix_importLibrary(FixKind kind, String importPath) {
     CompilationUnitElement libraryUnitElement =
         unitLibraryElement.definingCompilationUnit;
@@ -1075,8 +1182,10 @@
       if (prefix != null) {
         SourceRange range = rf.rangeStartLength(node, 0);
         _addReplaceEdit(range, '${prefix.displayName}.');
-        _addFix(FixKind.IMPORT_LIBRARY_PREFIX,
-            [libraryElement.displayName, prefix.displayName]);
+        _addFix(FixKind.IMPORT_LIBRARY_PREFIX, [
+          libraryElement.displayName,
+          prefix.displayName
+        ]);
         continue;
       }
       // may be update "show" directive
@@ -1274,6 +1383,30 @@
     _addFix(FixKind.REMOVE_UNNECASSARY_CAST, []);
   }
 
+  void _addFix_removeUnusedCatchClause() {
+    if (node is SimpleIdentifier) {
+      AstNode catchClause = node.parent;
+      if (catchClause is CatchClause &&
+          catchClause.exceptionParameter == node) {
+        _addRemoveEdit(
+            rf.rangeStartStart(catchClause.catchKeyword, catchClause.body));
+        _addFix(FixKind.REMOVE_UNUSED_CATCH_CLAUSE, []);
+      }
+    }
+  }
+
+  void _addFix_removeUnusedCatchStack() {
+    if (node is SimpleIdentifier) {
+      AstNode catchClause = node.parent;
+      if (catchClause is CatchClause &&
+          catchClause.stackTraceParameter == node &&
+          catchClause.exceptionParameter != null) {
+        _addRemoveEdit(rf.rangeEndEnd(catchClause.exceptionParameter, node));
+        _addFix(FixKind.REMOVE_UNUSED_CATCH_STACK, []);
+      }
+    }
+  }
+
   void _addFix_removeUnusedImport() {
     // prepare ImportDirective
     ImportDirective importDirective =
@@ -1359,6 +1492,62 @@
     }
   }
 
+  void _addFix_undefinedClassAccessor_useSimilar() {
+    AstNode node = this.node;
+    if (node is SimpleIdentifier) {
+      // prepare target
+      Expression target = null;
+      if (node.parent is PrefixedIdentifier) {
+        PrefixedIdentifier invocation = node.parent as PrefixedIdentifier;
+        target = invocation.prefix;
+      }
+      // find getter
+      if (node.inGetterContext()) {
+        _addFix_undefinedClassMember_useSimilar(target, (Element element) {
+          return element is PropertyAccessorElement && element.isGetter ||
+              element is FieldElement && element.getter != null;
+        });
+      }
+      // find setter
+      if (node.inSetterContext()) {
+        _addFix_undefinedClassMember_useSimilar(target, (Element element) {
+          return element is PropertyAccessorElement && element.isSetter ||
+              element is FieldElement && element.setter != null;
+        });
+      }
+    }
+  }
+
+  void _addFix_undefinedClassMember_useSimilar(
+      Expression target, ElementPredicate predicate) {
+    if (node is SimpleIdentifier) {
+      String name = (node as SimpleIdentifier).name;
+      _ClosestElementFinder finder =
+          new _ClosestElementFinder(name, predicate, MAX_LEVENSHTEIN_DISTANCE);
+      // unqualified invocation
+      if (target == null) {
+        ClassDeclaration clazz =
+            node.getAncestor((node) => node is ClassDeclaration);
+        if (clazz != null) {
+          ClassElement classElement = clazz.element;
+          _updateFinderWithClassMembers(finder, classElement);
+        }
+      } else {
+        DartType type = target.bestType;
+        if (type is InterfaceType) {
+          ClassElement classElement = type.element;
+          _updateFinderWithClassMembers(finder, classElement);
+        }
+      }
+      // if we have close enough element, suggest to use it
+      if (finder._element != null) {
+        String closestName = finder._element.name;
+        _addReplaceEdit(rf.rangeNode(node), closestName);
+        _addFix(FixKind.CHANGE_TO, [closestName]);
+      }
+    }
+  }
+
   void _addFix_undefinedFunction_create() {
     // should be the name of the invocation
     if (node is SimpleIdentifier && node.parent is MethodInvocation) {} else {
@@ -1549,34 +1738,50 @@
   }
 
   void _addFix_undefinedMethod_useSimilar() {
-    if (node is SimpleIdentifier && node.parent is MethodInvocation) {
+    if (node.parent is MethodInvocation) {
       MethodInvocation invocation = node.parent as MethodInvocation;
-      String name = (node as SimpleIdentifier).name;
-      _ClosestElementFinder finder = new _ClosestElementFinder(name,
-          (Element element) => element is MethodElement && !element.isOperator,
-          MAX_LEVENSHTEIN_DISTANCE);
-      // unqualified invocation
-      Expression target = invocation.realTarget;
-      if (target == null) {
-        ClassDeclaration clazz =
-            invocation.getAncestor((node) => node is ClassDeclaration);
-        if (clazz != null) {
-          ClassElement classElement = clazz.element;
-          _updateFinderWithClassMembers(finder, classElement);
+      _addFix_undefinedClassMember_useSimilar(invocation.realTarget,
+          (Element element) => element is MethodElement && !element.isOperator);
+    }
+  }
+
+  /**
+   * Here we handle cases when a constructors does not initialize all of the
+   * final fields.
+   */
+  void _addFix_updateConstructor_forUninitializedFinalFields() {
+    if (node is! SimpleIdentifier || node.parent is! ConstructorDeclaration) {
+      return;
+    }
+    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;
         }
+      }
+      // append new field formal initializers
+      if (lastRequiredParameter != null) {
+        _addInsertEdit(lastRequiredParameter.end, ', $fieldParametersCode');
       } else {
-        DartType type = target.bestType;
-        if (type is InterfaceType) {
-          ClassElement classElement = type.element;
-          _updateFinderWithClassMembers(finder, classElement);
+        int offset = constructor.parameters.leftParenthesis.end;
+        if (parameters.isNotEmpty) {
+          fieldParametersCode += ', ';
         }
+        _addInsertEdit(offset, fieldParametersCode);
       }
-      // if we have close enough element, suggest to use it
-      if (finder._element != null) {
-        String closestName = finder._element.name;
-        _addReplaceEdit(rf.rangeNode(node), closestName);
-        _addFix(FixKind.CHANGE_TO, [closestName]);
-      }
+      // add proposal
+      _addFix(FixKind.ADD_FIELD_FORMAL_PARAMETERS, []);
     }
   }
 
@@ -1585,8 +1790,7 @@
       if (n is MethodInvocation &&
           n.offset == errorOffset &&
           n.length == errorLength) {
-        MethodInvocation invocation = n as MethodInvocation;
-        Expression target = invocation.target;
+        Expression target = n.target;
         while (target is ParenthesizedExpression) {
           target = (target as ParenthesizedExpression).expression;
         }
@@ -1594,8 +1798,8 @@
         BinaryExpression binary = target as BinaryExpression;
         _addReplaceEdit(rf.rangeToken(binary.operator), '~/');
         // remove everything before and after
-        _addRemoveEdit(rf.rangeStartStart(invocation, binary.leftOperand));
-        _addRemoveEdit(rf.rangeEndEnd(binary.rightOperand, invocation));
+        _addRemoveEdit(rf.rangeStartStart(n, binary.leftOperand));
+        _addRemoveEdit(rf.rangeEndEnd(binary.rightOperand, n));
         // add proposal
         _addFix(FixKind.USE_EFFECTIVE_INTEGER_DIVISION, []);
         // done
@@ -1886,7 +2090,7 @@
   }
 
   /**
-   * Returns the [Type] with given name from the `dart:core` library.
+   * Returns the [DartType] with given name from the `dart:core` library.
    */
   DartType _getCoreType(String name) {
     List<LibraryElement> libraries = unitLibraryElement.importedLibraries;
@@ -2234,7 +2438,7 @@
  */
 class _ClosestElementFinder {
   final String _targetName;
-  final Predicate<Element> _predicate;
+  final ElementPredicate _predicate;
 
   Element _element = null;
   int _distance;
diff --git a/pkg/analysis_server/lib/src/services/correction/sort_members.dart b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
index a7270c2..c66c521 100644
--- a/pkg/analysis_server/lib/src/services/correction/sort_members.dart
+++ b/pkg/analysis_server/lib/src/services/correction/sort_members.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/protocol.dart' hide Element;
 import 'package:analysis_server/src/services/correction/strings.dart';
 import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
 
 /**
  * Sorter for unit/class members.
@@ -41,20 +42,11 @@
   final String initialCode;
   final CompilationUnit unit;
   String code;
+  String endOfLine;
 
   MemberSorter(this.initialCode, this.unit) {
     this.code = initialCode;
-  }
-
-  /**
-   * Return the EOL to use for [code].
-   */
-  String get endOfLine {
-    if (code.contains('\r\n')) {
-      return '\r\n';
-    } else {
-      return '\n';
-    }
+    this.endOfLine = getEOL(code);
   }
 
   /**
@@ -233,6 +225,29 @@
       directivesCode = sb.toString();
       directivesCode = directivesCode.trimRight();
     }
+    // append comment tokens which otherwise would be removed completely
+    {
+      bool firstCommentToken = true;
+      Token token = unit.beginToken;
+      while (token != null &&
+          token.type != TokenType.EOF &&
+          token.end < lastDirectiveEnd) {
+        Token commentToken = token.precedingComments;
+        while (commentToken != null) {
+          int offset = commentToken.offset;
+          int end = commentToken.end;
+          if (offset > firstDirectiveOffset && offset < lastDirectiveEnd) {
+            if (firstCommentToken) {
+              directivesCode += endOfLine;
+              firstCommentToken = false;
+            }
+            directivesCode += code.substring(offset, end) + endOfLine;
+          }
+          commentToken = commentToken.next;
+        }
+        token = token.next;
+      }
+    }
     // prepare code
     String beforeDirectives = code.substring(0, firstDirectiveOffset);
     String afterDirectives = code.substring(lastDirectiveEnd);
@@ -297,6 +312,17 @@
     _sortAndReorderMembers(members);
   }
 
+  /**
+   * Return the EOL to use for [code].
+   */
+  static String getEOL(String code) {
+    if (code.contains('\r\n')) {
+      return '\r\n';
+    } else {
+      return '\n';
+    }
+  }
+
   static int _getPriority(_PriorityItem item) {
     for (int i = 0; i < _PRIORITY_ITEMS.length; i++) {
       if (_PRIORITY_ITEMS[i] == item) {
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index f214c9f..c19a4c8 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -12,6 +12,7 @@
     show doSourceChange_addElementEdit;
 import 'package:analysis_server/src/services/correction/source_range.dart';
 import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -596,6 +597,33 @@
       new NodeLocator.con1(offset).searchWithin(unit);
 
   /**
+   * Returns names of elements that might conflict with a new local variable
+   * declared at [offset].
+   */
+  Set<String> findPossibleLocalVariableConflicts(int offset) {
+    Set<String> conflicts = new Set<String>();
+    AstNode enclosingNode = findNode(offset);
+    Block enclosingBlock = enclosingNode.getAncestor((node) => node is Block);
+    if (enclosingBlock != null) {
+      SourceRange newRange = rangeStartEnd(offset, enclosingBlock.end);
+      ExecutableElement enclosingExecutable =
+          getEnclosingExecutableElement(enclosingNode);
+      if (enclosingExecutable != null) {
+        visitChildren(enclosingExecutable, (Element element) {
+          if (element is LocalElement) {
+            SourceRange elementRange = element.visibleRange;
+            if (elementRange != null && elementRange.intersects(newRange)) {
+              conflicts.add(element.displayName);
+            }
+          }
+          return true;
+        });
+      }
+    }
+    return conflicts;
+  }
+
+  /**
    * Returns the actual type source of the given [Expression], may be `null`
    * if can not be resolved, should be treated as the `dynamic` type.
    */
@@ -973,6 +1001,11 @@
     // check if imported
     LibraryElement library = element.library;
     if (library != null && library != _library) {
+      // no source, if private
+      if (element.isPrivate) {
+        return null;
+      }
+      // ensure import
       ImportElement importElement = _getImportElement(element);
       if (importElement != null) {
         if (importElement.prefix != null) {
@@ -1005,7 +1038,11 @@
             sb.write(", ");
           }
           String argumentSrc = getTypeSource(argument, librariesToImport);
-          sb.write(argumentSrc);
+          if (argumentSrc != null) {
+            sb.write(argumentSrc);
+          } else {
+            return null;
+          }
         }
         sb.write(">");
       }
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index e01942c..8d7782c 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -17,7 +17,6 @@
 import 'package:analysis_server/src/services/refactoring/naming_conventions.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
-import 'package:analysis_server/src/services/search/element_visitors.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -51,7 +50,7 @@
   String stringLiteralPart;
   final List<SourceRange> occurrences = <SourceRange>[];
   final Map<Element, int> elementIds = <Element, int>{};
-  final Set<String> excludedVariableNames = new Set<String>();
+  Set<String> excludedVariableNames = new Set<String>();
 
   ExtractLocalRefactoringImpl(
       this.unit, this.selectionOffset, this.selectionLength) {
@@ -94,7 +93,8 @@
     _prepareOccurrences();
     _prepareOffsetsLengths();
     // names
-    _prepareExcludedNames();
+    excludedVariableNames =
+        utils.findPossibleLocalVariableConflicts(selectionOffset);
     _prepareNames();
     // done
     return new Future.value(result);
@@ -371,31 +371,6 @@
     return false;
   }
 
-  void _prepareExcludedNames() {
-    excludedVariableNames.clear();
-    AstNode enclosingNode =
-        new NodeLocator.con1(selectionOffset).searchWithin(unit);
-    Block enclosingBlock = enclosingNode.getAncestor((node) => node is Block);
-    if (enclosingBlock != null) {
-      SourceRange newVariableVisibleRange =
-          rangeStartEnd(selectionRange, enclosingBlock.end);
-      ExecutableElement enclosingExecutable =
-          getEnclosingExecutableElement(enclosingNode);
-      if (enclosingExecutable != null) {
-        visitChildren(enclosingExecutable, (Element element) {
-          if (element is LocalElement) {
-            SourceRange elementRange = element.visibleRange;
-            if (elementRange != null &&
-                elementRange.intersects(newVariableVisibleRange)) {
-              excludedVariableNames.add(element.displayName);
-            }
-          }
-          return true;
-        });
-      }
-    }
-  }
-
   void _prepareNames() {
     names.clear();
     if (stringLiteralPart != null) {
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 f6cb0b3..da4e4e4 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_method.dart
@@ -179,7 +179,8 @@
     _prepareOffsetsLengths();
     // getter
     canCreateGetter = _computeCanCreateGetter();
-    _initializeCreateGetter();
+    createGetter =
+        canCreateGetter && _isExpressionForGetter(_selectionExpression);
     // names
     _prepareExcludedNames();
     _prepareNames();
@@ -523,36 +524,6 @@
   }
 
   /**
-   * Initializes [createGetter] flag.
-   */
-  void _initializeCreateGetter() {
-    createGetter = false;
-    // maybe we cannot at all
-    if (!canCreateGetter) {
-      return;
-    }
-    // OK, just expression
-    if (_selectionExpression != null) {
-      createGetter = !_hasMethodInvocation(_selectionExpression);
-      return;
-    }
-    // allow code blocks without cycles
-    if (_selectionStatements != null) {
-      createGetter = true;
-      for (Statement statement in _selectionStatements) {
-        // method invocation is something heavy,
-        // so we don't want to extract it as a part of a getter
-        if (_hasMethodInvocation(statement)) {
-          createGetter = false;
-          return;
-        }
-        // don't allow cycles
-        statement.accept(new _ResetCanCreateGetterVisitor(this));
-      }
-    }
-  }
-
-  /**
    * Fills [_occurrences] field.
    */
   void _initializeOccurrences() {
@@ -706,12 +677,29 @@
   }
 
   /**
-   * Checks if [node] has a [MethodInvocation].
+   * Checks if the given [expression] is reasonable to extract as a getter.
    */
-  static bool _hasMethodInvocation(AstNode node) {
-    var visitor = new _HasMethodInvocationVisitor();
-    node.accept(visitor);
-    return visitor.result;
+  static bool _isExpressionForGetter(Expression expression) {
+    if (expression is BinaryExpression) {
+      return _isExpressionForGetter(expression.leftOperand) &&
+          _isExpressionForGetter(expression.rightOperand);
+    }
+    if (expression is Literal) {
+      return true;
+    }
+    if (expression is PrefixExpression) {
+      return _isExpressionForGetter(expression.operand);
+    }
+    if (expression is PrefixedIdentifier) {
+      return _isExpressionForGetter(expression.prefix);
+    }
+    if (expression is PropertyAccess) {
+      return _isExpressionForGetter(expression.target);
+    }
+    if (expression is SimpleIdentifier) {
+      return true;
+    }
+    return false;
   }
 
   /**
@@ -867,15 +855,6 @@
   }
 }
 
-class _HasMethodInvocationVisitor extends RecursiveAstVisitor {
-  bool result = false;
-
-  @override
-  visitMethodInvocation(MethodInvocation node) {
-    result = true;
-  }
-}
-
 class _HasReturnStatementVisitor extends RecursiveAstVisitor {
   bool hasReturn = false;
 
@@ -961,8 +940,8 @@
           new _Occurrence(nodeRange, ref.selectionRange.intersects(nodeRange));
       ref._occurrences.add(occurrence);
       // prepare mapping of parameter names to the occurrence variables
-      nodePattern.originalToPatternNames.forEach(
-          (String originalName, String patternName) {
+      nodePattern.originalToPatternNames
+          .forEach((String originalName, String patternName) {
         String selectionName = patternToSelectionName[patternName];
         occurrence._parameterOldToOccurrenceName[selectionName] = originalName;
       });
@@ -1079,36 +1058,6 @@
   _Occurrence(this.range, this.isSelection);
 }
 
-class _ResetCanCreateGetterVisitor extends RecursiveAstVisitor {
-  final ExtractMethodRefactoringImpl ref;
-
-  _ResetCanCreateGetterVisitor(this.ref);
-
-  @override
-  visitDoStatement(DoStatement node) {
-    ref.createGetter = false;
-    super.visitDoStatement(node);
-  }
-
-  @override
-  visitForEachStatement(ForEachStatement node) {
-    ref.createGetter = false;
-    super.visitForEachStatement(node);
-  }
-
-  @override
-  visitForStatement(ForStatement node) {
-    ref.createGetter = false;
-    super.visitForStatement(node);
-  }
-
-  @override
-  visitWhileStatement(WhileStatement node) {
-    ref.createGetter = false;
-    super.visitWhileStatement(node);
-  }
-}
-
 class _ReturnTypeComputer extends RecursiveAstVisitor {
   DartType returnType;
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index fe1cbe0..3f24fa9 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -11,16 +11,20 @@
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring_internal.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:path/path.dart' as pathos;
+import 'package:source_span/src/span.dart';
+import 'package:yaml/yaml.dart';
 
 /**
  * [ExtractLocalRefactoring] implementation.
  */
 class MoveFileRefactoringImpl extends RefactoringImpl
     implements MoveFileRefactoring {
+  final ResourceProvider resourceProvider;
   final pathos.Context pathContext;
   final SearchEngine searchEngine;
   final AnalysisContext context;
@@ -34,9 +38,13 @@
   String oldLibraryDir;
   String newLibraryDir;
 
-  MoveFileRefactoringImpl(
-      this.pathContext, this.searchEngine, this.context, this.source) {
-    oldFile = source.fullName;
+  MoveFileRefactoringImpl(ResourceProvider resourceProvider, this.searchEngine,
+      this.context, this.source, this.oldFile)
+      : resourceProvider = resourceProvider,
+        pathContext = resourceProvider.pathContext {
+    if (source != null) {
+      oldFile = source.fullName;
+    }
   }
 
   @override
@@ -56,6 +64,45 @@
 
   @override
   Future<SourceChange> createChange() async {
+    // move file
+    if (source != null) {
+      return _createFileChange();
+    }
+    // rename project
+    if (oldFile != null) {
+      Resource projectFolder = resourceProvider.getResource(oldFile);
+      if (projectFolder is Folder && projectFolder.exists) {
+        Resource pubspecFile = projectFolder.getChild('pubspec.yaml');
+        if (pubspecFile is File && pubspecFile.exists) {
+          return _createProjectChange(projectFolder, pubspecFile);
+        }
+      }
+    }
+    // no change
+    return null;
+  }
+
+  @override
+  bool requiresPreview() => false;
+
+  /**
+   * Computes the URI to use to reference [newFile] from [reference].
+   */
+  String _computeNewUri(SourceReference reference) {
+    String refDir = pathContext.dirname(reference.file);
+    // try to keep package: URI
+    if (_isPackageReference(reference)) {
+      Source newSource = new NonExistingSource(newFile, UriKind.FILE_URI);
+      Uri restoredUri = context.sourceFactory.restoreUri(newSource);
+      if (restoredUri != null) {
+        return restoredUri.toString();
+      }
+    }
+    // if no package: URI, prepare relative
+    return _getRelativeUri(newFile, refDir);
+  }
+
+  Future<SourceChange> _createFileChange() async {
     change = new SourceChange('Update File References');
     List<Source> librarySources = context.getLibrariesContaining(source);
     await Future.forEach(librarySources, (Source librarySource) async {
@@ -84,24 +131,57 @@
     return change;
   }
 
-  @override
-  bool requiresPreview() => false;
-
-  /**
-   * Computes the URI to use to reference [newFile] from [reference].
-   */
-  String _computeNewUri(SourceReference reference) {
-    String refDir = pathContext.dirname(reference.file);
-    // try to keep package: URI
-    if (_isPackageReference(reference)) {
-      Source newSource = new NonExistingSource(newFile, UriKind.FILE_URI);
-      Uri restoredUri = context.sourceFactory.restoreUri(newSource);
-      if (restoredUri != null) {
-        return restoredUri.toString();
+  Future<SourceChange> _createProjectChange(
+      Folder project, File pubspecFile) async {
+    change = new SourceChange('Rename project');
+    String oldPackageName = pathContext.basename(oldFile);
+    String newPackageName = pathContext.basename(newFile);
+    // add pubspec.yaml change
+    {
+      // prepare "name" field value location
+      SourceSpan nameSpan;
+      {
+        String pubspecString = pubspecFile.readAsStringSync();
+        YamlMap pubspecNode = loadYamlNode(pubspecString);
+        YamlNode nameNode = pubspecNode.nodes['name'];
+        nameSpan = nameNode.span;
       }
+      int nameOffset = nameSpan.start.offset;
+      int nameLength = nameSpan.length;
+      // add edit
+      change.addEdit(pubspecFile.path, pubspecFile.modificationStamp,
+          new SourceEdit(nameOffset, nameLength, newPackageName));
     }
-    // if no package: URI, prepare relative
-    return _getRelativeUri(newFile, refDir);
+    // check all local libraries
+    for (Source librarySource in context.librarySources) {
+      // should be a local library
+      if (!project.contains(librarySource.fullName)) {
+        continue;
+      }
+      // we need LibraryElement
+      LibraryElement library = context.getLibraryElement(librarySource);
+      if (library == null) {
+        continue;
+      }
+      // update all imports
+      updateUriElements(List<UriReferencedElement> uriElements) {
+        for (UriReferencedElement element in uriElements) {
+          String uri = element.uri;
+          if (uri != null) {
+            String oldPrefix = 'package:$oldPackageName/';
+            if (uri.startsWith(oldPrefix)) {
+              doSourceChange_addElementEdit(change, library, new SourceEdit(
+                  element.uriOffset + 1, oldPrefix.length,
+                  'package:$newPackageName/'));
+            }
+          }
+        }
+      }
+      updateUriElements(library.imports);
+      updateUriElements(library.exports);
+    }
+    // done
+    return change;
   }
 
   String _getRelativeUri(String path, String from) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart b/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart
index 3503311..aac5275 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart
@@ -6,6 +6,7 @@
 
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/src/generated/scanner.dart';
 
 /**
  * Returns the [RefactoringStatus] with severity:
@@ -164,6 +165,15 @@
     String message = "$desc must not be empty.";
     return new RefactoringStatus.fatal(message);
   }
+  // keyword
+  {
+    Keyword keyword = Keyword.keywords[identifier];
+    if (keyword != null && !keyword.isPseudoKeyword) {
+      String message = "$desc must not be a keyword.";
+      return new RefactoringStatus.fatal(message);
+    }
+  }
+  // first character
   int currentChar = identifier.codeUnitAt(0);
   if (!isLetter(currentChar) &&
       currentChar != CHAR_UNDERSCORE &&
@@ -171,6 +181,7 @@
     String message = "$desc must begin with $beginDesc.";
     return new RefactoringStatus.fatal(message);
   }
+  // other characters
   for (int i = 1; i < length; i++) {
     currentChar = identifier.codeUnitAt(i);
     if (!isLetterOrDigit(currentChar) &&
@@ -181,6 +192,7 @@
       return new RefactoringStatus.fatal(message);
     }
   }
+  // OK
   return new RefactoringStatus();
 }
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
index c73f98c..1a29c3e 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/refactoring.dart
@@ -24,11 +24,11 @@
 import 'package:analysis_server/src/services/refactoring/rename_local.dart';
 import 'package:analysis_server/src/services/refactoring/rename_unit_member.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:path/path.dart' as pathos;
 
 /**
  * [Refactoring] to convert getters into normal [MethodDeclaration]s.
@@ -278,10 +278,11 @@
   /**
    * Returns a new [MoveFileRefactoring] instance.
    */
-  factory MoveFileRefactoring(pathos.Context pathContext,
-      SearchEngine searchEngine, AnalysisContext context, Source source) {
+  factory MoveFileRefactoring(ResourceProvider resourceProvider,
+      SearchEngine searchEngine, AnalysisContext context, Source source,
+      String oldFile) {
     return new MoveFileRefactoringImpl(
-        pathContext, searchEngine, context, source);
+        resourceProvider, searchEngine, context, source, oldFile);
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index efeb876..e7ad5ac 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -12,6 +12,7 @@
 import 'package:analysis_server/src/services/index/local_file_index.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/plugin/plugin.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/sdk_io.dart';
 
@@ -33,6 +34,11 @@
    */
   AnalysisServer analysisServer;
 
+  /**
+   * The plugins that are defined outside the analysis_server package.
+   */
+  List<Plugin> userDefinedPlugins;
+
   SocketServer(this.analysisServerOptions, this.defaultSdk,
       this.instrumentationService, this.serverPlugin);
 
@@ -73,6 +79,7 @@
         analysisServerOptions, defaultSdk, instrumentationService,
         rethrowExceptions: false);
     _initializeHandlers(analysisServer);
+    analysisServer.userDefinedPlugins = userDefinedPlugins;
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/status/ast_writer.dart b/pkg/analysis_server/lib/src/status/ast_writer.dart
index 4d410d6..6cb30db 100644
--- a/pkg/analysis_server/lib/src/status/ast_writer.dart
+++ b/pkg/analysis_server/lib/src/status/ast_writer.dart
@@ -161,6 +161,9 @@
     buffer.write('..');
     buffer.write(node.offset + node.length - 1);
     buffer.write(']</span>');
+    if (node.isSynthetic) {
+      buffer.write(' (synthetic)');
+    }
     buffer.write('<br>');
   }
 }
diff --git a/pkg/analysis_server/lib/starter.dart b/pkg/analysis_server/lib/starter.dart
index 9483fff..8d5658a 100644
--- a/pkg/analysis_server/lib/starter.dart
+++ b/pkg/analysis_server/lib/starter.dart
@@ -4,9 +4,9 @@
 
 library driver;
 
-import 'package:analysis_server/plugin/plugin.dart';
 import 'package:analysis_server/src/server/driver.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/plugin/plugin.dart';
 
 /**
  * An object that can be used to start an analysis server.
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 3af3854..121f148 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -6,11 +6,12 @@
 environment:
   sdk: '>=1.0.0 <2.0.0'
 dependencies:
-  analyzer: 0.23.0
+  analyzer: 0.25.0-dev.1
   args: '>=0.12.1 <0.13.0'
   logging: any
   path: any
   watcher: any
+  yaml: any
 dev_dependencies:
   html5lib: any
   mock: '>=0.11.0 <0.12.0'
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index a39f616..d499a4c 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -81,6 +81,7 @@
       // element
       expect(hover.containingLibraryName, 'my.library');
       expect(hover.containingLibraryPath, testFile);
+      expect(hover.containingClassDescription, isNull);
       expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
       expect(hover.elementDescription, 'fff(int a, String b) → List<String>');
       expect(hover.elementKind, 'function');
@@ -101,6 +102,7 @@
 ''');
     return prepareHover('123').then((HoverInformation hover) {
       // literal, no Element
+      expect(hover.containingClassDescription, isNull);
       expect(hover.elementDescription, isNull);
       expect(hover.elementKind, isNull);
       // types
@@ -125,6 +127,7 @@
       // element
       expect(hover.containingLibraryName, 'my.library');
       expect(hover.containingLibraryPath, testFile);
+      expect(hover.containingClassDescription, 'A');
       expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
       expect(hover.elementDescription, 'A.mmm(int a, String b) → List<String>');
       expect(hover.elementKind, 'method');
@@ -180,6 +183,7 @@
       // element
       expect(hover.containingLibraryName, 'my.library');
       expect(hover.containingLibraryPath, testFile);
+      expect(hover.containingClassDescription, 'A');
       expect(hover.dartdoc, '''doc aaa\ndoc bbb''');
       expect(hover.elementDescription, 'String fff');
       expect(hover.elementKind, 'field');
diff --git a/pkg/analysis_server/test/analysis/notification_outline_test.dart b/pkg/analysis_server/test/analysis/notification_outline_test.dart
index be856cd..cae3f7b 100644
--- a/pkg/analysis_server/test/analysis/notification_outline_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_outline_test.dart
@@ -60,7 +60,7 @@
 
   test_class() {
     addTestFile('''
-class A {
+class A<K, V> {
   int fa, fb;
   String fc;
   A(int i, String s);
@@ -85,9 +85,10 @@
         Element element_A = outline_A.element;
         expect(element_A.kind, ElementKind.CLASS);
         expect(element_A.name, "A");
+        expect(element_A.typeParameters, "<K, V>");
         {
           Location location = element_A.location;
-          expect(location.offset, testCode.indexOf("A {"));
+          expect(location.offset, testCode.indexOf("A<K, V> {"));
           expect(location.length, 1);
         }
         expect(element_A.parameters, null);
@@ -227,6 +228,7 @@
         Element element_B = outline_B.element;
         expect(element_B.kind, ElementKind.CLASS);
         expect(element_B.name, "B");
+        expect(element_B.typeParameters, isNull);
         {
           Location location = element_B.location;
           expect(location.offset, testCode.indexOf("B {"));
@@ -677,11 +679,12 @@
 
   test_topLevel() {
     addTestFile('''
-typedef String FTA(int i, String s);
+typedef String FTA<K, V>(int i, String s);
 typedef FTB(int p);
-class A {}
+class A<T> {}
 class B {}
-class CTA = A with B;
+class CTA<T> = A<T> with B;
+class CTB = A with B;
 String fA(int i, String s) => null;
 fB(int p) => null;
 String get propA => null;
@@ -690,16 +693,17 @@
     return prepareOutline().then((_) {
       Outline unitOutline = outline;
       List<Outline> topOutlines = unitOutline.children;
-      expect(topOutlines, hasLength(9));
+      expect(topOutlines, hasLength(10));
       // FTA
       {
         Outline outline = topOutlines[0];
         Element element = outline.element;
         expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS);
         expect(element.name, "FTA");
+        expect(element.typeParameters, "<K, V>");
         {
           Location location = element.location;
-          expect(location.offset, testCode.indexOf("FTA("));
+          expect(location.offset, testCode.indexOf("FTA<K, V>("));
           expect(location.length, "FTA".length);
         }
         expect(element.parameters, "(int i, String s)");
@@ -711,6 +715,7 @@
         Element element = outline.element;
         expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS);
         expect(element.name, "FTB");
+        expect(element.typeParameters, isNull);
         {
           Location location = element.location;
           expect(location.offset, testCode.indexOf("FTB("));
@@ -725,18 +730,28 @@
         Element element = outline.element;
         expect(element.kind, ElementKind.CLASS_TYPE_ALIAS);
         expect(element.name, "CTA");
+        expect(element.typeParameters, '<T>');
         {
           Location location = element.location;
-          expect(location.offset, testCode.indexOf("CTA ="));
+          expect(location.offset, testCode.indexOf("CTA<T> ="));
           expect(location.length, "CTA".length);
         }
         expect(element.parameters, isNull);
         expect(element.returnType, isNull);
       }
-      // fA
+      // CTB
       {
         Outline outline = topOutlines[5];
         Element element = outline.element;
+        expect(element.kind, ElementKind.CLASS_TYPE_ALIAS);
+        expect(element.name, 'CTB');
+        expect(element.typeParameters, isNull);
+        expect(element.returnType, isNull);
+      }
+      // fA
+      {
+        Outline outline = topOutlines[6];
+        Element element = outline.element;
         expect(element.kind, ElementKind.FUNCTION);
         expect(element.name, "fA");
         {
@@ -749,7 +764,7 @@
       }
       // fB
       {
-        Outline outline = topOutlines[6];
+        Outline outline = topOutlines[7];
         Element element = outline.element;
         expect(element.kind, ElementKind.FUNCTION);
         expect(element.name, "fB");
@@ -763,7 +778,7 @@
       }
       // propA
       {
-        Outline outline = topOutlines[7];
+        Outline outline = topOutlines[8];
         Element element = outline.element;
         expect(element.kind, ElementKind.GETTER);
         expect(element.name, "propA");
@@ -777,7 +792,7 @@
       }
       // propB
       {
-        Outline outline = topOutlines[8];
+        Outline outline = topOutlines[9];
         Element element = outline.element;
         expect(element.kind, ElementKind.SETTER);
         expect(element.name, "propB");
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index 5913930..efd1c16 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -191,34 +191,6 @@
     });
   }
 
-  test_getAnalysisContext_nested() {
-    String dir1Path = '/dir1';
-    String dir2Path = dir1Path + '/dir2';
-    String filePath = dir2Path + '/file.dart';
-    Folder dir1 = resourceProvider.newFolder(dir1Path);
-    Folder dir2 = resourceProvider.newFolder(dir2Path);
-    resourceProvider.newFile(filePath, 'library lib;');
-
-    AnalysisContext context1 = AnalysisEngine.instance.createAnalysisContext();
-    AnalysisContext context2 = AnalysisEngine.instance.createAnalysisContext();
-    server.folderMap[dir1] = context1;
-    server.folderMap[dir2] = context2;
-
-    expect(server.getAnalysisContext(filePath), context2);
-  }
-
-  test_getAnalysisContext_simple() {
-    String dirPath = '/dir';
-    String filePath = dirPath + '/file.dart';
-    Folder dir = resourceProvider.newFolder(dirPath);
-    resourceProvider.newFile(filePath, 'library lib;');
-
-    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
-    server.folderMap[dir] = context;
-
-    expect(server.getAnalysisContext(filePath), context);
-  }
-
   Future test_getAnalysisContextForSource() {
     // Subscribe to STATUS so we'll know when analysis is done.
     server.serverServices = [ServerService.STATUS].toSet();
@@ -311,25 +283,6 @@
     expect(source.fullName, filePath);
   }
 
-  test_operationsRemovedOnContextDisposal() async {
-    resourceProvider.newFolder('/foo');
-    resourceProvider.newFile('/foo/baz.dart', 'library lib;');
-    resourceProvider.newFolder('/bar');
-    resourceProvider.newFile('/bar/baz.dart', 'library lib;');
-    server.setAnalysisRoots('0', ['/foo', '/bar'], [], {});
-    await pumpEventQueue();
-    AnalysisContext contextFoo = server.getAnalysisContext('/foo/baz.dart');
-    AnalysisContext contextBar = server.getAnalysisContext('/bar/baz.dart');
-    _MockServerOperation operationFoo = new _MockServerOperation(contextFoo);
-    _MockServerOperation operationBar = new _MockServerOperation(contextBar);
-    server.scheduleOperation(operationFoo);
-    server.scheduleOperation(operationBar);
-    server.setAnalysisRoots('1', ['/foo'], [], {});
-    await pumpEventQueue();
-    expect(operationFoo.isComplete, isTrue);
-    expect(operationBar.isComplete, isFalse);
-  }
-
   /**
    * Test that having multiple analysis contexts analyze the same file doesn't
    * cause that file to receive duplicate notifications when it's modified.
@@ -377,6 +330,25 @@
     }
   }
 
+  test_operationsRemovedOnContextDisposal() async {
+    resourceProvider.newFolder('/foo');
+    resourceProvider.newFile('/foo/baz.dart', 'library lib;');
+    resourceProvider.newFolder('/bar');
+    resourceProvider.newFile('/bar/baz.dart', 'library lib;');
+    server.setAnalysisRoots('0', ['/foo', '/bar'], [], {});
+    await pumpEventQueue();
+    AnalysisContext contextFoo = server.getAnalysisContext('/foo/baz.dart');
+    AnalysisContext contextBar = server.getAnalysisContext('/bar/baz.dart');
+    _MockServerOperation operationFoo = new _MockServerOperation(contextFoo);
+    _MockServerOperation operationBar = new _MockServerOperation(contextBar);
+    server.scheduleOperation(operationFoo);
+    server.scheduleOperation(operationBar);
+    server.setAnalysisRoots('1', ['/foo'], [], {});
+    await pumpEventQueue();
+    expect(operationFoo.isComplete, isTrue);
+    expect(operationBar.isComplete, isFalse);
+  }
+
   Future test_prioritySourcesChangedEvent() {
     resourceProvider.newFolder('/foo');
 
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index 633c380..1909ee9 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -1178,6 +1178,7 @@
  *   "flags": int
  *   "parameters": optional String
  *   "returnType": optional String
+ *   "typeParameters": optional String
  * }
  */
 final Matcher isElement = new LazyMatcher(() => new MatchesJsonObject(
@@ -1188,7 +1189,8 @@
   }, optionalFields: {
     "location": isLocation,
     "parameters": isString,
-    "returnType": isString
+    "returnType": isString,
+    "typeParameters": isString
   }));
 
 /**
@@ -1444,6 +1446,7 @@
  *   "length": int
  *   "containingLibraryPath": optional String
  *   "containingLibraryName": optional String
+ *   "containingClassDescription": optional String
  *   "dartdoc": optional String
  *   "elementDescription": optional String
  *   "elementKind": optional String
@@ -1459,6 +1462,7 @@
   }, optionalFields: {
     "containingLibraryPath": isString,
     "containingLibraryName": isString,
+    "containingClassDescription": isString,
     "dartdoc": isString,
     "elementDescription": isString,
     "elementKind": isString,
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 8a3851b..26aae55 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -195,24 +195,38 @@
   void test_fromElement_CLASS() {
     engine.Source source = addSource('/test.dart', '''
 @deprecated
-abstract class _MyClass {}''');
+abstract class _A {}
+class B<K, V> {}''');
     engine.CompilationUnit unit = resolveLibraryUnit(source);
-    engine.ClassElement engineElement = findElementInUnit(unit, '_MyClass');
-    // create notification Element
-    Element element = newElement_fromEngine(engineElement);
-    expect(element.kind, ElementKind.CLASS);
-    expect(element.name, '_MyClass');
     {
-      Location location = element.location;
-      expect(location.file, '/test.dart');
-      expect(location.offset, 27);
-      expect(location.length, '_MyClass'.length);
-      expect(location.startLine, 2);
-      expect(location.startColumn, 16);
+      engine.ClassElement engineElement = findElementInUnit(unit, '_A');
+      // create notification Element
+      Element element = newElement_fromEngine(engineElement);
+      expect(element.kind, ElementKind.CLASS);
+      expect(element.name, '_A');
+      expect(element.typeParameters, isNull);
+      {
+        Location location = element.location;
+        expect(location.file, '/test.dart');
+        expect(location.offset, 27);
+        expect(location.length, '_A'.length);
+        expect(location.startLine, 2);
+        expect(location.startColumn, 16);
+      }
+      expect(element.parameters, isNull);
+      expect(element.flags, Element.FLAG_ABSTRACT |
+          Element.FLAG_DEPRECATED |
+          Element.FLAG_PRIVATE);
     }
-    expect(element.parameters, isNull);
-    expect(element.flags,
-        Element.FLAG_ABSTRACT | Element.FLAG_DEPRECATED | Element.FLAG_PRIVATE);
+    {
+      engine.ClassElement engineElement = findElementInUnit(unit, 'B');
+      // create notification Element
+      Element element = newElement_fromEngine(engineElement);
+      expect(element.kind, ElementKind.CLASS);
+      expect(element.name, 'B');
+      expect(element.typeParameters, '<K, V>');
+      expect(element.flags, 0);
+    }
   }
 
   void test_fromElement_CONSTRUCTOR() {
@@ -227,6 +241,7 @@
     Element element = newElement_fromEngine(engineElement);
     expect(element.kind, ElementKind.CONSTRUCTOR);
     expect(element.name, 'myConstructor');
+    expect(element.typeParameters, isNull);
     {
       Location location = element.location;
       expect(location.file, '/test.dart');
@@ -278,20 +293,21 @@
 
   void test_fromElement_FUNCTION_TYPE_ALIAS() {
     engine.Source source = addSource('/test.dart', '''
-typedef int f(String x);
+typedef int F<T>(String x);
 ''');
     engine.CompilationUnit unit = resolveLibraryUnit(source);
     engine.FunctionTypeAliasElement engineElement =
-        findElementInUnit(unit, 'f');
+        findElementInUnit(unit, 'F');
     // create notification Element
     Element element = newElement_fromEngine(engineElement);
     expect(element.kind, ElementKind.FUNCTION_TYPE_ALIAS);
-    expect(element.name, 'f');
+    expect(element.name, 'F');
+    expect(element.typeParameters, '<T>');
     {
       Location location = element.location;
       expect(location.file, '/test.dart');
       expect(location.offset, 12);
-      expect(location.length, 'f'.length);
+      expect(location.length, 'F'.length);
       expect(location.startLine, 1);
       expect(location.startColumn, 13);
     }
diff --git a/pkg/analysis_server/test/reflective_tests.dart b/pkg/analysis_server/test/reflective_tests.dart
index f421e6c..8180cf7 100644
--- a/pkg/analysis_server/test/reflective_tests.dart
+++ b/pkg/analysis_server/test/reflective_tests.dart
@@ -75,7 +75,7 @@
   var invocationResult = null;
   try {
     invocationResult = instanceMirror.invoke(symbol, []).reflectee;
-  } on NoSuchMethodError catch (e) {}
+  } on NoSuchMethodError {}
   if (invocationResult is Future) {
     return invocationResult;
   } else {
diff --git a/pkg/analysis_server/test/services/completion/completion_target_test.dart b/pkg/analysis_server/test/services/completion/completion_target_test.dart
index 16983af..0bf95cf 100644
--- a/pkg/analysis_server/test/services/completion/completion_target_test.dart
+++ b/pkg/analysis_server/test/services/completion/completion_target_test.dart
@@ -475,9 +475,9 @@
   }
 
   test_TypeArgumentList() {
-    // SimpleIdentifier  BinaryExpression  ExpressionStatement
+    // TypeName  TypeArgumentList  TypeName
     addTestSource('main() { C<^> c; }');
-    assertTarget('', 'C < ');
+    assertTarget('', '<>');
   }
 
   test_TypeArgumentList2() {
diff --git a/pkg/analysis_server/test/services/completion/local_computer_test.dart b/pkg/analysis_server/test/services/completion/local_computer_test.dart
index fed9d0f..e0aca46 100644
--- a/pkg/analysis_server/test/services/completion/local_computer_test.dart
+++ b/pkg/analysis_server/test/services/completion/local_computer_test.dart
@@ -194,15 +194,6 @@
     assertNotSuggested('x');
   }
 
-  test_overrides() {
-    addTestSource('''
-class A {m() {}}
-class B extends A {m() {^}}
-''');
-    expect(computeFast(), isTrue);
-    assertSuggestMethod('m', 'B', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
-  }
-
   test_break_ignores_unrelated_statements() {
     addTestSource('''
 void main() {
@@ -576,6 +567,13 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
+  test_ignore_symbol_being_completed() {
+    addTestSource('class MyClass { } main(MC^) { }');
+    expect(computeFast(), isTrue);
+    assertSuggestLocalClass('MyClass');
+    assertNotSuggested('MC');
+  }
+
   test_InstanceCreationExpression() {
     addTestSource('''
 class A {foo(){var f; {var x;}}}
@@ -743,6 +741,15 @@
     expect(suggestion.hasNamedParameters, false);
   }
 
+  test_overrides() {
+    addTestSource('''
+class A {m() {}}
+class B extends A {m() {^}}
+''');
+    expect(computeFast(), isTrue);
+    assertSuggestMethod('m', 'B', null, relevance: DART_RELEVANCE_LOCAL_METHOD);
+  }
+
   test_shadowed_name() {
     addTestSource('var a; class A { var a; m() { ^ } }');
     expect(computeFast(), isTrue);
diff --git a/pkg/analysis_server/test/services/completion/optype_test.dart b/pkg/analysis_server/test/services/completion/optype_test.dart
index 897fb20..a2634b1 100644
--- a/pkg/analysis_server/test/services/completion/optype_test.dart
+++ b/pkg/analysis_server/test/services/completion/optype_test.dart
@@ -657,6 +657,18 @@
     assertOpType(typeNames: true);
   }
 
+  test_FunctionExpression() {
+    // BlockFunctionBody  FunctionExpression  FunctionDeclaration
+    addTestSource('main()^ { int b = 2; b++; b. }');
+    assertOpType();
+  }
+
+  test_FunctionExpressionInvocation() {
+    // ArgumentList  FunctionExpressionInvocation  ExpressionStatement
+    addTestSource('main() { ((x) => x + 7)^(2) }');
+    assertOpType();
+  }
+
   test_FunctionTypeAlias() {
     // SimpleIdentifier  FunctionTypeAlias  CompilationUnit
     addTestSource('typedef n^ ;');
@@ -982,6 +994,12 @@
     assertOpType(invocation: true);
   }
 
+  test_PostfixExpression() {
+    // SimpleIdentifier  PostfixExpression  ForStatement
+    addTestSource('int x = 0; main() {ax+^+;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
   test_PrefixedIdentifier_class_const() {
     // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
     addTestSource('main() {A.^}');
@@ -1056,6 +1074,12 @@
     assertOpType(invocation: true);
   }
 
+  test_ThrowExpression() {
+    // SimpleIdentifier  ThrowExpression  ExpressionStatement
+    addTestSource('main() {throw ^;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
   test_TopLevelVariableDeclaration_typed_name() {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index d3c11d0..52764fe 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -97,6 +97,73 @@
     length = 0;
   }
 
+  void test_addTypeAnnotation_BAD_privateType_closureParameter() {
+    addSource('/my_lib.dart', '''
+library my_lib;
+class A {}
+class _B extends A {}
+foo(f(_B p)) {}
+''');
+    resolveTestUnit('''
+import 'my_lib.dart';
+main() {
+  foo((test) {});
+}
+ ''');
+    assertNoAssistAt('test)', AssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  void test_addTypeAnnotation_BAD_privateType_declaredIdentifier() {
+    addSource('/my_lib.dart', '''
+library my_lib;
+class A {}
+class _B extends A {}
+List<_B> getValues() => [];
+''');
+    resolveTestUnit('''
+import 'my_lib.dart';
+class A<T> {
+  main() {
+    for (var item in getValues()) {
+    }
+  }
+}
+''');
+    assertNoAssistAt('var item', AssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  void test_addTypeAnnotation_BAD_privateType_list() {
+    addSource('/my_lib.dart', '''
+library my_lib;
+class A {}
+class _B extends A {}
+List<_B> getValues() => [];
+''');
+    resolveTestUnit('''
+import 'my_lib.dart';
+main() {
+  var v = getValues();
+}
+''');
+    assertNoAssistAt('var ', AssistKind.ADD_TYPE_ANNOTATION);
+  }
+
+  void test_addTypeAnnotation_BAD_privateType_variable() {
+    addSource('/my_lib.dart', '''
+library my_lib;
+class A {}
+class _B extends A {}
+_B getValue() => new _B();
+''');
+    resolveTestUnit('''
+import 'my_lib.dart';
+main() {
+  var v = getValue();
+}
+''');
+    assertNoAssistAt('var ', AssistKind.ADD_TYPE_ANNOTATION);
+  }
+
   void test_addTypeAnnotation_classField_OK_final() {
     resolveTestUnit('''
 class A {
@@ -520,6 +587,23 @@
     assertNoAssistAt('var ', AssistKind.ADD_TYPE_ANNOTATION);
   }
 
+  void test_addTypeAnnotation_OK_privateType_sameLibrary() {
+    resolveTestUnit('''
+class _A {}
+_A getValue() => new _A();
+main() {
+  var v = getValue();
+}
+''');
+    assertHasAssistAt('var ', AssistKind.ADD_TYPE_ANNOTATION, '''
+class _A {}
+_A getValue() => new _A();
+main() {
+  _A v = getValue();
+}
+''');
+  }
+
   void test_addTypeAnnotation_parameter_BAD_hasExplicitType() {
     resolveTestUnit('''
 foo(f(int p)) {}
@@ -846,6 +930,153 @@
     assertNoAssistAt('fff()', AssistKind.CONVERT_INTO_EXPRESSION_BODY);
   }
 
+  void test_convertToForIndex_BAD_bodyNotBlock() {
+    resolveTestUnit('''
+main(List<String> items) {
+  for (String item in items) print(item);
+}
+''');
+    assertNoAssistAt('for (String', AssistKind.CONVERT_INTO_FOR_INDEX);
+  }
+
+  void test_convertToForIndex_BAD_doesNotDeclareVariable() {
+    resolveTestUnit('''
+main(List<String> items) {
+  String item;
+  for (item in items) {
+    print(item);
+  }
+}
+''');
+    assertNoAssistAt('for (item', AssistKind.CONVERT_INTO_FOR_INDEX);
+  }
+
+  void test_convertToForIndex_BAD_iterableIsNotVariable() {
+    resolveTestUnit('''
+main() {
+  for (String item in ['a', 'b', 'c']) {
+    print(item);
+  }
+}
+''');
+    assertNoAssistAt('for (String', AssistKind.CONVERT_INTO_FOR_INDEX);
+  }
+
+  void test_convertToForIndex_BAD_iterableNotList() {
+    resolveTestUnit('''
+main(Iterable<String> items) {
+  for (String item in items) {
+    print(item);
+  }
+}
+''');
+    assertNoAssistAt('for (String', AssistKind.CONVERT_INTO_FOR_INDEX);
+  }
+
+  void test_convertToForIndex_BAD_usesIJK() {
+    resolveTestUnit('''
+main(List<String> items) {
+  for (String item in items) {
+    print(item);
+    int i, j, k;
+  }
+}
+''');
+    assertNoAssistAt('for (String', AssistKind.CONVERT_INTO_FOR_INDEX);
+  }
+
+  void test_convertToForIndex_OK_onDeclaredIdentifier_name() {
+    resolveTestUnit('''
+main(List<String> items) {
+  for (String item in items) {
+    print(item);
+  }
+}
+''');
+    assertHasAssistAt('item in', AssistKind.CONVERT_INTO_FOR_INDEX, '''
+main(List<String> items) {
+  for (int i = 0; i < items.length; i++) {
+    String item = items[i];
+    print(item);
+  }
+}
+''');
+  }
+
+  void test_convertToForIndex_OK_onDeclaredIdentifier_type() {
+    resolveTestUnit('''
+main(List<String> items) {
+  for (String item in items) {
+    print(item);
+  }
+}
+''');
+    assertHasAssistAt('tring item', AssistKind.CONVERT_INTO_FOR_INDEX, '''
+main(List<String> items) {
+  for (int i = 0; i < items.length; i++) {
+    String item = items[i];
+    print(item);
+  }
+}
+''');
+  }
+
+  void test_convertToForIndex_OK_onFor() {
+    resolveTestUnit('''
+main(List<String> items) {
+  for (String item in items) {
+    print(item);
+  }
+}
+''');
+    assertHasAssistAt('for (String', AssistKind.CONVERT_INTO_FOR_INDEX, '''
+main(List<String> items) {
+  for (int i = 0; i < items.length; i++) {
+    String item = items[i];
+    print(item);
+  }
+}
+''');
+  }
+
+  void test_convertToForIndex_OK_usesI() {
+    resolveTestUnit('''
+main(List<String> items) {
+  for (String item in items) {
+    int i = 0;
+  }
+}
+''');
+    assertHasAssistAt('for (String', AssistKind.CONVERT_INTO_FOR_INDEX, '''
+main(List<String> items) {
+  for (int j = 0; j < items.length; j++) {
+    String item = items[j];
+    int i = 0;
+  }
+}
+''');
+  }
+
+  void test_convertToForIndex_OK_usesIJ() {
+    resolveTestUnit('''
+main(List<String> items) {
+  for (String item in items) {
+    print(item);
+    int i = 0, j = 1;
+  }
+}
+''');
+    assertHasAssistAt('for (String', AssistKind.CONVERT_INTO_FOR_INDEX, '''
+main(List<String> items) {
+  for (int k = 0; k < items.length; k++) {
+    String item = items[k];
+    print(item);
+    int i = 0, j = 1;
+  }
+}
+''');
+  }
+
   void test_convertToIsNot_OK_childOfIs_left() {
     resolveTestUnit('''
 main(p) {
@@ -1345,7 +1576,7 @@
     assertNoAssistAt('if (p', AssistKind.INTRODUCE_LOCAL_CAST_TYPE);
   }
 
-  void test_introduceLocalTestedType_OK_if() {
+  void test_introduceLocalTestedType_OK_if_is() {
     resolveTestUnit('''
 class MyTypeName {}
 main(p) {
@@ -1373,6 +1604,34 @@
     assertHasAssistAt('if (p', AssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
   }
 
+  void test_introduceLocalTestedType_OK_if_isNot() {
+    resolveTestUnit('''
+class MyTypeName {}
+main(p) {
+  if (p is! MyTypeName) {
+    return;
+  }
+}
+''');
+    String expected = '''
+class MyTypeName {}
+main(p) {
+  if (p is! MyTypeName) {
+    return;
+  }
+  MyTypeName myTypeName = p;
+}
+''';
+    assertHasAssistAt(
+        'is! MyType', AssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
+    _assertLinkedGroup(change.linkedEditGroups[0], [
+      'myTypeName = '
+    ], expectedSuggestions(
+        LinkedEditSuggestionKind.VARIABLE, ['myTypeName', 'typeName', 'name']));
+    // another good location
+    assertHasAssistAt('if (p', AssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
+  }
+
   void test_introduceLocalTestedType_OK_while() {
     resolveTestUnit('''
 main(p) {
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 339645b..aa12e4d 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -26,7 +26,13 @@
 
 @reflectiveTest
 class FixProcessorTest extends AbstractSingleUnitTest {
-  AnalysisErrorFilter errorFilter = null;
+  AnalysisErrorFilter errorFilter = (AnalysisError error) {
+    return 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_LOCAL_VARIABLE;
+  };
 
   Fix fix;
   SourceChange change;
@@ -97,6 +103,63 @@
     verifyNoTestUnitErrors = false;
   }
 
+  void test_addFieldFormalParameters_hasRequiredParameter() {
+    resolveTestUnit('''
+class Test {
+  final int a;
+  final int b;
+  final int c;
+  Test(this.a);
+}
+''');
+    assertHasFix(FixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
+class Test {
+  final int a;
+  final int b;
+  final int c;
+  Test(this.a, this.b, this.c);
+}
+''');
+  }
+
+  void test_addFieldFormalParameters_noParameters() {
+    resolveTestUnit('''
+class Test {
+  final int a;
+  final int b;
+  final int c;
+  Test();
+}
+''');
+    assertHasFix(FixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
+class Test {
+  final int a;
+  final int b;
+  final int c;
+  Test(this.a, this.b, this.c);
+}
+''');
+  }
+
+  void test_addFieldFormalParameters_noRequiredParameter() {
+    resolveTestUnit('''
+class Test {
+  final int a;
+  final int b;
+  final int c;
+  Test([this.c]);
+}
+''');
+    assertHasFix(FixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
+class Test {
+  final int a;
+  final int b;
+  final int c;
+  Test(this.a, this.b, [this.c]);
+}
+''');
+  }
+
   void test_addSync_blockFunctionBody() {
     resolveTestUnit('''
 foo() {}
@@ -287,6 +350,28 @@
     _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
   }
 
+  void test_createConstructor_forFinalFields() {
+    errorFilter = (AnalysisError error) {
+      return error.message.contains("'a'");
+    };
+    resolveTestUnit('''
+class Test {
+  final int a;
+  final int b = 2;
+  final int c;
+}
+''');
+    assertHasFix(FixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS, '''
+class Test {
+  final int a;
+  final int b = 2;
+  final int c;
+
+  Test(this.a, this.c);
+}
+''');
+  }
+
   void test_createConstructor_insteadOfSyntheticDefault() {
     resolveTestUnit('''
 class A {
@@ -673,6 +758,46 @@
 ''');
   }
 
+  void test_createField_hint() {
+    resolveTestUnit('''
+class A {
+}
+main(A a) {
+  var x = a;
+  int v = x.test;
+}
+''');
+    assertHasFix(FixKind.CREATE_FIELD, '''
+class A {
+  int test;
+}
+main(A a) {
+  var x = a;
+  int v = x.test;
+}
+''');
+  }
+
+  void test_createField_hint_setter() {
+    resolveTestUnit('''
+class A {
+}
+main(A a) {
+  var x = a;
+  x.test = 0;
+}
+''');
+    assertHasFix(FixKind.CREATE_FIELD, '''
+class A {
+  int test;
+}
+main(A a) {
+  var x = a;
+  x.test = 0;
+}
+''');
+  }
+
   void test_createField_importType() {
     addSource('/libA.dart', r'''
 library libA;
@@ -871,6 +996,24 @@
     expect(fileEdit.edits[0].replacement, contains('library my.file;'));
   }
 
+  void test_createFile_forPart() {
+    testFile = '/my/project/bin/test.dart';
+    resolveTestUnit('''
+library my.lib;
+part 'my_part.dart';
+''');
+    AnalysisError error = _findErrorToFix();
+    fix = _assertHasFix(FixKind.CREATE_FILE, error);
+    change = fix.change;
+    // validate change
+    List<SourceFileEdit> fileEdits = change.edits;
+    expect(fileEdits, hasLength(1));
+    SourceFileEdit fileEdit = change.edits[0];
+    expect(fileEdit.file, '/my/project/bin/my_part.dart');
+    expect(fileEdit.fileStamp, -1);
+    expect(fileEdit.edits[0].replacement, contains('part of my.lib;'));
+  }
+
   void test_createGetter_BAD_inSDK() {
     resolveTestUnit('''
 main(List p) {
@@ -880,6 +1023,26 @@
     assertNoFix(FixKind.CREATE_GETTER);
   }
 
+  void test_createGetter_hint_getter() {
+    resolveTestUnit('''
+class A {
+}
+main(A a) {
+  var x = a;
+  int v = x.test;
+}
+''');
+    assertHasFix(FixKind.CREATE_GETTER, '''
+class A {
+  int get test => null;
+}
+main(A a) {
+  var x = a;
+  int v = x.test;
+}
+''');
+  }
+
   void test_createGetter_multiLevel() {
     resolveTestUnit('''
 class A {
@@ -1748,6 +1911,71 @@
 ''');
   }
 
+  void test_illegalAsyncReturnType_asyncLibrary_import() {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+    };
+    resolveTestUnit('''
+library main;
+int main() async {
+}
+''');
+    assertHasFix(FixKind.REPLACE_RETURN_TYPE_FUTURE, '''
+library main;
+import 'dart:async';
+Future<int> main() async {
+}
+''');
+  }
+
+  void test_illegalAsyncReturnType_asyncLibrary_usePrefix() {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+    };
+    resolveTestUnit('''
+import 'dart:async' as al;
+int main() async {
+}
+''');
+    assertHasFix(FixKind.REPLACE_RETURN_TYPE_FUTURE, '''
+import 'dart:async' as al;
+al.Future<int> main() async {
+}
+''');
+  }
+
+  void test_illegalAsyncReturnType_complexTypeName() {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+    };
+    resolveTestUnit('''
+import 'dart:async';
+List<int> main() async {
+}
+''');
+    assertHasFix(FixKind.REPLACE_RETURN_TYPE_FUTURE, '''
+import 'dart:async';
+Future<List<int>> main() async {
+}
+''');
+  }
+
+  void test_illegalAsyncReturnType_void() {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE;
+    };
+    resolveTestUnit('''
+import 'dart:async';
+void main() async {
+}
+''');
+    assertHasFix(FixKind.REPLACE_RETURN_TYPE_FUTURE, '''
+import 'dart:async';
+Future main() async {
+}
+''');
+  }
+
   void test_importLibraryPackage_withClass() {
     _configureMyPkg('''
 library my_lib;
@@ -2217,6 +2445,46 @@
 ''');
   }
 
+  void test_removeUnusedCatchClause() {
+    errorFilter = (AnalysisError error) => true;
+    resolveTestUnit('''
+main() {
+  try {
+    throw 42;
+  } on int catch (e) {
+  }
+}
+''');
+    assertHasFix(FixKind.REMOVE_UNUSED_CATCH_CLAUSE, '''
+main() {
+  try {
+    throw 42;
+  } on int {
+  }
+}
+''');
+  }
+
+  void test_removeUnusedCatchStack() {
+    errorFilter = (AnalysisError error) => true;
+    resolveTestUnit('''
+main() {
+  try {
+    throw 42;
+  } catch (e, stack) {
+  }
+}
+''');
+    assertHasFix(FixKind.REMOVE_UNUSED_CATCH_STACK, '''
+main() {
+  try {
+    throw 42;
+  } catch (e) {
+  }
+}
+''');
+  }
+
   void test_removeUnusedImport() {
     resolveTestUnit('''
 import 'dart:math';
@@ -2656,6 +2924,84 @@
 ''');
   }
 
+  void test_undefinedGetter_useSimilar_hint() {
+    resolveTestUnit('''
+class A {
+  int myField;
+}
+main(A a) {
+  var x = a;
+  print(x.myFild);
+}
+''');
+    assertHasFix(FixKind.CHANGE_TO, '''
+class A {
+  int myField;
+}
+main(A a) {
+  var x = a;
+  print(x.myField);
+}
+''');
+  }
+
+  void test_undefinedGetter_useSimilar_qualified() {
+    resolveTestUnit('''
+class A {
+  int myField;
+}
+main(A a) {
+  print(a.myFild);
+}
+''');
+    assertHasFix(FixKind.CHANGE_TO, '''
+class A {
+  int myField;
+}
+main(A a) {
+  print(a.myField);
+}
+''');
+  }
+
+  void test_undefinedGetter_useSimilar_qualified_static() {
+    resolveTestUnit('''
+class A {
+  static int MY_NAME = 1;
+}
+main() {
+  A.MY_NAM;
+}
+''');
+    assertHasFix(FixKind.CHANGE_TO, '''
+class A {
+  static int MY_NAME = 1;
+}
+main() {
+  A.MY_NAME;
+}
+''');
+  }
+
+  void test_undefinedGetter_useSimilar_unqualified() {
+    resolveTestUnit('''
+class A {
+  int myField;
+  main() {
+    print(myFild);
+  }
+}
+''');
+    assertHasFix(FixKind.CHANGE_TO, '''
+class A {
+  int myField;
+  main() {
+    print(myField);
+  }
+}
+''');
+  }
+
   void test_undefinedMethod_create_BAD_inSDK() {
     resolveTestUnit('''
 main() {
@@ -2846,26 +3192,26 @@
     int index = 0;
     _assertLinkedGroup(
         change.linkedEditGroups[index++], ['void myUndefinedMethod(']);
-    _assertLinkedGroup(change.linkedEditGroups[index++],
-        ['myUndefinedMethod(0', 'myUndefinedMethod(int']);
+    _assertLinkedGroup(change.linkedEditGroups[index++], [
+      'myUndefinedMethod(0',
+      'myUndefinedMethod(int'
+    ]);
     _assertLinkedGroup(change.linkedEditGroups[index++], [
       'int i'
     ], expectedSuggestions(
         LinkedEditSuggestionKind.TYPE, ['int', 'num', 'Object', 'Comparable']));
     _assertLinkedGroup(change.linkedEditGroups[index++], ['i,']);
-    _assertLinkedGroup(change.linkedEditGroups[index++], [
-      'double d'
-    ], expectedSuggestions(LinkedEditSuggestionKind.TYPE, [
+    _assertLinkedGroup(change.linkedEditGroups[index++], ['double d'],
+        expectedSuggestions(LinkedEditSuggestionKind.TYPE, [
       'double',
       'num',
       'Object',
       'Comparable'
     ]));
     _assertLinkedGroup(change.linkedEditGroups[index++], ['d,']);
-    _assertLinkedGroup(change.linkedEditGroups[index++], [
-      'String s'
-    ], expectedSuggestions(
-        LinkedEditSuggestionKind.TYPE, ['String', 'Object', 'Comparable']));
+    _assertLinkedGroup(change.linkedEditGroups[index++], ['String s'],
+        expectedSuggestions(
+            LinkedEditSuggestionKind.TYPE, ['String', 'Object', 'Comparable']));
     _assertLinkedGroup(change.linkedEditGroups[index++], ['s)']);
   }
 
@@ -2889,8 +3235,10 @@
 ''');
     // linked positions
     _assertLinkedGroup(change.linkedEditGroups[0], ['int myUndefinedMethod(']);
-    _assertLinkedGroup(change.linkedEditGroups[1],
-        ['myUndefinedMethod();', 'myUndefinedMethod() {']);
+    _assertLinkedGroup(change.linkedEditGroups[1], [
+      'myUndefinedMethod();',
+      'myUndefinedMethod() {'
+    ]);
   }
 
   void test_undefinedMethod_createUnqualified_staticFromField() {
@@ -3022,6 +3370,65 @@
 ''');
   }
 
+  void test_undefinedSetter_useSimilar_hint() {
+    resolveTestUnit('''
+class A {
+  int myField;
+}
+main(A a) {
+  var x = a;
+  x.myFild = 42;
+}
+''');
+    assertHasFix(FixKind.CHANGE_TO, '''
+class A {
+  int myField;
+}
+main(A a) {
+  var x = a;
+  x.myField = 42;
+}
+''');
+  }
+
+  void test_undefinedSetter_useSimilar_qualified() {
+    resolveTestUnit('''
+class A {
+  int myField;
+}
+main(A a) {
+  a.myFild = 42;
+}
+''');
+    assertHasFix(FixKind.CHANGE_TO, '''
+class A {
+  int myField;
+}
+main(A a) {
+  a.myField = 42;
+}
+''');
+  }
+
+  void test_undefinedSetter_useSimilar_unqualified() {
+    resolveTestUnit('''
+class A {
+  int myField;
+  main() {
+    myFild = 42;
+  }
+}
+''');
+    assertHasFix(FixKind.CHANGE_TO, '''
+class A {
+  int myField;
+  main() {
+    myField = 42;
+  }
+}
+''');
+  }
+
   void test_useEffectiveIntegerDivision() {
     resolveTestUnit('''
 main() {
@@ -3079,11 +3486,6 @@
 
   AnalysisError _findErrorToFix() {
     List<AnalysisError> errors = context.computeErrors(testSource);
-    errors.removeWhere((error) {
-      return error.errorCode == HintCode.UNUSED_ELEMENT ||
-          error.errorCode == HintCode.UNUSED_FIELD ||
-          error.errorCode == HintCode.UNUSED_LOCAL_VARIABLE;
-    });
     if (errorFilter != null) {
       errors = errors.where(errorFilter).toList();
     }
diff --git a/pkg/analysis_server/test/services/correction/sort_members_test.dart b/pkg/analysis_server/test/services/correction/sort_members_test.dart
index b0f96a4..46ff0d7 100644
--- a/pkg/analysis_server/test/services/correction/sort_members_test.dart
+++ b/pkg/analysis_server/test/services/correction/sort_members_test.dart
@@ -354,6 +354,37 @@
 ''');
   }
 
+  void test_directives_comments() {
+    _parseTestUnit(r'''
+// header
+library lib;
+
+import 'c.dart';// c
+import 'a.dart';// aa
+import 'b.dart';// bbb
+
+/** doc */
+main() {
+}
+''');
+    // validate change
+    _assertSort(r'''
+// header
+library lib;
+
+import 'a.dart';
+import 'b.dart';
+import 'c.dart';
+// c
+// aa
+// bbb
+
+/** doc */
+main() {
+}
+''');
+  }
+
   void test_unitMembers_class() {
     _parseTestUnit(r'''
 class C {}
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 13e7ed7..bec57bd 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -860,129 +860,10 @@
 ''');
   }
 
-  test_getExtractGetter_false_do() async {
+  test_getExtractGetter_expression_true_binaryExpression() async {
     indexTestUnit('''
 main() {
-// start
-  int v = 0;
-  do {
-    v++;
-  } while (v < 10);
-// end
-  print(v);
-}
-''');
-    _createRefactoringForStartEndComments();
-    // apply refactoring
-    await assertRefactoringConditionsOK();
-    expect(refactoring.createGetter, false);
-  }
-
-  test_getExtractGetter_false_for() async {
-    indexTestUnit('''
-main() {
-// start
-  int v = 0;
-  for (int i = 0; i < 10; i++) {
-    v += i;
-  }
-// end
-  print(v);
-}
-''');
-    _createRefactoringForStartEndComments();
-    // apply refactoring
-    await assertRefactoringConditionsOK();
-    expect(refactoring.createGetter, false);
-  }
-
-  test_getExtractGetter_false_forEach() async {
-    indexTestUnit('''
-main() {
-// start
-  int v = 0;
-  for (int i in [1, 2, 3]) {
-    v += i;
-  }
-// end
-  print(v);
-}
-''');
-    _createRefactoringForStartEndComments();
-    // apply refactoring
-    await assertRefactoringConditionsOK();
-    expect(refactoring.createGetter, false);
-  }
-
-  test_getExtractGetter_false_methodInvocation_expression() async {
-    indexTestUnit('''
-main() {
-  int v = calculateSomething() + 5;
-}
-int calculateSomething() => 42;
-''');
-    _createRefactoringForString('calculateSomething() + 5');
-    // apply refactoring
-    await assertRefactoringConditionsOK();
-    expect(refactoring.createGetter, false);
-  }
-
-  test_getExtractGetter_false_methodInvocation_statements() async {
-    indexTestUnit('''
-main() {
-// start
-  int v = calculateSomething();
-// end
-  print(v);
-}
-int calculateSomething() => 42;
-''');
-    _createRefactoringForStartEndComments();
-    // apply refactoring
-    await assertRefactoringConditionsOK();
-    expect(refactoring.createGetter, false);
-  }
-
-  test_getExtractGetter_false_while() async {
-    indexTestUnit('''
-main() {
-// start
-  int v = 0;
-  while (v < 10) {
-    v++;
-  }
-// end
-  print(v);
-}
-''');
-    _createRefactoringForStartEndComments();
-    // apply refactoring
-    await assertRefactoringConditionsOK();
-    expect(refactoring.createGetter, false);
-  }
-
-  test_getExtractGetter_true_simpleBlock() async {
-    indexTestUnit('''
-main() {
-// start
-  int v = 1 + 2;
-// end
-  print(v);
-}
-''');
-    _createRefactoringForStartEndComments();
-    // apply refactoring
-    await assertRefactoringConditionsOK();
-    expect(refactoring.createGetter, true);
-  }
-
-  test_getExtractGetter_true_singleExpression() async {
-    indexTestUnit('''
-main() {
-// start
-  int v = 1 + 2;
-// end
-  print(v);
+  print(1 + 2);
 }
 ''');
     _createRefactoringForString('1 + 2');
@@ -991,6 +872,70 @@
     expect(refactoring.createGetter, true);
   }
 
+  test_getExtractGetter_expression_true_literal() async {
+    indexTestUnit('''
+main() {
+  print(42);
+}
+''');
+    _createRefactoringForString('42');
+    // apply refactoring
+    await assertRefactoringConditionsOK();
+    expect(refactoring.createGetter, true);
+  }
+
+  test_getExtractGetter_expression_true_prefixedExpression() async {
+    indexTestUnit('''
+main() {
+  print(!true);
+}
+''');
+    _createRefactoringForString('!true');
+    // apply refactoring
+    await assertRefactoringConditionsOK();
+    expect(refactoring.createGetter, true);
+  }
+
+  test_getExtractGetter_expression_true_prefixedIdentifier() async {
+    indexTestUnit('''
+main() {
+  print(myValue.isEven);
+}
+int get myValue => 42;
+''');
+    _createRefactoringForString('myValue.isEven');
+    // apply refactoring
+    await assertRefactoringConditionsOK();
+    expect(refactoring.createGetter, true);
+  }
+
+  test_getExtractGetter_expression_true_propertyAccess() async {
+    indexTestUnit('''
+main() {
+  print(1.isEven);
+}
+''');
+    _createRefactoringForString('1.isEven');
+    // apply refactoring
+    await assertRefactoringConditionsOK();
+    expect(refactoring.createGetter, true);
+  }
+
+  test_getExtractGetter_statements() async {
+    indexTestUnit('''
+main() {
+// start
+  int v = 0;
+// end
+  print(v);
+}
+''');
+    _createRefactoringForStartEndComments();
+    // apply refactoring
+    await assertRefactoringConditionsOK();
+    expect(refactoring.createGetter, false);
+  }
+
   test_getRefactoringName_function() {
     indexTestUnit('''
 main() {
@@ -1045,6 +990,19 @@
     expect(refactoring.lengths, unorderedEquals([5, 6]));
   }
 
+  test_returnType_closure() async {
+    indexTestUnit('''
+process(f(x)) {}
+main() {
+  process((x) => x * 2);
+}
+''');
+    _createRefactoringForString('(x) => x * 2');
+    // do check
+    await refactoring.checkInitialConditions();
+    expect(refactoring.returnType, '');
+  }
+
   test_returnType_expression() async {
     indexTestUnit('''
 main() {
@@ -1072,19 +1030,6 @@
     expect(refactoring.returnType, 'double');
   }
 
-  test_returnType_closure() async {
-    indexTestUnit('''
-process(f(x)) {}
-main() {
-  process((x) => x * 2);
-}
-''');
-    _createRefactoringForString('(x) => x * 2');
-    // do check
-    await refactoring.checkInitialConditions();
-    expect(refactoring.returnType, '');
-  }
-
   test_returnType_statements_nullMix() async {
     indexTestUnit('''
 main(bool p) {
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index df7d396..ed220e5 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -26,7 +26,7 @@
 class MoveFileTest extends RefactoringTest {
   MoveFileRefactoring refactoring;
 
-  test_definingUnit() async {
+  test_file_definingUnit() async {
     String pathA = '/project/000/1111/a.dart';
     String pathB = '/project/000/1111/b.dart';
     String pathC = '/project/000/1111/22/c.dart';
@@ -62,7 +62,7 @@
 ''');
   }
 
-  test_importedLibrary() async {
+  test_file_importedLibrary() async {
     String pathA = '/project/000/1111/a.dart';
     testFile = '/project/000/1111/sub/folder/test.dart';
     addSource(pathA, '''
@@ -79,7 +79,7 @@
     assertNoFileChange(testFile);
   }
 
-  test_importedLibrary_down() async {
+  test_file_importedLibrary_down() async {
     String pathA = '/project/000/1111/a.dart';
     testFile = '/project/000/1111/test.dart';
     addSource(pathA, '''
@@ -96,7 +96,7 @@
     assertNoFileChange(testFile);
   }
 
-  test_importedLibrary_package() async {
+  test_file_importedLibrary_package() async {
     // configure packages
     testFile = '/packages/my_pkg/aaa/test.dart';
     provider.newFile(testFile, '');
@@ -124,7 +124,7 @@
     assertNoFileChange(testFile);
   }
 
-  test_importedLibrary_up() async {
+  test_file_importedLibrary_up() async {
     String pathA = '/project/000/1111/a.dart';
     testFile = '/project/000/1111/22/test.dart';
     addSource(pathA, '''
@@ -141,7 +141,7 @@
     assertNoFileChange(testFile);
   }
 
-  test_sourcedUnit() async {
+  test_file_sourcedUnit() async {
     String pathA = '/project/000/1111/a.dart';
     testFile = '/project/000/1111/22/test.dart';
     addSource(pathA, '''
@@ -158,7 +158,7 @@
     assertNoFileChange(testFile);
   }
 
-  test_sourcedUnit_multipleLibraries() async {
+  test_file_sourcedUnit_multipleLibraries() async {
     String pathA = '/project/000/1111/a.dart';
     String pathB = '/project/000/b.dart';
     testFile = '/project/000/1111/22/test.dart';
@@ -182,6 +182,45 @@
     assertNoFileChange(testFile);
   }
 
+  test_project() async {
+    String pubspecPath = '/testName/pubspec.yaml';
+    String appPath = '/testName/bin/myApp.dart';
+    provider.newFile(pubspecPath, '''
+name: testName
+version: 0.0.1
+description: My pubspec file.
+''');
+    addSource('/testName/lib/myLib.dart', '');
+    addSource(appPath, '''
+import 'package:testName/myLib.dart';
+export 'package:testName/myLib.dart';
+''');
+    // configure Uri resolves
+    context.sourceFactory = new SourceFactory([
+      AbstractContextTest.SDK_RESOLVER,
+      new PackageMapUriResolver(provider, <String, List<Folder>>{
+        'testName': [provider.getResource('/testName/lib')]
+      }),
+      resourceResolver,
+    ]);
+    // analyze
+    _performAnalysis();
+    // perform refactoring
+    refactoring = new MoveFileRefactoring(
+        provider, searchEngine, context, null, '/testName');
+    refactoring.newFile = '/newName';
+    await _assertSuccessfulRefactoring();
+    assertFileChangeResult(pubspecPath, '''
+name: newName
+version: 0.0.1
+description: My pubspec file.
+''');
+    assertFileChangeResult(appPath, '''
+import 'package:newName/myLib.dart';
+export 'package:newName/myLib.dart';
+''');
+  }
+
   /**
    * Checks that all conditions are OK.
    */
@@ -192,7 +231,7 @@
 
   void _createRefactoring(String newName) {
     refactoring = new MoveFileRefactoring(
-        provider.pathContext, searchEngine, context, testSource);
+        provider, searchEngine, context, testSource, null);
     refactoring.newFile = newName;
   }
 
diff --git a/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart b/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart
index 04f7e03..4652eca 100644
--- a/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart
@@ -479,6 +479,12 @@
         expectedMessage: "Method name must not be empty.");
   }
 
+  void test_validateMethodName_keyword() {
+    assertRefactoringStatus(
+        validateMethodName("for"), RefactoringProblemSeverity.FATAL,
+        expectedMessage: "Method name must not be a keyword.");
+  }
+
   void test_validateMethodName_leadingBlanks() {
     assertRefactoringStatus(
         validateMethodName(" newName"), RefactoringProblemSeverity.FATAL,
diff --git a/pkg/analysis_server/test/socket_server_test.dart b/pkg/analysis_server/test/socket_server_test.dart
index 5bc695a..5b4f5f0 100644
--- a/pkg/analysis_server/test/socket_server_test.dart
+++ b/pkg/analysis_server/test/socket_server_test.dart
@@ -13,10 +13,10 @@
 import 'package:analysis_server/src/socket_server.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/src/generated/sdk_io.dart';
+import 'package:analyzer/src/plugin/plugin_impl.dart';
 import 'package:unittest/unittest.dart';
 
 import 'mocks.dart';
-import 'package:analysis_server/src/plugin/plugin_impl.dart';
 
 main() {
   group('SocketServer', () {
@@ -44,8 +44,9 @@
     expect(channel2.responsesReceived[0].error, isNotNull);
     expect(channel2.responsesReceived[0].error.code,
         equals(RequestErrorCode.SERVER_ALREADY_STARTED));
-    channel2.sendRequest(new ServerShutdownParams().toRequest('0')).then(
-        (Response response) {
+    channel2
+        .sendRequest(new ServerShutdownParams().toRequest('0'))
+        .then((Response response) {
       expect(response.id, equals('0'));
       expect(response.error, isNotNull);
       expect(
@@ -60,8 +61,9 @@
     server.createAnalysisServer(channel);
     channel.expectMsgCount(notificationCount: 1);
     expect(channel.notificationsReceived[0].event, SERVER_CONNECTED);
-    return channel.sendRequest(new ServerShutdownParams().toRequest('0')).then(
-        (Response response) {
+    return channel
+        .sendRequest(new ServerShutdownParams().toRequest('0'))
+        .then((Response response) {
       expect(response.id, equals('0'));
       expect(response.error, isNull);
       channel.expectMsgCount(responseCount: 1, notificationCount: 1);
diff --git a/pkg/analysis_server/test/test_all.dart b/pkg/analysis_server/test/test_all.dart
index 189af22..862b77f 100644
--- a/pkg/analysis_server/test/test_all.dart
+++ b/pkg/analysis_server/test/test_all.dart
@@ -14,7 +14,6 @@
 import 'domain_server_test.dart' as domain_server_test;
 import 'edit/test_all.dart' as edit_all;
 import 'operation/test_all.dart' as operation_test_all;
-import 'plugin/test_all.dart' as plugin_test_all;
 import 'protocol_server_test.dart' as protocol_server_test;
 import 'protocol_test.dart' as protocol_test;
 import 'search/test_all.dart' as search_all;
@@ -38,7 +37,6 @@
     domain_server_test.main();
     edit_all.main();
     operation_test_all.main();
-    plugin_test_all.main();
     protocol_server_test.main();
     protocol_test.main();
     search_all.main();
diff --git a/pkg/analysis_server/tool/spec/codegen_java_types.dart b/pkg/analysis_server/tool/spec/codegen_java_types.dart
index 646e5ff..e7d289e 100644
--- a/pkg/analysis_server/tool/spec/codegen_java_types.dart
+++ b/pkg/analysis_server/tool/spec/codegen_java_types.dart
@@ -672,11 +672,11 @@
       // contains(int x)
       //
       if (className == 'Occurrences') {
-        publicMethod('contains', () {
-          writeln('public boolean contains(int x) {');
+        publicMethod('containsInclusive', () {
+          writeln('public boolean containsInclusive(int x) {');
           indent(() {
             writeln('for (int offset : offsets) {');
-            writeln('  if (offset <= x && x < offset + length) {');
+            writeln('  if (offset <= x && x <= offset + length) {');
             writeln('    return true;');
             writeln('  }');
             writeln('}');
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 54e0315..fa512df 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -6,7 +6,7 @@
   </head>
   <body>
     <h1>Analysis Server API Specification</h1>
-    <h1 style="color:#999999">Version <version>1.3.0</version></h1>
+    <h1 style="color:#999999">Version <version>1.5.0</version></h1>
     <p>
       This document contains a specification of the API provided by the
       analysis server.  The API in this document is currently under
@@ -2301,6 +2301,13 @@
               will contain an empty string.
             </p>
           </field>
+          <field name="typeParameters" optional="true">
+            <ref>String</ref>
+            <p>
+              The type parameter list for the element. If the element doesn't
+              have type parameters, this field will not be defined.
+            </p>
+          </field>
         </object>
       </type>
       <type name="ElementKind">
@@ -2531,6 +2538,14 @@
               file.
             </p>
           </field>
+          <field name="containingClassDescription" optional="true">
+            <ref>String</ref>
+            <p>
+              A human-readable description of the class declaring the element
+              being referenced. This data is omitted if there is no referenced
+              element, or if the element is not a class member.
+            </p>
+          </field>
           <field name="dartdoc" optional="true">
             <ref>String</ref>
             <p>
diff --git a/pkg/analysis_server/tool/spec/to_html.dart b/pkg/analysis_server/tool/spec/to_html.dart
index 68abc0c..f773e94 100644
--- a/pkg/analysis_server/tool/spec/to_html.dart
+++ b/pkg/analysis_server/tool/spec/to_html.dart
@@ -307,7 +307,14 @@
   @override
   void visitNotification(Notification notification) {
     dt('notification', () {
-      write(notification.longEvent);
+      anchor('notification_${notification.longEvent}', () {
+        write(notification.longEvent);
+      });
+      write(' (');
+      link('notification_${notification.longEvent}', () {
+        write('#');
+      });
+      write(')');
     });
     dd(() {
       box(() {
@@ -341,7 +348,14 @@
   @override
   void visitRequest(Request request) {
     dt('request', () {
-      write(request.longMethod);
+      anchor('request_${request.longMethod}', () {
+        write(request.longMethod);
+      });
+      write(' (');
+      link('request_${request.longMethod}', () {
+        write('#');
+      });
+      write(')');
     });
     dd(() {
       box(() {
diff --git a/pkg/analyzer/bin/formatter.dart b/pkg/analyzer/bin/formatter.dart
deleted file mode 100755
index 16769bb..0000000
--- a/pkg/analyzer/bin/formatter.dart
+++ /dev/null
@@ -1,260 +0,0 @@
-#!/usr/bin/env dart
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:path/path.dart' as path;
-
-import 'package:analyzer/src/services/formatter_impl.dart';
-
-const BINARY_NAME = 'dartfmt';
-final dartFileRegExp = new RegExp(r'^[^.].*\.dart$', caseSensitive: false);
-final argParser = _initArgParser();
-final defaultSelection = new Selection(-1, -1);
-
-var formatterSettings;
-
-CodeKind kind;
-bool machineFormat;
-bool overwriteFileContents;
-Selection selection;
-final List<String> paths = [];
-
-const HELP_FLAG = 'help';
-const KIND_FLAG = 'kind';
-const MACHINE_FLAG = 'machine';
-const WRITE_FLAG = 'write';
-const SELECTION_FLAG = 'selection';
-const TRANSFORM_FLAG = 'transform';
-const MAX_LINE_FLAG = 'max_line_length';
-const INDENT_FLAG = 'indent';
-
-const FOLLOW_LINKS = false;
-
-main(args) {
-  var options = argParser.parse(args);
-  if (options['help']) {
-    _printUsage();
-    return;
-  }
-
-  _readOptions(options);
-
-  if (options.rest.isEmpty) {
-    _formatStdin(kind);
-  } else {
-    paths.addAll(options.rest);
-    _formatPaths(paths);
-  }
-}
-
-_readOptions(options) {
-  kind = _parseKind(options[KIND_FLAG]);
-  machineFormat = options[MACHINE_FLAG];
-  overwriteFileContents = options[WRITE_FLAG];
-  selection = _parseSelection(options[SELECTION_FLAG]);
-  formatterSettings = new FormatterOptions(
-      codeTransforms: options[TRANSFORM_FLAG],
-      tabsForIndent: _parseTabsForIndent(options[INDENT_FLAG]),
-      spacesPerIndent: _parseSpacesPerIndent(options[INDENT_FLAG]),
-      pageWidth: _parseLineLength(options[MAX_LINE_FLAG]));
-}
-
-/// Translate the indent option into spaces per indent.
-int _parseSpacesPerIndent(String indentOption) {
-  if (indentOption == 'tab') {
-    return 1;
-  }
-  int spacesPerIndent = _toInt(indentOption);
-  if (spacesPerIndent == null) {
-    throw new FormatterException(
-        'Indentation is specified as an Integer or ' 'the value "tab".');
-  }
-  return spacesPerIndent;
-}
-
-/// Translate the indent option into tabs for indent.
-bool _parseTabsForIndent(String indentOption) => indentOption == 'tab';
-
-CodeKind _parseKind(kindOption) {
-  switch (kindOption) {
-    case 'stmt':
-      return CodeKind.STATEMENT;
-    default:
-      return CodeKind.COMPILATION_UNIT;
-  }
-}
-
-int _parseLineLength(String lengthOption) {
-  var length = _toInt(lengthOption);
-  if (length == null) {
-    var val = lengthOption.toUpperCase();
-    if (val == 'INF' || val == 'INFINITY') {
-      length = -1;
-    } else {
-      throw new FormatterException(
-          'Line length is specified as an Integer or ' 'the value "Inf".');
-    }
-  }
-  return length;
-}
-
-Selection _parseSelection(String selectionOption) {
-  if (selectionOption == null) return null;
-
-  var units = selectionOption.split(',');
-  if (units.length == 2) {
-    var offset = _toInt(units[0]);
-    var length = _toInt(units[1]);
-    if (offset != null && length != null) {
-      return new Selection(offset, length);
-    }
-  }
-  throw new FormatterException(
-      'Selections are specified as integer pairs ' '(e.g., "(offset, length)".');
-}
-
-int _toInt(str) => int.parse(str, onError: (_) => null);
-
-_formatPaths(paths) {
-  paths.forEach((path) {
-    if (FileSystemEntity.isDirectorySync(path)) {
-      _formatDirectory(new Directory(path));
-    } else {
-      _formatFile(new File(path));
-    }
-  });
-}
-
-_formatResource(resource) {
-  if (resource is Directory) {
-    _formatDirectory(resource);
-  } else if (resource is File) {
-    _formatFile(resource);
-  }
-}
-
-_formatDirectory(dir) => dir
-    .listSync(followLinks: FOLLOW_LINKS)
-    .forEach((resource) => _formatResource(resource));
-
-_formatFile(file) {
-  if (_isDartFile(file)) {
-    if (_isPatchFile(file) && !paths.contains(file.path)) {
-      _log('Skipping patch file "${file.path}"');
-      return;
-    }
-    try {
-      var rawSource = file.readAsStringSync();
-      var formatted = _format(rawSource, CodeKind.COMPILATION_UNIT);
-      if (overwriteFileContents) {
-        // Only touch files files whose contents will be changed
-        if (rawSource != formatted) {
-          file.writeAsStringSync(formatted);
-        }
-      } else {
-        print(formatted);
-      }
-    } catch (e) {
-      _log('Unable to format "${file.path}": $e');
-    }
-  }
-}
-
-_isPatchFile(file) => file.path.endsWith('_patch.dart');
-
-_isDartFile(file) => dartFileRegExp.hasMatch(path.basename(file.path));
-
-_formatStdin(kind) {
-  var input = new StringBuffer();
-  stdin.transform(new Utf8Decoder()).listen((data) => input.write(data),
-      onError: (error) => _log('Error reading from stdin'),
-      onDone: () => print(_format(input.toString(), kind)));
-}
-
-/// Initialize the arg parser instance.
-ArgParser _initArgParser() {
-  // NOTE: these flags are placeholders only!
-  var parser = new ArgParser();
-  parser.addFlag(WRITE_FLAG,
-      abbr: 'w',
-      negatable: false,
-      help: 'Write reformatted sources to files (overwriting contents).  '
-      'Do not print reformatted sources to standard output.');
-  parser.addFlag(TRANSFORM_FLAG,
-      abbr: 't', negatable: false, help: 'Perform code transformations.');
-  parser.addOption(MAX_LINE_FLAG,
-      abbr: 'l', defaultsTo: '80', help: 'Wrap lines longer than this length. '
-      'To never wrap, specify "Infinity" or "Inf" for short.');
-  parser.addOption(INDENT_FLAG,
-      abbr: 'i',
-      defaultsTo: '2',
-      help: 'Specify number of spaces per indentation. '
-      'To indent using tabs, specify "--$INDENT_FLAG tab".' '--- [PROVISIONAL API].',
-      hide: true);
-  parser.addOption(KIND_FLAG,
-      abbr: 'k',
-      defaultsTo: 'cu',
-      help: 'Specify source snippet kind ("stmt" or "cu") ' '--- [PROVISIONAL API].',
-      hide: true);
-  parser.addOption(SELECTION_FLAG,
-      abbr: 's', help: 'Specify selection information as an offset,length pair '
-      '(e.g., -s "0,4").', hide: true);
-  parser.addFlag(MACHINE_FLAG,
-      abbr: 'm',
-      negatable: false,
-      help: 'Produce output in a format suitable for parsing.');
-  parser.addFlag(HELP_FLAG,
-      abbr: 'h', negatable: false, help: 'Print this usage information.');
-  return parser;
-}
-
-/// Displays usage information.
-_printUsage() {
-  var buffer = new StringBuffer();
-  buffer
-    ..write('$BINARY_NAME formats Dart programs.')
-    ..write('\n\n')
-    ..write('Without an explicit path, $BINARY_NAME processes the standard '
-        'input.  Given a file, it operates on that file; given a '
-        'directory, it operates on all .dart files in that directory, '
-        'recursively. (Files starting with a period are ignored.) By '
-        'default, $BINARY_NAME prints the reformatted sources to ' 'standard output.')
-    ..write('\n\n')
-    ..write('Usage: $BINARY_NAME [flags] [path...]\n\n')
-    ..write('Supported flags are:\n')
-    ..write('${argParser.usage}\n\n');
-  _log(buffer.toString());
-}
-
-/// Format this [src], treating it as the given snippet [kind].
-String _format(src, kind) {
-  var formatResult = new CodeFormatter(formatterSettings).format(kind, src,
-      selection: selection);
-  if (machineFormat) {
-    if (formatResult.selection == null) {
-      formatResult.selection = defaultSelection;
-    }
-    return _toJson(formatResult);
-  }
-  return formatResult.source;
-}
-
-_toJson(formatResult) => // Actual JSON format TBD
-    JSON.encode({
-  'source': formatResult.source,
-  'selection': {
-    'offset': formatResult.selection.offset,
-    'length': formatResult.selection.length
-  }
-});
-
-/// Log the given [msg].
-_log(String msg) {
-  //TODO(pquitslund): add proper log support
-  print(msg);
-}
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index d510dbb..6fb9885 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -24,6 +24,12 @@
    * Create a new [Source] instance that serves this file.
    */
   Source createSource([Uri uri]);
+
+  /**
+   * Synchronously read the entire file contents as a [String].
+   * Throws [FileSystemException] if the file does not exist.
+   */
+  String readAsStringSync();
 }
 
 /**
@@ -70,18 +76,18 @@
   Resource getChild(String relPath);
 
   /**
-   * Return a list of existing direct children [Resource]s (folders and files)
-   * in this folder, in no particular order.
-   */
-  List<Resource> getChildren();
-
-  /**
    * Return a [Folder] representing a child [Resource] with the given
    * [relPath].  This call does not check whether a folder with the given name
    * exists on the filesystem--client must call the [Folder]'s `exists` getter
    * to determine whether the folder actually exists.
    */
   Folder getChildAssumingFolder(String relPath);
+
+  /**
+   * Return a list of existing direct children [Resource]s (folders and files)
+   * in this folder, in no particular order.
+   */
+  List<Resource> getChildren();
 }
 
 /**
@@ -172,10 +178,7 @@
   Uri restoreAbsolute(Source source) => source.uri;
 
   /**
-   * Return `true` if the given URI is a `file` URI.
-   *
-   * @param uri the URI being tested
-   * @return `true` if the given URI is a `file` URI
+   * Return `true` if the given [uri] is a `file` URI.
    */
   static bool _isFileUri(Uri uri) => uri.scheme == _FILE_SCHEME;
 }
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index da68f08..8d1f114 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -110,17 +110,6 @@
     return file;
   }
 
-  File updateFile(String path, String content, [int stamp]) {
-    path = posix.normalize(path);
-    newFolder(posix.dirname(path));
-    _MemoryFile file = new _MemoryFile(this, path);
-    _pathToResource[path] = file;
-    _pathToContent[path] = content;
-    _pathToTimestamp[path] = stamp != null ? stamp : nextStamp++;
-    _notifyWatchers(path, ChangeType.MODIFY);
-    return file;
-  }
-
   Folder newFolder(String path) {
     path = posix.normalize(path);
     if (!path.startsWith('/')) {
@@ -145,6 +134,17 @@
     }
   }
 
+  File updateFile(String path, String content, [int stamp]) {
+    path = posix.normalize(path);
+    newFolder(posix.dirname(path));
+    _MemoryFile file = new _MemoryFile(this, path);
+    _pathToResource[path] = file;
+    _pathToContent[path] = content;
+    _pathToTimestamp[path] = stamp != null ? stamp : nextStamp++;
+    _notifyWatchers(path, ChangeType.MODIFY);
+    return file;
+  }
+
   void _checkFileAtPath(String path) {
     _MemoryResource resource = _pathToResource[path];
     if (resource is! _MemoryFile) {
@@ -206,6 +206,11 @@
   bool isOrContains(String path) {
     return path == this.path;
   }
+
+  @override
+  String readAsStringSync() {
+    throw new FileSystemException(path, 'File could not be read');
+  }
 }
 
 /**
@@ -221,7 +226,7 @@
   int get modificationStamp {
     int stamp = _provider._pathToTimestamp[path];
     if (stamp == null) {
-      throw new FileSystemException(path, 'File does not exist.');
+      throw new FileSystemException(path, 'File "$path" does not exist.');
     }
     return stamp;
   }
@@ -229,7 +234,7 @@
   String get _content {
     String content = _provider._pathToContent[path];
     if (content == null) {
-      throw new FileSystemException(path, "File does not exist");
+      throw new FileSystemException(path, 'File "$path" does not exist.');
     }
     return content;
   }
@@ -246,6 +251,15 @@
   bool isOrContains(String path) {
     return path == this.path;
   }
+
+  @override
+  String readAsStringSync() {
+    String content = _provider._pathToContent[path];
+    if (content == null) {
+      throw new FileSystemException(path, 'File "$path" does not exist.');
+    }
+    return content;
+  }
 }
 
 /**
@@ -298,7 +312,7 @@
   int get modificationStamp {
     try {
       return file.modificationStamp;
-    } on FileSystemException catch (e) {
+    } on FileSystemException {
       return -1;
     }
   }
@@ -398,6 +412,9 @@
 
   @override
   List<Resource> getChildren() {
+    if (!exists) {
+      throw new FileSystemException(path, 'Folder does not exist.');
+    }
     List<Resource> children = <Resource>[];
     _provider._pathToResource.forEach((resourcePath, resource) {
       if (posix.dirname(resourcePath) == path) {
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 71c4020..2cd391a 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -80,7 +80,7 @@
       io.File file = _entry as io.File;
       return file.lastModifiedSync().millisecondsSinceEpoch;
     } on io.FileSystemException catch (exception) {
-      throw new FileSystemException(path, exception.message);
+      throw new FileSystemException(exception.path, exception.message);
     }
   }
 
@@ -98,6 +98,16 @@
   bool isOrContains(String path) {
     return path == this.path;
   }
+
+  @override
+  String readAsStringSync() {
+    try {
+      io.File file = _entry as io.File;
+      return file.readAsStringSync();
+    } on io.FileSystemException catch (exception) {
+      throw new FileSystemException(exception.path, exception.message);
+    }
+  }
 }
 
 /**
@@ -134,19 +144,23 @@
 
   @override
   List<Resource> getChildren() {
-    List<Resource> children = <Resource>[];
-    io.Directory directory = _entry as io.Directory;
-    List<io.FileSystemEntity> entries = directory.listSync(recursive: false);
-    int numEntries = entries.length;
-    for (int i = 0; i < numEntries; i++) {
-      io.FileSystemEntity entity = entries[i];
-      if (entity is io.Directory) {
-        children.add(new _PhysicalFolder(entity));
-      } else if (entity is io.File) {
-        children.add(new _PhysicalFile(entity));
+    try {
+      List<Resource> children = <Resource>[];
+      io.Directory directory = _entry as io.Directory;
+      List<io.FileSystemEntity> entries = directory.listSync(recursive: false);
+      int numEntries = entries.length;
+      for (int i = 0; i < numEntries; i++) {
+        io.FileSystemEntity entity = entries[i];
+        if (entity is io.Directory) {
+          children.add(new _PhysicalFolder(entity));
+        } else if (entity is io.File) {
+          children.add(new _PhysicalFile(entity));
+        }
       }
+      return children;
+    } on io.FileSystemException catch (exception) {
+      throw new FileSystemException(exception.path, exception.message);
     }
-    return children;
   }
 
   @override
diff --git a/pkg/analyzer/lib/formatter.dart b/pkg/analyzer/lib/formatter.dart
deleted file mode 100644
index 58de5ac..0000000
--- a/pkg/analyzer/lib/formatter.dart
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library formatter;
-
-export 'package:analyzer/src/services/formatter_impl.dart'
-    show CodeFormatter, FormatterOptions, FormattedSource, CodeKind;
diff --git a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
index 136ff8c..ba23b68 100644
--- a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
@@ -16,7 +16,7 @@
 
   FileInstrumentationServer(String path) {
     File file = new File(path);
-    _sink = file.openWrite(mode: FileMode.APPEND);
+    _sink = file.openWrite();
   }
 
   @override
diff --git a/pkg/analyzer/lib/options.dart b/pkg/analyzer/lib/options.dart
index 37e1b8a..1f7543e 100644
--- a/pkg/analyzer/lib/options.dart
+++ b/pkg/analyzer/lib/options.dart
@@ -27,6 +27,12 @@
   final bool displayVersion;
 
   /**
+   * Whether to strictly follow the specification when generating warnings on
+   * "call" methods (fixes dartbug.com/21938).
+   */
+  final bool enableStrictCallChecks;
+
+  /**
    * Whether to treat type mismatches found during constant evaluation as
    * errors.
    */
@@ -80,6 +86,7 @@
         this.definedVariables = definedVariables,
         disableHints = args['no-hints'],
         displayVersion = args['version'],
+        enableStrictCallChecks = args['enable-strict-call-checks'],
         enableTypeChecks = args['enable_type_checks'],
         ignoreUnrecognizedFlags = args['ignore-unrecognized-flags'],
         log = args['log'],
@@ -206,6 +213,11 @@
           defaultsTo: false,
           negatable: false,
           hide: true)
+      ..addFlag('enable-strict-call-checks',
+          help: 'Fix issue 21938',
+          defaultsTo: false,
+          negatable: false,
+          hide: true)
       ..addFlag('log',
           help: 'Log additional messages and exceptions',
           defaultsTo: false,
diff --git a/pkg/analysis_server/lib/plugin/plugin.dart b/pkg/analyzer/lib/plugin/plugin.dart
similarity index 98%
rename from pkg/analysis_server/lib/plugin/plugin.dart
rename to pkg/analyzer/lib/plugin/plugin.dart
index 9df0474..c81c83c 100644
--- a/pkg/analysis_server/lib/plugin/plugin.dart
+++ b/pkg/analyzer/lib/plugin/plugin.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analysis_server.plugin.plugin;
+library analyzer.plugin.plugin;
 
 /**
  * A function used to register the given [extension] to the extension point with
diff --git a/pkg/analyzer/lib/plugin/task.dart b/pkg/analyzer/lib/plugin/task.dart
new file mode 100644
index 0000000..42c9214
--- /dev/null
+++ b/pkg/analyzer/lib/plugin/task.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/**
+ * Support for client code that extends the analysis engine by adding new
+ * analysis tasks.
+ */
+library analyzer.plugin.task;
+
+import 'package:analyzer/plugin/plugin.dart';
+import 'package:analyzer/src/plugin/engine_plugin.dart';
+import 'package:analyzer/task/model.dart';
+
+/**
+ * The identifier of the extension point that allows plugins to register new
+ * analysis tasks with the analysis engine. The object used as an extension must
+ * be a [TaskDescriptor].
+ */
+final String TASK_EXTENSION_POINT_ID = Plugin.join(
+    EnginePlugin.UNIQUE_IDENTIFIER, EnginePlugin.TASK_EXTENSION_POINT);
diff --git a/pkg/analyzer/lib/src/analyzer_impl.dart b/pkg/analyzer/lib/src/analyzer_impl.dart
index 2897e8b..173d18a 100644
--- a/pkg/analyzer/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer/lib/src/analyzer_impl.dart
@@ -211,6 +211,7 @@
     AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl();
     contextOptions.cacheSize = _MAX_CACHE_SIZE;
     contextOptions.hint = !options.disableHints;
+    contextOptions.enableStrictCallChecks = options.enableStrictCallChecks;
     contextOptions.analyzeFunctionBodiesPredicate =
         _analyzeFunctionBodiesPredicate;
     contextOptions.generateImplicitErrors = options.showPackageWarnings;
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index f1290c0..516a895 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -235,7 +235,7 @@
    * The exception that caused one or more values to have a state of
    * [CacheState.ERROR].
    */
-  CaughtException exception;
+  CaughtException _exception;
 
   /**
    * A bit-encoding of boolean flags associated with this entry's target.
@@ -249,6 +249,12 @@
       new HashMap<ResultDescriptor, ResultData>();
 
   /**
+   * The exception that caused one or more values to have a state of
+   * [CacheState.ERROR].
+   */
+  CaughtException get exception => _exception;
+
+  /**
    * Return `true` if the source was explicitly added to the context or `false`
    * if the source was implicitly added because it was referenced by another
    * source.
@@ -280,18 +286,8 @@
    * Fix the state of the [exception] to match the current state of the entry.
    */
   void fixExceptionState() {
-    if (hasErrorState()) {
-      if (exception == null) {
-        //
-        // This code should never be reached, but is a fail-safe in case an
-        // exception is not recorded when it should be.
-        //
-        // TODO(brianwilkerson) Log this?
-        String message = 'State set to ERROR without setting an exception';
-        exception = new CaughtException(new AnalysisException(message), null);
-      }
-    } else {
-      exception = null;
+    if (!hasErrorState()) {
+      _exception = null;
     }
   }
 
@@ -348,7 +344,28 @@
    */
   void invalidateAllInformation() {
     _resultMap.clear();
-    exception = null;
+    _exception = null;
+  }
+
+  /**
+   * Set the [CacheState.ERROR] state for given [descriptors], their values to
+   * the corresponding default values, and remember the [exception] that caused
+   * this state.
+   */
+  void setErrorState(
+      CaughtException exception, List<ResultDescriptor> descriptors) {
+    if (descriptors == null || descriptors.isEmpty) {
+      throw new ArgumentError('at least one descriptor is expected');
+    }
+    if (exception == null) {
+      throw new ArgumentError('an exception is expected');
+    }
+    this._exception = exception;
+    for (ResultDescriptor descriptor in descriptors) {
+      ResultData data = _getResultData(descriptor);
+      data.state = CacheState.ERROR;
+      data.value = descriptor.defaultValue;
+    }
   }
 
   /**
@@ -356,10 +373,9 @@
    * given [state].
    */
   void setState(ResultDescriptor descriptor, CacheState state) {
-    // TODO(brianwilkerson) Consider introducing a different method used to set
-    // the state of a list of descriptors to ERROR that could validate that an
-    // exception was also provided. (It would then be an error to use this
-    // method to set the state to ERROR.)
+    if (state == CacheState.ERROR) {
+      throw new ArgumentError('use setErrorState() to set the state to ERROR');
+    }
     if (state == CacheState.VALID) {
       throw new ArgumentError('use setValue() to set the state to VALID');
     }
@@ -367,8 +383,7 @@
     if (state == CacheState.INVALID) {
       _resultMap.remove(descriptor);
     } else {
-      ResultData data =
-          _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor));
+      ResultData data = _getResultData(descriptor);
       data.state = state;
       if (state != CacheState.IN_PROCESS) {
         //
@@ -387,8 +402,7 @@
   /*<V>*/ void setValue(ResultDescriptor /*<V>*/ descriptor, dynamic /*V*/
       value) {
     _validateStateChange(descriptor, CacheState.VALID);
-    ResultData data =
-        _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor));
+    ResultData data = _getResultData(descriptor);
     data.state = CacheState.VALID;
     data.value = value == null ? descriptor.defaultValue : value;
   }
@@ -406,6 +420,14 @@
   bool _getFlag(int index) => BooleanArray.get(_flags, index);
 
   /**
+   * Look up the [ResultData] of [descriptor], or add a new one if it isn't
+   * there.
+   */
+  ResultData _getResultData(ResultDescriptor descriptor) {
+    return _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor));
+  }
+
+  /**
    * Set the value of the flag with the given [index] to the given [value].
    */
   void _setFlag(int index, bool value) {
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index b69d355..f202e83 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -1641,6 +1641,13 @@
   YieldStatement visitYieldStatement(YieldStatement node) => new YieldStatement(
       cloneToken(node.yieldKeyword), cloneToken(node.star),
       cloneNode(node.expression), cloneToken(node.semicolon));
+
+  /**
+   * Return a clone of the given [node].
+   */
+  static AstNode clone(AstNode node) {
+    return node.accept(new AstCloner());
+  }
 }
 
 /**
@@ -12398,7 +12405,7 @@
     }
     try {
       node.accept(this);
-    } on NodeLocator_NodeFoundException catch (exception) {
+    } on NodeLocator_NodeFoundException {
       // A node with the right source position was found.
     } catch (exception, stackTrace) {
       AnalysisEngine.instance.logger.logInformation(
@@ -12421,7 +12428,7 @@
     }
     try {
       node.visitChildren(this);
-    } on NodeLocator_NodeFoundException catch (exception) {
+    } on NodeLocator_NodeFoundException {
       rethrow;
     } catch (exception, stackTrace) {
       // Ignore the exception and proceed in order to visit the rest of the
@@ -16325,15 +16332,13 @@
     }
     // analyze usage
     if (parent is AssignmentExpression) {
-      AssignmentExpression expr = parent as AssignmentExpression;
-      if (identical(expr.leftHandSide, target) &&
-          expr.operator.type == TokenType.EQ) {
+      if (identical(parent.leftHandSide, target) &&
+          parent.operator.type == TokenType.EQ) {
         return false;
       }
     }
     if (parent is ForEachStatement) {
-      ForEachStatement stmt = parent as ForEachStatement;
-      if (identical(stmt.identifier, target)) {
+      if (identical(parent.identifier, target)) {
         return false;
       }
     }
@@ -16370,13 +16375,13 @@
     }
     // analyze usage
     if (parent is PrefixExpression) {
-      return (parent as PrefixExpression).operator.type.isIncrementOperator;
+      return parent.operator.type.isIncrementOperator;
     } else if (parent is PostfixExpression) {
       return true;
     } else if (parent is AssignmentExpression) {
-      return identical((parent as AssignmentExpression).leftHandSide, target);
+      return identical(parent.leftHandSide, target);
     } else if (parent is ForEachStatement) {
-      return identical((parent as ForEachStatement).identifier, target);
+      return identical(parent.identifier, target);
     }
     return false;
   }
@@ -16742,7 +16747,7 @@
     StringBuffer buffer = new StringBuffer();
     try {
       _appendStringValue(buffer);
-    } on IllegalArgumentException catch (exception) {
+    } on IllegalArgumentException {
       return null;
     }
     return buffer.toString();
@@ -19514,7 +19519,7 @@
     }
     try {
       parseUriWithException(Uri.encodeFull(uriContent));
-    } on URISyntaxException catch (exception) {
+    } on URISyntaxException {
       return UriValidationCode.INVALID_URI;
     }
     return null;
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index 635431a..c5b413d 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -23,8 +23,7 @@
 import 'utilities_dart.dart' show ParameterKind;
 
 /**
- * Instances of the class `BoolState` represent the state of an object representing a boolean
- * value.
+ * The state of an object representing a boolean value.
  */
 class BoolState extends InstanceState {
   /**
@@ -48,9 +47,7 @@
   final bool value;
 
   /**
-   * Initialize a newly created state to represent the given value.
-   *
-   * @param value the value of this instance
+   * Initialize a newly created state to represent the given [value].
    */
   BoolState(this.value);
 
@@ -60,11 +57,6 @@
   @override
   int get hashCode => value == null ? 0 : (value ? 2 : 3);
 
-  /**
-   * Return `true` if this object represents an object whose type is 'bool'.
-   *
-   * @return `true` if this object represents a boolean value
-   */
   @override
   bool get isBool => true;
 
@@ -145,56 +137,66 @@
   String toString() => value == null ? "-unknown-" : (value ? "true" : "false");
 
   /**
-   * Return the boolean state representing the given boolean value.
-   *
-   * @param value the value to be represented
-   * @return the boolean state representing the given boolean value
+   * Return the boolean state representing the given boolean [value].
    */
   static BoolState from(bool value) =>
       value ? BoolState.TRUE_STATE : BoolState.FALSE_STATE;
 }
 
 /**
- * Instances of the class `ConstantEvaluator` evaluate constant expressions to produce their
- * compile-time value. According to the Dart Language Specification: <blockquote> A constant
- * expression is one of the following:
+ * Instances of the class `ConstantEvaluator` evaluate constant expressions to
+ * produce their compile-time value. According to the Dart Language
+ * Specification:
+ * <blockquote>
+ * A constant expression is one of the following:
  * * A literal number.
  * * A literal boolean.
- * * A literal string where any interpolated expression is a compile-time constant that evaluates
- * to a numeric, string or boolean value or to <b>null</b>.
+ * * A literal string where any interpolated expression is a compile-time
+ *   constant that evaluates to a numeric, string or boolean value or to
+ *   <b>null</b>.
  * * A literal symbol.
  * * <b>null</b>.
  * * A qualified reference to a static constant variable.
- * * An identifier expression that denotes a constant variable, class or type alias.
+ * * An identifier expression that denotes a constant variable, class or type
+ *   alias.
  * * A constant constructor invocation.
  * * A constant list literal.
  * * A constant map literal.
- * * A simple or qualified identifier denoting a top-level function or a static method.
- * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant expression.
- * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> where
- * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions and <i>identical()</i> is
- * statically bound to the predefined dart function <i>identical()</i> discussed above.
- * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or <i>e<sub>1</sub>
- * != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions
- * that evaluate to a numeric, string or boolean value.
- * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp; e<sub>2</sub></i> or
- * <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>, <i>e1</sub></i> and <i>e2</sub></i> are
- * constant expressions that evaluate to a boolean value.
- * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ e<sub>2</sub></i>,
- * <i>e<sub>1</sub> &amp; e<sub>2</sub></i>, <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub>
- * &gt;&gt; e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where <i>e</i>,
- * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions that evaluate to an
- * integer value or to <b>null</b>.
- * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + e<sub>2</sub></i>,
- * <i>e<sub>1</sub> -e<sub>2</sub></i>, <i>e<sub>1</sub> * e<sub>2</sub></i>, <i>e<sub>1</sub> /
- * e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;
- * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
- * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or <i>e<sub>1</sub> %
- * e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
- * expressions that evaluate to a numeric value or to <b>null</b>.
- * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> where
- * <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and <i>e<sub>3</sub></i> are constant expressions, and
- * <i>e<sub>1</sub></i> evaluates to a boolean value.
+ * * A simple or qualified identifier denoting a top-level function or a static
+ *   method.
+ * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant
+ *   expression.
+ * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i>
+ *   where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ *   expressions and <i>identical()</i> is statically bound to the predefined
+ *   dart function <i>identical()</i> discussed above.
+ * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or
+ *   <i>e<sub>1</sub> != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and
+ *   <i>e<sub>2</sub></i> are constant expressions that evaluate to a numeric,
+ *   string or boolean value.
+ * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp;
+ *   e<sub>2</sub></i> or <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>,
+ *   <i>e1</sub></i> and <i>e2</sub></i> are constant expressions that evaluate
+ *   to a boolean value.
+ * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^
+ *   e<sub>2</sub></i>, <i>e<sub>1</sub> &amp; e<sub>2</sub></i>,
+ *   <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;&gt;
+ *   e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where
+ *   <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ *   expressions that evaluate to an integer value or to <b>null</b>.
+ * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> +
+ *   e<sub>2</sub></i>, <i>e<sub>1</sub> -e<sub>2</sub></i>, <i>e<sub>1</sub> *
+ *   e<sub>2</sub></i>, <i>e<sub>1</sub> / e<sub>2</sub></i>, <i>e<sub>1</sub>
+ *   ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &gt; e<sub>2</sub></i>,
+ *   <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
+ *   e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or
+ *   <i>e<sub>1</sub> % e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i>
+ *   and <i>e<sub>2</sub></i> are constant expressions that evaluate to a
+ *   numeric value or to <b>null</b>.
+ * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> :
+ *   e<sub>3</sub></i> where <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and
+ *   <i>e<sub>3</sub></i> are constant expressions, and <i>e<sub>1</sub></i>
+ *   evaluates to a boolean value.
  * </blockquote>
  */
 class ConstantEvaluator {
@@ -209,10 +211,9 @@
   final TypeProvider _typeProvider;
 
   /**
-   * Initialize a newly created evaluator to evaluate expressions in the given source.
-   *
-   * @param source the source containing the expression(s) that will be evaluated
-   * @param typeProvider the type provider used to access known types
+   * Initialize a newly created evaluator to evaluate expressions in the given
+   * [source]. The [typeProvider] is the type provider used to access known
+   * types.
    */
   ConstantEvaluator(this._source, this._typeProvider);
 
@@ -229,20 +230,22 @@
 }
 
 /**
- * Instances of the class `ConstantFinder` are used to traverse the AST
- * structures of all of the compilation units being resolved and build tables
- * of the constant variables, constant constructors, constant constructor
- * invocations, and annotations found in those compilation units.
+ * A visitor used to traverse the AST structures of all of the compilation units
+ * being resolved and build tables of the constant variables, constant
+ * constructors, constant constructor invocations, and annotations found in
+ * those compilation units.
  */
 class ConstantFinder extends RecursiveAstVisitor<Object> {
   /**
-   * A table mapping constant variable elements to the declarations of those variables.
+   * A table mapping constant variable elements to the declarations of those
+   * variables.
    */
   final HashMap<VariableElement, VariableDeclaration> variableMap =
       new HashMap<VariableElement, VariableDeclaration>();
 
   /**
-   * A table mapping constant constructors to the declarations of those constructors.
+   * A table mapping constant constructors to the declarations of those
+   * constructors.
    */
   final HashMap<ConstructorElement, ConstructorDeclaration> constructorMap =
       new HashMap<ConstructorElement, ConstructorDeclaration>();
@@ -301,11 +304,11 @@
 }
 
 /**
- * Instances of the class `ConstantValueComputer` compute the values of constant variables and
- * constant constructor invocations in one or more compilation units. The expected usage pattern is
- * for the compilation units to be added to this computer using the method
- * [add] and then for the method [computeValues] to be invoked
- * exactly once. Any use of an instance after invoking the method [computeValues] will
+ * An object used to compute the values of constant variables and constant
+ * constructor invocations in one or more compilation units. The expected usage
+ * pattern is for the compilation units to be added to this computer using the
+ * method [add] and then for the method [computeValues] to be invoked exactly
+ * once. Any use of an instance after invoking the method [computeValues] will
  * result in unpredictable behavior.
  */
 class ConstantValueComputer {
@@ -315,25 +318,29 @@
   static String _DEFAULT_VALUE_PARAM = "defaultValue";
 
   /**
-   * Source of RegExp matching declarable operator names. From sdk/lib/internal/symbol.dart.
+   * Source of RegExp matching declarable operator names.
+   * From sdk/lib/internal/symbol.dart.
    */
   static String _OPERATOR_RE =
       "(?:[\\-+*/%&|^]|\\[\\]=?|==|~/?|<[<=]?|>[>=]?|unary-)";
 
   /**
-   * Source of RegExp matching any public identifier. From sdk/lib/internal/symbol.dart.
+   * Source of RegExp matching any public identifier.
+   * From sdk/lib/internal/symbol.dart.
    */
   static String _PUBLIC_IDENTIFIER_RE =
       "(?!${ConstantValueComputer._RESERVED_WORD_RE}\\b(?!\\\$))[a-zA-Z\$][\\w\$]*";
 
   /**
-   * Source of RegExp matching Dart reserved words. From sdk/lib/internal/symbol.dart.
+   * Source of RegExp matching Dart reserved words.
+   * From sdk/lib/internal/symbol.dart.
    */
   static String _RESERVED_WORD_RE =
       "(?:assert|break|c(?:a(?:se|tch)|lass|on(?:st|tinue))|d(?:efault|o)|e(?:lse|num|xtends)|f(?:alse|inal(?:ly)?|or)|i[fns]|n(?:ew|ull)|ret(?:hrow|urn)|s(?:uper|witch)|t(?:h(?:is|row)|r(?:ue|y))|v(?:ar|oid)|w(?:hile|ith))";
 
   /**
-   * RegExp that validates a non-empty non-private symbol. From sdk/lib/internal/symbol.dart.
+   * RegExp that validates a non-empty non-private symbol.
+   * From sdk/lib/internal/symbol.dart.
    */
   static RegExp _PUBLIC_SYMBOL_PATTERN = new RegExp(
       "^(?:${ConstantValueComputer._OPERATOR_RE}\$|$_PUBLIC_IDENTIFIER_RE(?:=?\$|[.](?!\$)))+?\$");
@@ -344,14 +351,14 @@
   TypeProvider typeProvider;
 
   /**
-   * The object used to find constant variables and constant constructor invocations in the
-   * compilation units that were added.
+   * The object used to find constant variables and constant constructor
+   * invocations in the compilation units that were added.
    */
   ConstantFinder _constantFinder = new ConstantFinder();
 
   /**
-   * A graph in which the nodes are the constants, and the edges are from each constant to the other
-   * constants that are referenced by it.
+   * A graph in which the nodes are the constants, and the edges are from each
+   * constant to the other constants that are referenced by it.
    */
   DirectedGraph<AstNode> referenceGraph = new DirectedGraph<AstNode>();
 
@@ -361,7 +368,8 @@
   HashMap<VariableElement, VariableDeclaration> _variableDeclarationMap;
 
   /**
-   * A table mapping constant constructors to the declarations of those constructors.
+   * A table mapping constant constructors to the declarations of those
+   * constructors.
    */
   HashMap<ConstructorElement, ConstructorDeclaration> constructorDeclarationMap;
 
@@ -381,46 +389,45 @@
   final DeclaredVariables _declaredVariables;
 
   /**
-   * Initialize a newly created constant value computer.
-   *
-   * @param typeProvider the type provider used to access known types
-   * @param declaredVariables the set of variables declared on the command line using '-D'
+   * Initialize a newly created constant value computer. The [typeProvider] is
+   * the type provider used to access known types. The [declaredVariables] is
+   * the set of variables declared on the command line using '-D'.
    */
   ConstantValueComputer(TypeProvider typeProvider, this._declaredVariables) {
     this.typeProvider = typeProvider;
   }
 
   /**
-   * Add the constants in the given compilation unit to the list of constants whose value needs to
-   * be computed.
-   *
-   * @param unit the compilation unit defining the constants to be added
+   * Add the constants in the given compilation [unit] to the list of constants
+   * whose value needs to be computed.
    */
   void add(CompilationUnit unit) {
     unit.accept(_constantFinder);
   }
 
   /**
-   * This method is called just before computing the constant value associated with an AST node.
-   * Unit tests will override this method to introduce additional error checking.
+   * This method is called just before computing the constant value associated
+   * with [constNode]. Unit tests will override this method to introduce
+   * additional error checking.
    */
   void beforeComputeValue(AstNode constNode) {}
 
   /**
-   * This method is called just before getting the constant initializers associated with a
-   * constructor AST node. Unit tests will override this method to introduce additional error
-   * checking.
+   * This method is called just before getting the constant initializers
+   * associated with the [constructor]. Unit tests will override this method to
+   * introduce additional error checking.
    */
   void beforeGetConstantInitializers(ConstructorElement constructor) {}
 
   /**
-   * This method is called just before getting a parameter's default value. Unit tests will override
-   * this method to introduce additional error checking.
+   * This method is called just before getting a parameter's default value. Unit
+   * tests will override this method to introduce additional error checking.
    */
   void beforeGetParameterDefault(ParameterElement parameter) {}
 
   /**
-   * Compute values for all of the constants in the compilation units that were added.
+   * Compute values for all of the constants in the compilation units that were
+   * added.
    */
   void computeValues() {
     _variableDeclarationMap = _constantFinder.variableMap;
@@ -433,8 +440,8 @@
       referenceGraph.addNode(declaration);
       declaration.initializer.accept(referenceFinder);
     });
-    constructorDeclarationMap.forEach(
-        (ConstructorElement element, ConstructorDeclaration declaration) {
+    constructorDeclarationMap.forEach((ConstructorElement element,
+        ConstructorDeclaration declaration) {
       ReferenceFinder referenceFinder = new ReferenceFinder(declaration,
           referenceGraph, _variableDeclarationMap, constructorDeclarationMap);
       referenceGraph.addNode(declaration);
@@ -513,8 +520,8 @@
   }
 
   /**
-   * Create the ConstantVisitor used to evaluate constants. Unit tests will override this method to
-   * introduce additional error checking.
+   * Create the ConstantVisitor used to evaluate constants. Unit tests will
+   * override this method to introduce additional error checking.
    */
   ConstantVisitor createConstantVisitor(ErrorReporter errorReporter) =>
       new ConstantVisitor.con1(typeProvider, errorReporter);
@@ -524,14 +531,13 @@
       constructorDeclarationMap[_getConstructorBase(constructor)];
 
   /**
-   * Check that the arguments to a call to fromEnvironment() are correct.
-   *
-   * @param arguments the AST nodes of the arguments.
-   * @param argumentValues the values of the unnamed arguments.
-   * @param namedArgumentValues the values of the named arguments.
-   * @param expectedDefaultValueType the allowed type of the "defaultValue" parameter (if present).
-   *          Note: "defaultValue" is always allowed to be null.
-   * @return true if the arguments are correct, false if there is an error.
+   * Check that the arguments to a call to fromEnvironment() are correct. The
+   * [arguments] are the AST nodes of the arguments. The [argumentValues] are
+   * the values of the unnamed arguments. The [namedArgumentValues] are the
+   * values of the named arguments. The [expectedDefaultValueType] is the
+   * allowed type of the "defaultValue" parameter (if present). Note:
+   * "defaultValue" is always allowed to be null. Return `true` if the arguments
+   * are correct, `false` if there is an error.
    */
   bool _checkFromEnvironmentArguments(NodeList<Expression> arguments,
       List<DartObjectImpl> argumentValues,
@@ -566,12 +572,11 @@
   }
 
   /**
-   * Check that the arguments to a call to Symbol() are correct.
-   *
-   * @param arguments the AST nodes of the arguments.
-   * @param argumentValues the values of the unnamed arguments.
-   * @param namedArgumentValues the values of the named arguments.
-   * @return true if the arguments are correct, false if there is an error.
+   * Check that the arguments to a call to Symbol() are correct. The [arguments]
+   * are the AST nodes of the arguments. The [argumentValues] are the values of
+   * the unnamed arguments. The [namedArgumentValues] are the values of the
+   * named arguments. Return `true` if the arguments are correct, `false` if
+   * there is an error.
    */
   bool _checkSymbolArguments(NodeList<Expression> arguments,
       List<DartObjectImpl> argumentValues,
@@ -590,9 +595,7 @@
   }
 
   /**
-   * Compute a value for the given constant.
-   *
-   * @param constNode the constant for which a value is to be computed
+   * Compute a value for the given [constNode].
    */
   void _computeValueFor(AstNode constNode) {
     beforeComputeValue(constNode);
@@ -701,13 +704,13 @@
   }
 
   /**
-   * Evaluate a call to fromEnvironment() on the bool, int, or String class.
-   *
-   * @param environmentValue Value fetched from the environment
-   * @param builtInDefaultValue Value that should be used as the default if no "defaultValue"
-   *          argument appears in [namedArgumentValues].
-   * @param namedArgumentValues Named parameters passed to fromEnvironment()
-   * @return A [DartObjectImpl] object corresponding to the evaluated result
+   * Evaluate a call to fromEnvironment() on the bool, int, or String class. The
+   * [environmentValue] is the value fetched from the environment. The
+   * [builtInDefaultValue] is the value that should be used as the default if no
+   * "defaultValue" argument appears in [namedArgumentValues]. The
+   * [namedArgumentValues] are the values of the named parameters passed to
+   * fromEnvironment(). Return a [DartObjectImpl] object corresponding to the
+   * evaluated result.
    */
   DartObjectImpl _computeValueFromEnvironment(DartObject environmentValue,
       DartObjectImpl builtInDefaultValue,
@@ -754,7 +757,7 @@
         namedArgumentValues[name] =
             constantVisitor._valueOf(argument.expression);
         namedArgumentNodes[name] = argument;
-        argumentValues[i] = constantVisitor.null2;
+        argumentValues[i] = typeProvider.nullObject;
       } else {
         argumentValues[i] = constantVisitor._valueOf(argument);
         argumentNodes[i] = argument;
@@ -862,11 +865,10 @@
         // The parameter is an optional positional parameter for which no value
         // was provided, so use the default value.
         beforeGetParameterDefault(baseParameter);
-        EvaluationResultImpl evaluationResult =
-            (baseParameter as ParameterElementImpl).evaluationResult;
+        EvaluationResultImpl evaluationResult = baseParameter.evaluationResult;
         if (evaluationResult == null) {
           // No default was provided, so the default value is null.
-          argumentValue = constantVisitor.null2;
+          argumentValue = typeProvider.nullObject;
         } else if (evaluationResult.value != null) {
           argumentValue = evaluationResult.value;
         }
@@ -972,13 +974,12 @@
   }
 
   /**
-   * Attempt to follow the chain of factory redirections until a constructor is reached which is not
-   * a const factory constructor.
-   *
-   * @return the constant constructor which terminates the chain of factory redirections, if the
-   *         chain terminates. If there is a problem (e.g. a redirection can't be found, or a cycle
-   *         is encountered), the chain will be followed as far as possible and then a const factory
-   *         constructor will be returned.
+   * Attempt to follow the chain of factory redirections until a constructor is
+   * reached which is not a const factory constructor. Return the constant
+   * constructor which terminates the chain of factory redirections, if the
+   * chain terminates. If there is a problem (e.g. a redirection can't be found,
+   * or a cycle is encountered), the chain will be followed as far as possible
+   * and then a const factory constructor will be returned.
    */
   ConstructorElement _followConstantRedirectionChain(
       ConstructorElement constructor) {
@@ -1019,14 +1020,12 @@
   }
 
   /**
-   * Generate an error indicating that the given constant is not a valid compile-time constant
-   * because it references at least one of the constants in the given cycle, each of which directly
-   * or indirectly references the constant.
-   *
-   * @param constantsInCycle the constants in the cycle that includes the given constant
-   * @param constant the constant that is not a valid compile-time constant
+   * Generate an error indicating that the given [constant] is not a valid
+   * compile-time constant because it references at least one of the constants
+   * in the given [cycle], each of which directly or indirectly references the
+   * constant.
    */
-  void _generateCycleError(List<AstNode> constantsInCycle, AstNode constant) {
+  void _generateCycleError(List<AstNode> cycle, AstNode constant) {
     // TODO(brianwilkerson) Implement this.
   }
 
@@ -1038,8 +1037,8 @@
   }
 
   /**
-   * Check if the object [obj] matches the type [type] according
-   * to runtime type checking rules.
+   * Check if the object [obj] matches the type [type] according to runtime type
+   * checking rules.
    */
   bool _runtimeTypeMatch(DartObjectImpl obj, DartType type) {
     if (obj.isNull) {
@@ -1052,8 +1051,8 @@
   }
 
   /**
-   * Determine whether the given string is a valid name for a public symbol (i.e. whether it is
-   * allowed for a call to the Symbol constructor).
+   * Determine whether the given string is a valid name for a public symbol
+   * (i.e. whether it is allowed for a call to the Symbol constructor).
    */
   static bool isValidPublicSymbol(String name) => name.isEmpty ||
       name == "void" ||
@@ -1061,9 +1060,8 @@
 }
 
 /**
- * A `ConstantValueComputer_InitializerCloner` is an [AstCloner] that copies the
- * necessary information from the AST to allow const constructor initializers to
- * be evaluated.
+ * An [AstCloner] that copies the necessary information from the AST to allow
+ * const constructor initializers to be evaluated.
  */
 class ConstantValueComputer_InitializerCloner extends AstCloner {
   // TODO(brianwilkerson) Investigate replacing uses of this class with uses of
@@ -1107,46 +1105,58 @@
 }
 
 /**
- * Instances of the class `ConstantVisitor` evaluate constant expressions to produce their
- * compile-time value. According to the Dart Language Specification: <blockquote> A constant
+ * A visitor used to evaluate constant expressions to produce their compile-time
+ * value. According to the Dart Language Specification: <blockquote> A constant
  * expression is one of the following:
+ *
  * * A literal number.
  * * A literal boolean.
- * * A literal string where any interpolated expression is a compile-time constant that evaluates
- * to a numeric, string or boolean value or to <b>null</b>.
+ * * A literal string where any interpolated expression is a compile-time
+ *   constant that evaluates to a numeric, string or boolean value or to
+ *   <b>null</b>.
  * * A literal symbol.
  * * <b>null</b>.
  * * A qualified reference to a static constant variable.
- * * An identifier expression that denotes a constant variable, class or type alias.
+ * * An identifier expression that denotes a constant variable, class or type
+ *   alias.
  * * A constant constructor invocation.
  * * A constant list literal.
  * * A constant map literal.
- * * A simple or qualified identifier denoting a top-level function or a static method.
- * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant expression.
- * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i> where
- * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions and <i>identical()</i> is
- * statically bound to the predefined dart function <i>identical()</i> discussed above.
- * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or <i>e<sub>1</sub>
- * != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions
- * that evaluate to a numeric, string or boolean value.
- * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp; e<sub>2</sub></i> or
- * <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>, <i>e1</sub></i> and <i>e2</sub></i> are
- * constant expressions that evaluate to a boolean value.
- * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^ e<sub>2</sub></i>,
- * <i>e<sub>1</sub> &amp; e<sub>2</sub></i>, <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub>
- * &gt;&gt; e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where <i>e</i>,
- * <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant expressions that evaluate to an
- * integer value or to <b>null</b>.
- * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> + e<sub>2</sub></i>,
- * <i>e<sub>1</sub> - e<sub>2</sub></i>, <i>e<sub>1</sub> * e<sub>2</sub></i>, <i>e<sub>1</sub> /
- * e<sub>2</sub></i>, <i>e<sub>1</sub> ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;
- * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
- * e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or <i>e<sub>1</sub> %
- * e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
- * expressions that evaluate to a numeric value or to <b>null</b>.
- * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> where
- * <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and <i>e<sub>3</sub></i> are constant expressions, and
- * <i>e<sub>1</sub></i> evaluates to a boolean value.
+ * * A simple or qualified identifier denoting a top-level function or a static
+ *   method.
+ * * A parenthesized expression <i>(e)</i> where <i>e</i> is a constant
+ *   expression.
+ * * An expression of the form <i>identical(e<sub>1</sub>, e<sub>2</sub>)</i>
+ *   where <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ *   expressions and <i>identical()</i> is statically bound to the predefined
+ *   dart function <i>identical()</i> discussed above.
+ * * An expression of one of the forms <i>e<sub>1</sub> == e<sub>2</sub></i> or
+ *   <i>e<sub>1</sub> != e<sub>2</sub></i> where <i>e<sub>1</sub></i> and
+ *   <i>e<sub>2</sub></i> are constant expressions that evaluate to a numeric,
+ *   string or boolean value.
+ * * An expression of one of the forms <i>!e</i>, <i>e<sub>1</sub> &amp;&amp;
+ *   e<sub>2</sub></i> or <i>e<sub>1</sub> || e<sub>2</sub></i>, where <i>e</i>,
+ *   <i>e1</sub></i> and <i>e2</sub></i> are constant expressions that evaluate
+ *   to a boolean value.
+ * * An expression of one of the forms <i>~e</i>, <i>e<sub>1</sub> ^
+ *   e<sub>2</sub></i>, <i>e<sub>1</sub> &amp; e<sub>2</sub></i>,
+ *   <i>e<sub>1</sub> | e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;&gt;
+ *   e<sub>2</sub></i> or <i>e<sub>1</sub> &lt;&lt; e<sub>2</sub></i>, where
+ *   <i>e</i>, <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> are constant
+ *   expressions that evaluate to an integer value or to <b>null</b>.
+ * * An expression of one of the forms <i>-e</i>, <i>e<sub>1</sub> +
+ *   e<sub>2</sub></i>, <i>e<sub>1</sub> - e<sub>2</sub></i>, <i>e<sub>1</sub> *
+ *   e<sub>2</sub></i>, <i>e<sub>1</sub> / e<sub>2</sub></i>, <i>e<sub>1</sub>
+ *   ~/ e<sub>2</sub></i>, <i>e<sub>1</sub> &gt; e<sub>2</sub></i>,
+ *   <i>e<sub>1</sub> &lt; e<sub>2</sub></i>, <i>e<sub>1</sub> &gt;=
+ *   e<sub>2</sub></i>, <i>e<sub>1</sub> &lt;= e<sub>2</sub></i> or
+ *   <i>e<sub>1</sub> % e<sub>2</sub></i>, where <i>e</i>, <i>e<sub>1</sub></i>
+ *   and <i>e<sub>2</sub></i> are constant expressions that evaluate to a
+ *   numeric value or to <b>null</b>.
+ * * An expression of the form <i>e<sub>1</sub> ? e<sub>2</sub> :
+ *   e<sub>3</sub></i> where <i>e<sub>1</sub></i>, <i>e<sub>2</sub></i> and
+ *   <i>e<sub>3</sub></i> are constant expressions, and <i>e<sub>1</sub></i>
+ *   evaluates to a boolean value.
  * </blockquote>
  */
 class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
@@ -1155,15 +1165,11 @@
    */
   final TypeProvider _typeProvider;
 
-  /**
-   * An shared object representing the value 'null'.
-   */
-  DartObjectImpl _nullObject;
-
   HashMap<String, DartObjectImpl> _lexicalEnvironment;
 
   /**
-   * Error reporter that we use to report errors accumulated while computing the constant.
+   * Error reporter that we use to report errors accumulated while computing the
+   * constant.
    */
   final ErrorReporter _errorReporter;
 
@@ -1173,11 +1179,9 @@
   DartObjectComputer _dartObjectComputer;
 
   /**
-   * Initialize a newly created constant visitor.
-   *
-   * @param typeProvider the type provider used to access known types
-   * @param lexicalEnvironment values which should override simpleIdentifiers, or null if no
-   *          overriding is necessary.
+   * Initialize a newly created constant visitor. The [_typeProvider] is the
+   * type provider used to access known types. The [_errorReporter] is used to
+   * report errors found during evaluation.
    */
   ConstantVisitor.con1(this._typeProvider, this._errorReporter) {
     this._lexicalEnvironment = null;
@@ -1186,11 +1190,11 @@
   }
 
   /**
-   * Initialize a newly created constant visitor.
-   *
-   * @param typeProvider the type provider used to access known types
-   * @param lexicalEnvironment values which should override simpleIdentifiers, or null if no
-   *          overriding is necessary.
+   * Initialize a newly created constant visitor. The [_typeProvider] is the
+   * type provider used to access known types. The [lexicalEnvironment] is a map
+   * containing values which should override identifiers, or `null` if no
+   * overriding is necessary. The [_errorReporter] is used to report errors
+   * found during evaluation.
    */
   ConstantVisitor.con2(this._typeProvider,
       HashMap<String, DartObjectImpl> lexicalEnvironment, this._errorReporter) {
@@ -1200,27 +1204,15 @@
   }
 
   /**
-   * Return an object representing the value 'null'.
-   *
-   * @return an object representing the value 'null'
-   */
-  DartObjectImpl get null2 {
-    if (_nullObject == null) {
-      _nullObject =
-          new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE);
-    }
-    return _nullObject;
-  }
-
-  /**
-   * This method is called just before retrieving an evaluation result from an AST node. Unit tests
-   * will override it to introduce additional error checking.
+   * This method is called just before retrieving an evaluation result from an
+   * AST node. Unit tests will override it to introduce additional error
+   * checking.
    */
   void beforeGetEvaluationResult(AstNode node) {}
 
   /**
    * Return `true` if the given [element] represents the `length` getter in
-   * class [String].
+   * class 'String'.
    */
   bool isStringLength(Element element) {
     if (element is PropertyAccessorElement) {
@@ -1496,7 +1488,7 @@
   }
 
   @override
-  DartObjectImpl visitNullLiteral(NullLiteral node) => null2;
+  DartObjectImpl visitNullLiteral(NullLiteral node) => _typeProvider.nullObject;
 
   @override
   DartObjectImpl visitParenthesizedExpression(ParenthesizedExpression node) =>
@@ -1603,10 +1595,8 @@
   }
 
   /**
-   * Create an error associated with the given node.
-   *
-   * @param node the AST node associated with the error
-   * @param code the error code indicating the nature of the error
+   * Create an error associated with the given [node]. The error will have the
+   * given error [code].
    */
   void _error(AstNode node, ErrorCode code) {
     _errorReporter.reportErrorForNode(
@@ -1614,11 +1604,9 @@
   }
 
   /**
-   * Return the constant value of the static constant represented by the given element.
-   *
-   * @param node the node to be used if an error needs to be reported
-   * @param element the element whose value is to be returned
-   * @return the constant value of the static constant
+   * Return the constant value of the static constant represented by the given
+   * [element]. The [node] is the node to be used if an error needs to be
+   * reported.
    */
   DartObjectImpl _getConstantValue(AstNode node, Element element) {
     if (element is PropertyAccessorElement) {
@@ -1665,106 +1653,82 @@
   }
 
   /**
-   * Return the value of the given expression, or a representation of 'null' if the expression
-   * cannot be evaluated.
-   *
-   * @param expression the expression whose value is to be returned
-   * @return the value of the given expression
+   * Return the value of the given [expression], or a representation of 'null'
+   * if the expression cannot be evaluated.
    */
   DartObjectImpl _valueOf(Expression expression) {
     DartObjectImpl expressionValue = expression.accept(this);
     if (expressionValue != null) {
       return expressionValue;
     }
-    return null2;
+    return _typeProvider.nullObject;
   }
 }
 
 /**
- * The interface `DartObject` defines the behavior of objects that represent the state of a
- * Dart object.
+ * The state of a Dart object.
  */
 abstract class DartObject {
   /**
-   * Return the boolean value of this object, or `null` if either the value of this object is
-   * not known or this object is not of type 'bool'.
-   *
-   * @return the boolean value of this object
+   * Return the boolean value of this object, or `null` if either the value of
+   * this object is not known or this object is not of type 'bool'.
    */
   bool get boolValue;
 
   /**
-   * Return the floating point value of this object, or `null` if either the value of this
-   * object is not known or this object is not of type 'double'.
-   *
-   * @return the floating point value of this object
+   * Return the floating point value of this object, or `null` if either the
+   * value of this object is not known or this object is not of type 'double'.
    */
   double get doubleValue;
 
   /**
    * Return `true` if this object's value can be represented exactly.
-   *
-   * @return `true` if this object's value can be represented exactly
    */
   bool get hasExactValue;
 
   /**
-   * Return the integer value of this object, or `null` if either the value of this object is
-   * not known or this object is not of type 'int'.
-   *
-   * @return the integer value of this object
+   * Return the integer value of this object, or `null` if either the value of
+   * this object is not known or this object is not of type 'int'.
    */
   int get intValue;
 
   /**
    * Return `true` if this object represents the value 'false'.
-   *
-   * @return `true` if this object represents the value 'false'
    */
   bool get isFalse;
 
   /**
    * Return `true` if this object represents the value 'null'.
-   *
-   * @return `true` if this object represents the value 'null'
    */
   bool get isNull;
 
   /**
    * Return `true` if this object represents the value 'true'.
-   *
-   * @return `true` if this object represents the value 'true'
    */
   bool get isTrue;
 
   /**
-   * Return the string value of this object, or `null` if either the value of this object is
-   * not known or this object is not of type 'String'.
-   *
-   * @return the string value of this object
+   * Return the string value of this object, or `null` if either the value of
+   * this object is not known or this object is not of type 'String'.
    */
   String get stringValue;
 
   /**
    * Return the run-time type of this object.
-   *
-   * @return the run-time type of this object
    */
   ParameterizedType get type;
 
   /**
-   * Return this object's value if it can be represented exactly, or `null` if either the
-   * value cannot be represented exactly or if the value is `null`. Clients should use
-   * [hasExactValue] to distinguish between these two cases.
-   *
-   * @return this object's value
+   * Return this object's value if it can be represented exactly, or `null` if
+   * either the value cannot be represented exactly or if the value is `null`.
+   * Clients should use [hasExactValue] to distinguish between these two cases.
    */
   Object get value;
 }
 
 /**
- * Instances of the class `DartObjectComputer` contain methods for manipulating instances of a
- * Dart class and for collecting errors during evaluation.
+ * A utility class that contains methods for manipulating instances of a Dart
+ * class and for collecting errors during evaluation.
  */
 class DartObjectComputer {
   /**
@@ -1773,8 +1737,8 @@
   final ErrorReporter _errorReporter;
 
   /**
-   * The type provider. Used to create objects of the appropriate types, and to identify when an
-   * object is of a built-in type.
+   * The type provider used to create objects of the appropriate types, and to
+   * identify when an object is of a built-in type.
    */
   final TypeProvider _typeProvider;
 
@@ -1794,10 +1758,8 @@
   }
 
   /**
-   * Return the result of applying boolean conversion to this result.
-   *
-   * @param node the node against which errors should be reported
-   * @return the result of applying boolean conversion to the given value
+   * Return the result of applying boolean conversion to the [evaluationResult].
+   * The [node] is the node against which errors should be reported.
    */
   DartObjectImpl applyBooleanConversion(
       AstNode node, DartObjectImpl evaluationResult) {
@@ -2085,10 +2047,9 @@
   }
 
   /**
-   * Return the result of invoking the 'length' getter on this result.
-   *
-   * @param node the node against which errors should be reported
-   * @return the result of invoking the 'length' getter on this result
+   * Return the result of invoking the 'length' getter on the
+   * [evaluationResult]. The [node] is the node against which errors should be
+   * reported.
    */
   EvaluationResultImpl stringLength(
       Expression node, EvaluationResultImpl evaluationResult) {
@@ -2117,7 +2078,7 @@
 }
 
 /**
- * Instances of the class `DartObjectImpl` represent an instance of a Dart class.
+ * An instance of a Dart class.
  */
 class DartObjectImpl implements DartObject {
   /**
@@ -2136,10 +2097,7 @@
   final InstanceState _state;
 
   /**
-   * Initialize a newly created object to have the given type and state.
-   *
-   * @param type the run-time type of this object
-   * @param state the state of the object
+   * Initialize a newly created object to have the given [type] and [_state].
    */
   DartObjectImpl(this.type, this._state);
 
@@ -2177,16 +2135,12 @@
 
   /**
    * Return `true` if this object represents an object whose type is 'bool'.
-   *
-   * @return `true` if this object represents a boolean value
    */
   bool get isBool => _state.isBool;
 
   /**
-   * Return `true` if this object represents an object whose type is either 'bool', 'num',
-   * 'String', or 'Null'.
-   *
-   * @return `true` if this object represents either a boolean, numeric, string or null value
+   * Return `true` if this object represents an object whose type is either
+   * 'bool', 'num', 'String', or 'Null'.
    */
   bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
 
@@ -2202,14 +2156,13 @@
       _state is BoolState && identical((_state as BoolState).value, true);
 
   /**
-   * Return true if this object represents an unknown value.
+   * Return `true` if this object represents an unknown value.
    */
   bool get isUnknown => _state.isUnknown;
 
   /**
-   * Return `true` if this object represents an instance of a user-defined class.
-   *
-   * @return `true` if this object represents an instance of a user-defined class
+   * Return `true` if this object represents an instance of a user-defined
+   * class.
    */
   bool get isUserDefinedObject => _state is GenericState;
 
@@ -2234,12 +2187,12 @@
   }
 
   /**
-   * Return the result of invoking the '+' operator on this object with the given argument.
+   * Return the result of invoking the '+' operator on this object with the
+   * given [rightOperand]. The [typeProvider] is the type provider used to find
+   * known types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '+' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl add(TypeProvider typeProvider, DartObjectImpl rightOperand) {
     InstanceState result = _state.add(rightOperand._state);
@@ -2257,12 +2210,12 @@
   }
 
   /**
-   * Return the result of invoking the '&' operator on this object with the given argument.
+   * Return the result of invoking the '&' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl bitAnd(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2270,22 +2223,22 @@
           typeProvider.intType, _state.bitAnd(rightOperand._state));
 
   /**
-   * Return the result of invoking the '~' operator on this object.
+   * Return the result of invoking the '~' operator on this object. The
+   * [typeProvider] is the type provider used to find known types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @return the result of invoking the '~' operator on this object
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl bitNot(TypeProvider typeProvider) =>
       new DartObjectImpl(typeProvider.intType, _state.bitNot());
 
   /**
-   * Return the result of invoking the '|' operator on this object with the given argument.
+   * Return the result of invoking the '|' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '|' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl bitOr(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2293,12 +2246,12 @@
           typeProvider.intType, _state.bitOr(rightOperand._state));
 
   /**
-   * Return the result of invoking the '^' operator on this object with the given argument.
+   * Return the result of invoking the '^' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '^' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl bitXor(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2306,12 +2259,12 @@
           typeProvider.intType, _state.bitXor(rightOperand._state));
 
   /**
-   * Return the result of invoking the ' ' operator on this object with the given argument.
+   * Return the result of invoking the ' ' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the ' ' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl concatenate(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2319,11 +2272,11 @@
           typeProvider.stringType, _state.concatenate(rightOperand._state));
 
   /**
-   * Return the result of applying boolean conversion to this object.
+   * Return the result of applying boolean conversion to this object. The
+   * [typeProvider] is the type provider used to find known types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @return the result of applying boolean conversion to this object
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl convertToBool(TypeProvider typeProvider) {
     InterfaceType boolType = typeProvider.boolType;
@@ -2334,12 +2287,12 @@
   }
 
   /**
-   * Return the result of invoking the '/' operator on this object with the given argument.
+   * Return the result of invoking the '/' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '/' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for
+   * an object of this kind.
    */
   DartObjectImpl divide(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
@@ -2356,12 +2309,12 @@
   }
 
   /**
-   * Return the result of invoking the '==' operator on this object with the given argument.
+   * Return the result of invoking the '==' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '==' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl equalEqual(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
@@ -2383,12 +2336,12 @@
   }
 
   /**
-   * Return the result of invoking the '&gt;' operator on this object with the given argument.
+   * Return the result of invoking the '&gt;' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&gt;' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl greaterThan(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2396,24 +2349,24 @@
           typeProvider.boolType, _state.greaterThan(rightOperand._state));
 
   /**
-   * Return the result of invoking the '&gt;=' operator on this object with the given argument.
+   * Return the result of invoking the '&gt;=' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&gt;=' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl greaterThanOrEqual(TypeProvider typeProvider,
       DartObjectImpl rightOperand) => new DartObjectImpl(
       typeProvider.boolType, _state.greaterThanOrEqual(rightOperand._state));
 
   /**
-   * Return the result of invoking the '~/' operator on this object with the given argument.
+   * Return the result of invoking the '~/' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '~/' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl integerDivide(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2422,12 +2375,8 @@
 
   /**
    * Return the result of invoking the identical function on this object with
-   * the given argument.
-   *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the identical function on this object with
-   *         the given argument
+   * the [rightOperand]. The [typeProvider] is the type provider used to find
+   * known types.
    */
   DartObjectImpl isIdentical(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
@@ -2436,12 +2385,12 @@
   }
 
   /**
-   * Return the result of invoking the '&lt;' operator on this object with the given argument.
+   * Return the result of invoking the '&lt;' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&lt;' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl lessThan(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2449,12 +2398,12 @@
           typeProvider.boolType, _state.lessThan(rightOperand._state));
 
   /**
-   * Return the result of invoking the '&lt;=' operator on this object with the given argument.
+   * Return the result of invoking the '&lt;=' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&lt;=' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl lessThanOrEqual(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2462,12 +2411,12 @@
           typeProvider.boolType, _state.lessThanOrEqual(rightOperand._state));
 
   /**
-   * Return the result of invoking the '&&' operator on this object with the given argument.
+   * Return the result of invoking the '&&' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&&' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl logicalAnd(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2475,22 +2424,22 @@
           typeProvider.boolType, _state.logicalAnd(rightOperand._state));
 
   /**
-   * Return the result of invoking the '!' operator on this object.
+   * Return the result of invoking the '!' operator on this object. The
+   * [typeProvider] is the type provider used to find known types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @return the result of invoking the '!' operator on this object
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl logicalNot(TypeProvider typeProvider) =>
       new DartObjectImpl(typeProvider.boolType, _state.logicalNot());
 
   /**
-   * Return the result of invoking the '||' operator on this object with the given argument.
+   * Return the result of invoking the '||' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '||' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl logicalOr(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2498,12 +2447,12 @@
           typeProvider.boolType, _state.logicalOr(rightOperand._state));
 
   /**
-   * Return the result of invoking the '-' operator on this object with the given argument.
+   * Return the result of invoking the '-' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '-' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl minus(TypeProvider typeProvider, DartObjectImpl rightOperand) {
     InstanceState result = _state.minus(rightOperand._state);
@@ -2519,11 +2468,11 @@
   }
 
   /**
-   * Return the result of invoking the '-' operator on this object.
+   * Return the result of invoking the '-' operator on this object. The
+   * [typeProvider] is the type provider used to find known types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @return the result of invoking the '-' operator on this object
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl negated(TypeProvider typeProvider) {
     InstanceState result = _state.negated();
@@ -2539,12 +2488,12 @@
   }
 
   /**
-   * Return the result of invoking the '!=' operator on this object with the given argument.
+   * Return the result of invoking the '!=' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '!=' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl notEqual(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
@@ -2563,11 +2512,11 @@
   }
 
   /**
-   * Return the result of converting this object to a String.
+   * Return the result of converting this object to a 'String'. The
+   * [typeProvider] is the type provider used to find known types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @return the result of converting this object to a String
-   * @throws EvaluationException if the object cannot be converted to a String
+   * Throws an [EvaluationException] if the object cannot be converted to a
+   * 'String'.
    */
   DartObjectImpl performToString(TypeProvider typeProvider) {
     InterfaceType stringType = typeProvider.stringType;
@@ -2578,12 +2527,12 @@
   }
 
   /**
-   * Return the result of invoking the '%' operator on this object with the given argument.
+   * Return the result of invoking the '%' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '%' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl remainder(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
@@ -2601,12 +2550,12 @@
   }
 
   /**
-   * Return the result of invoking the '&lt;&lt;' operator on this object with the given argument.
+   * Return the result of invoking the '&lt;&lt;' operator on this object with
+   * the [rightOperand]. The [typeProvider] is the type provider used to find
+   * known types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&lt;&lt;' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl shiftLeft(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2614,12 +2563,12 @@
           typeProvider.intType, _state.shiftLeft(rightOperand._state));
 
   /**
-   * Return the result of invoking the '&gt;&gt;' operator on this object with the given argument.
+   * Return the result of invoking the '&gt;&gt;' operator on this object with
+   * the [rightOperand]. The [typeProvider] is the type provider used to find
+   * known types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&gt;&gt;' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl shiftRight(
           TypeProvider typeProvider, DartObjectImpl rightOperand) =>
@@ -2627,22 +2576,22 @@
           typeProvider.intType, _state.shiftRight(rightOperand._state));
 
   /**
-   * Return the result of invoking the 'length' getter on this object.
+   * Return the result of invoking the 'length' getter on this object. The
+   * [typeProvider] is the type provider used to find known types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @return the result of invoking the 'length' getter on this object
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl stringLength(TypeProvider typeProvider) =>
       new DartObjectImpl(typeProvider.intType, _state.stringLength());
 
   /**
-   * Return the result of invoking the '*' operator on this object with the given argument.
+   * Return the result of invoking the '*' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
    *
-   * @param typeProvider the type provider used to find known types
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '*' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   DartObjectImpl times(TypeProvider typeProvider, DartObjectImpl rightOperand) {
     InstanceState result = _state.times(rightOperand._state);
@@ -2662,8 +2611,8 @@
 }
 
 /**
- * Instances of the class `DeclaredVariables` provide access to the values of variables that
- * have been defined on the command line using the `-D` option.
+ * An object used to provide access to the values of variables that have been
+ * defined on the command line using the `-D` option.
  */
 class DeclaredVariables {
   /**
@@ -2672,26 +2621,21 @@
   HashMap<String, String> _declaredVariables = new HashMap<String, String>();
 
   /**
-   * Define a variable with the given name to have the given value.
-   *
-   * @param variableName the name of the variable being defined
-   * @param value the value of the variable
+   * Define a variable with the given [name] to have the given [value].
    */
-  void define(String variableName, String value) {
-    _declaredVariables[variableName] = value;
+  void define(String name, String value) {
+    _declaredVariables[name] = value;
   }
 
   /**
-   * Return the value of the variable with the given name interpreted as a boolean value. If the
-   * variable is not defined (or [variableName] is null), a DartObject representing "unknown"
-   * is returned. If the value can't be parsed as a boolean, a DartObject representing null is
-   * returned.
-   *
-   * @param typeProvider the type provider used to find the type 'bool'
-   * @param variableName the name of the variable whose value is to be returned
+   * Return the value of the variable with the given [name] interpreted as a
+   * 'boolean' value. If the variable is not defined (or [name] is `null`), a
+   * DartObject representing "unknown" is returned. If the value cannot be
+   * parsed as a boolean, a DartObject representing 'null' is returned. The
+   * [typeProvider] is the type provider used to find the type 'bool'.
    */
-  DartObject getBool(TypeProvider typeProvider, String variableName) {
-    String value = _declaredVariables[variableName];
+  DartObject getBool(TypeProvider typeProvider, String name) {
+    String value = _declaredVariables[name];
     if (value == null) {
       return new DartObjectImpl(typeProvider.boolType, BoolState.UNKNOWN_VALUE);
     }
@@ -2704,39 +2648,35 @@
   }
 
   /**
-   * Return the value of the variable with the given name interpreted as an integer value. If the
-   * variable is not defined (or [variableName] is null), a DartObject representing "unknown"
-   * is returned. If the value can't be parsed as an integer, a DartObject representing null is
-   * returned.
-   *
-   * @param typeProvider the type provider used to find the type 'int'
-   * @param variableName the name of the variable whose value is to be returned
+   * Return the value of the variable with the given [name] interpreted as an
+   * integer value. If the variable is not defined (or [name] is `null`), a
+   * DartObject representing "unknown" is returned. If the value cannot be
+   * parsed as an integer, a DartObject representing 'null' is returned.
    */
-  DartObject getInt(TypeProvider typeProvider, String variableName) {
-    String value = _declaredVariables[variableName];
+  DartObject getInt(TypeProvider typeProvider, String name) {
+    String value = _declaredVariables[name];
     if (value == null) {
       return new DartObjectImpl(typeProvider.intType, IntState.UNKNOWN_VALUE);
     }
     int bigInteger;
     try {
       bigInteger = int.parse(value);
-    } on FormatException catch (exception) {
+    } on FormatException {
       return new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE);
     }
     return new DartObjectImpl(typeProvider.intType, new IntState(bigInteger));
   }
 
   /**
-   * Return the value of the variable with the given name interpreted as a String value, or
-   * `null` if the variable is not defined. Return the value of the variable with the given
-   * name interpreted as a String value. If the variable is not defined (or [variableName] is
-   * null), a DartObject representing "unknown" is returned.
-   *
-   * @param typeProvider the type provider used to find the type 'String'
-   * @param variableName the name of the variable whose value is to be returned
+   * Return the value of the variable with the given [name] interpreted as a
+   * String value, or `null` if the variable is not defined. Return the value of
+   * the variable with the given name interpreted as a String value. If the
+   * variable is not defined (or [name] is `null`), a DartObject representing
+   * "unknown" is returned. The [typeProvider] is the type provider used to find
+   * the type 'String'.
    */
-  DartObject getString(TypeProvider typeProvider, String variableName) {
-    String value = _declaredVariables[variableName];
+  DartObject getString(TypeProvider typeProvider, String name) {
+    String value = _declaredVariables[name];
     if (value == null) {
       return new DartObjectImpl(
           typeProvider.stringType, StringState.UNKNOWN_VALUE);
@@ -2746,8 +2686,7 @@
 }
 
 /**
- * Instances of the class `DoubleState` represent the state of an object representing a
- * double.
+ * The state of an object representing a double.
  */
 class DoubleState extends NumState {
   /**
@@ -2761,9 +2700,8 @@
   final double value;
 
   /**
-   * Initialize a newly created state to represent a double with the given value.
-   *
-   * @param value the value of this instance
+   * Initialize a newly created state to represent a double with the given
+   * [value].
    */
   DoubleState(this.value);
 
@@ -3088,8 +3026,8 @@
 }
 
 /**
- * Instances of the class `DynamicState` represent the state of an object representing a Dart
- * object for which there is no type information.
+ * The state of an object representing a Dart object for which there is no type
+ * information.
  */
 class DynamicState extends InstanceState {
   /**
@@ -3241,11 +3179,8 @@
   }
 
   /**
-   * Return an object representing an unknown numeric value whose type is based on the type of the
-   * right-hand operand.
-   *
-   * @param rightOperand the operand whose type will determine the type of the result
-   * @return an object representing an unknown numeric value
+   * Return an object representing an unknown numeric value whose type is based
+   * on the type of the [rightOperand].
    */
   NumState _unknownNum(InstanceState rightOperand) {
     if (rightOperand is IntState) {
@@ -3258,8 +3193,7 @@
 }
 
 /**
- * Instances of the class `EvaluationException` represent a run-time exception that would be
- * thrown during the evaluation of Dart code.
+ * A run-time exception that would be thrown during the evaluation of Dart code.
  */
 class EvaluationException extends JavaException {
   /**
@@ -3268,16 +3202,13 @@
   final ErrorCode errorCode;
 
   /**
-   * Initialize a newly created exception to have the given error code.
-   *
-   * @param errorCode the error code associated with the exception
+   * Initialize a newly created exception to have the given [errorCode].
    */
   EvaluationException(this.errorCode);
 }
 
 /**
- * Instances of the class `EvaluationResult` represent the result of attempting to evaluate an
- * expression.
+ * The result of attempting to evaluate an expression.
  */
 class EvaluationResult {
   /**
@@ -3286,70 +3217,65 @@
   final DartObject value;
 
   /**
-   * The errors that should be reported for the expression(s) that were evaluated.
+   * The errors that should be reported for the expression(s) that were
+   * evaluated.
    */
   final List<AnalysisError> _errors;
 
   /**
-   * Initialize a newly created result object with the given state. Clients should use one of the
-   * factory methods: [forErrors] and [forValue].
-   *
-   * @param value the value of the expression
-   * @param errors the errors that should be reported for the expression(s) that were evaluated
+   * Initialize a newly created result object with the given [value] and set of
+   * [_errors]. Clients should use one of the factory methods: [forErrors] and
+   * [forValue].
    */
   EvaluationResult(this.value, this._errors);
 
   /**
-   * Return an array containing the errors that should be reported for the expression(s) that were
-   * evaluated. If there are no such errors, the array will be empty. The array can be empty even if
-   * the expression is not a valid compile time constant if the errors would have been reported by
-   * other parts of the analysis engine.
+   * Return a list containing the errors that should be reported for the
+   * expression(s) that were evaluated. If there are no such errors, the list
+   * will be empty. The list can be empty even if the expression is not a valid
+   * compile time constant if the errors would have been reported by other parts
+   * of the analysis engine.
    */
   List<AnalysisError> get errors =>
       _errors == null ? AnalysisError.NO_ERRORS : _errors;
 
   /**
-   * Return `true` if the expression is a compile-time constant expression that would not
-   * throw an exception when evaluated.
-   *
-   * @return `true` if the expression is a valid compile-time constant expression
+   * Return `true` if the expression is a compile-time constant expression that
+   * would not throw an exception when evaluated.
    */
   bool get isValid => _errors == null;
 
   /**
-   * Return an evaluation result representing the result of evaluating an expression that is not a
-   * compile-time constant because of the given errors.
-   *
-   * @param errors the errors that should be reported for the expression(s) that were evaluated
-   * @return the result of evaluating an expression that is not a compile-time constant
+   * Return an evaluation result representing the result of evaluating an
+   * expression that is not a compile-time constant because of the given
+   * [errors].
    */
   static EvaluationResult forErrors(List<AnalysisError> errors) =>
       new EvaluationResult(null, errors);
 
   /**
-   * Return an evaluation result representing the result of evaluating an expression that is a
-   * compile-time constant that evaluates to the given value.
-   *
-   * @param value the value of the expression
-   * @return the result of evaluating an expression that is a compile-time constant
+   * Return an evaluation result representing the result of evaluating an
+   * expression that is a compile-time constant that evaluates to the given
+   * [value].
    */
   static EvaluationResult forValue(DartObject value) =>
       new EvaluationResult(value, null);
 }
 
 /**
- * Instances of the class `InternalResult` represent the result of attempting to evaluate a
- * expression.
+ * The result of attempting to evaluate a expression.
  */
 class EvaluationResultImpl {
   /**
-   * The errors encountered while trying to evaluate the compile time constant. These errors may or
-   * may not have prevented the expression from being a valid compile time constant.
+   * The errors encountered while trying to evaluate the compile time constant.
+   * These errors may or may not have prevented the expression from being a
+   * valid compile time constant.
    */
   List<AnalysisError> _errors;
 
   /**
-   * The value of the expression, or null if the value couldn't be computed due to errors.
+   * The value of the expression, or `null` if the value couldn't be computed
+   * due to errors.
    */
   final DartObjectImpl value;
 
@@ -3384,8 +3310,7 @@
 }
 
 /**
- * Instances of the class `FunctionState` represent the state of an object representing a
- * function.
+ * The state of an object representing a function.
  */
 class FunctionState extends InstanceState {
   /**
@@ -3394,9 +3319,8 @@
   final ExecutableElement _element;
 
   /**
-   * Initialize a newly created state to represent the given function.
-   *
-   * @param element the element representing the function being modeled
+   * Initialize a newly created state to represent the function with the given
+   * [element].
    */
   FunctionState(this._element);
 
@@ -3445,8 +3369,8 @@
 }
 
 /**
- * Instances of the class `GenericState` represent the state of an object representing a Dart
- * object for which there is no more specific state.
+ * The state of an object representing a Dart object for which there is no more
+ * specific state.
  */
 class GenericState extends InstanceState {
   /**
@@ -3466,9 +3390,8 @@
   final HashMap<String, DartObjectImpl> _fieldMap;
 
   /**
-   * Initialize a newly created state to represent a newly created object.
-   *
-   * @param fieldMap the values of the fields of this instance
+   * Initialize a newly created state to represent a newly created object. The
+   * [fieldMap] contains the values of the fields of the instance.
    */
   GenericState(this._fieldMap);
 
@@ -3550,65 +3473,54 @@
 }
 
 /**
- * The class `InstanceState` defines the behavior of objects representing the state of a Dart
- * object.
+ * The state of an object representing a Dart object.
  */
 abstract class InstanceState {
   /**
-   * If this represents a generic dart object, return a map from its fieldnames to their values.
-   * Otherwise return null.
+   * If this represents a generic dart object, return a map from its field names
+   * to their values. Otherwise return null.
    */
   HashMap<String, DartObjectImpl> get fields => null;
 
   /**
    * Return `true` if this object's value can be represented exactly.
-   *
-   * @return `true` if this object's value can be represented exactly
    */
   bool get hasExactValue => false;
 
   /**
    * Return `true` if this object represents an object whose type is 'bool'.
-   *
-   * @return `true` if this object represents a boolean value
    */
   bool get isBool => false;
 
   /**
-   * Return `true` if this object represents an object whose type is either 'bool', 'num',
-   * 'String', or 'Null'.
-   *
-   * @return `true` if this object represents either a boolean, numeric, string or null value
+   * Return `true` if this object represents an object whose type is either
+   * 'bool', 'num', 'String', or 'Null'.
    */
   bool get isBoolNumStringOrNull => false;
 
   /**
-   * Return true if this object represents an unknown value.
+   * Return `true` if this object represents an unknown value.
    */
   bool get isUnknown => false;
 
   /**
    * Return the name of the type of this value.
-   *
-   * @return the name of the type of this value
    */
   String get typeName;
 
   /**
-   * Return this object's value if it can be represented exactly, or `null` if either the
-   * value cannot be represented exactly or if the value is `null`. Clients should use
-   * [hasExactValue] to distinguish between these two cases.
-   *
-   * @return this object's value
+   * Return this object's value if it can be represented exactly, or `null` if
+   * either the value cannot be represented exactly or if the value is `null`.
+   * Clients should use [hasExactValue] to distinguish between these two cases.
    */
   Object get value => null;
 
   /**
-   * Return the result of invoking the '+' operator on this object with the given argument.
+   * Return the result of invoking the '+' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '+' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   InstanceState add(InstanceState rightOperand) {
     if (this is StringState && rightOperand is StringState) {
@@ -3620,10 +3532,7 @@
   }
 
   /**
-   * Throw an exception if the given state does not represent a boolean value.
-   *
-   * @param state the state being tested
-   * @throws EvaluationException if the given state does not represent a boolean value
+   * Throw an exception if the given [state] does not represent a boolean value.
    */
   void assertBool(InstanceState state) {
     if (!(state is BoolState || state is DynamicState)) {
@@ -3632,12 +3541,8 @@
   }
 
   /**
-   * Throw an exception if the given state does not represent a boolean, numeric, string or null
-   * value.
-   *
-   * @param state the state being tested
-   * @throws EvaluationException if the given state does not represent a boolean, numeric, string or
-   *           null value
+   * Throw an exception if the given [state] does not represent a boolean,
+   * numeric, string or null value.
    */
   void assertBoolNumStringOrNull(InstanceState state) {
     if (!(state is BoolState ||
@@ -3653,10 +3558,8 @@
   }
 
   /**
-   * Throw an exception if the given state does not represent an integer or null value.
-   *
-   * @param state the state being tested
-   * @throws EvaluationException if the given state does not represent an integer or null value
+   * Throw an exception if the given [state] does not represent an integer or
+   * null value.
    */
   void assertIntOrNull(InstanceState state) {
     if (!(state is IntState ||
@@ -3668,12 +3571,8 @@
   }
 
   /**
-   * Throw an exception if the given state does not represent a boolean, numeric, string or null
-   * value.
-   *
-   * @param state the state being tested
-   * @throws EvaluationException if the given state does not represent a boolean, numeric, string or
-   *           null value
+   * Throw an exception if the given [state] does not represent a boolean,
+   * numeric, string or null value.
    */
   void assertNumOrNull(InstanceState state) {
     if (!(state is DoubleState ||
@@ -3686,10 +3585,7 @@
   }
 
   /**
-   * Throw an exception if the given state does not represent a String value.
-   *
-   * @param state the state being tested
-   * @throws EvaluationException if the given state does not represent a String value
+   * Throw an exception if the given [state] does not represent a String value.
    */
   void assertString(InstanceState state) {
     if (!(state is StringState || state is DynamicState)) {
@@ -3698,11 +3594,11 @@
   }
 
   /**
-   * Return the result of invoking the '&' operator on this object with the given argument.
+   * Return the result of invoking the '&' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   IntState bitAnd(InstanceState rightOperand) {
     assertIntOrNull(this);
@@ -3713,8 +3609,8 @@
   /**
    * Return the result of invoking the '~' operator on this object.
    *
-   * @return the result of invoking the '~' operator on this object
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   IntState bitNot() {
     assertIntOrNull(this);
@@ -3722,11 +3618,11 @@
   }
 
   /**
-   * Return the result of invoking the '|' operator on this object with the given argument.
+   * Return the result of invoking the '|' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '|' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   IntState bitOr(InstanceState rightOperand) {
     assertIntOrNull(this);
@@ -3735,11 +3631,11 @@
   }
 
   /**
-   * Return the result of invoking the '^' operator on this object with the given argument.
+   * Return the result of invoking the '^' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '^' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   IntState bitXor(InstanceState rightOperand) {
     assertIntOrNull(this);
@@ -3748,11 +3644,11 @@
   }
 
   /**
-   * Return the result of invoking the ' ' operator on this object with the given argument.
+   * Return the result of invoking the ' ' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the ' ' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   StringState concatenate(InstanceState rightOperand) {
     assertString(rightOperand);
@@ -3762,26 +3658,25 @@
   /**
    * Return the result of applying boolean conversion to this object.
    *
-   * @param typeProvider the type provider used to find known types
-   * @return the result of applying boolean conversion to this object
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   BoolState convertToBool() => BoolState.FALSE_STATE;
 
   /**
    * Return the result of converting this object to a String.
    *
-   * @return the result of converting this object to a String
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   StringState convertToString();
 
   /**
-   * Return the result of invoking the '/' operator on this object with the given argument.
+   * Return the result of invoking the '/' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '/' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   NumState divide(InstanceState rightOperand) {
     assertNumOrNull(this);
@@ -3790,20 +3685,20 @@
   }
 
   /**
-   * Return the result of invoking the '==' operator on this object with the given argument.
+   * Return the result of invoking the '==' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '==' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   BoolState equalEqual(InstanceState rightOperand);
 
   /**
-   * Return the result of invoking the '&gt;' operator on this object with the given argument.
+   * Return the result of invoking the '&gt;' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&gt;' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   BoolState greaterThan(InstanceState rightOperand) {
     assertNumOrNull(this);
@@ -3812,11 +3707,11 @@
   }
 
   /**
-   * Return the result of invoking the '&gt;=' operator on this object with the given argument.
+   * Return the result of invoking the '&gt;=' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&gt;=' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   BoolState greaterThanOrEqual(InstanceState rightOperand) {
     assertNumOrNull(this);
@@ -3825,11 +3720,11 @@
   }
 
   /**
-   * Return the result of invoking the '~/' operator on this object with the given argument.
+   * Return the result of invoking the '~/' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '~/' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   IntState integerDivide(InstanceState rightOperand) {
     assertNumOrNull(this);
@@ -3839,20 +3734,16 @@
 
   /**
    * Return the result of invoking the identical function on this object with
-   * the given argument.
-   *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the identical function on this object with
-   *         the given argument
+   * the [rightOperand].
    */
   BoolState isIdentical(InstanceState rightOperand);
 
   /**
-   * Return the result of invoking the '&lt;' operator on this object with the given argument.
+   * Return the result of invoking the '&lt;' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&lt;' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   BoolState lessThan(InstanceState rightOperand) {
     assertNumOrNull(this);
@@ -3861,11 +3752,11 @@
   }
 
   /**
-   * Return the result of invoking the '&lt;=' operator on this object with the given argument.
+   * Return the result of invoking the '&lt;=' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&lt;=' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   BoolState lessThanOrEqual(InstanceState rightOperand) {
     assertNumOrNull(this);
@@ -3874,11 +3765,11 @@
   }
 
   /**
-   * Return the result of invoking the '&&' operator on this object with the given argument.
+   * Return the result of invoking the '&&' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&&' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   BoolState logicalAnd(InstanceState rightOperand) {
     assertBool(this);
@@ -3889,8 +3780,8 @@
   /**
    * Return the result of invoking the '!' operator on this object.
    *
-   * @return the result of invoking the '!' operator on this object
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   BoolState logicalNot() {
     assertBool(this);
@@ -3898,11 +3789,11 @@
   }
 
   /**
-   * Return the result of invoking the '||' operator on this object with the given argument.
+   * Return the result of invoking the '||' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '||' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   BoolState logicalOr(InstanceState rightOperand) {
     assertBool(this);
@@ -3911,11 +3802,11 @@
   }
 
   /**
-   * Return the result of invoking the '-' operator on this object with the given argument.
+   * Return the result of invoking the '-' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '-' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   NumState minus(InstanceState rightOperand) {
     assertNumOrNull(this);
@@ -3926,8 +3817,8 @@
   /**
    * Return the result of invoking the '-' operator on this object.
    *
-   * @return the result of invoking the '-' operator on this object
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   NumState negated() {
     assertNumOrNull(this);
@@ -3935,11 +3826,11 @@
   }
 
   /**
-   * Return the result of invoking the '%' operator on this object with the given argument.
+   * Return the result of invoking the '%' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '%' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   NumState remainder(InstanceState rightOperand) {
     assertNumOrNull(this);
@@ -3948,11 +3839,11 @@
   }
 
   /**
-   * Return the result of invoking the '&lt;&lt;' operator on this object with the given argument.
+   * Return the result of invoking the '&lt;&lt;' operator on this object with
+   * the [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&lt;&lt;' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   IntState shiftLeft(InstanceState rightOperand) {
     assertIntOrNull(this);
@@ -3961,11 +3852,11 @@
   }
 
   /**
-   * Return the result of invoking the '&gt;&gt;' operator on this object with the given argument.
+   * Return the result of invoking the '&gt;&gt;' operator on this object with
+   * the [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '&gt;&gt;' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   IntState shiftRight(InstanceState rightOperand) {
     assertIntOrNull(this);
@@ -3976,8 +3867,8 @@
   /**
    * Return the result of invoking the 'length' getter on this object.
    *
-   * @return the result of invoking the 'length' getter on this object
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   IntState stringLength() {
     assertString(this);
@@ -3985,11 +3876,11 @@
   }
 
   /**
-   * Return the result of invoking the '*' operator on this object with the given argument.
+   * Return the result of invoking the '*' operator on this object with the
+   * [rightOperand].
    *
-   * @param rightOperand the right-hand operand of the operation
-   * @return the result of invoking the '*' operator on this object with the given argument
-   * @throws EvaluationException if the operator is not appropriate for an object of this kind
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
    */
   NumState times(InstanceState rightOperand) {
     assertNumOrNull(this);
@@ -3999,7 +3890,7 @@
 }
 
 /**
- * Instances of the class `IntState` represent the state of an object representing an int.
+ * The state of an object representing an int.
  */
 class IntState extends NumState {
   /**
@@ -4013,9 +3904,8 @@
   final int value;
 
   /**
-   * Initialize a newly created state to represent an int with the given value.
-   *
-   * @param value the value of this instance
+   * Initialize a newly created state to represent an int with the given
+   * [value].
    */
   IntState(this.value);
 
@@ -4143,19 +4033,15 @@
   NumState divide(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
     if (value == null) {
-      if (rightOperand is DoubleState) {
-        return DoubleState.UNKNOWN_VALUE;
-      }
-      return UNKNOWN_VALUE;
+      return DoubleState.UNKNOWN_VALUE;
     }
     if (rightOperand is IntState) {
       int rightValue = rightOperand.value;
       if (rightValue == null) {
-        return UNKNOWN_VALUE;
-      } else if (rightValue == 0) {
+        return DoubleState.UNKNOWN_VALUE;
+      } else {
         return new DoubleState(value.toDouble() / rightValue.toDouble());
       }
-      return new IntState(value ~/ rightValue);
     } else if (rightOperand is DoubleState) {
       double rightValue = rightOperand.value;
       if (rightValue == null) {
@@ -4163,7 +4049,7 @@
       }
       return new DoubleState(value.toDouble() / rightValue);
     } else if (rightOperand is DynamicState || rightOperand is NumState) {
-      return UNKNOWN_VALUE;
+      return DoubleState.UNKNOWN_VALUE;
     }
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -4468,8 +4354,7 @@
 }
 
 /**
- * The unique instance of the class `ListState` represents the state of an object representing
- * a list.
+ * The state of an object representing a list.
  */
 class ListState extends InstanceState {
   /**
@@ -4478,9 +4363,8 @@
   final List<DartObjectImpl> _elements;
 
   /**
-   * Initialize a newly created state to represent a list with the given elements.
-   *
-   * @param elements the elements of the list
+   * Initialize a newly created state to represent a list with the given
+   * [elements].
    */
   ListState(this._elements);
 
@@ -4578,8 +4462,7 @@
 }
 
 /**
- * The unique instance of the class `ListState` represents the state of an object representing
- * a map.
+ * The state of an object representing a map.
  */
 class MapState extends InstanceState {
   /**
@@ -4588,9 +4471,8 @@
   final HashMap<DartObjectImpl, DartObjectImpl> _entries;
 
   /**
-   * Initialize a newly created state to represent a map with the given entries.
-   *
-   * @param entries the entries in the map
+   * Initialize a newly created state to represent a map with the given
+   * [entries].
    */
   MapState(this._entries);
 
@@ -4690,11 +4572,11 @@
 }
 
 /**
- * The unique instance of the class `NullState` represents the state of the value 'null'.
+ * The state of an object representing the value 'null'.
  */
 class NullState extends InstanceState {
   /**
-   * An instance representing the boolean value 'true'.
+   * An instance representing the boolean value 'null'.
    */
   static NullState NULL_STATE = new NullState();
 
@@ -4747,8 +4629,7 @@
 }
 
 /**
- * Instances of the class `NumState` represent the state of an object representing a number of
- * an unknown type (a 'num').
+ * The state of an object representing a number of an unknown type (a 'num').
  */
 class NumState extends InstanceState {
   /**
@@ -4783,7 +4664,7 @@
   @override
   NumState divide(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
-    return UNKNOWN_VALUE;
+    return DoubleState.UNKNOWN_VALUE;
   }
 
   @override
@@ -4864,8 +4745,8 @@
 }
 
 /**
- * Instances of the class `ReferenceFinder` add reference information for a given variable to
- * the bi-directional mapping used to order the evaluation of constants.
+ * An object used to add reference information for a given variable to the
+ * bi-directional mapping used to order the evaluation of constants.
  */
 class ReferenceFinder extends RecursiveAstVisitor<Object> {
   /**
@@ -4874,8 +4755,9 @@
   final AstNode _source;
 
   /**
-   * A graph in which the nodes are the constant variables and the edges are from each variable to
-   * the other constant variables that are referenced in the head's initializer.
+   * A graph in which the nodes are the constant variables and the edges are
+   * from each variable to the other constant variables that are referenced in
+   * the head's initializer.
    */
   final DirectedGraph<AstNode> _referenceGraph;
 
@@ -4885,21 +4767,20 @@
   final HashMap<VariableElement, VariableDeclaration> _variableDeclarationMap;
 
   /**
-   * A table mapping constant constructors to the declarations of those constructors.
+   * A table mapping constant constructors to the declarations of those
+   * constructors.
    */
   final HashMap<ConstructorElement, ConstructorDeclaration> _constructorDeclarationMap;
 
   /**
-   * Initialize a newly created reference finder to find references from the given variable to other
-   * variables and to add those references to the given graph.
-   *
-   * @param source the element representing the variable whose initializer will be visited
-   * @param referenceGraph a graph recording which variables (heads) reference which other variables
-   *          (tails) in their initializers
-   * @param variableDeclarationMap A table mapping constant variables to the declarations of those
-   *          variables.
-   * @param constructorDeclarationMap A table mapping constant constructors to the declarations of
-   *          those constructors.
+   * Initialize a newly created reference finder to find references from a given
+   * variable to other variables and to add those references to the given graph.
+   * The [source] is the element representing the variable whose initializer
+   * will be visited. The [referenceGraph] is a graph recording which variables
+   * (heads) reference which other variables (tails) in their initializers. The
+   * [variableDeclarationMap] is a table mapping constant variables to the
+   * declarations of those variables. The [constructorDeclarationMap] is a table
+   * mapping constant constructors to the declarations of those constructors.
    */
   ReferenceFinder(this._source, this._referenceGraph,
       this._variableDeclarationMap, this._constructorDeclarationMap);
@@ -4934,10 +4815,9 @@
       element = (element as PropertyAccessorElement).variable;
     }
     if (element is VariableElement) {
-      VariableElement variable = element as VariableElement;
-      if (variable.isConst) {
+      if (element.isConst) {
         VariableDeclaration variableDeclaration =
-            _variableDeclarationMap[variable];
+            _variableDeclarationMap[element];
         // The declaration will be null when the variable is not defined in the
         // compilation units that were used to produce the
         // variableDeclarationMap.  In such cases, the variable should already
@@ -4972,8 +4852,7 @@
 }
 
 /**
- * Instances of the class `StringState` represent the state of an object representing a
- * string.
+ * The state of an object representing a string.
  */
 class StringState extends InstanceState {
   /**
@@ -4987,9 +4866,7 @@
   final String value;
 
   /**
-   * Initialize a newly created state to represent the given value.
-   *
-   * @param value the value of this instance
+   * Initialize a newly created state to represent the given [value].
    */
   StringState(this.value);
 
@@ -5068,8 +4945,7 @@
 }
 
 /**
- * Instances of the class `StringState` represent the state of an object representing a
- * symbol.
+ * The state of an object representing a symbol.
  */
 class SymbolState extends InstanceState {
   /**
@@ -5078,9 +4954,7 @@
   final String value;
 
   /**
-   * Initialize a newly created state to represent the given value.
-   *
-   * @param value the value of this instance
+   * Initialize a newly created state to represent the given [value].
    */
   SymbolState(this.value);
 
@@ -5133,7 +5007,7 @@
 }
 
 /**
- * Instances of the class `TypeState` represent the state of an object representing a type.
+ * The state of an object representing a type.
  */
 class TypeState extends InstanceState {
   /**
@@ -5142,9 +5016,7 @@
   final Element _element;
 
   /**
-   * Initialize a newly created state to represent the given value.
-   *
-   * @param element the element representing the type being modeled
+   * Initialize a newly created state to represent the given [value].
    */
   TypeState(this._element);
 
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index a7d8bf3..082415c 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -10,6 +10,7 @@
 import 'dart:collection';
 
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/task/model.dart' show AnalysisTarget;
 
 import 'ast.dart';
 import 'constant.dart' show EvaluationResultImpl;
@@ -25,54 +26,51 @@
 import 'utilities_dart.dart';
 
 /**
- * For AST nodes that could be in both the getter and setter contexts ([IndexExpression]s and
- * [SimpleIdentifier]s), the additional resolved elements are stored in the AST node, in an
- * [AuxiliaryElements]. Since resolved elements are either statically resolved or resolved
- * using propagated type information, this class is a wrapper for a pair of
- * [ExecutableElement]s, not just a single [ExecutableElement].
+ * For AST nodes that could be in both the getter and setter contexts
+ * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
+ * elements are stored in the AST node, in an [AuxiliaryElements]. Because
+ * resolved elements are either statically resolved or resolved using propagated
+ * type information, this class is a wrapper for a pair of [ExecutableElement]s,
+ * not just a single [ExecutableElement].
  */
 class AuxiliaryElements {
   /**
-   * The element based on propagated type information, or `null` if the AST structure has not
-   * been resolved or if this identifier could not be resolved.
+   * The element based on propagated type information, or `null` if the AST
+   * structure has not been resolved or if the node could not be resolved.
    */
   final ExecutableElement propagatedElement;
 
   /**
-   * The element associated with this identifier based on static type information, or `null`
-   * if the AST structure has not been resolved or if this identifier could not be resolved.
+   * The element based on static type information, or `null` if the AST
+   * structure has not been resolved or if the node could not be resolved.
    */
   final ExecutableElement staticElement;
 
   /**
-   * Create the [AuxiliaryElements] with a static and propagated [ExecutableElement].
-   *
-   * @param staticElement the static element
-   * @param propagatedElement the propagated element
+   * Initialize a newly created pair to have both the [staticElement] and the
+   * [propagatedElement].
    */
   AuxiliaryElements(this.staticElement, this.propagatedElement);
 }
 
 /**
- * The unique instance of the class `BottomTypeImpl` implements the type `bottom`.
+ * A [Type] that represents the type 'bottom'.
  */
 class BottomTypeImpl extends TypeImpl {
   /**
    * The unique instance of this class.
    */
-  static BottomTypeImpl _INSTANCE = new BottomTypeImpl();
+  static BottomTypeImpl _INSTANCE = new BottomTypeImpl._();
 
   /**
    * Return the unique instance of this class.
-   *
-   * @return the unique instance of this class
    */
   static BottomTypeImpl get instance => _INSTANCE;
 
   /**
    * Prevent the creation of instances of this class.
    */
-  BottomTypeImpl() : super(null, "<bottom>");
+  BottomTypeImpl._() : super(null, "<bottom>");
 
   @override
   int get hashCode => 0;
@@ -107,235 +105,196 @@
 }
 
 /**
- * The interface `ClassElement` defines the behavior of elements that represent a class.
+ * An element that represents a class.
  */
 abstract class ClassElement implements Element {
   /**
-   * Return an array containing all of the accessors (getters and setters) declared in this class.
-   *
-   * @return the accessors declared in this class
+   * Return a list containing all of the accessors (getters and setters)
+   * declared in this class.
    */
   List<PropertyAccessorElement> get accessors;
 
   /**
-   * Return an array containing all the supertypes defined for this class and its supertypes. This
-   * includes superclasses, mixins and interfaces.
-   *
-   * @return all the supertypes of this class, including mixins
+   * Return a list containing all the supertypes defined for this class and its
+   * supertypes. This includes superclasses, mixins and interfaces.
    */
   List<InterfaceType> get allSupertypes;
 
   /**
-   * Return an array containing all of the constructors declared in this class.
-   *
-   * @return the constructors declared in this class
+   * Return a list containing all of the constructors declared in this class.
    */
   List<ConstructorElement> get constructors;
 
   /**
-   * Return an array containing all of the fields declared in this class.
-   *
-   * @return the fields declared in this class
+   * Return a list containing all of the fields declared in this class.
    */
   List<FieldElement> get fields;
 
   /**
-   * Return `true` if this class or its superclass declares a non-final instance field.
-   *
-   * @return `true` if this class or its superclass declares a non-final instance field
+   * Return `true` if this class or its superclass declares a non-final instance
+   * field.
    */
   bool get hasNonFinalField;
 
   /**
-   * Return `true` if this class has reference to super (so, for example, cannot be used as a
-   * mixin).
-   *
-   * @return `true` if this class has reference to super
+   * Return `true` if this class has reference to super (so, for example, cannot
+   * be used as a mixin).
    */
   bool get hasReferenceToSuper;
 
   /**
    * Return `true` if this class declares a static member.
-   *
-   * @return `true` if this class declares a static member
    */
   bool get hasStaticMember;
 
   /**
-   * Return an array containing all of the interfaces that are implemented by this class.
+   * Return a list containing all of the interfaces that are implemented by this
+   * class.
    *
-   * <b>Note:</b> Because the element model represents the state of the code, it is possible for it
-   * to be semantically invalid. In particular, it is not safe to assume that the inheritance
-   * structure of a class does not contain a cycle. Clients that traverse the inheritance structure
-   * must explicitly guard against infinite loops.
-   *
-   * @return the interfaces that are implemented by this class
+   * <b>Note:</b> Because the element model represents the state of the code, it
+   * is possible for it to be semantically invalid. In particular, it is not
+   * safe to assume that the inheritance structure of a class does not contain a
+   * cycle. Clients that traverse the inheritance structure must explicitly
+   * guard against infinite loops.
    */
   List<InterfaceType> get interfaces;
 
   /**
-   * Return `true` if this class is abstract. A class is abstract if it has an explicit
-   * `abstract` modifier. Note, that this definition of <i>abstract</i> is different from
-   * <i>has unimplemented members</i>.
-   *
-   * @return `true` if this class is abstract
+   * Return `true` if this class is abstract. A class is abstract if it has an
+   * explicit `abstract` modifier. Note, that this definition of <i>abstract</i>
+   * is different from <i>has unimplemented members</i>.
    */
   bool get isAbstract;
 
   /**
    * Return `true` if this class is defined by an enum declaration.
-   *
-   * @return `true` if this class is defined by an enum declaration
    */
   bool get isEnum;
 
   /**
-   * Return `true` if this class [isProxy], or if it inherits the proxy annotation
-   * from a supertype.
-   *
-   * @return `true` if this class defines or inherits a proxy
+   * Return `true` if this class [isProxy], or if it inherits the proxy
+   * annotation from a supertype.
    */
   bool get isOrInheritsProxy;
 
   /**
    * Return `true` if this element has an annotation of the form '@proxy'.
-   *
-   * @return `true` if this element defines a proxy
    */
   bool get isProxy;
 
   /**
    * Return `true` if this class is defined by a typedef construct.
-   *
-   * @return `true` if this class is defined by a typedef construct
    */
   bool get isTypedef;
 
   /**
-   * Return `true` if this class can validly be used as a mixin when defining another class.
-   * The behavior of this method is defined by the Dart Language Specification in section 9:
-   * <blockquote>It is a compile-time error if a declared or derived mixin refers to super. It is a
-   * compile-time error if a declared or derived mixin explicitly declares a constructor. It is a
-   * compile-time error if a mixin is derived from a class whose superclass is not
-   * Object.</blockquote>
-   *
-   * @return `true` if this class can validly be used as a mixin
+   * Return `true` if this class can validly be used as a mixin when defining
+   * another class. The behavior of this method is defined by the Dart Language
+   * Specification in section 9:
+   * <blockquote>
+   * It is a compile-time error if a declared or derived mixin refers to super.
+   * It is a compile-time error if a declared or derived mixin explicitly
+   * declares a constructor. It is a compile-time error if a mixin is derived
+   * from a class whose superclass is not Object.
+   * </blockquote>
    */
   bool get isValidMixin;
 
   /**
-   * Return an array containing all of the methods declared in this class.
-   *
-   * @return the methods declared in this class
+   * Return a list containing all of the methods declared in this class.
    */
   List<MethodElement> get methods;
 
   /**
-   * Return an array containing all of the mixins that are applied to the class being extended in
-   * order to derive the superclass of this class.
+   * Return a list containing all of the mixins that are applied to the class
+   * being extended in order to derive the superclass of this class.
    *
-   * <b>Note:</b> Because the element model represents the state of the code, it is possible for it
-   * to be semantically invalid. In particular, it is not safe to assume that the inheritance
-   * structure of a class does not contain a cycle. Clients that traverse the inheritance structure
-   * must explicitly guard against infinite loops.
-   *
-   * @return the mixins that are applied to derive the superclass of this class
+   * <b>Note:</b> Because the element model represents the state of the code, it
+   * is possible for it to be semantically invalid. In particular, it is not
+   * safe to assume that the inheritance structure of a class does not contain a
+   * cycle. Clients that traverse the inheritance structure must explicitly
+   * guard against infinite loops.
    */
   List<InterfaceType> get mixins;
 
   /**
-   * Return the resolved [ClassDeclaration] node that declares this [ClassElement].
+   * Return the resolved [ClassDeclaration] or [EnumDeclaration] node that
+   * declares this [ClassElement].
    *
-   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
-   * resolving will be performed.
-   *
-   * @return the resolved [ClassDeclaration], not `null`.
+   * This method is expensive, because resolved AST might be evicted from cache,
+   * so parsing and resolving will be performed.
    */
   @override
-  ClassDeclaration get node;
+  AstNode get node;
 
   /**
-   * Return the superclass of this class, or `null` if the class represents the class
-   * 'Object'. All other classes will have a non-`null` superclass. If the superclass was not
-   * explicitly declared then the implicit superclass 'Object' will be returned.
+   * Return the superclass of this class, or `null` if the class represents the
+   * class 'Object'. All other classes will have a non-`null` superclass. If the
+   * superclass was not explicitly declared then the implicit superclass
+   * 'Object' will be returned.
    *
-   * <b>Note:</b> Because the element model represents the state of the code, it is possible for it
-   * to be semantically invalid. In particular, it is not safe to assume that the inheritance
-   * structure of a class does not contain a cycle. Clients that traverse the inheritance structure
-   * must explicitly guard against infinite loops.
-   *
-   * @return the superclass of this class
+   * <b>Note:</b> Because the element model represents the state of the code, it
+   * is possible for it to be semantically invalid. In particular, it is not
+   * safe to assume that the inheritance structure of a class does not contain a
+   * cycle. Clients that traverse the inheritance structure must explicitly
+   * guard against infinite loops.
    */
   InterfaceType get supertype;
 
   /**
    * Return the type defined by the class.
-   *
-   * @return the type defined by the class
    */
   InterfaceType get type;
 
   /**
-   * Return an array containing all of the type parameters declared for this class.
-   *
-   * @return the type parameters declared for this class
+   * Return a list containing all of the type parameters declared for this
+   * class.
    */
   List<TypeParameterElement> get typeParameters;
 
   /**
-   * Return the unnamed constructor declared in this class, or `null` if this class does not
-   * declare an unnamed constructor but does declare named constructors. The returned constructor
-   * will be synthetic if this class does not declare any constructors, in which case it will
-   * represent the default constructor for the class.
-   *
-   * @return the unnamed constructor defined in this class
+   * Return the unnamed constructor declared in this class, or `null` if this
+   * class does not declare an unnamed constructor but does declare named
+   * constructors. The returned constructor will be synthetic if this class does
+   * not declare any constructors, in which case it will represent the default
+   * constructor for the class.
    */
   ConstructorElement get unnamedConstructor;
 
   /**
-   * Return the field (synthetic or explicit) defined in this class that has the given name, or
-   * `null` if this class does not define a field with the given name.
-   *
-   * @param fieldName the name of the field to be returned
-   * @return the field with the given name that is defined in this class
+   * Return the field (synthetic or explicit) defined in this class that has the
+   * given [name], or `null` if this class does not define a field with the
+   * given name.
    */
-  FieldElement getField(String fieldName);
+  FieldElement getField(String name);
 
   /**
-   * Return the element representing the getter with the given name that is declared in this class,
-   * or `null` if this class does not declare a getter with the given name.
-   *
-   * @param getterName the name of the getter to be returned
-   * @return the getter declared in this class with the given name
+   * Return the element representing the getter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a getter
+   * with the given name.
    */
-  PropertyAccessorElement getGetter(String getterName);
+  PropertyAccessorElement getGetter(String name);
 
   /**
-   * Return the element representing the method with the given name that is declared in this class,
-   * or `null` if this class does not declare a method with the given name.
-   *
-   * @param methodName the name of the method to be returned
-   * @return the method declared in this class with the given name
+   * Return the element representing the method with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a method
+   * with the given name.
    */
-  MethodElement getMethod(String methodName);
+  MethodElement getMethod(String name);
 
   /**
-   * Return the named constructor declared in this class with the given name, or `null` if
-   * this class does not declare a named constructor with the given name.
-   *
-   * @param name the name of the constructor to be returned
-   * @return the element representing the specified constructor
+   * Return the named constructor declared in this class with the given [name],
+   * or `null` if this class does not declare a named constructor with the given
+   * name.
    */
   ConstructorElement getNamedConstructor(String name);
 
   /**
-   * Return the element representing the setter with the given name that is declared in this class,
-   * or `null` if this class does not declare a setter with the given name.
-   *
-   * @param setterName the name of the getter to be returned
-   * @return the setter declared in this class with the given name
+   * Return the element representing the setter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a setter
+   * with the given name.
    */
-  PropertyAccessorElement getSetter(String setterName);
+  PropertyAccessorElement getSetter(String name);
 
   /**
    * Determine whether the given [constructor], which exists in the superclass
@@ -344,170 +303,157 @@
   bool isSuperConstructorAccessible(ConstructorElement constructor);
 
   /**
-   * Return the element representing the method that results from looking up the given method in
-   * this class with respect to the given library, ignoring abstract methods, or `null` if the
-   * look up fails. The behavior of this method is defined by the Dart Language Specification in
-   * section 12.15.1: <blockquote> The result of looking up method <i>m</i> in class <i>C</i> with
-   * respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
-   * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then
-   * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect
-   * to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in this class with respect to the given [library],
+   * ignoring abstract methods, or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section
+   * 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is: If <i>C</i> declares an instance method named <i>m</i>
+   * that is accessible to <i>L</i>, then that method is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up method <i>m</i> in <i>S</i> with
+   * respect to <i>L</i>. Otherwise, we say that the lookup has failed.
    * </blockquote>
-   *
-   * @param methodName the name of the method being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given method in this class with respect to the given
-   *         library
    */
   MethodElement lookUpConcreteMethod(String methodName, LibraryElement library);
 
   /**
-   * Return the element representing the getter that results from looking up the given getter in
-   * this class with respect to the given library, or `null` if the look up fails. The
-   * behavior of this method is defined by the Dart Language Specification in section 12.15.1:
-   * <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
-   * with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
-   * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
-   * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
-   * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.
+   * Return the element representing the getter that results from looking up the
+   * given [getterName] in this class with respect to the given [library], or
+   * `null` if the look up fails. The behavior of this method is defined by the
+   * Dart Language Specification in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
    * </blockquote>
-   *
-   * @param getterName the name of the getter being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given getter in this class with respect to the given
-   *         library
    */
   PropertyAccessorElement lookUpGetter(
       String getterName, LibraryElement library);
 
   /**
-   * Return the element representing the getter that results from looking up the given getter in the
-   * superclass of this class with respect to the given library, ignoring abstract getters, or
-   * `null` if the look up fails. The behavior of this method is defined by the Dart Language
-   * Specification in section 12.15.1: <blockquote>The result of looking up getter (respectively
-   * setter) <i>m</i> in class <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
-   * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
-   * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
-   * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.
+   * Return the element representing the getter that results from looking up the
+   * given [getterName] in the superclass of this class with respect to the
+   * given [library], ignoring abstract getters, or `null` if the look up fails.
+   * The behavior of this method is defined by the Dart Language Specification
+   * in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
    * </blockquote>
-   *
-   * @param getterName the name of the getter being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given getter in this class with respect to the given
-   *         library
    */
   PropertyAccessorElement lookUpInheritedConcreteGetter(
       String getterName, LibraryElement library);
 
   /**
-   * Return the element representing the method that results from looking up the given method in the
-   * superclass of this class with respect to the given library, ignoring abstract methods, or
-   * `null` if the look up fails. The behavior of this method is defined by the Dart Language
-   * Specification in section 12.15.1: <blockquote> The result of looking up method <i>m</i> in
-   * class <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
-   * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then
-   * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect
-   * to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in the superclass of this class with respect to the
+   * given [library], ignoring abstract methods, or `null` if the look up fails.
+   * The behavior of this method is defined by the Dart Language Specification
+   * in section 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:  If <i>C</i> declares an instance method named
+   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+   * result of the lookup is the result of looking up method <i>m</i> in
+   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+   * failed.
    * </blockquote>
-   *
-   * @param methodName the name of the method being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given method in the superclass of this class with respect
-   *         to the given library
    */
   MethodElement lookUpInheritedConcreteMethod(
       String methodName, LibraryElement library);
 
   /**
-   * Return the element representing the setter that results from looking up the given setter in the
-   * superclass of this class with respect to the given library, ignoring abstract setters, or
-   * `null` if the look up fails. The behavior of this method is defined by the Dart Language
-   * Specification in section 12.16: <blockquote> The result of looking up getter (respectively
-   * setter) <i>m</i> in class <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
-   * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
-   * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
-   * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.
+   * Return the element representing the setter that results from looking up the
+   * given [setterName] in the superclass of this class with respect to the
+   * given [library], ignoring abstract setters, or `null` if the look up fails.
+   * The behavior of this method is defined by the Dart Language Specification
+   * in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:  If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
    * </blockquote>
-   *
-   * @param setterName the name of the setter being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given setter in this class with respect to the given
-   *         library
    */
   PropertyAccessorElement lookUpInheritedConcreteSetter(
       String setterName, LibraryElement library);
 
   /**
-   * Return the element representing the method that results from looking up the given method in the
-   * superclass of this class with respect to the given library, or `null` if the look up
-   * fails. The behavior of this method is defined by the Dart Language Specification in section
-   * 12.15.1: <blockquote> The result of looking up method <i>m</i> in class <i>C</i> with respect
-   * to library <i>L</i> is:
-   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
-   * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then
-   * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect
-   * to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in the superclass of this class with respect to the
+   * given [library], or `null` if the look up fails. The behavior of this
+   * method is defined by the Dart Language Specification in section 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:  If <i>C</i> declares an instance method named
+   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+   * result of the lookup is the result of looking up method <i>m</i> in
+   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+   * failed.
    * </blockquote>
-   *
-   * @param methodName the name of the method being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given method in the superclass of this class with respect
-   *         to the given library
    */
   MethodElement lookUpInheritedMethod(
       String methodName, LibraryElement library);
 
   /**
-   * Return the element representing the method that results from looking up the given method in
-   * this class with respect to the given library, or `null` if the look up fails. The
-   * behavior of this method is defined by the Dart Language Specification in section 12.15.1:
-   * <blockquote> The result of looking up method <i>m</i> in class <i>C</i> with respect to library
-   * <i>L</i> is:
-   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
-   * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then
-   * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect
-   * to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * Return the element representing the method that results from looking up the
+   * given [methodName] in this class with respect to the given [library], or
+   * `null` if the look up fails. The behavior of this method is defined by the
+   * Dart Language Specification in section 16.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:  If <i>C</i> declares an instance method named
+   * <i>m</i> that is accessible to <i>L</i>, then that method is the result of
+   * the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the
+   * result of the lookup is the result of looking up method <i>m</i> in
+   * <i>S</i> with respect to <i>L</i>. Otherwise, we say that the lookup has
+   * failed.
    * </blockquote>
-   *
-   * @param methodName the name of the method being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given method in this class with respect to the given
-   *         library
    */
   MethodElement lookUpMethod(String methodName, LibraryElement library);
 
   /**
-   * Return the element representing the setter that results from looking up the given setter in
-   * this class with respect to the given library, or `null` if the look up fails. The
-   * behavior of this method is defined by the Dart Language Specification in section 12.16:
-   * <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
-   * with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
-   * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
-   * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
-   * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.
+   * Return the element representing the setter that results from looking up the
+   * given [setterName] in this class with respect to the given [library], or
+   * `null` if the look up fails. The behavior of this method is defined by the
+   * Dart Language Specification in section 16.15.2:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is: If <i>C</i> declares an
+   * instance getter (respectively setter) named <i>m</i> that is accessible to
+   * <i>L</i>, then that getter (respectively setter) is the result of the
+   * lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result
+   * of the lookup is the result of looking up getter (respectively setter)
+   * <i>m</i> in <i>S</i> with respect to <i>L</i>. Otherwise, we say that the
+   * lookup has failed.
    * </blockquote>
-   *
-   * @param setterName the name of the setter being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given setter in this class with respect to the given
-   *         library
    */
   PropertyAccessorElement lookUpSetter(
       String setterName, LibraryElement library);
 }
 
 /**
- * Instances of the class `ClassElementImpl` implement a `ClassElement`.
+ * A concrete implementation of a [ClassElement].
  */
 class ClassElementImpl extends ElementImpl implements ClassElement {
   /**
@@ -516,39 +462,41 @@
   static const List<ClassElement> EMPTY_ARRAY = const <ClassElement>[];
 
   /**
-   * An array containing all of the accessors (getters and setters) contained in this class.
+   * A list containing all of the accessors (getters and setters) contained in
+   * this class.
    */
   List<PropertyAccessorElement> _accessors =
       PropertyAccessorElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the constructors contained in this class.
+   * A list containing all of the constructors contained in this class.
    */
   List<ConstructorElement> _constructors = ConstructorElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the fields contained in this class.
+   * A list containing all of the fields contained in this class.
    */
   List<FieldElement> _fields = FieldElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the mixins that are applied to the class being extended in order to
-   * derive the superclass of this class.
+   * A list containing all of the mixins that are applied to the class being
+   * extended in order to derive the superclass of this class.
    */
   List<InterfaceType> mixins = InterfaceType.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the interfaces that are implemented by this class.
+   * A list containing all of the interfaces that are implemented by this class.
    */
   List<InterfaceType> interfaces = InterfaceType.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the methods contained in this class.
+   * A list containing all of the methods contained in this class.
    */
   List<MethodElement> _methods = MethodElementImpl.EMPTY_ARRAY;
 
   /**
-   * The superclass of the class, or `null` if the class does not have an explicit superclass.
+   * The superclass of the class, or `null` if the class does not have an
+   * explicit superclass.
    */
   InterfaceType supertype;
 
@@ -558,31 +506,29 @@
   InterfaceType type;
 
   /**
-   * An array containing all of the type parameters defined for this class.
+   * A list containing all of the type parameters defined for this class.
    */
   List<TypeParameterElement> _typeParameters =
       TypeParameterElementImpl.EMPTY_ARRAY;
 
   /**
-   * Initialize a newly created class element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * The [SourceRange] of the `with` clause, `null` if there is no one.
    */
-  ClassElementImpl(String name, int nameOffset) : super(name, nameOffset);
+  SourceRange withClauseRange;
 
   /**
-   * Initialize a newly created class element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created class element to have the given [name] at the
+   * given [offset] in the file that contains the declaration of this element.
+   */
+  ClassElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize a newly created class element to have the given [name].
    */
   ClassElementImpl.forNode(Identifier name) : super.forNode(name);
 
   /**
-   * Set whether this class is abstract to correspond to the given value.
-   *
-   * @param isAbstract `true` if the class is abstract
+   * Set whether this class is abstract.
    */
   void set abstract(bool isAbstract) {
     setModifier(Modifier.ABSTRACT, isAbstract);
@@ -592,9 +538,7 @@
   List<PropertyAccessorElement> get accessors => _accessors;
 
   /**
-   * Set the accessors contained in this class to the given accessors.
-   *
-   * @param accessors the accessors contained in this class
+   * Set the accessors contained in this class to the given [accessors].
    */
   void set accessors(List<PropertyAccessorElement> accessors) {
     for (PropertyAccessorElement accessor in accessors) {
@@ -614,9 +558,7 @@
   List<ConstructorElement> get constructors => _constructors;
 
   /**
-   * Set the constructors contained in this class to the given constructors.
-   *
-   * @param constructors the constructors contained in this class
+   * Set the constructors contained in this class to the given [constructors].
    */
   void set constructors(List<ConstructorElement> constructors) {
     for (ConstructorElement constructor in constructors) {
@@ -626,9 +568,7 @@
   }
 
   /**
-   * Set whether this class is defined by an enum declaration to correspond to the given value.
-   *
-   * @param isEnum `true` if the class is defined by an enum declaration
+   * Set whether this class is defined by an enum declaration.
    */
   void set enum2(bool isEnum) {
     setModifier(Modifier.ENUM, isEnum);
@@ -638,9 +578,7 @@
   List<FieldElement> get fields => _fields;
 
   /**
-   * Set the fields contained in this class to the given fields.
-   *
-   * @param fields the fields contained in this class
+   * Set the fields contained in this class to the given [fields].
    */
   void set fields(List<FieldElement> fields) {
     for (FieldElement field in fields) {
@@ -689,9 +627,7 @@
   bool get hasReferenceToSuper => hasModifier(Modifier.REFERENCES_SUPER);
 
   /**
-   * Set whether this class references 'super' to the given value.
-   *
-   * @param isReferencedSuper `true` references 'super'
+   * Set whether this class references 'super'.
    */
   void set hasReferenceToSuper(bool isReferencedSuper) {
     setModifier(Modifier.REFERENCES_SUPER, isReferencedSuper);
@@ -745,9 +681,7 @@
   List<MethodElement> get methods => _methods;
 
   /**
-   * Set the methods contained in this class to the given methods.
-   *
-   * @param methods the methods contained in this class
+   * Set the methods contained in this class to the given [methods].
    */
   void set methods(List<MethodElement> methods) {
     for (MethodElement method in methods) {
@@ -767,13 +701,17 @@
   }
 
   @override
-  ClassDeclaration get node =>
-      getNodeMatching((node) => node is ClassDeclaration);
+  AstNode get node {
+    if (isEnum) {
+      return getNodeMatching((node) => node is EnumDeclaration);
+    } else {
+      return getNodeMatching(
+          (node) => node is ClassDeclaration || node is ClassTypeAlias);
+    }
+  }
 
   /**
-   * Set whether this class is defined by a typedef construct to correspond to the given value.
-   *
-   * @param isTypedef `true` if the class is defined by a typedef construct
+   * Set whether this class is defined by a typedef construct.
    */
   void set typedef(bool isTypedef) {
     setModifier(Modifier.TYPEDEF, isTypedef);
@@ -783,9 +721,8 @@
   List<TypeParameterElement> get typeParameters => _typeParameters;
 
   /**
-   * Set the type parameters defined for this class to the given type parameters.
-   *
-   * @param typeParameters the type parameters defined for this class
+   * Set the type parameters defined for this class to the given
+   * [typeParameters].
    */
   void set typeParameters(List<TypeParameterElement> typeParameters) {
     for (TypeParameterElement typeParameter in typeParameters) {
@@ -806,9 +743,7 @@
   }
 
   /**
-   * Set whether this class is a valid mixin to correspond to the given value.
-   *
-   * @param isValidMixin `true` if this class can be used as a mixin
+   * Set whether this class is a valid mixin.
    */
   void set validMixin(bool isValidMixin) {
     setModifier(Modifier.MIXIN, isValidMixin);
@@ -1198,125 +1133,101 @@
 }
 
 /**
- * The interface `ClassMemberElement` defines the behavior of elements that are contained
- * within a [ClassElement].
+ * An element that is contained within a [ClassElement].
  */
 abstract class ClassMemberElement implements Element {
   /**
    * Return the type in which this member is defined.
-   *
-   * @return the type in which this member is defined
    */
   @override
   ClassElement get enclosingElement;
 
   /**
-   * Return `true` if this element is a static element. A static element is an element that is
-   * not associated with a particular instance, but rather with an entire library or class.
-   *
-   * @return `true` if this executable element is a static element
+   * Return `true` if this element is a static element. A static element is an
+   * element that is not associated with a particular instance, but rather with
+   * an entire library or class.
    */
   bool get isStatic;
 }
 
 /**
- * The interface `CompilationUnitElement` defines the behavior of elements representing a
- * compilation unit.
+ * An element representing a compilation unit.
  */
 abstract class CompilationUnitElement implements Element, UriReferencedElement {
   /**
-   * Return an array containing all of the top-level accessors (getters and setters) contained in
-   * this compilation unit.
-   *
-   * @return the top-level accessors contained in this compilation unit
+   * Return a list containing all of the top-level accessors (getters and
+   * setters) contained in this compilation unit.
    */
   List<PropertyAccessorElement> get accessors;
 
   /**
    * Return the library in which this compilation unit is defined.
-   *
-   * @return the library in which this compilation unit is defined
    */
   @override
   LibraryElement get enclosingElement;
 
   /**
-   * Return an array containing all of the enums contained in this compilation unit.
-   *
-   * @return an array containing all of the enums contained in this compilation unit
+   * Return a list containing all of the enums contained in this compilation
+   * unit.
    */
   List<ClassElement> get enums;
 
   /**
-   * Return an array containing all of the top-level functions contained in this compilation unit.
-   *
-   * @return the top-level functions contained in this compilation unit
+   * Return a list containing all of the top-level functions contained in this
+   * compilation unit.
    */
   List<FunctionElement> get functions;
 
   /**
-   * Return an array containing all of the function type aliases contained in this compilation unit.
-   *
-   * @return the function type aliases contained in this compilation unit
+   * Return a list containing all of the function type aliases contained in this
+   * compilation unit.
    */
   List<FunctionTypeAliasElement> get functionTypeAliases;
 
   /**
    * Return `true` if this compilation unit defines a top-level function named
    * `loadLibrary`.
-   *
-   * @return `true` if this compilation unit defines a top-level function named
-   *         `loadLibrary`
    */
   bool get hasLoadLibraryFunction;
 
   /**
    * Return the resolved [CompilationUnit] node that declares this element.
    *
-   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
-   * resolving will be performed.
-   *
-   * @return the resolved [CompilationUnit], not `null`.
+   * This method is expensive, because resolved AST might be evicted from cache,
+   * so parsing and resolving will be performed.
    */
   @override
   CompilationUnit get node;
 
   /**
-   * Return an array containing all of the top-level variables contained in this compilation unit.
-   *
-   * @return the top-level variables contained in this compilation unit
+   * Return a list containing all of the top-level variables contained in this
+   * compilation unit.
    */
   List<TopLevelVariableElement> get topLevelVariables;
 
   /**
-   * Return an array containing all of the classes contained in this compilation unit.
-   *
-   * @return the classes contained in this compilation unit
+   * Return a list containing all of the classes contained in this compilation
+   * unit.
    */
   List<ClassElement> get types;
 
   /**
-   * Return the enum defined in this compilation unit that has the given name, or `null` if
-   * this compilation unit does not define an enum with the given name.
-   *
-   * @param enumName the name of the enum to be returned
-   * @return the enum with the given name that is defined in this compilation unit
+   * Return the enum defined in this compilation unit that has the given [name],
+   * or `null` if this compilation unit does not define an enum with the given
+   * name.
    */
-  ClassElement getEnum(String enumName);
+  ClassElement getEnum(String name);
 
   /**
-   * Return the class defined in this compilation unit that has the given name, or `null` if
-   * this compilation unit does not define a class with the given name.
-   *
-   * @param className the name of the class to be returned
-   * @return the class with the given name that is defined in this compilation unit
+   * Return the class defined in this compilation unit that has the given
+   * [name], or `null` if this compilation unit does not define a class with the
+   * given name.
    */
-  ClassElement getType(String className);
+  ClassElement getType(String name);
 }
 
 /**
- * Instances of the class `CompilationUnitElementImpl` implement a
- * [CompilationUnitElement].
+ * A concrete implementation of a [CompilationUnitElement].
  */
 class CompilationUnitElementImpl extends UriReferencedElementImpl
     implements CompilationUnitElement {
@@ -1332,43 +1243,44 @@
   Source source;
 
   /**
-   * An array containing all of the top-level accessors (getters and setters) contained in this
-   * compilation unit.
+   * A list containing all of the top-level accessors (getters and setters)
+   * contained in this compilation unit.
    */
   List<PropertyAccessorElement> _accessors =
       PropertyAccessorElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the enums contained in this compilation unit.
+   * A list containing all of the enums contained in this compilation unit.
    */
   List<ClassElement> _enums = ClassElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the top-level functions contained in this compilation unit.
+   * A list containing all of the top-level functions contained in this
+   * compilation unit.
    */
   List<FunctionElement> _functions = FunctionElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the function type aliases contained in this compilation unit.
+   * A list containing all of the function type aliases contained in this
+   * compilation unit.
    */
   List<FunctionTypeAliasElement> _typeAliases =
       FunctionTypeAliasElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the types contained in this compilation unit.
+   * A list containing all of the types contained in this compilation unit.
    */
   List<ClassElement> _types = ClassElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the variables contained in this compilation unit.
+   * A list containing all of the variables contained in this compilation unit.
    */
   List<TopLevelVariableElement> _variables =
       TopLevelVariableElementImpl.EMPTY_ARRAY;
 
   /**
-   * Initialize a newly created compilation unit element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created compilation unit element to have the given
+   * [name].
    */
   CompilationUnitElementImpl(String name) : super(name, -1);
 
@@ -1376,10 +1288,8 @@
   List<PropertyAccessorElement> get accessors => _accessors;
 
   /**
-   * Set the top-level accessors (getters and setters) contained in this compilation unit to the
-   * given accessors.
-   *
-   * @param the top-level accessors (getters and setters) contained in this compilation unit
+   * Set the top-level accessors (getters and setters) contained in this
+   * compilation unit to the given [accessors].
    */
   void set accessors(List<PropertyAccessorElement> accessors) {
     for (PropertyAccessorElement accessor in accessors) {
@@ -1396,9 +1306,7 @@
   List<ClassElement> get enums => _enums;
 
   /**
-   * Set the enums contained in this compilation unit to the given enums.
-   *
-   * @param enums enums contained in this compilation unit
+   * Set the enums contained in this compilation unit to the given [enums].
    */
   void set enums(List<ClassElement> enums) {
     for (ClassElement enumDeclaration in enums) {
@@ -1411,9 +1319,8 @@
   List<FunctionElement> get functions => _functions;
 
   /**
-   * Set the top-level functions contained in this compilation unit to the given functions.
-   *
-   * @param functions the top-level functions contained in this compilation unit
+   * Set the top-level functions contained in this compilation unit to the given
+   * [functions].
    */
   void set functions(List<FunctionElement> functions) {
     for (FunctionElement function in functions) {
@@ -1451,9 +1358,8 @@
   List<TopLevelVariableElement> get topLevelVariables => _variables;
 
   /**
-   * Set the top-level variables contained in this compilation unit to the given variables.
-   *
-   * @param variables the top-level variables contained in this compilation unit
+   * Set the top-level variables contained in this compilation unit to the given
+   * [variables].
    */
   void set topLevelVariables(List<TopLevelVariableElement> variables) {
     for (TopLevelVariableElement field in variables) {
@@ -1463,9 +1369,8 @@
   }
 
   /**
-   * Set the function type aliases contained in this compilation unit to the given type aliases.
-   *
-   * @param typeAliases the function type aliases contained in this compilation unit
+   * Set the function type aliases contained in this compilation unit to the
+   * given [typeAliases].
    */
   void set typeAliases(List<FunctionTypeAliasElement> typeAliases) {
     for (FunctionTypeAliasElement typeAlias in typeAliases) {
@@ -1478,9 +1383,7 @@
   List<ClassElement> get types => _types;
 
   /**
-   * Set the types contained in this compilation unit to the given types.
-   *
-   * @param types types contained in this compilation unit
+   * Set the types contained in this compilation unit to the given [types].
    */
   void set types(List<ClassElement> types) {
     for (ClassElement type in types) {
@@ -1566,6 +1469,15 @@
     return null;
   }
 
+  /**
+   * Replace the given [from] top-level variable with [to] in this compilation unit.
+   */
+  void replaceTopLevelVariable(
+      TopLevelVariableElement from, TopLevelVariableElement to) {
+    int index = _variables.indexOf(from);
+    _variables[index] = to;
+  }
+
   @override
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
@@ -1579,8 +1491,7 @@
 }
 
 /**
- * Instances of the class `ConstFieldElementImpl` implement a `FieldElement` for a
- * 'const' field that has an initializer.
+ * A [FieldElement] for a 'const' field that has an initializer.
  */
 class ConstFieldElementImpl extends FieldElementImpl {
   /**
@@ -1589,18 +1500,13 @@
   EvaluationResultImpl _result;
 
   /**
-   * Initialize a newly created field element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created field element to have the given [name].
    */
   ConstFieldElementImpl.con1(Identifier name) : super.forNode(name);
 
   /**
-   * Initialize a newly created synthetic field element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created synthetic field element to have the given
+   * [name] and [offset].
    */
   ConstFieldElementImpl.con2(String name, int offset) : super(name, offset);
 
@@ -1614,8 +1520,8 @@
 }
 
 /**
- * Instances of the class `ConstLocalVariableElementImpl` implement a
- * `LocalVariableElement` for a local 'const' variable that has an initializer.
+ * A [LocalVariableElement] for a local 'const' variable that has an
+ * initializer.
  */
 class ConstLocalVariableElementImpl extends LocalVariableElementImpl {
   /**
@@ -1624,9 +1530,7 @@
   EvaluationResultImpl _result;
 
   /**
-   * Initialize a newly created local variable element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created local variable element to have the given [name].
    */
   ConstLocalVariableElementImpl(Identifier name) : super.forNode(name);
 
@@ -1640,30 +1544,24 @@
 }
 
 /**
- * The interface `ConstructorElement` defines the behavior of elements representing a
- * constructor or a factory method defined within a type.
+ * An element representing a constructor or a factory method defined within a
+ * class.
  */
 abstract class ConstructorElement
     implements ClassMemberElement, ExecutableElement {
   /**
    * Return `true` if this constructor is a const constructor.
-   *
-   * @return `true` if this constructor is a const constructor
    */
   bool get isConst;
 
   /**
-   * Return `true` if this constructor can be used as a default constructor - unnamed and has
-   * no required parameters.
-   *
-   * @return `true` if this constructor can be used as a default constructor.
+   * Return `true` if this constructor can be used as a default constructor -
+   * unnamed and has no required parameters.
    */
   bool get isDefaultConstructor;
 
   /**
    * Return `true` if this constructor represents a factory constructor.
-   *
-   * @return `true` if this constructor represents a factory constructor
    */
   bool get isFactory;
 
@@ -1677,10 +1575,8 @@
    * Return the resolved [ConstructorDeclaration] node that declares this
    * [ConstructorElement] .
    *
-   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
-   * resolving will be performed.
-   *
-   * @return the resolved [ConstructorDeclaration], not `null`.
+   * This method is expensive, because resolved AST might be evicted from cache,
+   * so parsing and resolving will be performed.
    */
   @override
   ConstructorDeclaration get node;
@@ -1692,17 +1588,15 @@
   int get periodOffset;
 
   /**
-   * Return the constructor to which this constructor is redirecting, or `null` if this
-   * constructor does not redirect to another constructor or if the library containing this
-   * constructor has not yet been resolved.
-   *
-   * @return the constructor to which this constructor is redirecting
+   * Return the constructor to which this constructor is redirecting, or `null`
+   * if this constructor does not redirect to another constructor or if the
+   * library containing this constructor has not yet been resolved.
    */
   ConstructorElement get redirectedConstructor;
 }
 
 /**
- * Instances of the class `ConstructorElementImpl` implement a `ConstructorElement`.
+ * A concrete implementation of a [ConstructorElement].
  */
 class ConstructorElementImpl extends ExecutableElementImpl
     implements ConstructorElement {
@@ -1718,8 +1612,8 @@
   ConstructorElement redirectedConstructor;
 
   /**
-   * The initializers for this constructor (used for evaluating constant instance creation
-   * expressions).
+   * The initializers for this constructor (used for evaluating constant
+   * instance creation expressions).
    */
   List<ConstructorInitializer> constantInitializers;
 
@@ -1735,25 +1629,18 @@
   int nameEnd;
 
   /**
-   * Initialize a newly created constructor element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created constructor element to have the given [name] and
+   * [offset].
    */
-  ConstructorElementImpl(String name, int nameOffset) : super(name, nameOffset);
+  ConstructorElementImpl(String name, int offset) : super(name, offset);
 
   /**
-   * Initialize a newly created constructor element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created constructor element to have the given [name].
    */
   ConstructorElementImpl.forNode(Identifier name) : super.forNode(name);
 
   /**
-   * Set whether this constructor represents a 'const' constructor to the given value.
-   *
-   * @param isConst `true` if this constructor represents a 'const' constructor
+   * Set whether this constructor represents a 'const' constructor.
    */
   void set const2(bool isConst) {
     setModifier(Modifier.CONST, isConst);
@@ -1763,9 +1650,7 @@
   ClassElement get enclosingElement => super.enclosingElement as ClassElement;
 
   /**
-   * Set whether this constructor represents a factory method to the given value.
-   *
-   * @param isFactory `true` if this constructor represents a factory method
+   * Set whether this constructor represents a factory method.
    */
   void set factory(bool isFactory) {
     setModifier(Modifier.FACTORY, isFactory);
@@ -1833,15 +1718,13 @@
 }
 
 /**
- * Instances of the class `ConstructorMember` represent a constructor element defined in a
- * parameterized type where the values of the type parameters are known.
+ * A constructor element defined in a parameterized type where the values of the
+ * type parameters are known.
  */
 class ConstructorMember extends ExecutableMember implements ConstructorElement {
   /**
-   * Initialize a newly created element to represent a constructor of the given parameterized type.
-   *
-   * @param baseElement the element on which the parameterized element was created
-   * @param definingType the type in which the element is defined
+   * Initialize a newly created element to represent a constructor, based on the
+   * [baseElement], defined by the [definingType].
    */
   ConstructorMember(ConstructorElement baseElement, InterfaceType definingType)
       : super(baseElement, definingType);
@@ -1909,43 +1792,39 @@
   }
 
   /**
-   * If the given constructor's type is different when any type parameters from the defining type's
-   * declaration are replaced with the actual type arguments from the defining type, create a
-   * constructor member representing the given constructor. Return the member that was created, or
-   * the base constructor if no member was created.
-   *
-   * @param baseConstructor the base constructor for which a member might be created
-   * @param definingType the type defining the parameters and arguments to be used in the
-   *          substitution
-   * @return the constructor element that will return the correctly substituted types
+   * If the given [constructor]'s type is different when any type parameters
+   * from the defining type's declaration are replaced with the actual type
+   * arguments from the [definingType], create a constructor member representing
+   * the given constructor. Return the member that was created, or the original
+   * constructor if no member was created.
    */
   static ConstructorElement from(
-      ConstructorElement baseConstructor, InterfaceType definingType) {
-    if (baseConstructor == null || definingType.typeArguments.length == 0) {
-      return baseConstructor;
+      ConstructorElement constructor, InterfaceType definingType) {
+    if (constructor == null || definingType.typeArguments.length == 0) {
+      return constructor;
     }
-    FunctionType baseType = baseConstructor.type;
+    FunctionType baseType = constructor.type;
     if (baseType == null) {
       // TODO(brianwilkerson) We need to understand when this can happen.
-      return baseConstructor;
+      return constructor;
     }
     List<DartType> argumentTypes = definingType.typeArguments;
     List<DartType> parameterTypes = definingType.element.type.typeArguments;
     FunctionType substitutedType =
         baseType.substitute2(argumentTypes, parameterTypes);
     if (baseType == substitutedType) {
-      return baseConstructor;
+      return constructor;
     }
     // TODO(brianwilkerson) Consider caching the substituted type in the
     // instance. It would use more memory but speed up some operations.
     // We need to see how often the type is being re-computed.
-    return new ConstructorMember(baseConstructor, definingType);
+    return new ConstructorMember(constructor, definingType);
   }
 }
 
 /**
- * Instances of the class `ConstTopLevelVariableElementImpl` implement a
- * `TopLevelVariableElement` for a top-level 'const' variable that has an initializer.
+ * A [TopLevelVariableElement] for a top-level 'const' variable that has an
+ * initializer.
  */
 class ConstTopLevelVariableElementImpl extends TopLevelVariableElementImpl {
   /**
@@ -1954,9 +1833,8 @@
   EvaluationResultImpl _result;
 
   /**
-   * Initialize a newly created top-level variable element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created top-level variable element to have the given
+   * [name].
    */
   ConstTopLevelVariableElementImpl(Identifier name) : super.forNode(name);
 
@@ -1970,8 +1848,7 @@
 }
 
 /**
- * The interface `DartType` defines the behavior of objects representing the
- * declared type of elements in the element model.
+ * The type associated with elements in the element model.
  */
 abstract class DartType {
   /**
@@ -2077,8 +1954,7 @@
 }
 
 /**
- * Instances of the class `DefaultFieldFormalParameterElementImpl` implement a
- * `FieldFormalParameterElementImpl` for parameters that have an initializer.
+ * A [FieldFormalParameterElementImpl] for parameters that have an initializer.
  */
 class DefaultFieldFormalParameterElementImpl
     extends FieldFormalParameterElementImpl {
@@ -2088,9 +1964,7 @@
   EvaluationResultImpl _result;
 
   /**
-   * Initialize a newly created parameter element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created parameter element to have the given [name].
    */
   DefaultFieldFormalParameterElementImpl(Identifier name) : super(name);
 
@@ -2104,8 +1978,7 @@
 }
 
 /**
- * Instances of the class `DefaultParameterElementImpl` implement a `ParameterElement`
- * for parameters that have an initializer.
+ * A [ParameterElement] for parameters that have an initializer.
  */
 class DefaultParameterElementImpl extends ParameterElementImpl {
   /**
@@ -2114,9 +1987,7 @@
   EvaluationResultImpl _result;
 
   /**
-   * Initialize a newly created parameter element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created parameter element to have the given [name].
    */
   DefaultParameterElementImpl(Identifier name) : super.forNode(name);
 
@@ -2130,14 +2001,11 @@
 }
 
 /**
- * Instances of the class `DynamicElementImpl` represent the synthetic element representing
- * the declaration of the type `dynamic`.
+ * The synthetic element representing the declaration of the type `dynamic`.
  */
 class DynamicElementImpl extends ElementImpl {
   /**
    * Return the unique instance of this class.
-   *
-   * @return the unique instance of this class
    */
   static DynamicElementImpl get instance =>
       DynamicTypeImpl.instance.element as DynamicElementImpl;
@@ -2148,9 +2016,10 @@
   DynamicTypeImpl type;
 
   /**
-   * Initialize a newly created instance of this class. Instances of this class should <b>not</b> be
-   * created except as part of creating the type associated with this element. The single instance
-   * of this class should be accessed through the method [getInstance].
+   * Initialize a newly created instance of this class. Instances of this class
+   * should <b>not</b> be created except as part of creating the type associated
+   * with this element. The single instance of this class should be accessed
+   * through the method [getInstance].
    */
   DynamicElementImpl() : super(Keyword.DYNAMIC.syntax, -1) {
     setModifier(Modifier.SYNTHETIC, true);
@@ -2164,7 +2033,7 @@
 }
 
 /**
- * The unique instance of the class `DynamicTypeImpl` implements the type `dynamic`.
+ * The [Type] representing the type `dynamic`.
  */
 class DynamicTypeImpl extends TypeImpl {
   /**
@@ -2174,8 +2043,6 @@
 
   /**
    * Return the unique instance of this class.
-   *
-   * @return the unique instance of this class
    */
   static DynamicTypeImpl get instance => _INSTANCE;
 
@@ -2235,32 +2102,37 @@
 }
 
 /**
- * The interface `Element` defines the behavior common to all of the elements in the element
- * model. Generally speaking, the element model is a semantic model of the program that represents
- * things that are declared with a name and hence can be referenced elsewhere in the code.
+ * The base class for all of the elements in the element model. Generally
+ * speaking, the element model is a semantic model of the program that
+ * represents things that are declared with a name and hence can be referenced
+ * elsewhere in the code.
  *
- * There are two exceptions to the general case. First, there are elements in the element model that
- * are created for the convenience of various kinds of analysis but that do not have any
- * corresponding declaration within the source code. Such elements are marked as being
- * <i>synthetic</i>. Examples of synthetic elements include
- * * default constructors in classes that do not define any explicit constructors,
+ * There are two exceptions to the general case. First, there are elements in
+ * the element model that are created for the convenience of various kinds of
+ * analysis but that do not have any corresponding declaration within the source
+ * code. Such elements are marked as being <i>synthetic</i>. Examples of
+ * synthetic elements include
+ * * default constructors in classes that do not define any explicit
+ *   constructors,
  * * getters and setters that are induced by explicit field declarations,
- * * fields that are induced by explicit declarations of getters and setters, and
+ * * fields that are induced by explicit declarations of getters and setters,
+ *   and
  * * functions representing the initialization expression for a variable.
  *
- * Second, there are elements in the element model that do not have a name. These correspond to
- * unnamed functions and exist in order to more accurately represent the semantic structure of the
- * program.
+ * Second, there are elements in the element model that do not have a name.
+ * These correspond to unnamed functions and exist in order to more accurately
+ * represent the semantic structure of the program.
  */
-abstract class Element {
+abstract class Element implements AnalysisTarget {
   /**
    * An Unicode right arrow.
    */
   static final String RIGHT_ARROW = " \u2192 ";
 
   /**
-   * A comparator that can be used to sort elements by their name offset. Elements with a smaller
-   * offset will be sorted to be before elements with a larger name offset.
+   * A comparator that can be used to sort elements by their name offset.
+   * Elements with a smaller offset will be sorted to be before elements with a
+   * larger name offset.
    */
   static final Comparator<Element> SORT_BY_OFFSET = (Element firstElement,
           Element secondElement) =>
@@ -2268,27 +2140,23 @@
 
   /**
    * Return the analysis context in which this element is defined.
-   *
-   * @return the analysis context in which this element is defined
    */
   AnalysisContext get context;
 
   /**
-   * Return the display name of this element, or `null` if this element does not have a name.
+   * Return the display name of this element, or `null` if this element does not
+   * have a name.
    *
-   * In most cases the name and the display name are the same. Differences though are cases such as
-   * setters where the name of some setter `set f(x)` is `f=`, instead of `f`.
-   *
-   * @return the display name of this element
+   * In most cases the name and the display name are the same. Differences
+   * though are cases such as setters where the name of some setter `set f(x)`
+   * is `f=`, instead of `f`.
    */
   String get displayName;
 
   /**
-   * Return the element that either physically or logically encloses this element. This will be
-   * `null` if this element is a library because libraries are the top-level elements in the
-   * model.
-   *
-   * @return the element that encloses this element
+   * Return the element that either physically or logically encloses this
+   * element. This will be `null` if this element is a library because libraries
+   * are the top-level elements in the model.
    */
   Element get enclosingElement;
 
@@ -2298,224 +2166,184 @@
   int get id;
 
   /**
-   * Return `true` if this element has an annotation of the form '@deprecated' or
-   * '@Deprecated('..')'.
-   *
-   * @return `true` if this element is deprecated
+   * Return `true` if this element has an annotation of the form '@deprecated'
+   * or '@Deprecated('..')'.
    */
   bool get isDeprecated;
 
   /**
    * Return `true` if this element has an annotation of the form '@override'.
-   *
-   * @return `true` if this element is overridden
    */
   bool get isOverride;
 
   /**
-   * Return `true` if this element is private. Private elements are visible only within the
-   * library in which they are declared.
-   *
-   * @return `true` if this element is private
+   * Return `true` if this element is private. Private elements are visible only
+   * within the library in which they are declared.
    */
   bool get isPrivate;
 
   /**
-   * Return `true` if this element is public. Public elements are visible within any library
-   * that imports the library in which they are declared.
-   *
-   * @return `true` if this element is public
+   * Return `true` if this element is public. Public elements are visible within
+   * any library that imports the library in which they are declared.
    */
   bool get isPublic;
 
   /**
-   * Return `true` if this element is synthetic. A synthetic element is an element that is not
-   * represented in the source code explicitly, but is implied by the source code, such as the
-   * default constructor for a class that does not explicitly define any constructors.
-   *
-   * @return `true` if this element is synthetic
+   * Return `true` if this element is synthetic. A synthetic element is an
+   * element that is not represented in the source code explicitly, but is
+   * implied by the source code, such as the default constructor for a class
+   * that does not explicitly define any constructors.
    */
   bool get isSynthetic;
 
   /**
    * Return the kind of element that this is.
-   *
-   * @return the kind of this element
    */
   ElementKind get kind;
 
   /**
-   * Return the library that contains this element. This will be the element itself if it is a
-   * library element. This will be `null` if this element is an HTML file because HTML files
-   * are not contained in libraries.
-   *
-   * @return the library that contains this element
+   * Return the library that contains this element. This will be the element
+   * itself if it is a library element. This will be `null` if this element is
+   * an HTML file because HTML files are not contained in libraries.
    */
   LibraryElement get library;
 
   /**
-   * Return an object representing the location of this element in the element model. The object can
-   * be used to locate this element at a later time.
-   *
-   * @return the location of this element in the element model
+   * Return an object representing the location of this element in the element
+   * model. The object can be used to locate this element at a later time.
    */
   ElementLocation get location;
 
   /**
-   * Return an array containing all of the metadata associated with this element. The array will be
-   * empty if the element does not have any metadata or if the library containing this element has
-   * not yet been resolved.
-   *
-   * @return the metadata associated with this element
+   * Return a list containing all of the metadata associated with this element.
+   * The array will be empty if the element does not have any metadata or if the
+   * library containing this element has not yet been resolved.
    */
   List<ElementAnnotation> get metadata;
 
   /**
-   * Return the name of this element, or `null` if this element does not have a name.
-   *
-   * @return the name of this element
+   * Return the name of this element, or `null` if this element does not have a
+   * name.
    */
   String get name;
 
   /**
-   * Return the offset of the name of this element in the file that contains the declaration of this
-   * element, or `-1` if this element is synthetic, does not have a name, or otherwise does
-   * not have an offset.
-   *
-   * @return the offset of the name of this element
+   * Return the offset of the name of this element in the file that contains the
+   * declaration of this element, or `-1` if this element is synthetic, does not
+   * have a name, or otherwise does not have an offset.
    */
   int get nameOffset;
 
   /**
-   * Return the resolved [AstNode] node that declares this [Element].
+   * Return the resolved [AstNode] node that declares this element, or `null` if
+   * this element is synthetic or isn't contained in a compilation unit, such as
+   * a [LibraryElement].
    *
-   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
-   * resolving will be performed.
+   * This method is expensive, because resolved AST might be evicted from cache,
+   * so parsing and resolving will be performed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @return the resolved [AstNode], maybe `null` if [Element] is synthetic or
-   *         isn't contained in a compilation unit, such as a [LibraryElement].
    */
   AstNode get node;
 
   /**
-   * Return the source that contains this element, or `null` if this element is not contained
-   * in a source.
-   *
-   * @return the source that contains this element
+   * Return the source that contains this element, or `null` if this element is
+   * not contained in a source.
    */
   Source get source;
 
   /**
-   * Return the resolved [CompilationUnit] that declares this [Element].
+   * Return the resolved [CompilationUnit] that declares this element, or `null`
+   * if this element is synthetic.
    *
-   * This method is expensive, because resolved AST might have been already evicted from cache, so
-   * parsing and resolving will be performed.
-   *
-   * @return the resolved [CompilationUnit], maybe `null` if synthetic [Element].
+   * This method is expensive, because resolved AST might have been already
+   * evicted from cache, so parsing and resolving will be performed.
    */
   CompilationUnit get unit;
 
   /**
-   * Use the given visitor to visit this element.
-   *
-   * @param visitor the visitor that will visit this element
-   * @return the value returned by the visitor as a result of visiting this element
+   * Use the given [visitor] to visit this element. Return the value returned by
+   * the visitor as a result of visiting this element.
    */
   accept(ElementVisitor visitor);
 
   /**
-   * Return the documentation comment for this element as it appears in the original source
-   * (complete with the beginning and ending delimiters), or `null` if this element does not
-   * have a documentation comment associated with it. This can be a long-running operation if the
-   * information needed to access the comment is not cached.
+   * Return the documentation comment for this element as it appears in the
+   * original source (complete with the beginning and ending delimiters), or
+   * `null` if this element does not have a documentation comment associated
+   * with it. This can be a long-running operation if the information needed to
+   * access the comment is not cached.
    *
-   * @return this element's documentation comment
-   * @throws AnalysisException if the documentation comment could not be determined because the
-   *           analysis could not be performed
+   * Throws [AnalysisException] if the documentation comment could not be
+   * determined because the analysis could not be performed
    */
   String computeDocumentationComment();
 
   /**
-   * Return the element of the given class that most immediately encloses this element, or
-   * `null` if there is no enclosing element of the given class.
-   *
-   * @param elementClass the class of the element to be returned
-   * @return the element that encloses this element
+   * Return the most immediate ancestor of this element for which the
+   * [predicate] returns `true`, or `null` if there is no such ancestor. Note
+   * that this element will never be returned.
    */
   Element getAncestor(Predicate<Element> predicate);
 
   /**
-   * Return a display name for the given element that includes the path to the compilation unit in
-   * which the type is defined.
-   *
-   * @param shortName the short display name. If null, [getDisplayName] is used.
-   * @return a display name that can help distinguish between two types with the same name
+   * Return a display name for the given element that includes the path to the
+   * compilation unit in which the type is defined. If [shortName] is `null`
+   * then [getDisplayName] will be used as the name of this element. Otherwise
+   * the provided name will be used.
    */
+  // TODO(brianwilkerson) Make the parameter optional.
   String getExtendedDisplayName(String shortName);
 
   /**
-   * Return `true` if this element, assuming that it is within scope, is accessible to code in
-   * the given library. This is defined by the Dart Language Specification in section 3.2:
-   * <blockquote> A declaration <i>m</i> is accessible to library <i>L</i> if <i>m</i> is declared
-   * in <i>L</i> or if <i>m</i> is public. </blockquote>
-   *
-   * @param library the library in which a possible reference to this element would occur
-   * @return `true` if this element is accessible to code in the given library
+   * Return `true` if this element, assuming that it is within scope, is
+   * accessible to code in the given [library]. This is defined by the Dart
+   * Language Specification in section 3.2:
+   * <blockquote>
+   * A declaration <i>m</i> is accessible to library <i>L</i> if <i>m</i> is
+   * declared in <i>L</i> or if <i>m</i> is public.
+   * </blockquote>
    */
   bool isAccessibleIn(LibraryElement library);
 
   /**
-   * Use the given visitor to visit all of the children of this element. There is no guarantee of
-   * the order in which the children will be visited.
-   *
-   * @param visitor the visitor that will be used to visit the children of this element
+   * Use the given [visitor] to visit all of the children of this element. There
+   * is no guarantee of the order in which the children will be visited.
    */
   void visitChildren(ElementVisitor visitor);
 }
 
 /**
- * The interface `ElementAnnotation` defines the behavior of objects representing a single
- * annotation associated with an element.
+ * A single annotation associated with an element.
  */
 abstract class ElementAnnotation {
   /**
-   * Return the element representing the field, variable, or const constructor being used as an
-   * annotation.
-   *
-   * @return the field, variable, or constructor being used as an annotation
+   * Return the element representing the field, variable, or const constructor
+   * being used as an annotation.
    */
   Element get element;
 
   /**
-   * Return `true` if this annotation marks the associated element as being deprecated.
-   *
-   * @return `true` if this annotation marks the associated element as being deprecated
+   * Return `true` if this annotation marks the associated element as being
+   * deprecated.
    */
   bool get isDeprecated;
 
   /**
-   * Return `true` if this annotation marks the associated method as being expected to
-   * override an inherited method.
-   *
-   * @return `true` if this annotation marks the associated method as overriding another
-   *         method
+   * Return `true` if this annotation marks the associated method as being
+   * expected to override an inherited method.
    */
   bool get isOverride;
 
   /**
-   * Return `true` if this annotation marks the associated class as implementing a proxy
-   * object.
-   *
-   * @return `true` if this annotation marks the associated class as implementing a proxy
-   *         object
+   * Return `true` if this annotation marks the associated class as implementing
+   * a proxy object.
    */
   bool get isProxy;
 }
 
 /**
- * Instances of the class `ElementAnnotationImpl` implement an [ElementAnnotation].
+ * A concrete implementation of an [ElementAnnotation].
  */
 class ElementAnnotationImpl implements ElementAnnotation {
   /**
@@ -2530,23 +2358,26 @@
   static String _DEPRECATED_CLASS_NAME = "Deprecated";
 
   /**
-   * The name of the top-level variable used to mark an element as being deprecated.
+   * The name of the top-level variable used to mark an element as being
+   * deprecated.
    */
   static String _DEPRECATED_VARIABLE_NAME = "deprecated";
 
   /**
-   * The name of the top-level variable used to mark a method as being expected to override an
-   * inherited method.
+   * The name of the top-level variable used to mark a method as being expected
+   * to override an inherited method.
    */
   static String _OVERRIDE_VARIABLE_NAME = "override";
 
   /**
-   * The name of the top-level variable used to mark a class as implementing a proxy object.
+   * The name of the top-level variable used to mark a class as implementing a
+   * proxy object.
    */
   static String PROXY_VARIABLE_NAME = "proxy";
 
   /**
-   * The element representing the field, variable, or constructor being used as an annotation.
+   * The element representing the field, variable, or constructor being used as
+   * an annotation.
    */
   final Element element;
 
@@ -2558,10 +2389,9 @@
   EvaluationResultImpl evaluationResult;
 
   /**
-   * Initialize a newly created annotation.
-   *
-   * @param element the element representing the field, variable, or constructor being used as an
-   *          annotation
+   * Initialize a newly created annotation. The given [element] is the element
+   * representing the field, variable, or constructor being used as an
+   * annotation.
    */
   ElementAnnotationImpl(this.element);
 
@@ -2618,8 +2448,7 @@
 }
 
 /**
- * The abstract class `ElementImpl` implements the behavior common to objects that implement
- * an [Element].
+ * A base class for concrete implementations of an [Element].
  */
 abstract class ElementImpl implements Element {
   static int _NEXT_ID = 0;
@@ -2627,8 +2456,8 @@
   final int id = _NEXT_ID++;
 
   /**
-   * The enclosing element of this element, or `null` if this element is at the root of the
-   * element structure.
+   * The enclosing element of this element, or `null` if this element is at the
+   * root of the element structure.
    */
   ElementImpl _enclosingElement;
 
@@ -2649,7 +2478,7 @@
   int _modifiers = 0;
 
   /**
-   * An array containing all of the metadata associated with this element.
+   * A list containing all of the metadata associated with this element.
    */
   List<ElementAnnotation> metadata = ElementAnnotationImpl.EMPTY_ARRAY;
 
@@ -2664,20 +2493,15 @@
   ElementLocation _cachedLocation;
 
   /**
-   * Initialize a newly created element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created element to have the given [name] at the given
+   * [_nameOffset].
    */
   ElementImpl(String name, this._nameOffset) {
     this._name = StringUtilities.intern(name);
   }
 
   /**
-   * Initialize a newly created element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created element to have the given [name].
    */
   ElementImpl.forNode(Identifier name)
       : this(name == null ? "" : name.name, name == null ? -1 : name.offset);
@@ -2697,9 +2521,7 @@
   Element get enclosingElement => _enclosingElement;
 
   /**
-   * Set the enclosing element of this element to the given element.
-   *
-   * @param element the enclosing element of this element
+   * Set the enclosing element of this element to the given [element].
    */
   void set enclosingElement(Element element) {
     _enclosingElement = element as ElementImpl;
@@ -2724,10 +2546,8 @@
   }
 
   /**
-   * Return an identifier that uniquely identifies this element among the children of this element's
-   * parent.
-   *
-   * @return an identifier that uniquely identifies this element relative to its parent
+   * Return an identifier that uniquely identifies this element among the
+   * children of this element's parent.
    */
   String get identifier => name;
 
@@ -2815,9 +2635,7 @@
   }
 
   /**
-   * Set whether this element is synthetic to correspond to the given value.
-   *
-   * @param isSynthetic `true` if the element is synthetic
+   * Set whether this element is synthetic.
    */
   void set synthetic(bool isSynthetic) {
     setModifier(Modifier.SYNTHETIC, isSynthetic);
@@ -2861,9 +2679,7 @@
   }
 
   /**
-   * Set this [Element] as an enclosing for given.
-   *
-   * @param element the element to enclose, must be [ElementImpl]
+   * Set this element as the enclosing element for given [element].
    */
   void encloseElement(ElementImpl element) {
     element.enclosingElement = this;
@@ -2879,11 +2695,8 @@
   }
 
   /**
-   * Return the child of this element that is uniquely identified by the given identifier, or
-   * `null` if there is no such child.
-   *
-   * @param identifier the identifier used to select a child
-   * @return the child of this element with the given identifier
+   * Return the child of this element that is uniquely identified by the given
+   * [identifier], or `null` if there is no such child.
    */
   ElementImpl getChild(String identifier) => null;
 
@@ -2916,10 +2729,7 @@
   }
 
   /**
-   * Return `true` if this element has the given modifier associated with it.
-   *
-   * @param modifier the modifier being tested for
-   * @return `true` if this element has the given modifier associated with it
+   * Return `true` if this element has the given [modifier] associated with it.
    */
   bool hasModifier(Modifier modifier) =>
       BooleanArray.getEnum(_modifiers, modifier);
@@ -2933,10 +2743,7 @@
   }
 
   /**
-   * If the given child is not `null`, use the given visitor to visit it.
-   *
-   * @param child the child to be visited
-   * @param visitor the visitor to be used to visit the child
+   * If the given [child] is not `null`, use the given [visitor] to visit it.
    */
   void safelyVisitChild(Element child, ElementVisitor visitor) {
     if (child != null) {
@@ -2945,10 +2752,7 @@
   }
 
   /**
-   * Use the given visitor to visit all of the children in the given array.
-   *
-   * @param children the children to be visited
-   * @param visitor the visitor being used to visit the children
+   * Use the given [visitor] to visit all of the [children] in the given array.
    */
   void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
     if (children != null) {
@@ -2959,11 +2763,8 @@
   }
 
   /**
-   * Set whether the given modifier is associated with this element to correspond to the given
-   * value.
-   *
-   * @param modifier the modifier to be set
-   * @param value `true` if the modifier is to be associated with this element
+   * Set whether the given [modifier] is associated with this element to
+   * correspond to the given [value].
    */
   void setModifier(Modifier modifier, bool value) {
     _modifiers = BooleanArray.setEnum(_modifiers, modifier, value);
@@ -2983,7 +2784,8 @@
 }
 
 /**
- * The enumeration `ElementKind` defines the various kinds of elements in the element model.
+ * The enumeration `ElementKind` defines the various kinds of elements in the
+ * element model.
  */
 class ElementKind extends Enum<ElementKind> {
   static const ElementKind CLASS = const ElementKind('CLASS', 0, "class");
@@ -3086,19 +2888,15 @@
   final String displayName;
 
   /**
-   * Initialize a newly created element kind to have the given display name.
-   *
-   * @param displayName the name displayed in the UI for this kind of element
+   * Initialize a newly created element kind to have the given [displayName].
    */
   const ElementKind(String name, int ordinal, this.displayName)
       : super(name, ordinal);
 
   /**
-   * Return the kind of the given element, or [ERROR] if the element is `null`. This is
-   * a utility method that can reduce the need for null checks in other places.
-   *
-   * @param element the element whose kind is to be returned
-   * @return the kind of the given element
+   * Return the kind of the given [element], or [ERROR] if the element is
+   * `null`. This is a utility method that can reduce the need for null checks
+   * in other places.
    */
   static ElementKind of(Element element) {
     if (element == null) {
@@ -3109,29 +2907,24 @@
 }
 
 /**
- * The interface `ElementLocation` defines the behavior of objects that represent the location
- * of an element within the element model.
+ * The location of an element within the element model.
  */
 abstract class ElementLocation {
   /**
-   * Return the path to the element whose location is represented by this object. Clients must not
-   * modify the returned array.
-   *
-   * @return the path to the element whose location is represented by this object
+   * Return the path to the element whose location is represented by this
+   * object. Clients must not modify the returned array.
    */
   List<String> get components;
 
   /**
-   * Return an encoded representation of this location that can be used to create a location that is
-   * equal to this location.
-   *
-   * @return an encoded representation of this location
+   * Return an encoded representation of this location that can be used to
+   * create a location that is equal to this location.
    */
   String get encoding;
 }
 
 /**
- * Instances of the class `ElementLocationImpl` implement an [ElementLocation].
+ * A concrete implementation of an [ElementLocation].
  */
 class ElementLocationImpl implements ElementLocation {
   /**
@@ -3160,9 +2953,7 @@
   int indexLocationId;
 
   /**
-   * Initialize a newly created location to represent the given element.
-   *
-   * @param element the element whose location is being represented
+   * Initialize a newly created location to represent the given [element].
    */
   ElementLocationImpl.con1(Element element) {
     List<String> components = new List<String>();
@@ -3175,18 +2966,14 @@
   }
 
   /**
-   * Initialize a newly created location from the given encoded form.
-   *
-   * @param encoding the encoded form of a location
+   * Initialize a newly created location from the given [encoding].
    */
   ElementLocationImpl.con2(String encoding) {
     this._components = _decode(encoding);
   }
 
   /**
-   * Initialize a newly created location from the given components.
-   *
-   * @param components the components of a location
+   * Initialize a newly created location from the given [components].
    */
   ElementLocationImpl.con3(List<String> components) {
     this._components = components;
@@ -3244,10 +3031,8 @@
   String toString() => encoding;
 
   /**
-   * Decode the encoded form of a location into an array of components.
-   *
-   * @param encoding the encoded form of a location
-   * @return the components that were encoded
+   * Decode the [encoding] of a location into a list of components and return
+   * the components.
    */
   List<String> _decode(String encoding) {
     List<String> components = new List<String>();
@@ -3276,10 +3061,7 @@
   }
 
   /**
-   * Append an encoded form of the given component to the given builder.
-   *
-   * @param builder the builder to which the encoded component is to be appended
-   * @param component the component to be appended to the builder
+   * Append an encoded form of the given [component] to the given [buffer].
    */
   void _encode(StringBuffer buffer, String component) {
     int length = component.length;
@@ -3294,7 +3076,7 @@
 }
 
 /**
- * The class `ElementPair` is a pair of [Element]s. [Object.==] and
+ * A pair of [Element]s. [Object.==] and
  * [Object.hashCode] so this class can be used in hashed data structures.
  */
 class ElementPair {
@@ -3314,10 +3096,8 @@
   int _cachedHashCode;
 
   /**
-   * The sole constructor for this class, taking two [Element]s.
-   *
-   * @param first the first element
-   * @param second the second element
+   * Initialize a newly created pair of elements consisting of the [_first] and
+   * [_second] elements.
    */
   ElementPair(this._first, this._second) {
     _cachedHashCode = JenkinsSmiHash.hash2(_first.hashCode, _second.hashCode);
@@ -3325,8 +3105,6 @@
 
   /**
    * Return the first element.
-   *
-   * @return the first element
    */
   Element get firstElt => _first;
 
@@ -3337,8 +3115,6 @@
 
   /**
    * Return the second element
-   *
-   * @return the second element
    */
   Element get secondElt => _second;
 
@@ -3354,8 +3130,7 @@
 }
 
 /**
- * The interface `ElementVisitor` defines the behavior of objects that can be used to visit an
- * element structure.
+ * An object that can be used to visit an element structure.
  */
 abstract class ElementVisitor<R> {
   R visitClassElement(ClassElement element);
@@ -3404,21 +3179,17 @@
 }
 
 /**
- * The interface `EmbeddedHtmlScriptElement` defines the behavior of elements representing a
- * script tag in an HTML file having content that defines a Dart library.
+ * A script tag in an HTML file having content that defines a Dart library.
  */
 abstract class EmbeddedHtmlScriptElement implements HtmlScriptElement {
   /**
    * Return the library element defined by the content of the script tag.
-   *
-   * @return the library element (not `null`)
    */
   LibraryElement get scriptLibrary;
 }
 
 /**
- * Instances of the class `EmbeddedHtmlScriptElementImpl` implement an
- * [EmbeddedHtmlScriptElement].
+ * A concrete implementation of an [EmbeddedHtmlScriptElement].
  */
 class EmbeddedHtmlScriptElementImpl extends HtmlScriptElementImpl
     implements EmbeddedHtmlScriptElement {
@@ -3428,9 +3199,7 @@
   LibraryElement _scriptLibrary;
 
   /**
-   * Initialize a newly created script element to have the specified tag name and offset.
-   *
-   * @param node the XML node from which this element is derived (not `null`)
+   * Initialize a newly created script element to represent the given [node].
    */
   EmbeddedHtmlScriptElementImpl(XmlTagNode node) : super(node);
 
@@ -3441,13 +3210,12 @@
   LibraryElement get scriptLibrary => _scriptLibrary;
 
   /**
-   * Set the script library defined by the script tag's content.
-   *
-   * @param scriptLibrary the library or `null` if none
+   * Set the script library defined by the script tag's content to the given
+   * [library].
    */
-  void set scriptLibrary(LibraryElementImpl scriptLibrary) {
-    scriptLibrary.enclosingElement = this;
-    this._scriptLibrary = scriptLibrary;
+  void set scriptLibrary(LibraryElementImpl library) {
+    library.enclosingElement = this;
+    _scriptLibrary = library;
   }
 
   @override
@@ -3461,121 +3229,114 @@
 }
 
 /**
- * The interface `ExecutableElement` defines the behavior of elements representing an
- * executable object, including functions, methods, constructors, getters, and setters.
+ * An element representing an executable object, including functions, methods,
+ * constructors, getters, and setters.
  */
 abstract class ExecutableElement implements Element {
   /**
-   * Return an array containing all of the functions defined within this executable element.
-   *
-   * @return the functions defined within this executable element
+   * Return a list containing all of the functions defined within this
+   * executable element.
    */
   List<FunctionElement> get functions;
 
   /**
-   * Return `true` if this executable element has body marked as being asynchronous.
-   *
-   * @return `true` if this executable element has body marked as being asynchronous
+   * Return `true` if this executable element is abstract.
+   * Executable elements are abstract if they are not external and have no body.
+   */
+  bool get isAbstract;
+
+  /**
+   * Return `true` if this executable element has body marked as being
+   * asynchronous.
    */
   bool get isAsynchronous;
 
   /**
-   * Return `true` if this executable element has a body marked as being a generator.
-   *
-   * @return `true` if this executable element has a body marked as being a generator
+   * Return `true` if this executable element has a body marked as being a
+   * generator.
    */
   bool get isGenerator;
 
   /**
-   * Return `true` if this executable element is an operator. The test may be based on the
-   * name of the executable element, in which case the result will be correct when the name is
-   * legal.
-   *
-   * @return `true` if this executable element is an operator
+   * Return `true` if this executable element is an operator. The test may be
+   * based on the name of the executable element, in which case the result will
+   * be correct when the name is legal.
    */
   bool get isOperator;
 
   /**
-   * Return `true` if this element is a static element. A static element is an element that is
-   * not associated with a particular instance, but rather with an entire library or class.
-   *
-   * @return `true` if this executable element is a static element
+   * Return `true` if this element is a static element. A static element is an
+   * element that is not associated with a particular instance, but rather with
+   * an entire library or class.
    */
   bool get isStatic;
 
   /**
-   * Return `true` if this executable element has a body marked as being synchronous.
-   *
-   * @return `true` if this executable element has a body marked as being synchronous
+   * Return `true` if this executable element has a body marked as being
+   * synchronous.
    */
   bool get isSynchronous;
 
   /**
-   * Return an array containing all of the labels defined within this executable element.
-   *
-   * @return the labels defined within this executable element
+   * Return a list containing all of the labels defined within this executable
+   * element.
    */
   List<LabelElement> get labels;
 
   /**
-   * Return an array containing all of the local variables defined within this executable element.
-   *
-   * @return the local variables defined within this executable element
+   * Return a list containing all of the local variables defined within this
+   * executable element.
    */
   List<LocalVariableElement> get localVariables;
 
   /**
-   * Return an array containing all of the parameters defined by this executable element.
-   *
-   * @return the parameters defined by this executable element
+   * Return a list containing all of the parameters defined by this executable
+   * element.
    */
   List<ParameterElement> get parameters;
 
   /**
    * Return the return type defined by this executable element.
-   *
-   * @return the return type defined by this executable element
    */
   DartType get returnType;
 
   /**
    * Return the type of function defined by this executable element.
-   *
-   * @return the type of function defined by this executable element
    */
   FunctionType get type;
 }
 
 /**
- * The abstract class `ExecutableElementImpl` implements the behavior common to
- * `ExecutableElement`s.
+ * A base class for concrete implementations of an [ExecutableElement].
  */
 abstract class ExecutableElementImpl extends ElementImpl
     implements ExecutableElement {
   /**
    * An empty list of executable elements.
    */
-  static const List<ExecutableElement> EMPTY_ARRAY = const <ExecutableElement>[
-  ];
+  static const List<ExecutableElement> EMPTY_ARRAY =
+      const <ExecutableElement>[];
 
   /**
-   * An array containing all of the functions defined within this executable element.
+   * A list containing all of the functions defined within this executable
+   * element.
    */
   List<FunctionElement> _functions = FunctionElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the labels defined within this executable element.
+   * A list containing all of the labels defined within this executable element.
    */
   List<LabelElement> _labels = LabelElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the local variables defined within this executable element.
+   * A list containing all of the local variables defined within this executable
+   * element.
    */
   List<LocalVariableElement> _localVariables =
       LocalVariableElementImpl.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the parameters defined by this executable element.
+   * A list containing all of the parameters defined by this executable element.
    */
   List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
 
@@ -3590,25 +3351,18 @@
   FunctionType type;
 
   /**
-   * Initialize a newly created executable element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created executable element to have the given [name] and
+   * [offset].
    */
-  ExecutableElementImpl(String name, int nameOffset) : super(name, nameOffset);
+  ExecutableElementImpl(String name, int offset) : super(name, offset);
 
   /**
-   * Initialize a newly created executable element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created executable element to have the given [name].
    */
   ExecutableElementImpl.forNode(Identifier name) : super.forNode(name);
 
   /**
-   * Set whether this method's body is asynchronous to correspond to the given value.
-   *
-   * @param isAsynchronous `true` if the method's body is asynchronous
+   * Set whether this method's body is asynchronous.
    */
   void set asynchronous(bool isAsynchronous) {
     setModifier(Modifier.ASYNCHRONOUS, isAsynchronous);
@@ -3618,9 +3372,8 @@
   List<FunctionElement> get functions => _functions;
 
   /**
-   * Set the functions defined within this executable element to the given functions.
-   *
-   * @param functions the functions defined within this executable element
+   * Set the functions defined within this executable element to the given
+   * [functions].
    */
   void set functions(List<FunctionElement> functions) {
     for (FunctionElement function in functions) {
@@ -3630,15 +3383,16 @@
   }
 
   /**
-   * Set whether this method's body is a generator to correspond to the given value.
-   *
-   * @param isGenerator `true` if the method's body is a generator
+   * Set whether this method's body is a generator.
    */
   void set generator(bool isGenerator) {
     setModifier(Modifier.GENERATOR, isGenerator);
   }
 
   @override
+  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
+
+  @override
   bool get isAsynchronous => hasModifier(Modifier.ASYNCHRONOUS);
 
   @override
@@ -3654,9 +3408,8 @@
   List<LabelElement> get labels => _labels;
 
   /**
-   * Set the labels defined within this executable element to the given labels.
-   *
-   * @param labels the labels defined within this executable element
+   * Set the labels defined within this executable element to the given
+   * [labels].
    */
   void set labels(List<LabelElement> labels) {
     for (LabelElement label in labels) {
@@ -3669,24 +3422,22 @@
   List<LocalVariableElement> get localVariables => _localVariables;
 
   /**
-   * Set the local variables defined within this executable element to the given variables.
-   *
-   * @param localVariables the local variables defined within this executable element
+   * Set the local variables defined within this executable element to the given
+   * [variables].
    */
-  void set localVariables(List<LocalVariableElement> localVariables) {
-    for (LocalVariableElement variable in localVariables) {
+  void set localVariables(List<LocalVariableElement> variables) {
+    for (LocalVariableElement variable in variables) {
       (variable as LocalVariableElementImpl).enclosingElement = this;
     }
-    this._localVariables = localVariables;
+    this._localVariables = variables;
   }
 
   @override
   List<ParameterElement> get parameters => _parameters;
 
   /**
-   * Set the parameters defined by this executable element to the given parameters.
-   *
-   * @param parameters the parameters defined by this executable element
+   * Set the parameters defined by this executable element to the given
+   * [parameters].
    */
   void set parameters(List<ParameterElement> parameters) {
     for (ParameterElement parameter in parameters) {
@@ -3772,17 +3523,13 @@
 }
 
 /**
- * The abstract class `ExecutableMember` defines the behavior common to members that represent
- * an executable element defined in a parameterized type where the values of the type parameters are
- * known.
+ * An executable element defined in a parameterized type where the values of the
+ * type parameters are known.
  */
 abstract class ExecutableMember extends Member implements ExecutableElement {
   /**
-   * Initialize a newly created element to represent an executable element of the given
-   * parameterized type.
-   *
-   * @param baseElement the element on which the parameterized element was created
-   * @param definingType the type in which the element is defined
+   * Initialize a newly created element to represent a constructor, based on the
+   * [baseElement], defined by the [definingType].
    */
   ExecutableMember(ExecutableElement baseElement, InterfaceType definingType)
       : super(baseElement, definingType);
@@ -3801,6 +3548,9 @@
   }
 
   @override
+  bool get isAbstract => baseElement.isAbstract;
+
+  @override
   bool get isAsynchronous => baseElement.isAsynchronous;
 
   @override
@@ -3863,8 +3613,7 @@
 }
 
 /**
- * The interface `ExportElement` defines the behavior of objects representing information
- * about a single export directive within a library.
+ * An export directive within a library.
  */
 abstract class ExportElement implements Element, UriReferencedElement {
   /**
@@ -3873,23 +3622,20 @@
   static const List<ExportElement> EMPTY_ARRAY = const <ExportElement>[];
 
   /**
-   * Return an array containing the combinators that were specified as part of the export directive
-   * in the order in which they were specified.
-   *
-   * @return the combinators specified in the export directive
+   * Return a list containing the combinators that were specified as part of the
+   * export directive in the order in which they were specified.
    */
   List<NamespaceCombinator> get combinators;
 
   /**
-   * Return the library that is exported from this library by this export directive.
-   *
-   * @return the library that is exported from this library
+   * Return the library that is exported from this library by this export
+   * directive.
    */
   LibraryElement get exportedLibrary;
 }
 
 /**
- * Instances of the class `ExportElementImpl` implement an [ExportElement].
+ * A concrete implementation of an [ExportElement].
  */
 class ExportElementImpl extends UriReferencedElementImpl
     implements ExportElement {
@@ -3899,15 +3645,15 @@
   LibraryElement exportedLibrary;
 
   /**
-   * The combinators that were specified as part of the export directive in the order in which they
-   * were specified.
+   * The combinators that were specified as part of the export directive in the
+   * order in which they were specified.
    */
   List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_ARRAY;
 
   /**
-   * Initialize a newly created export element.
+   * Initialize a newly created export element at the given [offset].
    */
-  ExportElementImpl() : super(null, -1);
+  ExportElementImpl(int offset) : super(null, offset);
 
   @override
   String get identifier => exportedLibrary.name;
@@ -3926,23 +3672,19 @@
 }
 
 /**
- * The interface `ExternalHtmlScriptElement` defines the behavior of elements representing a
- * script tag in an HTML file having a `source` attribute that references a Dart library
- * source file.
+ * A script tag in an HTML file having a `source` attribute that references a
+ * Dart library source file.
  */
 abstract class ExternalHtmlScriptElement implements HtmlScriptElement {
   /**
-   * Return the source referenced by this element, or `null` if this element does not
-   * reference a Dart library source file.
-   *
-   * @return the source for the external Dart library
+   * Return the source referenced by this element, or `null` if this element
+   * does not reference a Dart library source file.
    */
   Source get scriptSource;
 }
 
 /**
- * Instances of the class `ExternalHtmlScriptElementImpl` implement an
- * [ExternalHtmlScriptElement].
+ * A concrete implementation of an [ExternalHtmlScriptElement].
  */
 class ExternalHtmlScriptElementImpl extends HtmlScriptElementImpl
     implements ExternalHtmlScriptElement {
@@ -3952,9 +3694,8 @@
   Source scriptSource;
 
   /**
-   * Initialize a newly created script element to have the specified tag name and offset.
-   *
-   * @param node the XML node from which this element is derived (not `null`)
+   * Initialize a newly created script element to correspond to the given
+   * [node].
    */
   ExternalHtmlScriptElementImpl(XmlTagNode node) : super(node);
 
@@ -3967,21 +3708,28 @@
 }
 
 /**
- * The interface `FieldElement` defines the behavior of elements representing a field defined
- * within a type.
+ * A field defined within a type.
  */
 abstract class FieldElement
     implements ClassMemberElement, PropertyInducingElement {
   /**
    * Return {@code true} if this element is an enum constant.
-   *
-   * @return {@code true} if this an enum constant
    */
   bool get isEnumConstant;
+
+  /**
+   * Return the resolved [VariableDeclaration] or [EnumConstantDeclaration]
+   * node that declares this [FieldElement].
+   *
+   * This method is expensive, because resolved AST might be evicted from cache,
+   * so parsing and resolving will be performed.
+   */
+  @override
+  AstNode get node;
 }
 
 /**
- * Instances of the class `FieldElementImpl` implement a `FieldElement`.
+ * A concrete implementation of a [FieldElement].
  */
 class FieldElementImpl extends PropertyInducingElementImpl
     implements FieldElement {
@@ -3991,18 +3739,13 @@
   static const List<FieldElement> EMPTY_ARRAY = const <FieldElement>[];
 
   /**
-   * Initialize a newly created synthetic field element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created synthetic field element to have the given [name]
+   * at the given [offset].
    */
-  FieldElementImpl(String name, int nameOffset) : super(name, nameOffset);
+  FieldElementImpl(String name, int offset) : super(name, offset);
 
   /**
-   * Initialize a newly created field element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created field element to have the given [name].
    */
   FieldElementImpl.forNode(Identifier name) : super.forNode(name);
 
@@ -4019,10 +3762,17 @@
   @override
   ElementKind get kind => ElementKind.FIELD;
 
+  @override
+  AstNode get node {
+    if (isEnumConstant) {
+      return getNodeMatching((node) => node is EnumConstantDeclaration);
+    } else {
+      return getNodeMatching((node) => node is VariableDeclaration);
+    }
+  }
+
   /**
-   * Set whether this field is static to correspond to the given value.
-   *
-   * @param isStatic `true` if the field is static
+   * Set whether this field is static.
    */
   void set static(bool isStatic) {
     setModifier(Modifier.STATIC, isStatic);
@@ -4033,23 +3783,19 @@
 }
 
 /**
- * The interface `FieldFormalParameterElement` defines the behavior of elements representing a
- * field formal parameter defined within a constructor element.
+ * A field formal parameter defined within a constructor element.
  */
 abstract class FieldFormalParameterElement implements ParameterElement {
   /**
-   * Return the field element associated with this field formal parameter, or `null` if the
-   * parameter references a field that doesn't exist.
-   *
-   * @return the field element associated with this field formal parameter
+   * Return the field element associated with this field formal parameter, or
+   * `null` if the parameter references a field that doesn't exist.
    */
   FieldElement get field;
 }
 
 /**
- * Instances of the class `FieldFormalParameterElementImpl` extend
- * [ParameterElementImpl] to provide the additional information of the [FieldElement]
- * associated with the parameter.
+ * A [ParameterElementImpl] that has the additional information of the
+ * [FieldElement] associated with the parameter.
  */
 class FieldFormalParameterElementImpl extends ParameterElementImpl
     implements FieldFormalParameterElement {
@@ -4059,9 +3805,7 @@
   FieldElement field;
 
   /**
-   * Initialize a newly created parameter element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created parameter element to have the given [name].
    */
   FieldFormalParameterElementImpl(Identifier name) : super.forNode(name);
 
@@ -4074,16 +3818,14 @@
 }
 
 /**
- * Instances of the class `FieldFormalParameterMember` represent a parameter element defined
- * in a parameterized type where the values of the type parameters are known.
+ * A parameter element defined in a parameterized type where the values of the
+ * type parameters are known.
  */
 class FieldFormalParameterMember extends ParameterMember
     implements FieldFormalParameterElement {
   /**
-   * Initialize a newly created element to represent a parameter of the given parameterized type.
-   *
-   * @param baseElement the element on which the parameterized element was created
-   * @param definingType the type in which the element is defined
+   * Initialize a newly created element to represent a constructor, based on the
+   * [baseElement], defined by the [definingType].
    */
   FieldFormalParameterMember(
       FieldFormalParameterElement baseElement, ParameterizedType definingType)
@@ -4104,15 +3846,13 @@
 }
 
 /**
- * Instances of the class `FieldMember` represent a field element defined in a parameterized
- * type where the values of the type parameters are known.
+ * A field element defined in a parameterized type where the values of the type
+ * parameters are known.
  */
 class FieldMember extends VariableMember implements FieldElement {
   /**
-   * Initialize a newly created element to represent a field of the given parameterized type.
-   *
-   * @param baseElement the element on which the parameterized element was created
-   * @param definingType the type in which the element is defined
+   * Initialize a newly created element to represent a constructor, based on the
+   * [baseElement], defined by the [definingType].
    */
   FieldMember(FieldElement baseElement, InterfaceType definingType)
       : super(baseElement, definingType);
@@ -4150,40 +3890,32 @@
   String toString() => '$type $displayName';
 
   /**
-   * If the given field's type is different when any type parameters from the defining type's
-   * declaration are replaced with the actual type arguments from the defining type, create a field
-   * member representing the given field. Return the member that was created, or the base field if
-   * no member was created.
-   *
-   * @param baseField the base field for which a member might be created
-   * @param definingType the type defining the parameters and arguments to be used in the
-   *          substitution
-   * @return the field element that will return the correctly substituted types
+   * If the given [field]'s type is different when any type parameters from the
+   * defining type's declaration are replaced with the actual type arguments
+   * from the [definingType], create a field member representing the given
+   * field. Return the member that was created, or the base field if no member
+   * was created.
    */
-  static FieldElement from(FieldElement baseField, InterfaceType definingType) {
-    if (!_isChangedByTypeSubstitution(baseField, definingType)) {
-      return baseField;
+  static FieldElement from(FieldElement field, InterfaceType definingType) {
+    if (!_isChangedByTypeSubstitution(field, definingType)) {
+      return field;
     }
     // TODO(brianwilkerson) Consider caching the substituted type in the
     // instance. It would use more memory but speed up some operations.
     // We need to see how often the type is being re-computed.
-    return new FieldMember(baseField, definingType);
+    return new FieldMember(field, definingType);
   }
 
   /**
-   * Determine whether the given field's type is changed when type parameters from the defining
-   * type's declaration are replaced with the actual type arguments from the defining type.
-   *
-   * @param baseField the base field
-   * @param definingType the type defining the parameters and arguments to be used in the
-   *          substitution
-   * @return true if the type is changed by type substitution.
+   * Determine whether the given [field]'s type is changed when type parameters
+   * from the [definingType]'s declaration are replaced with the actual type
+   * arguments from the defining type.
    */
   static bool _isChangedByTypeSubstitution(
-      FieldElement baseField, InterfaceType definingType) {
+      FieldElement field, InterfaceType definingType) {
     List<DartType> argumentTypes = definingType.typeArguments;
-    if (baseField != null && argumentTypes.length != 0) {
-      DartType baseType = baseField.type;
+    if (field != null && argumentTypes.length != 0) {
+      DartType baseType = field.type;
       List<DartType> parameterTypes = definingType.element.type.typeArguments;
       if (baseType != null) {
         DartType substitutedType =
@@ -4194,7 +3926,7 @@
       }
       // If the field has a propagated type, then we need to check whether the
       // propagated type needs substitution.
-      DartType basePropagatedType = baseField.propagatedType;
+      DartType basePropagatedType = field.propagatedType;
       if (basePropagatedType != null) {
         DartType substitutedPropagatedType =
             basePropagatedType.substitute2(argumentTypes, parameterTypes);
@@ -4208,41 +3940,51 @@
 }
 
 /**
- * The interface `FunctionElement` defines the behavior of elements representing a function.
+ * A (non-method) function. This can be either a top-level function, a local
+ * function, a closure, or the initialization expression for a field or
+ * variable.
  */
 abstract class FunctionElement implements ExecutableElement, LocalElement {
   /**
-   * The name of the method that can be implemented by a class to allow its instances to be invoked
-   * as if they were a function.
+   * The name of the method that can be implemented by a class to allow its
+   * instances to be invoked as if they were a function.
    */
   static final String CALL_METHOD_NAME = "call";
 
   /**
-   * The name of the method that will be invoked if an attempt is made to invoke an undefined method
-   * on an object.
-   */
-  static final String NO_SUCH_METHOD_METHOD_NAME = "noSuchMethod";
-
-  /**
    * The name of the synthetic function defined for libraries that are deferred.
    */
   static final String LOAD_LIBRARY_NAME = "loadLibrary";
 
   /**
-   * Return the resolved [FunctionDeclaration] node that declares this [FunctionElement]
-   * .
+   * The name of the function used as an entry point.
+   */
+  static const String MAIN_FUNCTION_NAME = "main";
+
+  /**
+   * The name of the method that will be invoked if an attempt is made to invoke
+   * an undefined method on an object.
+   */
+  static final String NO_SUCH_METHOD_METHOD_NAME = "noSuchMethod";
+
+  /**
+   * Return `true` if the function is an entry point, i.e. a top-level function
+   * and has the name `main`.
+   */
+  bool get isEntryPoint;
+
+  /**
+   * Return the resolved function declaration node that declares this element.
    *
-   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
-   * resolving will be performed.
-   *
-   * @return the resolved [FunctionDeclaration], not `null`.
+   * This method is expensive, because resolved AST might be evicted from cache,
+   * so parsing and resolving will be performed.
    */
   @override
   FunctionDeclaration get node;
 }
 
 /**
- * Instances of the class `FunctionElementImpl` implement a `FunctionElement`.
+ * A concrete implementation of a [FunctionElement].
  */
 class FunctionElementImpl extends ExecutableElementImpl
     implements FunctionElement {
@@ -4257,33 +3999,25 @@
   int _visibleRangeOffset = 0;
 
   /**
-   * The length of the visible range for this element, or `-1` if this element does not have a
-   * visible range.
+   * The length of the visible range for this element, or `-1` if this element
+   * does not have a visible range.
    */
   int _visibleRangeLength = -1;
 
   /**
-   * Initialize a newly created function element to have the given name and offset.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created function element to have the given [name] and
+   * [offset].
    */
-  FunctionElementImpl(String name, int nameOffset) : super(name, nameOffset);
+  FunctionElementImpl(String name, int offset) : super(name, offset);
 
   /**
-   * Initialize a newly created function element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created function element to have the given [name].
    */
   FunctionElementImpl.forNode(Identifier name) : super.forNode(name);
 
   /**
-   * Initialize a newly created function element to have no name and the given offset. This is used
-   * for function expressions, which have no name.
-   *
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created function element to have no name and the given
+   * [offset]. This is used for function expressions, that have no name.
    */
   FunctionElementImpl.forOffset(int nameOffset) : super("", nameOffset);
 
@@ -4297,6 +4031,11 @@
   }
 
   @override
+  bool get isEntryPoint {
+    return isStatic && displayName == FunctionElement.MAIN_FUNCTION_NAME;
+  }
+
+  @override
   bool get isStatic => enclosingElement is CompilationUnitElement;
 
   @override
@@ -4327,12 +4066,8 @@
   }
 
   /**
-   * Set the visible range for this element to the range starting at the given offset with the given
-   * length.
-   *
-   * @param offset the offset to the beginning of the visible range for this element
-   * @param length the length of the visible range for this element, or `-1` if this element
-   *          does not have a visible range
+   * Set the visible range for this element to the range starting at the given
+   * [offset] with the given [length].
    */
   void setVisibleRange(int offset, int length) {
     _visibleRangeOffset = offset;
@@ -4341,114 +4076,114 @@
 }
 
 /**
- * The interface `FunctionType` defines the behavior common to objects representing the type
- * of a function, method, constructor, getter, or setter. Function types come in three variations:
- * <ol>
- * * The types of functions that only have required parameters. These have the general form
- * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i>.
- * * The types of functions with optional positional parameters. These have the general form
- * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>]) &rarr;
- * T</i>.
- * * The types of functions with named parameters. These have the general form <i>(T<sub>1</sub>,
- * &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;, T<sub>xk</sub> xk}) &rarr; T</i>.
- * </ol>
+ * The type of a function, method, constructor, getter, or setter. Function
+ * types come in three variations:
+ *
+ * * The types of functions that only have required parameters. These have the
+ *   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i>.
+ * * The types of functions with optional positional parameters. These have the
+ *   general form <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>
+ *   &hellip;, T<sub>n+k</sub>]) &rarr; T</i>.
+ * * The types of functions with named parameters. These have the general form
+ *   <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;,
+ *   T<sub>xk</sub> xk}) &rarr; T</i>.
  */
 abstract class FunctionType implements ParameterizedType {
   /**
-   * Return a map from the names of named parameters to the types of the named parameters of this
-   * type of function. The entries in the map will be iterated in the same order as the order in
-   * which the named parameters were defined. If there were no named parameters declared then the
-   * map will be empty.
-   *
-   * @return a map from the name to the types of the named parameters of this type of function
+   * Return a map from the names of named parameters to the types of the named
+   * parameters of this type of function. The entries in the map will be
+   * iterated in the same order as the order in which the named parameters were
+   * defined. If there were no named parameters declared then the map will be
+   * empty.
    */
   Map<String, DartType> get namedParameterTypes;
 
   /**
-   * Return an array containing the types of the normal parameters of this type of function. The
-   * parameter types are in the same order as they appear in the declaration of the function.
-   *
-   * @return the types of the normal parameters of this type of function
+   * Return a list containing the types of the normal parameters of this type of
+   * function. The parameter types are in the same order as they appear in the
+   * declaration of the function.
    */
   List<DartType> get normalParameterTypes;
 
   /**
-   * Return a map from the names of optional (positional) parameters to the types of the optional
-   * parameters of this type of function. The entries in the map will be iterated in the same order
-   * as the order in which the optional parameters were defined. If there were no optional
-   * parameters declared then the map will be empty.
-   *
-   * @return a map from the name to the types of the optional parameters of this type of function
+   * Return a map from the names of optional (positional) parameters to the
+   * types of the optional parameters of this type of function. The entries in
+   * the map will be iterated in the same order as the order in which the
+   * optional parameters were defined. If there were no optional parameters
+   * declared then the map will be empty.
    */
   List<DartType> get optionalParameterTypes;
 
   /**
-   * Return an array containing the parameters elements of this type of function. The parameter
-   * types are in the same order as they appear in the declaration of the function.
-   *
-   * @return the parameters elements of this type of function
+   * Return a list containing the parameters elements of this type of function.
+   * The parameter types are in the same order as they appear in the declaration
+   * of the function.
    */
   List<ParameterElement> get parameters;
 
   /**
    * Return the type of object returned by this type of function.
-   *
-   * @return the type of object returned by this type of function
    */
   DartType get returnType;
 
   /**
-   * Return `true` if this type is a subtype of the given type.
+   * Return `true` if this type is a subtype of the given [type].
    *
-   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i> is a subtype of the
-   * function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>) &rarr; S</i>, if all of the following
-   * conditions are met:
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T</i> is
+   * a subtype of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>)
+   * &rarr; S</i>, if all of the following conditions are met:
+   *
    * * Either
-   * * <i>S</i> is void, or
-   * * <i>T &hArr; S</i>.
+   *   * <i>S</i> is void, or
+   *   * <i>T &hArr; S</i>.
    *
-   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr; S<sub>i</sub></i>.
-   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, [T<sub>n+1</sub>, &hellip;,
-   * T<sub>n+k</sub>]) &rarr; T</i> is a subtype of the function type <i>(S<sub>1</sub>, &hellip;,
-   * S<sub>n</sub>, [S<sub>n+1</sub>, &hellip;, S<sub>n+m</sub>]) &rarr; S</i>, if all of the
+   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr;
+   *   S<sub>i</sub></i>.
+   *
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>,
+   * [T<sub>n+1</sub>, &hellip;, T<sub>n+k</sub>]) &rarr; T</i> is a subtype of
+   * the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>,
+   * [S<sub>n+1</sub>, &hellip;, S<sub>n+m</sub>]) &rarr; S</i>, if all of the
    * following conditions are met:
-   * * Either
-   * * <i>S</i> is void, or
-   * * <i>T &hArr; S</i>.
    *
-   * * <i>k</i> >= <i>m</i> and for all <i>i</i>, 1 <= <i>i</i> <= <i>n+m</i>, <i>T<sub>i</sub>
-   * &hArr; S<sub>i</sub></i>.
-   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {T<sub>x1</sub> x1, &hellip;,
-   * T<sub>xk</sub> xk}) &rarr; T</i> is a subtype of the function type <i>(S<sub>1</sub>, &hellip;,
-   * S<sub>n</sub>, {S<sub>y1</sub> y1, &hellip;, S<sub>ym</sub> ym}) &rarr; S</i>, if all of the
-   * following conditions are met:
    * * Either
-   * * <i>S</i> is void,
-   * * or <i>T &hArr; S</i>.
+   *   * <i>S</i> is void, or
+   *   * <i>T &hArr; S</i>.
    *
-   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr; S<sub>i</sub></i>.
-   * * <i>k</i> >= <i>m</i> and <i>y<sub>i</sub></i> in <i>{x<sub>1</sub>, &hellip;,
-   * x<sub>k</sub>}</i>, 1 <= <i>i</i> <= <i>m</i>.
-   * * For all <i>y<sub>i</sub></i> in <i>{y<sub>1</sub>, &hellip;, y<sub>m</sub>}</i>,
-   * <i>y<sub>i</sub> = x<sub>j</sub> => Tj &hArr; Si</i>.
+   * * <i>k</i> >= <i>m</i> and for all <i>i</i>, 1 <= <i>i</i> <= <i>n+m</i>,
+   *   <i>T<sub>i</sub> &hArr; S<sub>i</sub></i>.
+   *
+   * A function type <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>,
+   * {T<sub>x1</sub> x1, &hellip;, T<sub>xk</sub> xk}) &rarr; T</i> is a subtype
+   * of the function type <i>(S<sub>1</sub>, &hellip;, S<sub>n</sub>,
+   * {S<sub>y1</sub> y1, &hellip;, S<sub>ym</sub> ym}) &rarr; S</i>, if all of
+   * the following conditions are met:
+   * * Either
+   *   * <i>S</i> is void,
+   *   * or <i>T &hArr; S</i>.
+   *
+   * * For all <i>i</i>, 1 <= <i>i</i> <= <i>n</i>, <i>T<sub>i</sub> &hArr;
+   *   S<sub>i</sub></i>.
+   * * <i>k</i> >= <i>m</i> and <i>y<sub>i</sub></i> in <i>{x<sub>1</sub>,
+   *   &hellip;, x<sub>k</sub>}</i>, 1 <= <i>i</i> <= <i>m</i>.
+   * * For all <i>y<sub>i</sub></i> in <i>{y<sub>1</sub>, &hellip;,
+   *   y<sub>m</sub>}</i>, <i>y<sub>i</sub> = x<sub>j</sub> => Tj &hArr; Si</i>.
+   *
    * In addition, the following subtype rules apply:
    *
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, []) &rarr; T <: (T<sub>1</sub>, &hellip;,
-   * T<sub>n</sub>) &rarr; T.</i><br>
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>, &hellip;,
-   * T<sub>n</sub>, {}) &rarr; T.</i><br>
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {}) &rarr; T <: (T<sub>1</sub>, &hellip;,
-   * T<sub>n</sub>) &rarr; T.</i><br>
-   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>, &hellip;,
-   * T<sub>n</sub>, []) &rarr; T.</i>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, []) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>, {}) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>, {}) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>) &rarr; T.</i><br>
+   * <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub>) &rarr; T <: (T<sub>1</sub>,
+   * &hellip;, T<sub>n</sub>, []) &rarr; T.</i>
    *
-   * All functions implement the class `Function`. However not all function types are a
-   * subtype of `Function`. If an interface type <i>I</i> includes a method named
-   * `call()`, and the type of `call()` is the function type <i>F</i>, then <i>I</i> is
-   * considered to be a subtype of <i>F</i>.
-   *
-   * @param type the type being compared with this type
-   * @return `true` if this type is a subtype of the given type
+   * All functions implement the class `Function`. However not all function
+   * types are a subtype of `Function`. If an interface type <i>I</i> includes a
+   * method named `call()`, and the type of `call()` is the function type
+   * <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
    */
   @override
   bool isSubtypeOf(DartType type);
@@ -4458,72 +4193,55 @@
       List<DartType> argumentTypes, List<DartType> parameterTypes);
 
   /**
-   * Return the type resulting from substituting the given arguments for this type's parameters.
-   * This is fully equivalent to `substitute(argumentTypes, getTypeArguments())`.
-   *
-   * @param argumentTypes the actual type arguments being substituted for the type parameters
-   * @return the result of performing the substitution
+   * Return the type resulting from substituting the given [argumentTypes] for
+   * this type's parameters. This is fully equivalent to
+   * `substitute(argumentTypes, getTypeArguments())`.
    */
   FunctionType substitute3(List<DartType> argumentTypes);
 }
 
 /**
- * The interface `FunctionTypeAliasElement` defines the behavior of elements representing a
- * function type alias (`typedef`).
+ * A function type alias (`typedef`).
  */
 abstract class FunctionTypeAliasElement implements Element {
   /**
    * Return the compilation unit in which this type alias is defined.
-   *
-   * @return the compilation unit in which this type alias is defined
    */
   @override
   CompilationUnitElement get enclosingElement;
 
   /**
-   * Return the resolved [FunctionTypeAlias] node that declares this
-   * [FunctionTypeAliasElement] .
+   * Return the resolved function type alias node that declares this element.
    *
-   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
-   * resolving will be performed.
-   *
-   * @return the resolved [FunctionTypeAlias], not `null`.
+   * This method is expensive, because resolved AST might be evicted from cache,
+   * so parsing and resolving will be performed.
    */
   @override
   FunctionTypeAlias get node;
 
   /**
-   * Return an array containing all of the parameters defined by this type alias.
-   *
-   * @return the parameters defined by this type alias
+   * Return a list containing all of the parameters defined by this type alias.
    */
   List<ParameterElement> get parameters;
 
   /**
    * Return the return type defined by this type alias.
-   *
-   * @return the return type defined by this type alias
    */
   DartType get returnType;
 
   /**
    * Return the type of function defined by this type alias.
-   *
-   * @return the type of function defined by this type alias
    */
   FunctionType get type;
 
   /**
-   * Return an array containing all of the type parameters defined for this type.
-   *
-   * @return the type parameters defined for this type
+   * Return a list containing all of the type parameters defined for this type.
    */
   List<TypeParameterElement> get typeParameters;
 }
 
 /**
- * Instances of the class `FunctionTypeAliasElementImpl` implement a
- * `FunctionTypeAliasElement`.
+ * A concrete implementation of a [FunctionTypeAliasElement].
  */
 class FunctionTypeAliasElementImpl extends ElementImpl
     implements FunctionTypeAliasElement {
@@ -4534,7 +4252,7 @@
       new List<FunctionTypeAliasElement>(0);
 
   /**
-   * An array containing all of the parameters defined by this type alias.
+   * A list containing all of the parameters defined by this type alias.
    */
   List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
 
@@ -4549,7 +4267,7 @@
   FunctionType type;
 
   /**
-   * An array containing all of the type parameters defined for this type.
+   * A list containing all of the type parameters defined for this type.
    */
   List<TypeParameterElement> _typeParameters =
       TypeParameterElementImpl.EMPTY_ARRAY;
@@ -4565,9 +4283,7 @@
       : super(name, nameOffset);
 
   /**
-   * Initialize a newly created type alias element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created type alias element to have the given [name].
    */
   FunctionTypeAliasElementImpl.forNode(Identifier name) : super.forNode(name);
 
@@ -4586,9 +4302,7 @@
   List<ParameterElement> get parameters => _parameters;
 
   /**
-   * Set the parameters defined by this type alias to the given parameters.
-   *
-   * @param parameters the parameters defined by this type alias
+   * Set the parameters defined by this type alias to the given [parameters].
    */
   void set parameters(List<ParameterElement> parameters) {
     if (parameters != null) {
@@ -4603,9 +4317,8 @@
   List<TypeParameterElement> get typeParameters => _typeParameters;
 
   /**
-   * Set the type parameters defined for this type to the given parameters.
-   *
-   * @param typeParameters the type parameters defined for this type
+   * Set the type parameters defined for this type to the given
+   * [typeParameters].
    */
   void set typeParameters(List<TypeParameterElement> typeParameters) {
     for (TypeParameterElement typeParameter in typeParameters) {
@@ -4667,22 +4380,18 @@
   }
 
   /**
-   * Set the parameters defined by this type alias to the given parameters without becoming the
-   * parent of the parameters. This should only be used by the [TypeResolverVisitor] when
-   * creating a synthetic type alias.
-   *
-   * @param parameters the parameters defined by this type alias
+   * Set the parameters defined by this type alias to the given [parameters]
+   * without becoming the parent of the parameters. This should only be used by
+   * the [TypeResolverVisitor] when creating a synthetic type alias.
    */
   void shareParameters(List<ParameterElement> parameters) {
     this._parameters = parameters;
   }
 
   /**
-   * Set the type parameters defined for this type to the given parameters without becoming the
-   * parent of the parameters. This should only be used by the [TypeResolverVisitor] when
-   * creating a synthetic type alias.
-   *
-   * @param typeParameters the type parameters defined for this type
+   * Set the type parameters defined for this type to the given [typeParameters]
+   * without becoming the parent of the parameters. This should only be used by
+   * the [TypeResolverVisitor] when creating a synthetic type alias.
    */
   void shareTypeParameters(List<TypeParameterElement> typeParameters) {
     this._typeParameters = typeParameters;
@@ -4697,34 +4406,29 @@
 }
 
 /**
- * Instances of the class `FunctionTypeImpl` defines the behavior common to objects
- * representing the type of a function, method, constructor, getter, or setter.
+ * The type of a function, method, constructor, getter, or setter.
  */
 class FunctionTypeImpl extends TypeImpl implements FunctionType {
   /**
-   * An array containing the actual types of the type arguments.
+   * A list containing the actual types of the type arguments.
    */
   List<DartType> typeArguments = TypeImpl.EMPTY_ARRAY;
 
   /**
-   * Initialize a newly created function type to be declared by the given element and to have the
-   * given name.
-   *
-   * @param element the element representing the declaration of the function type
+   * Initialize a newly created function type to be declared by the given
+   * [element].
    */
   FunctionTypeImpl.con1(ExecutableElement element) : super(element, null);
 
   /**
-   * Initialize a newly created function type to be declared by the given element and to have the
-   * given name.
-   *
-   * @param element the element representing the declaration of the function type
+   * Initialize a newly created function type to be declared by the given
+   * [element].
    */
   FunctionTypeImpl.con2(FunctionTypeAliasElement element)
       : super(element, element == null ? null : element.name);
 
   /**
-   * @return the base parameter elements of this function element, not `null`.
+   * Return the base parameter elements of this function element.
    */
   List<ParameterElement> get baseParameters {
     Element element = this.element;
@@ -4737,8 +4441,6 @@
 
   /**
    * Return the return type defined by this function's element.
-   *
-   * @return the return type defined by this function's element
    */
   DartType get baseReturnType {
     Element element = this.element;
@@ -5302,14 +5004,11 @@
   }
 
   /**
-   * Return `true` if this type is assignable to the given type. A function type <i>T</i> may
-   * be assigned to a function type <i>S</i>, written <i>T</i> &hArr; <i>S</i>, iff <i>T</i> <:
-   * <i>S</i> (Function Types section of spec). Note that this is more restrictive than the
-   * "may be assigned to" rule for interface types.
-   *
-   *
-   * @param type the type being compared with this type
-   * @return `true` if this type is assignable to the given type
+   * Return `true` if this type is assignable to the given [type]. A function
+   * type <i>T</i> may be assigned to a function type <i>S</i>, written <i>T</i>
+   * &hArr; <i>S</i>, iff <i>T</i> <: <i>S</i> (Function Types section of spec).
+   * Note that this is more restrictive than the "may be assigned to" rule for
+   * interface types.
    */
   @override
   bool isAssignableTo(DartType type) =>
@@ -5339,15 +5038,12 @@
       substitute2(argumentTypes, typeArguments);
 
   /**
-   * Return `true` if all of the name/type pairs in the first map are equal to the
-   * corresponding name/type pairs in the second map. The maps are expected to iterate over their
-   * entries in the same order in which those entries were added to the map.
-   *
-   * @param firstTypes the first map of name/type pairs being compared
-   * @param secondTypes the second map of name/type pairs being compared
-   * @param visitedElementPairs a set of visited element pairs
-   * @return `true` if all of the name/type pairs in the first map are equal to the
-   *         corresponding name/type pairs in the second map
+   * Return `true` if all of the name/type pairs in the first map ([firstTypes])
+   * are equal to the corresponding name/type pairs in the second map
+   * ([secondTypes]). The maps are expected to iterate over their entries in the
+   * same order in which those entries were added to the map. The set of
+   * [visitedElementPairs] is used to prevent infinite recursion in the case of
+   * cyclic type structures.
    */
   static bool _equals(Map<String, DartType> firstTypes,
       Map<String, DartType> secondTypes, Set<ElementPair> visitedElementPairs) {
@@ -5371,35 +5067,36 @@
 }
 
 /**
- * Instances of the class `GeneralizingElementVisitor` implement an element visitor that will
- * recursively visit all of the elements in an element model (like instances of the class
- * [RecursiveElementVisitor]). In addition, when an element of a specific type is visited not
- * only will the visit method for that specific type of element be invoked, but additional methods
- * for the supertypes of that element will also be invoked. For example, using an instance of this
- * class to visit a [MethodElement] will cause the method
- * [visitMethodElement] to be invoked but will also cause the methods
- * [visitExecutableElement] and [visitElement] to be
- * subsequently invoked. This allows visitors to be written that visit all executable elements
- * without needing to override the visit method for each of the specific subclasses of
+ * An element visitor that will recursively visit all of the elements in an
+ * element model (like instances of the class [RecursiveElementVisitor]). In
+ * addition, when an element of a specific type is visited not only will the
+ * visit method for that specific type of element be invoked, but additional
+ * methods for the supertypes of that element will also be invoked. For example,
+ * using an instance of this class to visit a [MethodElement] will cause the
+ * method [visitMethodElement] to be invoked but will also cause the methods
+ * [visitExecutableElement] and [visitElement] to be subsequently invoked. This
+ * allows visitors to be written that visit all executable elements without
+ * needing to override the visit method for each of the specific subclasses of
  * [ExecutableElement].
  *
- * Note, however, that unlike many visitors, element visitors visit objects based on the interfaces
- * implemented by those elements. Because interfaces form a graph structure rather than a tree
- * structure the way classes do, and because it is generally undesirable for an object to be visited
- * more than once, this class flattens the interface graph into a pseudo-tree. In particular, this
- * class treats elements as if the element types were structured in the following way:
- *
+ * Note, however, that unlike many visitors, element visitors visit objects
+ * based on the interfaces implemented by those elements. Because interfaces
+ * form a graph structure rather than a tree structure the way classes do, and
+ * because it is generally undesirable for an object to be visited more than
+ * once, this class flattens the interface graph into a pseudo-tree. In
+ * particular, this class treats elements as if the element types were
+ * structured in the following way:
  *
  * <pre>
  * Element
  *   ClassElement
  *   CompilationUnitElement
  *   ExecutableElement
- *      ConstructorElement
- *      LocalElement
- *         FunctionElement
- *      MethodElement
- *      PropertyAccessorElement
+ *       ConstructorElement
+ *       LocalElement
+ *           FunctionElement
+ *       MethodElement
+ *       PropertyAccessorElement
  *   ExportElement
  *   HtmlElement
  *   ImportElement
@@ -5411,19 +5108,19 @@
  *   TypeParameterElement
  *   UndefinedElement
  *   VariableElement
- *      PropertyInducingElement
- *         FieldElement
- *         TopLevelVariableElement
- *      LocalElement
- *         LocalVariableElement
- *         ParameterElement
- *            FieldFormalParameterElement
+ *       PropertyInducingElement
+ *           FieldElement
+ *           TopLevelVariableElement
+ *       LocalElement
+ *           LocalVariableElement
+ *           ParameterElement
+ *               FieldFormalParameterElement
  * </pre>
  *
- * Subclasses that override a visit method must either invoke the overridden visit method or
- * explicitly invoke the more general visit method. Failure to do so will cause the visit methods
- * for superclasses of the element to not be invoked and will cause the children of the visited node
- * to not be visited.
+ * Subclasses that override a visit method must either invoke the overridden
+ * visit method or explicitly invoke the more general visit method. Failure to
+ * do so will cause the visit methods for superclasses of the element to not be
+ * invoked and will cause the children of the visited node to not be visited.
  */
 class GeneralizingElementVisitor<R> implements ElementVisitor<R> {
   @override
@@ -5533,27 +5230,24 @@
 }
 
 /**
- * The interface `HideElementCombinator` defines the behavior of combinators that cause some
- * of the names in a namespace to be hidden when being imported.
+ * A combinator that causes some of the names in a namespace to be hidden when
+ * being imported.
  */
 abstract class HideElementCombinator implements NamespaceCombinator {
   /**
-   * Return an array containing the names that are not to be made visible in the importing library
-   * even if they are defined in the imported library.
-   *
-   * @return the names from the imported library that are hidden from the importing library
+   * Return a list containing the names that are not to be made visible in the
+   * importing library even if they are defined in the imported library.
    */
   List<String> get hiddenNames;
 }
 
 /**
- * Instances of the class `HideElementCombinatorImpl` implement a
- * [HideElementCombinator].
+ * A concrete implementation of a [HideElementCombinator].
  */
 class HideElementCombinatorImpl implements HideElementCombinator {
   /**
-   * The names that are not to be made visible in the importing library even if they are defined in
-   * the imported library.
+   * The names that are not to be made visible in the importing library even if
+   * they are defined in the imported library.
    */
   List<String> hiddenNames = StringUtilities.EMPTY_ARRAY;
 
@@ -5573,21 +5267,20 @@
 }
 
 /**
- * The interface `HtmlElement` defines the behavior of elements representing an HTML file.
+ * An HTML file.
  */
 abstract class HtmlElement implements Element {
   /**
-   * Return an array containing all of the script elements contained in the HTML file. This includes
-   * scripts with libraries that are defined by the content of a script tag as well as libraries
-   * that are referenced in the {@core source} attribute of a script tag.
-   *
-   * @return the script elements in the HTML file (not `null`, contains no `null`s)
+   * Return a list containing all of the script elements contained in the HTML
+   * file. This includes scripts with libraries that are defined by the content
+   * of a script tag as well as libraries that are referenced in the `source`
+   * attribute of a script tag.
    */
   List<HtmlScriptElement> get scripts;
 }
 
 /**
- * Instances of the class `HtmlElementImpl` implement an [HtmlElement].
+ * A concrete implementation of an [HtmlElement].
  */
 class HtmlElementImpl extends ElementImpl implements HtmlElement {
   /**
@@ -5611,10 +5304,8 @@
   Source source;
 
   /**
-   * Initialize a newly created HTML element to have the given name.
-   *
-   * @param context the analysis context in which the HTML file is defined
-   * @param name the name of this element
+   * Initialize a newly created HTML element in the given [context] to have the
+   * given [name].
    */
   HtmlElementImpl(this.context, String name) : super(name, -1);
 
@@ -5631,9 +5322,7 @@
   List<HtmlScriptElement> get scripts => _scripts;
 
   /**
-   * Set the scripts contained in the HTML file to the given scripts.
-   *
-   * @param scripts the scripts
+   * Set the scripts contained in the HTML file to the given [scripts].
    */
   void set scripts(List<HtmlScriptElement> scripts) {
     if (scripts.length == 0) {
@@ -5674,36 +5363,33 @@
 }
 
 /**
- * The interface `HtmlScriptElement` defines the behavior of elements representing a script
- * tag in an HTML file.
+ * A script tag in an HTML file.
  *
- * See [EmbeddedHtmlScriptElement], and [ExternalHtmlScriptElement],
+ * See [EmbeddedHtmlScriptElement], and [ExternalHtmlScriptElement].
  */
 abstract class HtmlScriptElement implements Element {}
 
 /**
- * Instances of the class `HtmlScriptElementImpl` implement an [HtmlScriptElement].
+ * A concrete implementation of an [HtmlScriptElement].
  */
 abstract class HtmlScriptElementImpl extends ElementImpl
     implements HtmlScriptElement {
   /**
    * An empty list of HTML script elements.
    */
-  static const List<HtmlScriptElement> EMPTY_ARRAY = const <HtmlScriptElement>[
-  ];
+  static const List<HtmlScriptElement> EMPTY_ARRAY =
+      const <HtmlScriptElement>[];
 
   /**
-   * Initialize a newly created script element to have the specified tag name and offset.
-   *
-   * @param node the XML node from which this element is derived (not `null`)
+   * Initialize a newly created script element corresponding to the given
+   * [node].
    */
   HtmlScriptElementImpl(XmlTagNode node)
       : super(node.tag, node.tagToken.offset);
 }
 
 /**
- * The interface `ImportElement` defines the behavior of objects representing information
- * about a single import directive within a library.
+ * A single import directive within a library.
  */
 abstract class ImportElement implements Element, UriReferencedElement {
   /**
@@ -5712,53 +5398,44 @@
   static const List<ImportElement> EMPTY_ARRAY = const <ImportElement>[];
 
   /**
-   * Return an array containing the combinators that were specified as part of the import directive
-   * in the order in which they were specified.
-   *
-   * @return the combinators specified in the import directive
+   * Return a list containing the combinators that were specified as part of the
+   * import directive in the order in which they were specified.
    */
   List<NamespaceCombinator> get combinators;
 
   /**
-   * Return the library that is imported into this library by this import directive.
-   *
-   * @return the library that is imported into this library
+   * Return the library that is imported into this library by this import
+   * directive.
    */
   LibraryElement get importedLibrary;
 
   /**
    * Return `true` if this import is for a deferred library.
-   *
-   * @return `true` if this import is for a deferred library
    */
   bool get isDeferred;
 
   /**
-   * Return the prefix that was specified as part of the import directive, or `null` if there
-   * was no prefix specified.
-   *
-   * @return the prefix that was specified as part of the import directive
+   * Return the prefix that was specified as part of the import directive, or
+   * `null` if there was no prefix specified.
    */
   PrefixElement get prefix;
 
   /**
-   * Return the offset of the prefix of this import in the file that contains this import directive,
-   * or `-1` if this import is synthetic, does not have a prefix, or otherwise does not have
-   * an offset.
-   *
-   * @return the offset of the prefix of this import
+   * Return the offset of the prefix of this import in the file that contains
+   * this import directive, or `-1` if this import is synthetic, does not have a
+   * prefix, or otherwise does not have an offset.
    */
   int get prefixOffset;
 }
 
 /**
- * Instances of the class `ImportElementImpl` implement an [ImportElement].
+ * A concrete implementation of an [ImportElement].
  */
 class ImportElementImpl extends UriReferencedElementImpl
     implements ImportElement {
   /**
-   * The offset of the prefix of this import in the file that contains the this import directive, or
-   * `-1` if this import is synthetic.
+   * The offset of the prefix of this import in the file that contains the this
+   * import directive, or `-1` if this import is synthetic.
    */
   int prefixOffset = 0;
 
@@ -5768,28 +5445,25 @@
   LibraryElement importedLibrary;
 
   /**
-   * The combinators that were specified as part of the import directive in the order in which they
-   * were specified.
+   * The combinators that were specified as part of the import directive in the
+   * order in which they were specified.
    */
   List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_ARRAY;
 
   /**
-   * The prefix that was specified as part of the import directive, or `null` if there was no
-   * prefix specified.
+   * The prefix that was specified as part of the import directive, or `null` if
+   * there was no prefix specified.
    */
   PrefixElement prefix;
 
   /**
-   * Initialize a newly created import element.
-   *
-   * @param offset the directive offset, may be `-1` if synthetic.
+   * Initialize a newly created import element at the given [offset].
+   * The offset may be `-1` if the import is synthetic.
    */
   ImportElementImpl(int offset) : super(null, offset);
 
   /**
-   * Set whether this import is for a deferred library to correspond to the given value.
-   *
-   * @param isDeferred `true` if this import is for a deferred library
+   * Set whether this import is for a deferred library.
    */
   void set deferred(bool isDeferred) {
     setModifier(Modifier.DEFERRED, isDeferred);
@@ -5822,8 +5496,8 @@
 }
 
 /**
- * The interface `InterfaceType` defines the behavior common to objects representing the type
- * introduced by either a class or an interface, or a reference to such a type.
+ * The type introduced by either a class or an interface, or a reference to such
+ * a type.
  */
 abstract class InterfaceType implements ParameterizedType {
   /**
@@ -5832,9 +5506,8 @@
   static const List<InterfaceType> EMPTY_ARRAY = const <InterfaceType>[];
 
   /**
-   * Return an array containing all of the accessors (getters and setters) declared in this type.
-   *
-   * @return the accessors declared in this type
+   * Return a list containing all of the accessors (getters and setters)
+   * declared in this type.
    */
   List<PropertyAccessorElement> get accessors;
 
@@ -5842,273 +5515,240 @@
   ClassElement get element;
 
   /**
-   * Return an array containing all of the interfaces that are implemented by this interface. Note
-   * that this is <b>not</b>, in general, equivalent to getting the interfaces from this type's
-   * element because the types returned by this method will have had their type parameters replaced.
-   *
-   * @return the interfaces that are implemented by this type
+   * Return a list containing all of the interfaces that are implemented by this
+   * interface. Note that this is <b>not</b>, in general, equivalent to getting
+   * the interfaces from this type's element because the types returned by this
+   * method will have had their type parameters replaced.
    */
   List<InterfaceType> get interfaces;
 
   /**
-   * Return an array containing all of the methods declared in this type.
-   *
-   * @return the methods declared in this type
+   * Return a list containing all of the methods declared in this type.
    */
   List<MethodElement> get methods;
 
   /**
-   * Return an array containing all of the mixins that are applied to the class being extended in
-   * order to derive the superclass of this class. Note that this is <b>not</b>, in general,
-   * equivalent to getting the mixins from this type's element because the types returned by this
-   * method will have had their type parameters replaced.
-   *
-   * @return the mixins that are applied to derive the superclass of this class
+   * Return a list containing all of the mixins that are applied to the class
+   * being extended in order to derive the superclass of this class. Note that
+   * this is <b>not</b>, in general, equivalent to getting the mixins from this
+   * type's element because the types returned by this method will have had
+   * their type parameters replaced.
    */
   List<InterfaceType> get mixins;
 
   /**
-   * Return the type representing the superclass of this type, or null if this type represents the
-   * class 'Object'. Note that this is <b>not</b>, in general, equivalent to getting the superclass
-   * from this type's element because the type returned by this method will have had it's type
-   * parameters replaced.
-   *
-   * @return the superclass of this type
+   * Return the type representing the superclass of this type, or null if this
+   * type represents the class 'Object'. Note that this is <b>not</b>, in
+   * general, equivalent to getting the superclass from this type's element
+   * because the type returned by this method will have had it's type parameters
+   * replaced.
    */
   InterfaceType get superclass;
 
   /**
-   * Return the element representing the getter with the given name that is declared in this class,
-   * or `null` if this class does not declare a getter with the given name.
-   *
-   * @param getterName the name of the getter to be returned
-   * @return the getter declared in this class with the given name
+   * Return the element representing the getter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a getter
+   * with the given name.
    */
-  PropertyAccessorElement getGetter(String getterName);
+  PropertyAccessorElement getGetter(String name);
 
   /**
-   * Return the least upper bound of this type and the given type, or `null` if there is no
-   * least upper bound.
+   * Return the least upper bound of this type and the given [type], or `null`
+   * if there is no least upper bound.
    *
-   * Given two interfaces <i>I</i> and <i>J</i>, let <i>S<sub>I</sub></i> be the set of
-   * superinterfaces of <i>I<i>, let <i>S<sub>J</sub></i> be the set of superinterfaces of <i>J</i>
-   * and let <i>S = (I &cup; S<sub>I</sub>) &cap; (J &cup; S<sub>J</sub>)</i>. Furthermore, we
-   * define <i>S<sub>n</sub> = {T | T &isin; S &and; depth(T) = n}</i> for any finite <i>n</i>,
-   * where <i>depth(T)</i> is the number of steps in the longest inheritance path from <i>T</i> to
-   * <i>Object</i>. Let <i>q</i> be the largest number such that <i>S<sub>q</sub></i> has
-   * cardinality one. The least upper bound of <i>I</i> and <i>J</i> is the sole element of
-   * <i>S<sub>q</sub></i>.
-   *
-   * @param type the other type used to compute the least upper bound
-   * @return the least upper bound of this type and the given type
+   * Given two interfaces <i>I</i> and <i>J</i>, let <i>S<sub>I</sub></i> be the
+   * set of superinterfaces of <i>I<i>, let <i>S<sub>J</sub></i> be the set of
+   * superinterfaces of <i>J</i> and let <i>S = (I &cup; S<sub>I</sub>) &cap;
+   * (J &cup; S<sub>J</sub>)</i>. Furthermore, we define <i>S<sub>n</sub> =
+   * {T | T &isin; S &and; depth(T) = n}</i> for any finite <i>n</i>, where
+   * <i>depth(T)</i> is the number of steps in the longest inheritance path from
+   * <i>T</i> to <i>Object</i>. Let <i>q</i> be the largest number such that
+   * <i>S<sub>q</sub></i> has cardinality one. The least upper bound of <i>I</i>
+   * and <i>J</i> is the sole element of <i>S<sub>q</sub></i>.
    */
   @override
   DartType getLeastUpperBound(DartType type);
 
   /**
-   * Return the element representing the method with the given name that is declared in this class,
-   * or `null` if this class does not declare a method with the given name.
-   *
-   * @param methodName the name of the method to be returned
-   * @return the method declared in this class with the given name
+   * Return the element representing the method with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a method
+   * with the given name.
    */
-  MethodElement getMethod(String methodName);
+  MethodElement getMethod(String name);
 
   /**
-   * Return the element representing the setter with the given name that is declared in this class,
-   * or `null` if this class does not declare a setter with the given name.
-   *
-   * @param setterName the name of the setter to be returned
-   * @return the setter declared in this class with the given name
+   * Return the element representing the setter with the given [name] that is
+   * declared in this class, or `null` if this class does not declare a setter
+   * with the given name.
    */
-  PropertyAccessorElement getSetter(String setterName);
+  PropertyAccessorElement getSetter(String name);
 
   /**
-   * Return `true` if this type is a direct supertype of the given type. The implicit
-   * interface of class <i>I</i> is a direct supertype of the implicit interface of class <i>J</i>
-   * iff:
+   * Return `true` if this type is a direct supertype of the given [type]. The
+   * implicit interface of class <i>I</i> is a direct supertype of the implicit
+   * interface of class <i>J</i> iff:
+   *
    * * <i>I</i> is Object, and <i>J</i> has no extends clause.
    * * <i>I</i> is listed in the extends clause of <i>J</i>.
    * * <i>I</i> is listed in the implements clause of <i>J</i>.
    * * <i>I</i> is listed in the with clause of <i>J</i>.
    * * <i>J</i> is a mixin application of the mixin of <i>I</i>.
-   *
-   * @param type the type being compared with this type
-   * @return `true` if this type is a direct supertype of the given type
    */
   bool isDirectSupertypeOf(InterfaceType type);
 
   /**
-   * Return `true` if this type is more specific than the given type. An interface type
-   * <i>T</i> is more specific than an interface type <i>S</i>, written <i>T &laquo; S</i>, if one
-   * of the following conditions is met:
+   * Return `true` if this type is more specific than the given [type]. An
+   * interface type <i>T</i> is more specific than an interface type <i>S</i>,
+   * written <i>T &laquo; S</i>, if one of the following conditions is met:
+   *
    * * Reflexivity: <i>T</i> is <i>S</i>.
    * * <i>T</i> is bottom.
    * * <i>S</i> is dynamic.
    * * Direct supertype: <i>S</i> is a direct supertype of <i>T</i>.
    * * <i>T</i> is a type parameter and <i>S</i> is the upper bound of <i>T</i>.
-   * * Covariance: <i>T</i> is of the form <i>I&lt;T<sub>1</sub>, &hellip;, T<sub>n</sub>&gt;</i>
-   * and S</i> is of the form <i>I&lt;S<sub>1</sub>, &hellip;, S<sub>n</sub>&gt;</i> and
-   * <i>T<sub>i</sub> &laquo; S<sub>i</sub></i>, <i>1 <= i <= n</i>.
+   * * Covariance: <i>T</i> is of the form <i>I&lt;T<sub>1</sub>, &hellip;,
+   *   T<sub>n</sub>&gt;</i> and S</i> is of the form <i>I&lt;S<sub>1</sub>,
+   *   &hellip;, S<sub>n</sub>&gt;</i> and <i>T<sub>i</sub> &laquo;
+   *   S<sub>i</sub></i>, <i>1 <= i <= n</i>.
    * * Transitivity: <i>T &laquo; U</i> and <i>U &laquo; S</i>.
-   *
-   * @param type the type being compared with this type
-   * @return `true` if this type is more specific than the given type
    */
   @override
   bool isMoreSpecificThan(DartType type);
 
   /**
-   * Return `true` if this type is a subtype of the given type. An interface type <i>T</i> is
-   * a subtype of an interface type <i>S</i>, written <i>T</i> <: <i>S</i>, iff
-   * <i>[bottom/dynamic]T</i> &laquo; <i>S</i> (<i>T</i> is more specific than <i>S</i>). If an
-   * interface type <i>I</i> includes a method named <i>call()</i>, and the type of <i>call()</i> is
-   * the function type <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
-   *
-   * @param type the type being compared with this type
-   * @return `true` if this type is a subtype of the given type
+   * Return `true` if this type is a subtype of the given [type]. An interface
+   * type <i>T</i> is a subtype of an interface type <i>S</i>, written <i>T</i>
+   * <: <i>S</i>, iff <i>[bottom/dynamic]T</i> &laquo; <i>S</i> (<i>T</i> is
+   * more specific than <i>S</i>). If an interface type <i>I</i> includes a
+   * method named <i>call()</i>, and the type of <i>call()</i> is the function
+   * type <i>F</i>, then <i>I</i> is considered to be a subtype of <i>F</i>.
    */
   @override
   bool isSubtypeOf(DartType type);
 
   /**
-   * Return the element representing the constructor that results from looking up the given
-   * constructor in this class with respect to the given library, or `null` if the look up
-   * fails. The behavior of this method is defined by the Dart Language Specification in section
-   * 12.11.1: <blockquote>If <i>e</i> is of the form <b>new</b> <i>T.id()</i> then let <i>q<i> be
-   * the constructor <i>T.id</i>, otherwise let <i>q<i> be the constructor <i>T<i>. Otherwise, if
-   * <i>q</i> is not defined or not accessible, a NoSuchMethodException is thrown. </blockquote>
-   *
-   * @param constructorName the name of the constructor being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given constructor in this class with respect to the given
-   *         library
-   */
-  ConstructorElement lookUpConstructor(
-      String constructorName, LibraryElement library);
-
-  /**
-   * Return the element representing the getter that results from looking up the given getter in
-   * this class with respect to the given library, or `null` if the look up fails. The
-   * behavior of this method is defined by the Dart Language Specification in section 12.15.1:
-   * <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
-   * with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
-   * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
-   * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
-   * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.
+   * Return the element representing the constructor that results from looking
+   * up the constructor with the given [name] in this class with respect to the
+   * given [library], or `null` if the look up fails. The behavior of this
+   * method is defined by the Dart Language Specification in section 12.11.1:
+   * <blockquote>
+   * If <i>e</i> is of the form <b>new</b> <i>T.id()</i> then let <i>q<i> be the
+   * constructor <i>T.id</i>, otherwise let <i>q<i> be the constructor <i>T<i>.
+   * Otherwise, if <i>q</i> is not defined or not accessible, a
+   * NoSuchMethodException is thrown.
    * </blockquote>
-   *
-   * @param getterName the name of the getter being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given getter in this class with respect to the given
-   *         library
    */
-  PropertyAccessorElement lookUpGetter(
-      String getterName, LibraryElement library);
+  ConstructorElement lookUpConstructor(String name, LibraryElement library);
 
   /**
-   * Return the element representing the getter that results from looking up the given getter in the
-   * superclass of this class with respect to the given library, or `null` if the look up
-   * fails. The behavior of this method is defined by the Dart Language Specification in section
-   * 12.15.1: <blockquote>The result of looking up getter (respectively setter) <i>m</i> in class
+   * Return the element representing the getter that results from looking up the
+   * getter with the given [name] in this class with respect to the given
+   * [library], or `null` if the look up fails. The behavior of this method is
+   * defined by the Dart Language Specification in section 12.15.1:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
    * <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
-   * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
-   * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
-   * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
    * </blockquote>
-   *
-   * @param getterName the name of the getter being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given getter in this class with respect to the given
-   *         library
+   */
+  PropertyAccessorElement lookUpGetter(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the getter that results from looking up the
+   * getter with the given [name] in the superclass of this class with respect
+   * to the given [library], or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section
+   * 12.15.1:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
    */
   PropertyAccessorElement lookUpGetterInSuperclass(
-      String getterName, LibraryElement library);
+      String name, LibraryElement library);
 
   /**
-   * Return the element representing the method that results from looking up the given method in
-   * this class with respect to the given library, or `null` if the look up fails. The
-   * behavior of this method is defined by the Dart Language Specification in section 12.15.1:
-   * <blockquote> The result of looking up method <i>m</i> in class <i>C</i> with respect to library
-   * <i>L</i> is:
-   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
-   * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then
-   * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect
-   * to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * Return the element representing the method that results from looking up the
+   * method with the given [name] in this class with respect to the given
+   * [library], or `null` if the look up fails. The behavior of this method is
+   * defined by the Dart Language Specification in section 12.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:
+   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible
+   *   to <i>L</i>, then that method is the result of the lookup. Otherwise, if
+   *   <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the
+   *   result of looking up method <i>m</i> in <i>S</i> with respect to <i>L</i>
+   *   Otherwise, we say that the lookup has failed.
    * </blockquote>
-   *
-   * @param methodName the name of the method being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given method in this class with respect to the given
-   *         library
    */
-  MethodElement lookUpMethod(String methodName, LibraryElement library);
+  MethodElement lookUpMethod(String name, LibraryElement library);
 
   /**
-   * Return the element representing the method that results from looking up the given method in the
-   * superclass of this class with respect to the given library, or `null` if the look up
-   * fails. The behavior of this method is defined by the Dart Language Specification in section
-   * 12.15.1: <blockquote> The result of looking up method <i>m</i> in class <i>C</i> with respect
-   * to library <i>L</i> is:
-   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible to <i>L</i>, then
-   * that method is the result of the lookup. Otherwise, if <i>C</i> has a superclass <i>S</i>, then
-   * the result of the lookup is the result of looking up method <i>m</i> in <i>S</i> with respect
-   * to <i>L</i>. Otherwise, we say that the lookup has failed.
-   * </blockquote>
-   *
-   * @param methodName the name of the method being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given method in this class with respect to the given
-   *         library
-   */
-  MethodElement lookUpMethodInSuperclass(
-      String methodName, LibraryElement library);
-
-  /**
-   * Return the element representing the setter that results from looking up the given setter in
-   * this class with respect to the given library, or `null` if the look up fails. The
-   * behavior of this method is defined by the Dart Language Specification in section 12.16:
-   * <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class <i>C</i>
-   * with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
-   * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
-   * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
-   * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
+   * Return the element representing the method that results from looking up the
+   * method with the given [name] in the superclass of this class with respect
+   * to the given [library], or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section
+   * 12.15.1:
+   * <blockquote>
+   * The result of looking up method <i>m</i> in class <i>C</i> with respect to
+   * library <i>L</i> is:
+   * * If <i>C</i> declares an instance method named <i>m</i> that is accessible
+   *   to <i>L</i>, then that method is the result of the lookup. Otherwise, if
+   * <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the
+   * result of looking up method <i>m</i> in <i>S</i> with respect to <i>L</i>.
    * Otherwise, we say that the lookup has failed.
    * </blockquote>
-   *
-   * @param setterName the name of the setter being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given setter in this class with respect to the given
-   *         library
    */
-  PropertyAccessorElement lookUpSetter(
-      String setterName, LibraryElement library);
+  MethodElement lookUpMethodInSuperclass(String name, LibraryElement library);
 
   /**
-   * Return the element representing the setter that results from looking up the given setter in the
-   * superclass of this class with respect to the given library, or `null` if the look up
-   * fails. The behavior of this method is defined by the Dart Language Specification in section
-   * 12.16: <blockquote> The result of looking up getter (respectively setter) <i>m</i> in class
+   * Return the element representing the setter that results from looking up the
+   * setter with the given [name] in this class with respect to the given
+   * [library], or `null` if the look up fails. The behavior of this method is
+   * defined by the Dart Language Specification in section 12.16:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
    * <i>C</i> with respect to library <i>L</i> is:
-   * * If <i>C</i> declares an instance getter (respectively setter) named <i>m</i> that is
-   * accessible to <i>L</i>, then that getter (respectively setter) is the result of the lookup.
-   * Otherwise, if <i>C</i> has a superclass <i>S</i>, then the result of the lookup is the result
-   * of looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect to <i>L</i>.
-   * Otherwise, we say that the lookup has failed.
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
    * </blockquote>
-   *
-   * @param setterName the name of the setter being looked up
-   * @param library the library with respect to which the lookup is being performed
-   * @return the result of looking up the given setter in this class with respect to the given
-   *         library
+   */
+  PropertyAccessorElement lookUpSetter(String name, LibraryElement library);
+
+  /**
+   * Return the element representing the setter that results from looking up the
+   * setter with the given [name] in the superclass of this class with respect
+   * to the given [library], or `null` if the look up fails. The behavior of
+   * this method is defined by the Dart Language Specification in section 12.16:
+   * <blockquote>
+   * The result of looking up getter (respectively setter) <i>m</i> in class
+   * <i>C</i> with respect to library <i>L</i> is:
+   * * If <i>C</i> declares an instance getter (respectively setter) named
+   *   <i>m</i> that is accessible to <i>L</i>, then that getter (respectively
+   *   setter) is the result of the lookup. Otherwise, if <i>C</i> has a
+   *   superclass <i>S</i>, then the result of the lookup is the result of
+   *   looking up getter (respectively setter) <i>m</i> in <i>S</i> with respect
+   *   to <i>L</i>. Otherwise, we say that the lookup has failed.
+   * </blockquote>
    */
   PropertyAccessorElement lookUpSetterInSuperclass(
-      String setterName, LibraryElement library);
+      String name, LibraryElement library);
 
   @override
   InterfaceType substitute2(
@@ -6184,29 +5824,23 @@
 }
 
 /**
- * Instances of the class `InterfaceTypeImpl` defines the behavior common to objects
- * representing the type introduced by either a class or an interface, or a reference to such a
- * type.
+ * A concrete implementation of an [InterfaceType].
  */
 class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
   /**
-   * An array containing the actual types of the type arguments.
+   * A list containing the actual types of the type arguments.
    */
   List<DartType> typeArguments = TypeImpl.EMPTY_ARRAY;
 
   /**
-   * Initialize a newly created type to be declared by the given element.
-   *
-   * @param element the element representing the declaration of the type
+   * Initialize a newly created type to be declared by the given [element].
    */
   InterfaceTypeImpl.con1(ClassElement element)
       : super(element, element.displayName);
 
   /**
-   * Initialize a newly created type to have the given name. This constructor should only be used in
-   * cases where there is no declaration of the type.
-   *
-   * @param name the name of the type
+   * Initialize a newly created type to have the given [name]. This constructor
+   * should only be used in cases where there is no declaration of the type.
    */
   InterfaceTypeImpl.con2(String name) : super(null, name);
 
@@ -6769,6 +6403,15 @@
   InterfaceTypeImpl substitute4(List<DartType> argumentTypes) =>
       substitute2(argumentTypes, typeArguments);
 
+  /**
+   * Return `true` if the given element has an instance method named 'call'.
+   */
+  bool _hasCallMethod(ClassElement elementT) {
+    MethodElement method = elementT.lookUpMethod(
+        FunctionElement.CALL_METHOD_NAME, elementT.library);
+    return method != null && !method.isStatic;
+  }
+
   bool _isMoreSpecificThan(InterfaceType s,
       HashSet<ClassElement> visitedClasses, bool withDynamic,
       Set<TypeImpl_TypePair> visitedTypePairs) {
@@ -6872,7 +6515,7 @@
         }
       }
       return true;
-    } else if (typeS.isDartCoreFunction && elementT.getMethod("call") != null) {
+    } else if (typeS.isDartCoreFunction && _hasCallMethod(elementT)) {
       return true;
     }
     InterfaceType supertype = superclass;
@@ -6900,11 +6543,9 @@
   }
 
   /**
-   * This method computes the longest inheritance path from some passed [Type] to Object.
+   * Return the length of the longest inheritance path from the given [type] to
+   * Object.
    *
-   * @param type the [Type] to compute the longest inheritance path of from the passed
-   *          [Type] to Object
-   * @return the computed longest inheritance path to Object
    * See [InterfaceType.getLeastUpperBound].
    */
   static int computeLongestInheritancePathToObject(InterfaceType type) =>
@@ -6912,38 +6553,31 @@
           type, 0, new HashSet<ClassElement>());
 
   /**
-   * Returns the set of all superinterfaces of the passed [Type].
+   * Returns the set of all superinterfaces of the given [type].
    *
-   * @param type the [Type] to compute the set of superinterfaces of
-   * @return the [Set] of superinterfaces of the passed [Type]
    * See [getLeastUpperBound].
    */
   static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type) =>
       _computeSuperinterfaceSet(type, new HashSet<InterfaceType>());
 
   /**
-   * This method computes the longest inheritance path from some passed [Type] to Object. This
-   * method calls itself recursively, callers should use the public method
-   * [computeLongestInheritancePathToObject].
+   * Return the length of the longest inheritance path from a subtype of the
+   * given [type] to Object, where the given [depth] is the length of the
+   * longest path from the subtype to this type. The set of [visitedTypes] is
+   * used to prevent infinite recursion in the case of a cyclic type structure.
    *
-   * @param type the [Type] to compute the longest inheritance path of from the passed
-   *          [Type] to Object
-   * @param depth a field used recursively
-   * @param visitedClasses the classes that have already been visited
-   * @return the computed longest inheritance path to Object
    * See [computeLongestInheritancePathToObject], and [getLeastUpperBound].
    */
   static int _computeLongestInheritancePathToObject(
-      InterfaceType type, int depth, HashSet<ClassElement> visitedClasses) {
+      InterfaceType type, int depth, HashSet<ClassElement> visitedTypes) {
     ClassElement classElement = type.element;
     // Object case
-    if (classElement.supertype == null ||
-        visitedClasses.contains(classElement)) {
+    if (classElement.supertype == null || visitedTypes.contains(classElement)) {
       return depth;
     }
     int longestPath = 1;
     try {
-      visitedClasses.add(classElement);
+      visitedTypes.add(classElement);
       List<InterfaceType> superinterfaces = classElement.interfaces;
       int pathLength;
       if (superinterfaces.length > 0) {
@@ -6951,7 +6585,7 @@
         // method and keeping track of the longest path to return
         for (InterfaceType superinterface in superinterfaces) {
           pathLength = _computeLongestInheritancePathToObject(
-              superinterface, depth + 1, visitedClasses);
+              superinterface, depth + 1, visitedTypes);
           if (pathLength > longestPath) {
             longestPath = pathLength;
           }
@@ -6962,23 +6596,20 @@
       // classes?
       InterfaceType supertype = classElement.supertype;
       pathLength = _computeLongestInheritancePathToObject(
-          supertype, depth + 1, visitedClasses);
+          supertype, depth + 1, visitedTypes);
       if (pathLength > longestPath) {
         longestPath = pathLength;
       }
     } finally {
-      visitedClasses.remove(classElement);
+      visitedTypes.remove(classElement);
     }
     return longestPath;
   }
 
   /**
-   * Returns the set of all superinterfaces of the passed [Type]. This is a recursive method,
-   * callers should call the public [computeSuperinterfaceSet].
+   * Add all of the superinterfaces of the given [type] to the given [set].
+   * Return the [set] as a convenience.
    *
-   * @param type the [Type] to compute the set of superinterfaces of
-   * @param set a [HashSet] used recursively by this method
-   * @return the [Set] of superinterfaces of the passed [Type]
    * See [computeSuperinterfaceSet], and [getLeastUpperBound].
    */
   static Set<InterfaceType> _computeSuperinterfaceSet(
@@ -7002,12 +6633,8 @@
   }
 
   /**
-   * Return the intersection of the given sets of types, where intersection is based on the equality
-   * of the types themselves.
-   *
-   * @param first the first set of types to be intersected
-   * @param second the second set of types to be intersected
-   * @return the intersection of the given sets of types
+   * Return the intersection of the [first] and [second] sets of types, where
+   * intersection is based on the equality of the types themselves.
    */
   static List<InterfaceType> _intersection(
       Set<InterfaceType> first, Set<InterfaceType> second) {
@@ -7018,21 +6645,18 @@
 }
 
 /**
- * The interface `LabelElement` defines the behavior of elements representing a label
- * associated with a statement.
+ * A label associated with a statement.
  */
 abstract class LabelElement implements Element {
   /**
    * Return the executable element in which this label is defined.
-   *
-   * @return the executable element in which this label is defined
    */
   @override
   ExecutableElement get enclosingElement;
 }
 
 /**
- * Instances of the class `LabelElementImpl` implement a `LabelElement`.
+ * A concrete implementation of a [LabelElement].
  */
 class LabelElementImpl extends ElementImpl implements LabelElement {
   /**
@@ -7041,23 +6665,24 @@
   static const List<LabelElement> EMPTY_ARRAY = const <LabelElement>[];
 
   /**
-   * A flag indicating whether this label is associated with a `switch` statement.
+   * A flag indicating whether this label is associated with a `switch`
+   * statement.
    */
+  // TODO(brianwilkerson) Make this a modifier.
   final bool _onSwitchStatement;
 
   /**
-   * A flag indicating whether this label is associated with a `switch` member (`case`
-   * or `default`).
+   * A flag indicating whether this label is associated with a `switch` member
+   * (`case` or `default`).
    */
+  // TODO(brianwilkerson) Make this a modifier.
   final bool _onSwitchMember;
 
   /**
-   * Initialize a newly created label element to have the given name.
-   *
-   * @param name the name of this element
-   * @param onSwitchStatement `true` if this label is associated with a `switch`
-   *          statement
-   * @param onSwitchMember `true` if this label is associated with a `switch` member
+   * Initialize a newly created label element to have the given [name].
+   * [onSwitchStatement] should be `true` if this label is associated with a
+   * `switch` statement and [onSwitchMember] should be `true` if this label is
+   * associated with a `switch` member.
    */
   LabelElementImpl(
       Identifier name, this._onSwitchStatement, this._onSwitchMember)
@@ -7070,15 +6695,11 @@
   /**
    * Return `true` if this label is associated with a `switch` member (`case` or
    * `default`).
-   *
-   * @return `true` if this label is associated with a `switch` member
    */
   bool get isOnSwitchMember => _onSwitchMember;
 
   /**
    * Return `true` if this label is associated with a `switch` statement.
-   *
-   * @return `true` if this label is associated with a `switch` statement
    */
   bool get isOnSwitchStatement => _onSwitchStatement;
 
@@ -7090,156 +6711,140 @@
 }
 
 /**
- * The interface `LibraryElement` defines the behavior of elements representing a library.
+ * A library.
  */
 abstract class LibraryElement implements Element {
   /**
    * Return the compilation unit that defines this library.
-   *
-   * @return the compilation unit that defines this library
    */
   CompilationUnitElement get definingCompilationUnit;
 
   /**
-   * Return the entry point for this library, or `null` if this library does not have an entry
-   * point. The entry point is defined to be a zero argument top-level function whose name is
-   * `main`.
-   *
-   * @return the entry point for this library
+   * Return the entry point for this library, or `null` if this library does not
+   * have an entry point. The entry point is defined to be a zero argument
+   * top-level function whose name is `main`.
    */
   FunctionElement get entryPoint;
 
   /**
-   * Return an array containing all of the libraries that are exported from this library.
-   *
-   * @return an array containing all of the libraries that are exported from this library
+   * Return a list containing all of the libraries that are exported from this
+   * library.
    */
   List<LibraryElement> get exportedLibraries;
 
   /**
-   * Return an array containing all of the exports defined in this library.
-   *
-   * @return the exports defined in this library
+   * The export [Namespace] of this library, `null` if it has not been
+   * computed yet.
+   */
+  Namespace get exportNamespace;
+
+  /**
+   * Return a list containing all of the exports defined in this library.
    */
   List<ExportElement> get exports;
 
   /**
-   * Return `true` if the defining compilation unit of this library contains at least one
-   * import directive whose URI uses the "dart-ext" scheme.
+   * Return `true` if the defining compilation unit of this library contains at
+   * least one import directive whose URI uses the "dart-ext" scheme.
    */
   bool get hasExtUri;
 
   /**
-   * Return `true` if this library defines a top-level function named `loadLibrary`.
-   *
-   * @return `true` if this library defines a top-level function named `loadLibrary`
+   * Return `true` if this library defines a top-level function named
+   * `loadLibrary`.
    */
   bool get hasLoadLibraryFunction;
 
   /**
-   * Return an array containing all of the libraries that are imported into this library. This
-   * includes all of the libraries that are imported using a prefix (also available through the
-   * prefixes returned by [getPrefixes]) and those that are imported without a prefix.
-   *
-   * @return an array containing all of the libraries that are imported into this library
+   * Return a list containing all of the libraries that are imported into this
+   * library. This includes all of the libraries that are imported using a
+   * prefix (also available through the prefixes returned by [getPrefixes]) and
+   * those that are imported without a prefix.
    */
   List<LibraryElement> get importedLibraries;
 
   /**
-   * Return an array containing all of the imports defined in this library.
-   *
-   * @return the imports defined in this library
+   * Return a list containing all of the imports defined in this library.
    */
   List<ImportElement> get imports;
 
   /**
-   * Return `true` if this library is an application that can be run in the browser.
-   *
-   * @return `true` if this library is an application that can be run in the browser
+   * Return `true` if this library is an application that can be run in the
+   * browser.
    */
   bool get isBrowserApplication;
 
   /**
    * Return `true` if this library is the dart:core library.
-   *
-   * @return `true` if this library is the dart:core library
    */
   bool get isDartCore;
 
   /**
    * Return `true` if this library is the dart:core library.
-   *
-   * @return `true` if this library is the dart:core library
    */
   bool get isInSdk;
 
   /**
-   * Return the element representing the synthetic function `loadLibrary` that is implicitly
-   * defined for this library if the library is imported using a deferred import.
+   * Return the element representing the synthetic function `loadLibrary` that
+   * is implicitly defined for this library if the library is imported using a
+   * deferred import.
    */
   FunctionElement get loadLibraryFunction;
 
   /**
-   * Return an array containing all of the compilation units that are included in this library using
-   * a `part` directive. This does not include the defining compilation unit that contains the
-   * `part` directives.
-   *
-   * @return the compilation units that are included in this library
+   * Return a list containing all of the compilation units that are included in
+   * this library using a `part` directive. This does not include the defining
+   * compilation unit that contains the `part` directives.
    */
   List<CompilationUnitElement> get parts;
 
   /**
-   * Return an array containing elements for each of the prefixes used to `import` libraries
-   * into this library. Each prefix can be used in more than one `import` directive.
-   *
-   * @return the prefixes used to `import` libraries into this library
+   * Return a list containing elements for each of the prefixes used to `import`
+   * libraries into this library. Each prefix can be used in more than one
+   * `import` directive.
    */
   List<PrefixElement> get prefixes;
 
   /**
-   * Return an array containing all of the compilation units this library consists of. This includes
-   * the defining compilation unit and units included using the `part` directive.
-   *
-   * @return the compilation units this library consists of
+   * The public [Namespace] of this library, `null` if it has not been
+   * computed yet.
+   */
+  Namespace get publicNamespace;
+
+  /**
+   * Return a list containing all of the compilation units this library consists
+   * of. This includes the defining compilation unit and units included using
+   * the `part` directive.
    */
   List<CompilationUnitElement> get units;
 
   /**
-   * Return an array containing all directly and indirectly imported libraries.
-   *
-   * @return all directly and indirectly imported libraries
+   * Return a list containing all directly and indirectly imported libraries.
    */
   List<LibraryElement> get visibleLibraries;
 
   /**
-   * Return an array containing all of the imports that share the given prefix, or an empty array if
-   * there are no such imports.
-   *
-   * @param prefixElement the prefix element shared by the returned imports
+   * Return a list containing all of the imports that share the given [prefix],
+   * or an empty array if there are no such imports.
    */
-  List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement);
+  List<ImportElement> getImportsWithPrefix(PrefixElement prefix);
 
   /**
-   * Return the class defined in this library that has the given name, or `null` if this
-   * library does not define a class with the given name.
-   *
-   * @param className the name of the class to be returned
-   * @return the class with the given name that is defined in this library
+   * Return the class defined in this library that has the given [name], or
+   * `null` if this library does not define a class with the given name.
    */
   ClassElement getType(String className);
 
   /**
-   * Return `true` if this library is up to date with respect to the given time stamp. If any
-   * transitively referenced Source is newer than the time stamp, this method returns false.
-   *
-   * @param timeStamp the time stamp to compare against
-   * @return `true` if this library is up to date with respect to the given time stamp
+   * Return `true` if this library is up to date with respect to the given
+   * [timeStamp]. If any transitively referenced Source is newer than the time
+   * stamp, this method returns false.
    */
   bool isUpToDate(int timeStamp);
 }
 
 /**
- * Instances of the class `LibraryElementImpl` implement a `LibraryElement`.
+ * A concrete implementation of a [LibraryElement].
  */
 class LibraryElementImpl extends ElementImpl implements LibraryElement {
   /**
@@ -7258,48 +6863,59 @@
   CompilationUnitElement _definingCompilationUnit;
 
   /**
-   * The entry point for this library, or `null` if this library does not have an entry point.
+   * The entry point for this library, or `null` if this library does not have
+   * an entry point.
    */
   FunctionElement entryPoint;
 
   /**
-   * An array containing specifications of all of the imports defined in this library.
+   * A list containing specifications of all of the imports defined in this
+   * library.
    */
   List<ImportElement> _imports = ImportElement.EMPTY_ARRAY;
 
   /**
-   * An array containing specifications of all of the exports defined in this library.
+   * A list containing specifications of all of the exports defined in this
+   * library.
    */
   List<ExportElement> _exports = ExportElement.EMPTY_ARRAY;
 
   /**
-   * An array containing all of the compilation units that are included in this library using a
-   * `part` directive.
+   * A list containing all of the compilation units that are included in this
+   * library using a `part` directive.
    */
   List<CompilationUnitElement> _parts = CompilationUnitElementImpl.EMPTY_ARRAY;
 
   /**
-   * The element representing the synthetic function `loadLibrary` that is defined for this
-   * library, or `null` if the element has not yet been created.
+   * The element representing the synthetic function `loadLibrary` that is
+   * defined for this library, or `null` if the element has not yet been created.
    */
   FunctionElement _loadLibraryFunction;
 
   /**
-   * Initialize a newly created library element to have the given name.
-   *
-   * @param context the analysis context in which the library is defined
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * The export [Namespace] of this library, `null` if it has not been
+   * computed yet.
    */
-  LibraryElementImpl(this.context, String name, int nameOffset)
-      : super(name, nameOffset);
+  @override
+  Namespace exportNamespace;
 
   /**
-   * Initialize a newly created library element to have the given name.
-   *
-   * @param context the analysis context in which the library is defined
-   * @param name the name of this element
+   * The public [Namespace] of this library, `null` if it has not been
+   * computed yet.
+   */
+  @override
+  Namespace publicNamespace;
+
+  /**
+   * Initialize a newly created library element in the given [context] to have
+   * the given [name] and [offset].
+   */
+  LibraryElementImpl(this.context, String name, int offset)
+      : super(name, offset);
+
+  /**
+   * Initialize a newly created library element in the given [context] to have
+   * the given [name].
    */
   LibraryElementImpl.forNode(this.context, LibraryIdentifier name)
       : super.forNode(name);
@@ -7309,15 +6925,12 @@
       _definingCompilationUnit;
 
   /**
-   * Set the compilation unit that defines this library to the given compilation unit.
-   *
-   * @param definingCompilationUnit the compilation unit that defines this library
+   * Set the compilation unit that defines this library to the given compilation
+   * [unit].
    */
-  void set definingCompilationUnit(
-      CompilationUnitElement definingCompilationUnit) {
-    (definingCompilationUnit as CompilationUnitElementImpl).enclosingElement =
-        this;
-    this._definingCompilationUnit = definingCompilationUnit;
+  void set definingCompilationUnit(CompilationUnitElement unit) {
+    (unit as CompilationUnitElementImpl).enclosingElement = this;
+    this._definingCompilationUnit = unit;
   }
 
   @override
@@ -7336,9 +6949,8 @@
   List<ExportElement> get exports => _exports;
 
   /**
-   * Set the specifications of all of the exports defined in this library to the given array.
-   *
-   * @param exports the specifications of all of the exports defined in this library
+   * Set the specifications of all of the exports defined in this library to the
+   * given list of [exports].
    */
   void set exports(List<ExportElement> exports) {
     for (ExportElement exportElement in exports) {
@@ -7351,9 +6963,7 @@
   bool get hasExtUri => hasModifier(Modifier.HAS_EXT_URI);
 
   /**
-   * Set whether this library has an import of a "dart-ext" URI to the given value.
-   *
-   * @param hasExtUri `true` if this library has an import of a "dart-ext" URI
+   * Set whether this library has an import of a "dart-ext" URI.
    */
   void set hasExtUri(bool hasExtUri) {
     setModifier(Modifier.HAS_EXT_URI, hasExtUri);
@@ -7394,9 +7004,8 @@
   List<ImportElement> get imports => _imports;
 
   /**
-   * Set the specifications of all of the imports defined in this library to the given array.
-   *
-   * @param imports the specifications of all of the imports defined in this library
+   * Set the specifications of all of the imports defined in this library to the
+   * given list of [imports].
    */
   void set imports(List<ImportElement> imports) {
     for (ImportElement importElement in imports) {
@@ -7421,9 +7030,8 @@
       StringUtilities.startsWith5(name, 0, 0x64, 0x61, 0x72, 0x74, 0x2E);
 
   /**
-   * Answer `true` if the receiver directly or indirectly imports the dart:html libraries.
-   *
-   * @return `true` if the receiver directly or indirectly imports the dart:html libraries
+   * Return `true` if the receiver directly or indirectly imports the
+   * 'dart:html' libraries.
    */
   bool get isOrImportsBrowserLibrary {
     List<LibraryElement> visited = new List<LibraryElement>();
@@ -7470,10 +7078,8 @@
   }
 
   /**
-   * Return the object representing the type "Future" from the dart:async library, or the type
-   * "void" if the type "Future" cannot be accessed.
-   *
-   * @return the type "Future" from the dart:async library
+   * Return the object representing the type 'Future' from the 'dart:async'
+   * library, or the type 'void' if the type 'Future' cannot be accessed.
    */
   DartType get loadLibraryReturnType {
     try {
@@ -7509,10 +7115,8 @@
   List<CompilationUnitElement> get parts => _parts;
 
   /**
-   * Set the compilation units that are included in this library using a `part` directive.
-   *
-   * @param parts the compilation units that are included in this library using a `part`
-   *          directive
+   * Set the compilation units that are included in this library using a `part`
+   * directive to the given list of [parts].
    */
   void set parts(List<CompilationUnitElement> parts) {
     for (CompilationUnitElement compilationUnit in parts) {
@@ -7543,10 +7147,9 @@
 
   @override
   List<CompilationUnitElement> get units {
-    List<CompilationUnitElement> units =
-        new List<CompilationUnitElement>(1 + _parts.length);
-    units[0] = _definingCompilationUnit;
-    JavaSystem.arraycopy(_parts, 0, units, 1, _parts.length);
+    List<CompilationUnitElement> units = new List<CompilationUnitElement>();
+    units.add(_definingCompilationUnit);
+    units.addAll(_parts);
     return units;
   }
 
@@ -7631,7 +7234,8 @@
   }
 
   /**
-   * Recursively fills set of visible libraries for [getVisibleElementsLibraries].
+   * Recursively fills set of visible libraries for
+   * [getVisibleElementsLibraries].
    */
   void _addVisibleLibraries(
       Set<LibraryElement> visibleLibraries, bool includeExports) {
@@ -7660,11 +7264,9 @@
   }
 
   /**
-   * Determine if the given library is up to date with respect to the given time stamp.
-   *
-   * @param library the library to process
-   * @param timeStamp the time stamp to check against
-   * @param visitedLibraries the set of visited libraries
+   * Return `true` if the given [library] is up to date with respect to the
+   * given [timeStamp]. The set of [visitedLibraries] is used to prevent
+   * infinite recusion in the case of mutually dependent libraries.
    */
   static bool _safeIsUpToDate(LibraryElement library, int timeStamp,
       Set<LibraryElement> visitedLibraries) {
@@ -7701,36 +7303,36 @@
 }
 
 /**
- * The interface `LocalElement` defines the behavior of elements that can be (but are not
- * required to be) defined within a method or function (an [ExecutableElement]).
+ * An element that can be (but are not required to be) defined within a method
+ * or function (an [ExecutableElement]).
  */
 abstract class LocalElement implements Element {
   /**
-   * Return a source range that covers the approximate portion of the source in which the name of
-   * this element is visible, or `null` if there is no single range of characters within which
-   * the element name is visible.
-   * * For a local variable, this includes everything from the end of the variable's initializer
-   * to the end of the block that encloses the variable declaration.
-   * * For a parameter, this includes the body of the method or function that declares the
-   * parameter.
-   * * For a local function, this includes everything from the beginning of the function's body to
-   * the end of the block that encloses the function declaration.
-   * * For top-level functions, `null` will be returned because they are potentially visible
-   * in multiple sources.
+   * Return a source range that covers the approximate portion of the source in
+   * which the name of this element is visible, or `null` if there is no single
+   * range of characters within which the element name is visible.
    *
-   * @return the range of characters in which the name of this element is visible
+   * * For a local variable, this includes everything from the end of the
+   *   variable's initializer to the end of the block that encloses the variable
+   *   declaration.
+   * * For a parameter, this includes the body of the method or function that
+   *   declares the parameter.
+   * * For a local function, this includes everything from the beginning of the
+   *   function's body to the end of the block that encloses the function
+   *   declaration.
+   * * For top-level functions, `null` will be returned because they are
+   *   potentially visible in multiple sources.
    */
   SourceRange get visibleRange;
 }
 
 /**
- * The interface `LocalVariableElement` defines the behavior common to elements that represent
- * a local variable.
+ * A local variable.
  */
 abstract class LocalVariableElement implements LocalElement, VariableElement {}
 
 /**
- * Instances of the class `LocalVariableElementImpl` implement a `LocalVariableElement`.
+ * A concrete implementation of a [LocalVariableElement].
  */
 class LocalVariableElementImpl extends VariableElementImpl
     implements LocalVariableElement {
@@ -7746,25 +7348,19 @@
   int _visibleRangeOffset = 0;
 
   /**
-   * The length of the visible range for this element, or `-1` if this element does not have a
-   * visible range.
+   * The length of the visible range for this element, or `-1` if this element
+   * does not have a visible range.
    */
   int _visibleRangeLength = -1;
 
   /**
-   * Initialize a newly created method element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created method element to have the given [name] and
+   * [offset].
    */
-  LocalVariableElementImpl(String name, int nameOffset)
-      : super(name, nameOffset);
+  LocalVariableElementImpl(String name, int offset) : super(name, offset);
 
   /**
-   * Initialize a newly created local variable element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created local variable element to have the given [name].
    */
   LocalVariableElementImpl.forNode(Identifier name) : super.forNode(name);
 
@@ -7820,12 +7416,8 @@
   }
 
   /**
-   * Set the visible range for this element to the range starting at the given offset with the given
-   * length.
-   *
-   * @param offset the offset to the beginning of the visible range for this element
-   * @param length the length of the visible range for this element, or `-1` if this element
-   *          does not have a visible range
+   * Set the visible range for this element to the range starting at the given
+   * [offset] with the given [length].
    */
   void setVisibleRange(int offset, int length) {
     _visibleRangeOffset = offset;
@@ -7834,8 +7426,8 @@
 }
 
 /**
- * The abstract class `Member` defines the behavior common to elements that represent members
- * of parameterized types.
+ * An element defined in a parameterized type where the values of the type
+ * parameters are known.
  */
 abstract class Member implements Element {
   /**
@@ -7849,17 +7441,13 @@
   final ParameterizedType _definingType;
 
   /**
-   * Initialize a newly created element to represent the member of the given parameterized type.
-   *
-   * @param baseElement the element on which the parameterized element was created
-   * @param definingType the type in which the element is defined
+   * Initialize a newly created element to represent a constructor, based on the
+   * [baseElement], defined by the [definingType].
    */
   Member(this._baseElement, this._definingType);
 
   /**
    * Return the element on which the parameterized element was created.
-   *
-   * @return the element on which the parameterized element was created
    */
   Element get baseElement => _baseElement;
 
@@ -7868,8 +7456,6 @@
 
   /**
    * Return the type in which the element is defined.
-   *
-   * @return the type in which the element is defined
    */
   ParameterizedType get definingType => _definingType;
 
@@ -7937,24 +7523,20 @@
       _baseElement.isAccessibleIn(library);
 
   /**
-   * If the given child is not `null`, use the given visitor to visit it.
-   *
-   * @param child the child to be visited
-   * @param visitor the visitor to be used to visit the child
+   * If the given [child] is not `null`, use the given [visitor] to visit it.
    */
   void safelyVisitChild(Element child, ElementVisitor visitor) {
+    // TODO(brianwilkerson) Make this private
     if (child != null) {
       child.accept(visitor);
     }
   }
 
   /**
-   * Use the given visitor to visit all of the children in the given array.
-   *
-   * @param children the children to be visited
-   * @param visitor the visitor being used to visit the children
+   * Use the given [visitor] to visit all of the [children].
    */
   void safelyVisitChildren(List<Element> children, ElementVisitor visitor) {
+    // TODO(brianwilkerson) Make this private
     if (children != null) {
       for (Element child in children) {
         child.accept(visitor);
@@ -7963,11 +7545,8 @@
   }
 
   /**
-   * Return the type that results from replacing the type parameters in the given type with the type
-   * arguments.
-   *
-   * @param type the type to be transformed
-   * @return the result of transforming the type
+   * Return the type that results from replacing the type parameters in the
+   * given [type] with the type arguments associated with this member.
    */
   DartType substituteFor(DartType type) {
     if (type == null) {
@@ -7980,11 +7559,8 @@
   }
 
   /**
-   * Return the array of types that results from replacing the type parameters in the given types
-   * with the type arguments.
-   *
-   * @param types the types to be transformed
-   * @return the result of transforming the types
+   * Return the list of types that results from replacing the type parameters in
+   * the given [types] with the type arguments associated with this member.
    */
   List<InterfaceType> substituteFor2(List<InterfaceType> types) {
     int count = types.length;
@@ -8002,32 +7578,22 @@
 }
 
 /**
- * The interface `MethodElement` defines the behavior of elements that represent a method
- * defined within a type.
+ * An element that represents a method defined within a type.
  */
 abstract class MethodElement implements ClassMemberElement, ExecutableElement {
   /**
-   * Return `true` if this method is abstract. Methods are abstract if they are not external
-   * and have no body.
+   * Return the resolved [MethodDeclaration] node that declares this
+   * [MethodElement].
    *
-   * @return `true` if this method is abstract
-   */
-  bool get isAbstract;
-
-  /**
-   * Return the resolved [MethodDeclaration] node that declares this [MethodElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
-   * resolving will be performed.
-   *
-   * @return the resolved [MethodDeclaration], not `null`.
+   * This method is expensive, because resolved AST might be evicted from cache,
+   * so parsing and resolving will be performed.
    */
   @override
   MethodDeclaration get node;
 }
 
 /**
- * Instances of the class `MethodElementImpl` implement a `MethodElement`.
+ * A concrete implementation of a [MethodElement].
  */
 class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
   /**
@@ -8036,25 +7602,18 @@
   static const List<MethodElement> EMPTY_ARRAY = const <MethodElement>[];
 
   /**
-   * Initialize a newly created method element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created method element to have the given [name] at the
+   * given [offset].
    */
-  MethodElementImpl(String name, int nameOffset) : super(name, nameOffset);
+  MethodElementImpl(String name, int offset) : super(name, offset);
 
   /**
-   * Initialize a newly created method element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created method element to have the given [name].
    */
   MethodElementImpl.forNode(Identifier name) : super.forNode(name);
 
   /**
-   * Set whether this method is abstract to correspond to the given value.
-   *
-   * @param isAbstract `true` if the method is abstract
+   * Set whether this method is abstract.
    */
   void set abstract(bool isAbstract) {
     setModifier(Modifier.ABSTRACT, isAbstract);
@@ -8073,9 +7632,6 @@
   ClassElement get enclosingElement => super.enclosingElement as ClassElement;
 
   @override
-  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
-
-  @override
   bool get isOperator {
     String name = displayName;
     if (name.isEmpty) {
@@ -8110,9 +7666,7 @@
       getNodeMatching((node) => node is MethodDeclaration);
 
   /**
-   * Set whether this method is static to correspond to the given value.
-   *
-   * @param isStatic `true` if the method is static
+   * Set whether this method is static.
    */
   void set static(bool isStatic) {
     setModifier(Modifier.STATIC, isStatic);
@@ -8131,15 +7685,13 @@
 }
 
 /**
- * Instances of the class `MethodMember` represent a method element defined in a parameterized
- * type where the values of the type parameters are known.
+ * A method element defined in a parameterized type where the values of the type
+ * parameters are known.
  */
 class MethodMember extends ExecutableMember implements MethodElement {
   /**
-   * Initialize a newly created element to represent a method of the given parameterized type.
-   *
-   * @param baseElement the element on which the parameterized element was created
-   * @param definingType the type in which the element is defined
+   * Initialize a newly created element to represent a constructor, based on the
+   * [baseElement], defined by the [definingType].
    */
   MethodMember(MethodElement baseElement, InterfaceType definingType)
       : super(baseElement, definingType);
@@ -8151,9 +7703,6 @@
   ClassElement get enclosingElement => baseElement.enclosingElement;
 
   @override
-  bool get isAbstract => baseElement.isAbstract;
-
-  @override
   MethodDeclaration get node => baseElement.node;
 
   @override
@@ -8185,39 +7734,34 @@
   }
 
   /**
-   * If the given method's type is different when any type parameters from the defining type's
-   * declaration are replaced with the actual type arguments from the defining type, create a method
-   * member representing the given method. Return the member that was created, or the base method if
-   * no member was created.
-   *
-   * @param baseMethod the base method for which a member might be created
-   * @param definingType the type defining the parameters and arguments to be used in the
-   *          substitution
-   * @return the method element that will return the correctly substituted types
+   * If the given [method]'s type is different when any type parameters from the
+   * defining type's declaration are replaced with the actual type arguments
+   * from the [definingType], create a method member representing the given
+   * method. Return the member that was created, or the base method if no member
+   * was created.
    */
-  static MethodElement from(
-      MethodElement baseMethod, InterfaceType definingType) {
-    if (baseMethod == null || definingType.typeArguments.length == 0) {
-      return baseMethod;
+  static MethodElement from(MethodElement method, InterfaceType definingType) {
+    if (method == null || definingType.typeArguments.length == 0) {
+      return method;
     }
-    FunctionType baseType = baseMethod.type;
+    FunctionType baseType = method.type;
     List<DartType> argumentTypes = definingType.typeArguments;
     List<DartType> parameterTypes = definingType.element.type.typeArguments;
     FunctionType substitutedType =
         baseType.substitute2(argumentTypes, parameterTypes);
     if (baseType == substitutedType) {
-      return baseMethod;
+      return method;
     }
     // TODO(brianwilkerson) Consider caching the substituted type in the
     // instance. It would use more memory but speed up some operations.
     // We need to see how often the type is being re-computed.
-    return new MethodMember(baseMethod, definingType);
+    return new MethodMember(method, definingType);
   }
 }
 
 /**
- * The enumeration `Modifier` defines constants for all of the modifiers defined by the Dart
- * language and for a few additional flags that are useful.
+ * The enumeration `Modifier` defines constants for all of the modifiers defined
+ * by the Dart language and for a few additional flags that are useful.
  */
 class Modifier extends Enum<Modifier> {
   /**
@@ -8226,7 +7770,8 @@
   static const Modifier ABSTRACT = const Modifier('ABSTRACT', 0);
 
   /**
-   * Indicates that an executable element has a body marked as being asynchronous.
+   * Indicates that an executable element has a body marked as being
+   * asynchronous.
    */
   static const Modifier ASYNCHRONOUS = const Modifier('ASYNCHRONOUS', 1);
 
@@ -8256,7 +7801,8 @@
   static const Modifier FINAL = const Modifier('FINAL', 6);
 
   /**
-   * Indicates that an executable element has a body marked as being a generator.
+   * Indicates that an executable element has a body marked as being a
+   * generator.
    */
   static const Modifier GENERATOR = const Modifier('GENERATOR', 7);
 
@@ -8266,8 +7812,9 @@
   static const Modifier GETTER = const Modifier('GETTER', 8);
 
   /**
-   * A flag used for libraries indicating that the defining compilation unit contains at least one
-   * import directive whose URI uses the "dart-ext" scheme.
+   * A flag used for libraries indicating that the defining compilation unit
+   * contains at least one import directive whose URI uses the "dart-ext"
+   * scheme.
    */
   static const Modifier HAS_EXT_URI = const Modifier('HAS_EXT_URI', 9);
 
@@ -8284,13 +7831,15 @@
       const Modifier('MIXIN_ERRORS_REPORTED', 11);
 
   /**
-   * Indicates that the value of a parameter or local variable might be mutated within the context.
+   * Indicates that the value of a parameter or local variable might be mutated
+   * within the context.
    */
   static const Modifier POTENTIALLY_MUTATED_IN_CONTEXT =
       const Modifier('POTENTIALLY_MUTATED_IN_CONTEXT', 12);
 
   /**
-   * Indicates that the value of a parameter or local variable might be mutated within the scope.
+   * Indicates that the value of a parameter or local variable might be mutated
+   * within the scope.
    */
   static const Modifier POTENTIALLY_MUTATED_IN_SCOPE =
       const Modifier('POTENTIALLY_MUTATED_IN_SCOPE', 13);
@@ -8312,15 +7861,16 @@
   static const Modifier STATIC = const Modifier('STATIC', 16);
 
   /**
-   * Indicates that the element does not appear in the source code but was implicitly created. For
-   * example, if a class does not define any constructors, an implicit zero-argument constructor
-   * will be created and it will be marked as being synthetic.
+   * Indicates that the element does not appear in the source code but was
+   * implicitly created. For example, if a class does not define any
+   * constructors, an implicit zero-argument constructor will be created and it
+   * will be marked as being synthetic.
    */
   static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 17);
 
   /**
-   * Indicates that a class was defined using an alias. TODO(brianwilkerson) This should be renamed
-   * to 'ALIAS'.
+   * Indicates that a class was defined using an alias.
+   * TODO(brianwilkerson) This should be renamed to 'ALIAS'.
    */
   static const Modifier TYPEDEF = const Modifier('TYPEDEF', 18);
 
@@ -8350,32 +7900,27 @@
 }
 
 /**
- * The interface `MultiplyDefinedElement` defines the behavior of pseudo-elements that
- * represent multiple elements defined within a single scope that have the same name. This situation
- * is not allowed by the language, so objects implementing this interface always represent an error.
- * As a result, most of the normal operations on elements do not make sense and will return useless
- * results.
+ * A pseudo-element that represents multiple elements defined within a single
+ * scope that have the same name. This situation is not allowed by the language,
+ * so objects implementing this interface always represent an error. As a
+ * result, most of the normal operations on elements do not make sense and will
+ * return useless results.
  */
 abstract class MultiplyDefinedElement implements Element {
   /**
-   * Return an array containing all of the elements that were defined within the scope to have the
-   * same name.
-   *
-   * @return the elements that were defined with the same name
+   * Return a list containing all of the elements that were defined within the
+   * scope to have the same name.
    */
   List<Element> get conflictingElements;
 
   /**
    * Return the type of this element as the dynamic type.
-   *
-   * @return the type of this element as the dynamic type
    */
   DartType get type;
 }
 
 /**
- * Instances of the class `MultiplyDefinedElementImpl` represent a collection of elements that
- * have the same name within the same scope.
+ * A concrete implementation of a [MultiplyDefinedElement].
  */
 class MultiplyDefinedElementImpl implements MultiplyDefinedElement {
   /**
@@ -8399,10 +7944,8 @@
   final List<Element> conflictingElements;
 
   /**
-   * Initialize a newly created element to represent a list of conflicting elements.
-   *
-   * @param context the analysis context in which the multiply defined elements are defined
-   * @param conflictingElements the elements that conflict
+   * Initialize a newly created element in the given [context] to represent a
+   * list of [conflictingElements].
    */
   MultiplyDefinedElementImpl(this.context, this.conflictingElements) {
     _name = conflictingElements[0].name;
@@ -8513,11 +8056,9 @@
   }
 
   /**
-   * Return an element that represents the given conflicting elements.
-   *
-   * @param context the analysis context in which the multiply defined elements are defined
-   * @param firstElement the first element that conflicts
-   * @param secondElement the second element that conflicts
+   * Return an element in the given [context] that represents the fact that the
+   * [firstElement] and [secondElement] conflict. (If the elements are the same,
+   * then one of the two will be returned directly.)
    */
   static Element fromElements(
       AnalysisContext context, Element firstElement, Element secondElement) {
@@ -8533,11 +8074,9 @@
   }
 
   /**
-   * Add the given element to the list of elements. If the element is a multiply-defined element,
-   * add all of the conflicting elements that it represents.
-   *
-   * @param elements the list to which the element(s) are to be added
-   * @param element the element(s) to be added
+   * Add the given [element] to the list of [elements]. If the element is a
+   * multiply-defined element, add all of the conflicting elements that it
+   * represents.
    */
   static void _add(HashSet<Element> elements, Element element) {
     if (element is MultiplyDefinedElementImpl) {
@@ -8550,13 +8089,10 @@
   }
 
   /**
-   * Use the given elements to construct an array of conflicting elements. If either of the given
-   * elements are multiply-defined elements then the conflicting elements they represent will be
-   * included in the array. Otherwise, the element itself will be included.
-   *
-   * @param firstElement the first element to be included
-   * @param secondElement the second element to be included
-   * @return an array containing all of the conflicting elements
+   * Use the given elements to construct a list of conflicting elements. If
+   * either the [firstElement] or [secondElement] are multiply-defined elements
+   * then the conflicting elements they represent will be included in the array.
+   * Otherwise, the element itself will be included.
    */
   static List<Element> _computeConflictingElements(
       Element firstElement, Element secondElement) {
@@ -8568,29 +8104,26 @@
 }
 
 /**
- * The interface [MultiplyInheritedExecutableElement] defines all of the behavior of an
- * [ExecutableElement], with the additional information of an array of
+ * An [ExecutableElement], with the additional information of a list of
  * [ExecutableElement]s from which this element was composed.
  */
 abstract class MultiplyInheritedExecutableElement implements ExecutableElement {
   /**
-   * Return an array containing all of the executable elements defined within this executable
-   * element.
-   *
-   * @return the elements defined within this executable element
+   * Return a list containing all of the executable elements defined within this
+   * executable element.
    */
   List<ExecutableElement> get inheritedElements;
 }
 
 /**
- * The interface [MultiplyInheritedMethodElementImpl] defines all of the behavior of an
- * [MethodElementImpl], with the additional information of an array of
+ * A [MethodElementImpl], with the additional information of a list of
  * [ExecutableElement]s from which this element was composed.
  */
 class MultiplyInheritedMethodElementImpl extends MethodElementImpl
     implements MultiplyInheritedExecutableElement {
   /**
-   * An array the array of executable elements that were used to compose this element.
+   * A list the array of executable elements that were used to compose this
+   * element.
    */
   List<ExecutableElement> _elements = MethodElementImpl.EMPTY_ARRAY;
 
@@ -8607,15 +8140,15 @@
 }
 
 /**
- * The interface [MultiplyInheritedPropertyAccessorElementImpl] defines all of the behavior of
- * an [PropertyAccessorElementImpl], with the additional information of an array of
+ * A [PropertyAccessorElementImpl], with the additional information of a list of
  * [ExecutableElement]s from which this element was composed.
  */
 class MultiplyInheritedPropertyAccessorElementImpl
     extends PropertyAccessorElementImpl
     implements MultiplyInheritedExecutableElement {
   /**
-   * An array the array of executable elements that were used to compose this element.
+   * A list the array of executable elements that were used to compose this
+   * element.
    */
   List<ExecutableElement> _elements = PropertyAccessorElementImpl.EMPTY_ARRAY;
 
@@ -8633,8 +8166,7 @@
 }
 
 /**
- * The interface `NamespaceCombinator` defines the behavior common to objects that control how
- * namespaces are combined.
+ * An object that controls how namespaces are combined.
  */
 abstract class NamespaceCombinator {
   /**
@@ -8645,42 +8177,34 @@
 }
 
 /**
- * The interface `ParameterElement` defines the behavior of elements representing a parameter
- * defined within an executable element.
+ * A parameter defined within an executable element.
  */
 abstract class ParameterElement implements LocalElement, VariableElement {
   /**
    * Return the Dart code of the default value, or `null` if no default value.
-   *
-   * @return the Dart code of the default value
    */
   String get defaultValueCode;
 
   /**
    * Return `true` if this parameter is an initializing formal parameter.
-   *
-   * @return `true` if this parameter is an initializing formal parameter
    */
   bool get isInitializingFormal;
 
   /**
    * Return the kind of this parameter.
-   *
-   * @return the kind of this parameter
    */
   ParameterKind get parameterKind;
 
   /**
-   * Return an array containing all of the parameters defined by this parameter. A parameter will
-   * only define other parameters if it is a function typed parameter.
-   *
-   * @return the parameters defined by this parameter element
+   * Return a list containing all of the parameters defined by this parameter.
+   * A parameter will only define other parameters if it is a function typed
+   * parameter.
    */
   List<ParameterElement> get parameters;
 }
 
 /**
- * Instances of the class `ParameterElementImpl` implement a `ParameterElement`.
+ * A concrete implementation of a [ParameterElement].
  */
 class ParameterElementImpl extends VariableElementImpl
     implements ParameterElement {
@@ -8690,8 +8214,9 @@
   static const List<ParameterElement> EMPTY_ARRAY = const <ParameterElement>[];
 
   /**
-   * An array containing all of the parameters defined by this parameter element. There will only be
-   * parameters if this parameter is a function typed parameter.
+   * A list containing all of the parameters defined by this parameter element.
+   * There will only be parameters if this parameter is a function typed
+   * parameter.
    */
   List<ParameterElement> _parameters = ParameterElementImpl.EMPTY_ARRAY;
 
@@ -8711,24 +8236,19 @@
   int _visibleRangeOffset = 0;
 
   /**
-   * The length of the visible range for this element, or `-1` if this element does not have a
-   * visible range.
+   * The length of the visible range for this element, or `-1` if this element
+   * does not have a visible range.
    */
   int _visibleRangeLength = -1;
 
   /**
-   * Initialize a newly created parameter element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created parameter element to have the given [name] and
+   * [offset].
    */
   ParameterElementImpl(String name, int nameOffset) : super(name, nameOffset);
 
   /**
-   * Initialize a newly created parameter element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created parameter element to have the given [name].
    */
   ParameterElementImpl.forNode(Identifier name) : super.forNode(name);
 
@@ -8760,9 +8280,8 @@
   List<ParameterElement> get parameters => _parameters;
 
   /**
-   * Set the parameters defined by this executable element to the given parameters.
-   *
-   * @param parameters the parameters defined by this executable element
+   * Set the parameters defined by this executable element to the given
+   * [parameters].
    */
   void set parameters(List<ParameterElement> parameters) {
     for (ParameterElement parameter in parameters) {
@@ -8802,9 +8321,7 @@
   }
 
   /**
-   * Append the type and name of this parameter to the given builder.
-   *
-   * @param builder the builder to which the type and name are to be appended
+   * Append the type and name of this parameter to the given [buffer].
    */
   void appendToWithoutDelimiters(StringBuffer buffer) {
     buffer.write(type);
@@ -8846,12 +8363,8 @@
   }
 
   /**
-   * Set the visible range for this element to the range starting at the given offset with the given
-   * length.
-   *
-   * @param offset the offset to the beginning of the visible range for this element
-   * @param length the length of the visible range for this element, or `-1` if this element
-   *          does not have a visible range
+   * Set the visible range for this element to the range starting at the given
+   * [offset] with the given [length].
    */
   void setVisibleRange(int offset, int length) {
     _visibleRangeOffset = offset;
@@ -8866,39 +8379,33 @@
 }
 
 /**
- * The interface `ParameterizedType` defines the behavior common to objects representing a
- * type with type parameters, such as a class or function type alias.
+ * A type with type parameters, such as a class or function type alias.
  */
 abstract class ParameterizedType implements DartType {
   /**
-   * Return an array containing the actual types of the type arguments. If this type's element does
-   * not have type parameters, then the array should be empty (although it is possible for type
-   * arguments to be erroneously declared). If the element has type parameters and the actual type
-   * does not explicitly include argument values, then the type "dynamic" will be automatically
-   * provided.
-   *
-   * @return the actual types of the type arguments
+   * Return a list containing the actual types of the type arguments. If this
+   * type's element does not have type parameters, then the array should be
+   * empty (although it is possible for type arguments to be erroneously
+   * declared). If the element has type parameters and the actual type does not
+   * explicitly include argument values, then the type "dynamic" will be
+   * automatically provided.
    */
   List<DartType> get typeArguments;
 
   /**
-   * Return an array containing all of the type parameters declared for this type.
-   *
-   * @return the type parameters declared for this type
+   * Return a list containing all of the type parameters declared for this type.
    */
   List<TypeParameterElement> get typeParameters;
 }
 
 /**
- * Instances of the class `ParameterMember` represent a parameter element defined in a
- * parameterized type where the values of the type parameters are known.
+ * A parameter element defined in a parameterized type where the values of the
+ * type parameters are known.
  */
 class ParameterMember extends VariableMember implements ParameterElement {
   /**
-   * Initialize a newly created element to represent a parameter of the given parameterized type.
-   *
-   * @param baseElement the element on which the parameterized element was created
-   * @param definingType the type in which the element is defined
+   * Initialize a newly created element to represent a constructor, based on the
+   * [baseElement], defined by the [definingType].
    */
   ParameterMember(ParameterElement baseElement, ParameterizedType definingType)
       : super(baseElement, definingType);
@@ -8982,34 +8489,30 @@
   }
 
   /**
-   * If the given parameter's type is different when any type parameters from the defining type's
-   * declaration are replaced with the actual type arguments from the defining type, create a
-   * parameter member representing the given parameter. Return the member that was created, or the
-   * base parameter if no member was created.
-   *
-   * @param baseParameter the base parameter for which a member might be created
-   * @param definingType the type defining the parameters and arguments to be used in the
-   *          substitution
-   * @return the parameter element that will return the correctly substituted types
+   * If the given [parameter]'s type is different when any type parameters from
+   * the defining type's declaration are replaced with the actual type
+   * arguments from the [definingType], create a parameter member representing
+   * the given parameter. Return the member that was created, or the base
+   * parameter if no member was created.
    */
   static ParameterElement from(
-      ParameterElement baseParameter, ParameterizedType definingType) {
-    if (baseParameter == null || definingType.typeArguments.length == 0) {
-      return baseParameter;
+      ParameterElement parameter, ParameterizedType definingType) {
+    if (parameter == null || definingType.typeArguments.length == 0) {
+      return parameter;
     }
     // Check if parameter type depends on defining type type arguments.
     // It is possible that we did not resolve field formal parameter yet,
     // so skip this check for it.
-    bool isFieldFormal = baseParameter is FieldFormalParameterElement;
+    bool isFieldFormal = parameter is FieldFormalParameterElement;
     if (!isFieldFormal) {
-      DartType baseType = baseParameter.type;
+      DartType baseType = parameter.type;
       List<DartType> argumentTypes = definingType.typeArguments;
       List<DartType> parameterTypes =
           TypeParameterTypeImpl.getTypes(definingType.typeParameters);
       DartType substitutedType =
           baseType.substitute2(argumentTypes, parameterTypes);
       if (baseType == substitutedType) {
-        return baseParameter;
+        return parameter;
       }
     }
     // TODO(brianwilkerson) Consider caching the substituted type in the
@@ -9017,35 +8520,32 @@
     // We need to see how often the type is being re-computed.
     if (isFieldFormal) {
       return new FieldFormalParameterMember(
-          baseParameter as FieldFormalParameterElement, definingType);
+          parameter as FieldFormalParameterElement, definingType);
     }
-    return new ParameterMember(baseParameter, definingType);
+    return new ParameterMember(parameter, definingType);
   }
 }
 
 /**
- * The interface `PrefixElement` defines the behavior common to elements that represent a
- * prefix used to import one or more libraries into another library.
+ * A prefix used to import one or more libraries into another library.
  */
 abstract class PrefixElement implements Element {
   /**
-   * Return the library into which other libraries are imported using this prefix.
-   *
-   * @return the library into which other libraries are imported using this prefix
+   * Return the library into which other libraries are imported using this
+   * prefix.
    */
   @override
   LibraryElement get enclosingElement;
 
   /**
-   * Return an array containing all of the libraries that are imported using this prefix.
-   *
-   * @return the libraries that are imported using this prefix
+   * Return a list containing all of the libraries that are imported using this
+   * prefix.
    */
   List<LibraryElement> get importedLibraries;
 }
 
 /**
- * Instances of the class `PrefixElementImpl` implement a `PrefixElement`.
+ * A concrete implementation of a [PrefixElement].
  */
 class PrefixElementImpl extends ElementImpl implements PrefixElement {
   /**
@@ -9054,23 +8554,18 @@
   static const List<PrefixElement> EMPTY_ARRAY = const <PrefixElement>[];
 
   /**
-   * An array containing all of the libraries that are imported using this prefix.
+   * A list containing all of the libraries that are imported using this prefix.
    */
   List<LibraryElement> _importedLibraries = LibraryElementImpl.EMPTY_ARRAY;
 
   /**
-   * Initialize a newly created method element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created method element to have the given [name] and
+   * [offset].
    */
   PrefixElementImpl(String name, int nameOffset) : super(name, nameOffset);
 
   /**
-   * Initialize a newly created prefix element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created prefix element to have the given [name].
    */
   PrefixElementImpl.forNode(Identifier name) : super.forNode(name);
 
@@ -9085,15 +8580,14 @@
   List<LibraryElement> get importedLibraries => _importedLibraries;
 
   /**
-   * Set the libraries that are imported using this prefix to the given libraries.
-   *
-   * @param importedLibraries the libraries that are imported using this prefix
+   * Set the libraries that are imported using this prefix to the given
+   * [libraries].
    */
-  void set importedLibraries(List<LibraryElement> importedLibraries) {
-    for (LibraryElement library in importedLibraries) {
+  void set importedLibraries(List<LibraryElement> libraries) {
+    for (LibraryElement library in libraries) {
       (library as LibraryElementImpl).enclosingElement = this;
     }
-    this._importedLibraries = importedLibraries;
+    _importedLibraries = libraries;
   }
 
   @override
@@ -9110,71 +8604,53 @@
 }
 
 /**
- * The interface `PropertyAccessorElement` defines the behavior of elements representing a
- * getter or a setter. Note that explicitly defined property accessors implicitly define a synthetic
- * field. Symmetrically, synthetic accessors are implicitly created for explicitly defined fields.
- * The following rules apply:
+ * A getter or a setter. Note that explicitly defined property accessors
+ * implicitly define a synthetic field. Symmetrically, synthetic accessors are
+ * implicitly created for explicitly defined fields. The following rules apply:
+ *
  * * Every explicit field is represented by a non-synthetic [FieldElement].
- * * Every explicit field induces a getter and possibly a setter, both of which are represented by
- * synthetic [PropertyAccessorElement]s.
+ * * Every explicit field induces a getter and possibly a setter, both of which
+ *   are represented by synthetic [PropertyAccessorElement]s.
  * * Every explicit getter or setter is represented by a non-synthetic
- * [PropertyAccessorElement].
- * * Every explicit getter or setter (or pair thereof if they have the same name) induces a field
- * that is represented by a synthetic [FieldElement].
+ *   [PropertyAccessorElement].
+ * * Every explicit getter or setter (or pair thereof if they have the same
+ *   name) induces a field that is represented by a synthetic [FieldElement].
  */
 abstract class PropertyAccessorElement implements ExecutableElement {
   /**
-   * Return the accessor representing the getter that corresponds to (has the same name as) this
-   * setter, or `null` if this accessor is not a setter or if there is no corresponding
-   * getter.
-   *
-   * @return the getter that corresponds to this setter
+   * Return the accessor representing the getter that corresponds to (has the
+   * same name as) this setter, or `null` if this accessor is not a setter or if
+   * there is no corresponding getter.
    */
   PropertyAccessorElement get correspondingGetter;
 
   /**
-   * Return the accessor representing the setter that corresponds to (has the same name as) this
-   * getter, or `null` if this accessor is not a getter or if there is no corresponding
-   * setter.
-   *
-   * @return the setter that corresponds to this getter
+   * Return the accessor representing the setter that corresponds to (has the
+   * same name as) this getter, or `null` if this accessor is not a getter or if
+   * there is no corresponding setter.
    */
   PropertyAccessorElement get correspondingSetter;
 
   /**
-   * Return `true` if this accessor is abstract. Accessors are abstract if they are not
-   * external and have no body.
-   *
-   * @return `true` if this accessor is abstract
-   */
-  bool get isAbstract;
-
-  /**
    * Return `true` if this accessor represents a getter.
-   *
-   * @return `true` if this accessor represents a getter
    */
   bool get isGetter;
 
   /**
    * Return `true` if this accessor represents a setter.
-   *
-   * @return `true` if this accessor represents a setter
    */
   bool get isSetter;
 
   /**
-   * Return the field or top-level variable associated with this accessor. If this accessor was
-   * explicitly defined (is not synthetic) then the variable associated with it will be synthetic.
-   *
-   * @return the variable associated with this accessor
+   * Return the field or top-level variable associated with this accessor. If
+   * this accessor was explicitly defined (is not synthetic) then the variable
+   * associated with it will be synthetic.
    */
   PropertyInducingElement get variable;
 }
 
 /**
- * Instances of the class `PropertyAccessorElementImpl` implement a
- * `PropertyAccessorElement`.
+ * A concrete implementation of a [PropertyAccessorElement].
  */
 class PropertyAccessorElementImpl extends ExecutableElementImpl
     implements PropertyAccessorElement {
@@ -9190,17 +8666,14 @@
   PropertyInducingElement variable;
 
   /**
-   * Initialize a newly created property accessor element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created property accessor element to have the given
+   * [name].
    */
   PropertyAccessorElementImpl.forNode(Identifier name) : super.forNode(name);
 
   /**
-   * Initialize a newly created synthetic property accessor element to be associated with the given
-   * variable.
-   *
-   * @param variable the variable with which this access is associated
+   * Initialize a newly created synthetic property accessor element to be
+   * associated with the given [variable].
    */
   PropertyAccessorElementImpl.forVariable(PropertyInducingElementImpl variable)
       : super(variable.name, variable.nameOffset) {
@@ -9210,9 +8683,7 @@
   }
 
   /**
-   * Set whether this accessor is abstract to correspond to the given value.
-   *
-   * @param isAbstract `true` if the accessor is abstract
+   * Set whether this accessor is abstract.
    */
   void set abstract(bool isAbstract) {
     setModifier(Modifier.ABSTRACT, isAbstract);
@@ -9235,9 +8706,7 @@
   }
 
   /**
-   * Set whether this accessor is a getter to correspond to the given value.
-   *
-   * @param isGetter `true` if the accessor is a getter
+   * Set whether this accessor is a getter.
    */
   void set getter(bool isGetter) {
     setModifier(Modifier.GETTER, isGetter);
@@ -9254,9 +8723,6 @@
   }
 
   @override
-  bool get isAbstract => hasModifier(Modifier.ABSTRACT);
-
-  @override
   bool get isGetter => hasModifier(Modifier.GETTER);
 
   @override
@@ -9296,18 +8762,14 @@
   }
 
   /**
-   * Set whether this accessor is a setter to correspond to the given value.
-   *
-   * @param isSetter `true` if the accessor is a setter
+   * Set whether this accessor is a setter.
    */
   void set setter(bool isSetter) {
     setModifier(Modifier.SETTER, isSetter);
   }
 
   /**
-   * Set whether this accessor is static to correspond to the given value.
-   *
-   * @param isStatic `true` if the accessor is static
+   * Set whether this accessor is static.
    */
   void set static(bool isStatic) {
     setModifier(Modifier.STATIC, isStatic);
@@ -9329,17 +8791,14 @@
 }
 
 /**
- * Instances of the class `PropertyAccessorMember` represent a property accessor element
- * defined in a parameterized type where the values of the type parameters are known.
+ * A property accessor element defined in a parameterized type where the values
+ * of the type parameters are known.
  */
 class PropertyAccessorMember extends ExecutableMember
     implements PropertyAccessorElement {
   /**
-   * Initialize a newly created element to represent a property accessor of the given parameterized
-   * type.
-   *
-   * @param baseElement the element on which the parameterized element was created
-   * @param definingType the type in which the element is defined
+   * Initialize a newly created element to represent a constructor, based on the
+   * [baseElement], defined by the [definingType].
    */
   PropertyAccessorMember(
       PropertyAccessorElement baseElement, InterfaceType definingType)
@@ -9364,9 +8823,6 @@
   Element get enclosingElement => baseElement.enclosingElement;
 
   @override
-  bool get isAbstract => baseElement.isAbstract;
-
-  @override
   bool get isGetter => baseElement.isGetter;
 
   @override
@@ -9415,44 +8871,36 @@
   }
 
   /**
-   * If the given property accessor's type is different when any type parameters from the defining
-   * type's declaration are replaced with the actual type arguments from the defining type, create a
-   * property accessor member representing the given property accessor. Return the member that was
-   * created, or the base accessor if no member was created.
-   *
-   * @param baseAccessor the base property accessor for which a member might be created
-   * @param definingType the type defining the parameters and arguments to be used in the
-   *          substitution
-   * @return the property accessor element that will return the correctly substituted types
+   * If the given [accessor]'s type is different when any type parameters from
+   * the defining type's declaration are replaced with the actual type
+   * arguments from the [definingType], create an accessor member representing
+   * the given accessor. Return the member that was created, or the base
+   * accessor if no member was created.
    */
   static PropertyAccessorElement from(
-      PropertyAccessorElement baseAccessor, InterfaceType definingType) {
-    if (!_isChangedByTypeSubstitution(baseAccessor, definingType)) {
-      return baseAccessor;
+      PropertyAccessorElement accessor, InterfaceType definingType) {
+    if (!_isChangedByTypeSubstitution(accessor, definingType)) {
+      return accessor;
     }
     // TODO(brianwilkerson) Consider caching the substituted type in the
     // instance. It would use more memory but speed up some operations.
     // We need to see how often the type is being re-computed.
-    return new PropertyAccessorMember(baseAccessor, definingType);
+    return new PropertyAccessorMember(accessor, definingType);
   }
 
   /**
-   * Determine whether the given property accessor's type is changed when type parameters from the
-   * defining type's declaration are replaced with the actual type arguments from the defining type.
-   *
-   * @param baseAccessor the base property accessor
-   * @param definingType the type defining the parameters and arguments to be used in the
-   *          substitution
-   * @return true if the type is changed by type substitution.
+   * Determine whether the given property [accessor]'s type is changed when type
+   * parameters from the defining type's declaration are replaced with the
+   * actual type arguments from the [definingType].
    */
   static bool _isChangedByTypeSubstitution(
-      PropertyAccessorElement baseAccessor, InterfaceType definingType) {
+      PropertyAccessorElement accessor, InterfaceType definingType) {
     List<DartType> argumentTypes = definingType.typeArguments;
-    if (baseAccessor != null && argumentTypes.length != 0) {
-      FunctionType baseType = baseAccessor.type;
+    if (accessor != null && argumentTypes.length != 0) {
+      FunctionType baseType = accessor.type;
       if (baseType == null) {
         AnalysisEngine.instance.logger.logInformation(
-            'Type of $baseAccessor is null in PropertyAccessorMember._isChangedByTypeSubstitution');
+            'Type of $accessor is null in PropertyAccessorMember._isChangedByTypeSubstitution');
         return false;
       }
       List<DartType> parameterTypes = definingType.element.type.typeArguments;
@@ -9464,7 +8912,7 @@
       // If this property accessor is based on a field, that field might have a
       // propagated type. In which case we need to check whether the propagated
       // type of the field needs substitution.
-      PropertyInducingElement field = baseAccessor.variable;
+      PropertyInducingElement field = accessor.variable;
       if (!field.isSynthetic) {
         DartType baseFieldType = field.propagatedType;
         if (baseFieldType != null) {
@@ -9481,59 +8929,57 @@
 }
 
 /**
- * The interface `PropertyInducingElement` defines the behavior of elements representing a
- * variable that has an associated getter and possibly a setter. Note that explicitly defined
- * variables implicitly define a synthetic getter and that non-`final` explicitly defined
- * variables implicitly define a synthetic setter. Symmetrically, synthetic fields are implicitly
- * created for explicitly defined getters and setters. The following rules apply:
- * * Every explicit variable is represented by a non-synthetic [PropertyInducingElement].
- * * Every explicit variable induces a getter and possibly a setter, both of which are represented
- * by synthetic [PropertyAccessorElement]s.
+ * A variable that has an associated getter and possibly a setter. Note that
+ * explicitly defined variables implicitly define a synthetic getter and that
+ * non-`final` explicitly defined variables implicitly define a synthetic
+ * setter. Symmetrically, synthetic fields are implicitly created for explicitly
+ * defined getters and setters. The following rules apply:
+ *
+ * * Every explicit variable is represented by a non-synthetic
+ *   [PropertyInducingElement].
+ * * Every explicit variable induces a getter and possibly a setter, both of
+ *   which are represented by synthetic [PropertyAccessorElement]s.
  * * Every explicit getter or setter is represented by a non-synthetic
- * [PropertyAccessorElement].
- * * Every explicit getter or setter (or pair thereof if they have the same name) induces a
- * variable that is represented by a synthetic [PropertyInducingElement].
+ *   [PropertyAccessorElement].
+ * * Every explicit getter or setter (or pair thereof if they have the same
+ *   name) induces a variable that is represented by a synthetic
+ *   [PropertyInducingElement].
  */
 abstract class PropertyInducingElement implements VariableElement {
   /**
-   * Return the getter associated with this variable. If this variable was explicitly defined (is
-   * not synthetic) then the getter associated with it will be synthetic.
-   *
-   * @return the getter associated with this variable
+   * Return the getter associated with this variable. If this variable was
+   * explicitly defined (is not synthetic) then the getter associated with it
+   * will be synthetic.
    */
   PropertyAccessorElement get getter;
 
   /**
-   * Return `true` if this element is a static element. A static element is an element that is
-   * not associated with a particular instance, but rather with an entire library or class.
-   *
-   * @return `true` if this executable element is a static element
+   * Return `true` if this element is a static element. A static element is an
+   * element that is not associated with a particular instance, but rather with
+   * an entire library or class.
    */
   bool get isStatic;
 
   /**
-   * Return the propagated type of this variable, or `null` if type propagation has not been
-   * performed, for example because the variable is not final.
-   *
-   * @return the propagated type of this variable
+   * Return the propagated type of this variable, or `null` if type propagation
+   * has not been performed, for example because the variable is not final.
    */
   DartType get propagatedType;
 
   /**
-   * Return the setter associated with this variable, or `null` if the variable is effectively
-   * `final` and therefore does not have a setter associated with it. (This can happen either
-   * because the variable is explicitly defined as being `final` or because the variable is
-   * induced by an explicit getter that does not have a corresponding setter.) If this variable was
-   * explicitly defined (is not synthetic) then the setter associated with it will be synthetic.
-   *
-   * @return the setter associated with this variable
+   * Return the setter associated with this variable, or `null` if the variable
+   * is effectively `final` and therefore does not have a setter associated with
+   * it. (This can happen either because the variable is explicitly defined as
+   * being `final` or because the variable is induced by an explicit getter that
+   * does not have a corresponding setter.) If this variable was explicitly
+   * defined (is not synthetic) then the setter associated with it will be
+   * synthetic.
    */
   PropertyAccessorElement get setter;
 }
 
 /**
- * Instances of the class `PropertyInducingElementImpl` implement a
- * `PropertyInducingElement`.
+ * A concrete implementation of a [PropertyInducingElement].
  */
 abstract class PropertyInducingElementImpl extends VariableElementImpl
     implements PropertyInducingElement {
@@ -9549,44 +8995,40 @@
   PropertyAccessorElement getter;
 
   /**
-   * The setter associated with this element, or `null` if the element is effectively
-   * `final` and therefore does not have a setter associated with it.
+   * The setter associated with this element, or `null` if the element is
+   * effectively `final` and therefore does not have a setter associated with
+   * it.
    */
   PropertyAccessorElement setter;
 
   /**
-   * The propagated type of this variable, or `null` if type propagation has not been
-   * performed.
+   * The propagated type of this variable, or `null` if type propagation has not
+   * been performed.
    */
   DartType propagatedType;
 
   /**
-   * Initialize a newly created synthetic element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created synthetic element to have the given [name] and
+   * [offset].
    */
-  PropertyInducingElementImpl(String name, int nameOffset)
-      : super(name, nameOffset);
+  PropertyInducingElementImpl(String name, int offset) : super(name, offset);
 
   /**
-   * Initialize a newly created element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created element to have the given [name].
    */
   PropertyInducingElementImpl.forNode(Identifier name) : super.forNode(name);
 }
 
 /**
- * Instances of the class `RecursiveElementVisitor` implement an element visitor that will
- * recursively visit all of the element in an element model. For example, using an instance of this
- * class to visit a [CompilationUnitElement] will also cause all of the types in the
- * compilation unit to be visited.
+ * A visitor that will recursively visit all of the element in an element model.
+ * For example, using an instance of this class to visit a
+ * [CompilationUnitElement] will also cause all of the types in the compilation
+ * unit to be visited.
  *
- * Subclasses that override a visit method must either invoke the overridden visit method or must
- * explicitly ask the visited element to visit its children. Failure to do so will cause the
- * children of the visited element to not be visited.
+ * Subclasses that override a visit method must either invoke the overridden
+ * visit method or must explicitly ask the visited element to visit its
+ * children. Failure to do so will cause the children of the visited element to
+ * not be visited.
  */
 class RecursiveElementVisitor<R> implements ElementVisitor<R> {
   @override
@@ -9723,46 +9165,41 @@
 }
 
 /**
- * The interface `ShowElementCombinator` defines the behavior of combinators that cause some
- * of the names in a namespace to be visible (and the rest hidden) when being imported.
+ * A combinator that cause some of the names in a namespace to be visible (and
+ * the rest hidden) when being imported.
  */
 abstract class ShowElementCombinator implements NamespaceCombinator {
   /**
-   * Return the offset of the character immediately following the last character of this node.
-   *
-   * @return the offset of the character just past this node
+   * Return the offset of the character immediately following the last character
+   * of this node.
    */
   int get end;
 
   /**
    * Return the offset of the 'show' keyword of this element.
-   *
-   * @return the offset of the 'show' keyword of this element
    */
   int get offset;
 
   /**
-   * Return an array containing the names that are to be made visible in the importing library if
-   * they are defined in the imported library.
-   *
-   * @return the names from the imported library that are visible in the importing library
+   * Return a list containing the names that are to be made visible in the
+   * importing library if they are defined in the imported library.
    */
   List<String> get shownNames;
 }
 
 /**
- * Instances of the class `ShowElementCombinatorImpl` implement a
- * [ShowElementCombinator].
+ * A concrete implementation of a [ShowElementCombinator].
  */
 class ShowElementCombinatorImpl implements ShowElementCombinator {
   /**
-   * The names that are to be made visible in the importing library if they are defined in the
-   * imported library.
+   * The names that are to be made visible in the importing library if they are
+   * defined in the imported library.
    */
   List<String> shownNames = StringUtilities.EMPTY_ARRAY;
 
   /**
-   * The offset of the character immediately following the last character of this node.
+   * The offset of the character immediately following the last character of
+   * this node.
    */
   int end = -1;
 
@@ -9787,10 +9224,10 @@
 }
 
 /**
- * Instances of the class `SimpleElementVisitor` implement an element visitor that will do
- * nothing when visiting an element. It is intended to be a superclass for classes that use the
- * visitor pattern primarily as a dispatch mechanism (and hence don't need to recursively visit a
- * whole structure) and that only need to visit a small number of element types.
+ * A visitor that will do nothing when visiting an element. It is intended to be
+ * a superclass for classes that use the visitor pattern primarily as a dispatch
+ * mechanism (and hence don't need to recursively visit a whole structure) and
+ * that only need to visit a small number of element types.
  */
 class SimpleElementVisitor<R> implements ElementVisitor<R> {
   @override
@@ -9862,14 +9299,12 @@
 }
 
 /**
- * The interface `TopLevelVariableElement` defines the behavior of elements representing a
- * top-level variable.
+ * A top-level variable.
  */
 abstract class TopLevelVariableElement implements PropertyInducingElement {}
 
 /**
- * Instances of the class `TopLevelVariableElementImpl` implement a
- * `TopLevelVariableElement`.
+ * A concrete implementation of a [TopLevelVariableElement].
  */
 class TopLevelVariableElementImpl extends PropertyInducingElementImpl
     implements TopLevelVariableElement {
@@ -9880,19 +9315,14 @@
       const <TopLevelVariableElement>[];
 
   /**
-   * Initialize a newly created synthetic top-level variable element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created synthetic top-level variable element to have the
+   * given [name] and [offset].
    */
-  TopLevelVariableElementImpl(String name, int nameOffset)
-      : super(name, nameOffset);
+  TopLevelVariableElementImpl(String name, int offset) : super(name, offset);
 
   /**
-   * Initialize a newly created top-level variable element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created top-level variable element to have the given
+   * [name].
    */
   TopLevelVariableElementImpl.forNode(Identifier name) : super.forNode(name);
 
@@ -9917,8 +9347,8 @@
   static const List<DartType> EMPTY_ARRAY = const <DartType>[];
 
   /**
-   * The element representing the declaration of this type, or `null` if the type has not, or
-   * cannot, be associated with an element.
+   * The element representing the declaration of this type, or `null` if the
+   * type has not, or cannot, be associated with an element.
    */
   final Element _element;
 
@@ -9928,10 +9358,8 @@
   final String name;
 
   /**
-   * Initialize a newly created type to be declared by the given element and to have the given name.
-   *
-   * @param element the element representing the declaration of the type
-   * @param name the name of the type
+   * Initialize a newly created type to be declared by the given [element] and
+   * to have the given [name].
    */
   TypeImpl(this._element, this.name);
 
@@ -9993,17 +9421,15 @@
       isAssignableTo2(type, new HashSet<TypeImpl_TypePair>());
 
   /**
-   * Return `true` if this type is assignable to the given type. A type <i>T</i> may be
-   * assigned to a type <i>S</i>, written <i>T</i> &hArr; <i>S</i>, iff either <i>T</i> <: <i>S</i>
-   * or <i>S</i> <: <i>T</i> (Interface Types section of spec).
+   * Return `true` if this type is assignable to the given [type]. A type
+   * <i>T</i> may be assigned to a type <i>S</i>, written <i>T</i> &hArr;
+   * <i>S</i>, iff either <i>T</i> <: <i>S</i> or <i>S</i> <: <i>T</i>
+   * (Interface Types section of spec).
    *
-   * The given set of pairs of types (T1, T2), where each pair indicates that we invoked this method
-   * because we are in the process of answering the question of whether T1 is a subtype of T2, is
-   * used to prevent infinite loops.
-   *
-   * @param type the type being compared with this type
-   * @param visitedTypePairs the set of pairs of types used to prevent infinite loops
-   * @return `true` if this type is assignable to the given type
+   * The given set of [visitedTypePairs] of types (T1, T2), where each pair
+   * indicates that we invoked this method because we are in the process of
+   * answering the question of whether T1 is a subtype of T2, is used to prevent
+   * infinite loops.
    */
   bool isAssignableTo2(DartType type, Set<TypeImpl_TypePair> visitedTypePairs) {
     // Strictness matters for union types on the LHS, but not for union types
@@ -10053,16 +9479,14 @@
       isMoreSpecificThan2(type, false, new HashSet<TypeImpl_TypePair>());
 
   /**
-   * Return `true` if this type is more specific than the given type.
+   * Return `true` if this type is more specific than the given [type]. If
+   * [withDynamic] is `true`, then "dynamic" should be considered as a subtype
+   * of any type.
    *
-   * The given set of pairs of types (T1, T2), where each pair indicates that we invoked this method
-   * because we are in the process of answering the question of whether T1 is a subtype of T2, is
-   * used to prevent infinite loops.
-   *
-   * @param type the type being compared with this type
-   * @param withDynamic `true` if "dynamic" should be considered as a subtype of any type
-   * @param visitedTypePairs the set of pairs of types used to prevent infinite loops
-   * @return `true` if this type is more specific than the given type
+   * The given set of [visitedTypePairs] of types (T1, T2), where each pair
+   * indicates that we invoked this method because we are in the process of
+   * answering the question of whether T1 is a subtype of T2, is used to prevent
+   * infinite loops.
    */
   bool isMoreSpecificThan2(DartType type, bool withDynamic,
       Set<TypeImpl_TypePair> visitedTypePairs) {
@@ -10082,15 +9506,12 @@
       isSubtypeOf2(type, new HashSet<TypeImpl_TypePair>());
 
   /**
-   * Return `true` if this type is a subtype of the given type.
+   * Return `true` if this type is a subtype of the given [type].
    *
-   * The given set of pairs of types (T1, T2), where each pair indicates that we invoked this method
-   * because we are in the process of answering the question of whether T1 is a subtype of T2, is
-   * used to prevent infinite loops.
-   *
-   * @param type the type being compared with this type
-   * @param visitedTypePairs the set of pairs of types used to prevent infinite loops
-   * @return `true` if this type is a subtype of the given type
+   * The given set of [visitedTypePairs] of types (T1, T2), where each pair
+   * indicates that we invoked this method because we are in the process of
+   * answering the question of whether T1 is a subtype of T2, is used to prevent
+   * infinite loops.
    */
   bool isSubtypeOf2(DartType type, Set<TypeImpl_TypePair> visitedTypePairs) {
     // If the visitedTypePairs already has the pair (this, type), return false
@@ -10142,13 +9563,8 @@
   }
 
   /**
-   * Return an array containing the results of using the given argument types and parameter types to
-   * perform a substitution on all of the given types.
-   *
-   * @param types the types on which a substitution is to be performed
-   * @param argumentTypes the argument types for the substitution
-   * @param parameterTypes the parameter types for the substitution
-   * @return the result of performing the substitution on each of the types
+   * Return a list containing the results of using the given [argumentTypes] and
+   * [parameterTypes] to perform a substitution on all of the given [types].
    */
   static List<DartType> substitute(List<DartType> types,
       List<DartType> argumentTypes, List<DartType> parameterTypes) {
@@ -10164,13 +9580,31 @@
   }
 }
 
+/**
+ * A pair of types, used to prevent infinite recursion when performing certain
+ * computations.
+ */
 class TypeImpl_TypePair {
+  /**
+   * The first type in the pair.
+   */
   final DartType _firstType;
 
+  /**
+   * The second type in the pair.
+   */
   final DartType _secondType;
 
+  /**
+   * The hash code of the pair. This is cached on first access in order to
+   * improve performance.
+   */
   int _cachedHashCode;
 
+  /**
+   * Initialize a newly created pair of types to have the given [_firstType] and
+   * [_secondType].
+   */
   TypeImpl_TypePair(this._firstType, this._secondType);
 
   @override
@@ -10207,28 +9641,23 @@
 }
 
 /**
- * The interface `TypeParameterElement` defines the behavior of elements representing a type
- * parameter.
+ * A type parameter.
  */
 abstract class TypeParameterElement implements Element {
   /**
-   * Return the type representing the bound associated with this parameter, or `null` if this
-   * parameter does not have an explicit bound.
-   *
-   * @return the type representing the bound associated with this parameter
+   * Return the type representing the bound associated with this parameter, or
+   * `null` if this parameter does not have an explicit bound.
    */
   DartType get bound;
 
   /**
    * Return the type defined by this type parameter.
-   *
-   * @return the type defined by this type parameter
    */
   TypeParameterType get type;
 }
 
 /**
- * Instances of the class `TypeParameterElementImpl` implement a [TypeParameterElement].
+ * A concrete implementation of a [TypeParameterElement].
  */
 class TypeParameterElementImpl extends ElementImpl
     implements TypeParameterElement {
@@ -10244,25 +9673,19 @@
   TypeParameterType type;
 
   /**
-   * The type representing the bound associated with this parameter, or `null` if this
-   * parameter does not have an explicit bound.
+   * The type representing the bound associated with this parameter, or `null`
+   * if this parameter does not have an explicit bound.
    */
   DartType bound;
 
   /**
-   * Initialize a newly created method element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created method element to have the given [name] and
+   * [offset].
    */
-  TypeParameterElementImpl(String name, int nameOffset)
-      : super(name, nameOffset);
+  TypeParameterElementImpl(String name, int offset) : super(name, offset);
 
   /**
-   * Initialize a newly created type parameter element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created type parameter element to have the given [name].
    */
   TypeParameterElementImpl.forNode(Identifier name) : super.forNode(name);
 
@@ -10283,8 +9706,7 @@
 }
 
 /**
- * The interface `TypeParameterType` defines the behavior of objects representing the type
- * introduced by a type parameter.
+ * The type introduced by a type parameter.
  */
 abstract class TypeParameterType implements DartType {
   @override
@@ -10292,21 +9714,18 @@
 }
 
 /**
- * Instances of the class `TypeParameterTypeImpl` defines the behavior of objects representing
- * the type introduced by a type parameter.
+ * A concrete implementation of a [TypeParameterType].
  */
 class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
   /**
    * An empty list of type parameter types.
    */
-  static const List<TypeParameterType> EMPTY_ARRAY = const <TypeParameterType>[
-  ];
+  static const List<TypeParameterType> EMPTY_ARRAY =
+      const <TypeParameterType>[];
 
   /**
-   * Initialize a newly created type parameter type to be declared by the given element and to have
-   * the given name.
-   *
-   * @param element the element representing the declaration of the type parameter
+   * Initialize a newly created type parameter type to be declared by the given
+   * [element] and to have the given name.
    */
   TypeParameterTypeImpl(TypeParameterElement element)
       : super(element, element.name);
@@ -10405,12 +9824,8 @@
   }
 
   /**
-   * Return an array containing the type parameter types defined by the given array of type
-   * parameter elements.
-   *
-   * @param typeParameters the type parameter elements defining the type parameter types to be
-   *          returned
-   * @return the type parameter types defined by the type parameter elements
+   * Return a list containing the type parameter types defined by the given
+   * array of type parameter elements ([typeParameters]).
    */
   static List<TypeParameterType> getTypes(
       List<TypeParameterElement> typeParameters) {
@@ -10427,10 +9842,10 @@
 }
 
 /**
- * The interface `UndefinedElement` defines the behavior of pseudo-elements that represent
- * names that are undefined. This situation is not allowed by the language, so objects implementing
- * this interface always represent an error. As a result, most of the normal operations on elements
- * do not make sense and will return useless results.
+ * A pseudo-elements that represents names that are undefined. This situation is
+ * not allowed by the language, so objects implementing this interface always
+ * represent an error. As a result, most of the normal operations on elements do
+ * not make sense and will return useless results.
  */
 abstract class UndefinedElement implements Element {}
 
@@ -10449,8 +9864,6 @@
 
   /**
    * Return the unique instance of this class.
-   *
-   * @return the unique instance of this class
    */
   static UndefinedTypeImpl get instance => _INSTANCE;
 
@@ -10511,19 +9924,19 @@
 }
 
 /**
- * A flat immutable union of `Type`s. Here "flat" means a union type never contains another
- * union type.
+ * A union of other types. Union types are "flattened" in the sense that a union
+ * type never contains another union type.
  */
 abstract class UnionType implements DartType {
   /**
-   * @return an immutable view of the types in this union type.
+   * Return an immutable view of the types in this union type.
    */
   Set<DartType> get elements;
 }
 
 /**
- * In addition to the methods of the `UnionType` interface we add a factory method
- * `union` for building unions.
+ * In addition to the methods of the `UnionType` interface we add a factory
+ * method `union` for building unions.
  */
 class UnionTypeImpl extends TypeImpl implements UnionType {
   /**
@@ -10532,10 +9945,8 @@
   final Set<DartType> _types;
 
   /**
-   * This constructor should only be called by the `union` factory: it does not check that its
-   * argument `types` contains no union types.
-   *
-   * @param types
+   * This constructor should only be called by the `union` factory: it does not
+   * check that its argument [types] contains no union types.
    */
   UnionTypeImpl(this._types) : super(null, null);
 
@@ -10644,13 +10055,9 @@
   }
 
   /**
-   * The more-specific-than test for union types on the RHS is uniform in non-union LHSs. So, other
-   * `TypeImpl`s can call this method to implement `internalIsMoreSpecificThan` for
-   * union types.
-   *
-   * @param type
-   * @param visitedTypePairs
-   * @return true if `type` is more specific than this union type
+   * The more-specific-than test for union types on the RHS is uniform in
+   * non-union LHSs. So, other `TypeImpl`s can call this method to implement
+   * [internalIsMoreSpecificThan] for union types.
    */
   bool internalUnionTypeIsLessSpecificThan(DartType type, bool withDynamic,
       Set<TypeImpl_TypePair> visitedTypePairs) {
@@ -10670,12 +10077,9 @@
   }
 
   /**
-   * The supertype test for union types is uniform in non-union subtypes. So, other `TypeImpl`
-   * s can call this method to implement `internalIsSubtypeOf` for union types.
-   *
-   * @param type
-   * @param visitedTypePairs
-   * @return true if this union type is a super type of `type`
+   * The supertype test for union types is uniform in non-union subtypes. So,
+   * other `TypeImpl`s can call this method to implement `internalIsSubtypeOf`
+   * for union types.
    */
   bool internalUnionTypeIsSuperTypeOf(
       DartType type, Set<TypeImpl_TypePair> visitedTypePairs) {
@@ -10703,12 +10107,10 @@
   }
 
   /**
-   * Any unions in the `types` will be flattened in the returned union. If there is only one
-   * type after flattening then it will be returned directly, instead of a singleton union. Nulls
-   * are discarded, unless all types are null, in which case an exception is raised.
-   *
-   * @param types the `Type`s to union
-   * @return a `Type` comprising the `Type`s in `types`
+   * Return the union of the given [types]. Any unions in the [types] will be
+   * flattened in the returned union. If there is only one type after flattening
+   * then it will be returned directly, instead of a singleton union. Nulls are
+   * discarded, unless all types are null, in which case an exception is raised.
    */
   static DartType union(List<DartType> types) {
     Set<DartType> set = new HashSet<DartType>();
@@ -10737,37 +10139,30 @@
 }
 
 /**
- * The interface `UriReferencedElement` defines the behavior of objects included into a
- * library using some URI.
+ * An element included into a library using some URI.
  */
 abstract class UriReferencedElement implements Element {
   /**
-   * Return the URI that is used to include this element into the enclosing library, or `null`
-   * if this is the defining compilation unit of a library.
-   *
-   * @return the URI that is used to include this element into the enclosing library
+   * Return the URI that is used to include this element into the enclosing
+   * library, or `null` if this is the defining compilation unit of a library.
    */
   String get uri;
 
   /**
-   * Return the offset of the character immediately following the last character of this node's URI,
-   * or `-1` for synthetic import.
-   *
-   * @return the offset of the character just past the node's URI
+   * Return the offset of the character immediately following the last character
+   * of this node's URI, or `-1` for synthetic import.
    */
   int get uriEnd;
 
   /**
-   * Return the offset of the URI in the file, or `-1` if this element is synthetic.
-   *
-   * @return the offset of the URI
+   * Return the offset of the URI in the file, or `-1` if this element is
+   * synthetic.
    */
   int get uriOffset;
 }
 
 /**
- * Instances of the class `UriReferencedElementImpl` implement an [UriReferencedElement]
- * .
+ * A concrete implementation of a [UriReferencedElement].
  */
 abstract class UriReferencedElementImpl extends ElementImpl
     implements UriReferencedElement {
@@ -10777,8 +10172,8 @@
   int uriOffset = -1;
 
   /**
-   * The offset of the character immediately following the last character of this node's URI, may be
-   * `-1` if synthetic.
+   * The offset of the character immediately following the last character of
+   * this node's URI, may be `-1` if synthetic.
    */
   int uriEnd = -1;
 
@@ -10788,67 +10183,56 @@
   String uri;
 
   /**
-   * Initialize a newly created import element.
-   *
-   * @param name the name of this element
-   * @param offset the directive offset, may be `-1` if synthetic.
+   * Initialize a newly created import element to heve the given [name] and
+   * [offset]. The offset may be `-1` if the element is synthetic.
    */
   UriReferencedElementImpl(String name, int offset) : super(name, offset);
 }
 
 /**
- * The interface `VariableElement` defines the behavior common to elements that represent a
- * variable.
+ * A variable. There are concrete subclasses for different kinds of variables.
  */
 abstract class VariableElement implements Element {
   /**
-   * Return a synthetic function representing this variable's initializer, or `null` if this
-   * variable does not have an initializer. The function will have no parameters. The return type of
-   * the function will be the compile-time type of the initialization expression.
-   *
-   * @return a synthetic function representing this variable's initializer
+   * Return a synthetic function representing this variable's initializer, or
+   * `null` if this variable does not have an initializer. The function will
+   * have no parameters. The return type of the function will be the
+   * compile-time type of the initialization expression.
    */
   FunctionElement get initializer;
 
   /**
    * Return `true` if this variable was declared with the 'const' modifier.
-   *
-   * @return `true` if this variable was declared with the 'const' modifier
    */
   bool get isConst;
 
   /**
-   * Return `true` if this variable was declared with the 'final' modifier. Variables that are
-   * declared with the 'const' modifier will return `false` even though they are implicitly
-   * final.
-   *
-   * @return `true` if this variable was declared with the 'final' modifier
+   * Return `true` if this variable was declared with the 'final' modifier.
+   * Variables that are declared with the 'const' modifier will return `false`
+   * even though they are implicitly final.
    */
   bool get isFinal;
 
   /**
-   * Return the resolved [VariableDeclaration] node that declares this [VariableElement]
-   * .
+   * Return the resolved [VariableDeclaration] node that declares this
+   * [VariableElement].
    *
-   * This method is expensive, because resolved AST might be evicted from cache, so parsing and
-   * resolving will be performed.
-   *
-   * @return the resolved [VariableDeclaration], not `null`.
+   * This method is expensive, because resolved AST might be evicted from cache,
+   * so parsing and resolving will be performed.
    */
   @override
   VariableDeclaration get node;
 
   /**
-   * Return the declared type of this variable, or `null` if the variable did not have a
-   * declared type (such as if it was declared using the keyword 'var').
-   *
-   * @return the declared type of this variable
+   * Return the declared type of this variable, or `null` if the variable did
+   * not have a declared type (such as if it was declared using the keyword
+   * 'var').
    */
   DartType get type;
 }
 
 /**
- * Instances of the class `VariableElementImpl` implement a `VariableElement`.
+ * A concrete implementation of a [VariableElement].
  */
 abstract class VariableElementImpl extends ElementImpl
     implements VariableElement {
@@ -10863,50 +10247,40 @@
   DartType type;
 
   /**
-   * A synthetic function representing this variable's initializer, or `null` if this variable
-   * does not have an initializer.
+   * A synthetic function representing this variable's initializer, or `null` if
+   * this variable does not have an initializer.
    */
   FunctionElement _initializer;
 
   /**
-   * Initialize a newly created variable element to have the given name.
-   *
-   * @param name the name of this element
-   * @param nameOffset the offset of the name of this element in the file that contains the
-   *          declaration of this element
+   * Initialize a newly created variable element to have the given [name] and
+   * [offset].
    */
-  VariableElementImpl(String name, int nameOffset) : super(name, nameOffset);
+  VariableElementImpl(String name, int offset) : super(name, offset);
 
   /**
-   * Initialize a newly created variable element to have the given name.
-   *
-   * @param name the name of this element
+   * Initialize a newly created variable element to have the given [name].
    */
   VariableElementImpl.forNode(Identifier name) : super.forNode(name);
 
   /**
-   * Set whether this variable is const to correspond to the given value.
-   *
-   * @param isConst `true` if the variable is const
+   * Set whether this variable is const.
    */
   void set const3(bool isConst) {
     setModifier(Modifier.CONST, isConst);
   }
 
   /**
-   * Return the result of evaluating this variable's initializer as a compile-time constant
-   * expression, or `null` if this variable is not a 'const' variable, if it does not have an
-   * initializer, or if the compilation unit containing the variable has not been resolved.
-   *
-   * @return the result of evaluating this variable's initializer
+   * Return the result of evaluating this variable's initializer as a
+   * compile-time constant expression, or `null` if this variable is not a
+   * 'const' variable, if it does not have an initializer, or if the compilation
+   * unit containing the variable has not been resolved.
    */
   EvaluationResultImpl get evaluationResult => null;
 
   /**
-   * Set the result of evaluating this variable's initializer as a compile-time constant expression
-   * to the given result.
-   *
-   * @param result the result of evaluating this variable's initializer
+   * Set the result of evaluating this variable's initializer as a compile-time
+   * constant expression to the given [result].
    */
   void set evaluationResult(EvaluationResultImpl result) {
     throw new IllegalStateException(
@@ -10914,9 +10288,7 @@
   }
 
   /**
-   * Set whether this variable is final to correspond to the given value.
-   *
-   * @param isFinal `true` if the variable is final
+   * Set whether this variable is final.
    */
   void set final2(bool isFinal) {
     setModifier(Modifier.FINAL, isFinal);
@@ -10926,15 +10298,14 @@
   FunctionElement get initializer => _initializer;
 
   /**
-   * Set the function representing this variable's initializer to the given function.
-   *
-   * @param initializer the function representing this variable's initializer
+   * Set the function representing this variable's initializer to the given
+   * [function].
    */
-  void set initializer(FunctionElement initializer) {
-    if (initializer != null) {
-      (initializer as FunctionElementImpl).enclosingElement = this;
+  void set initializer(FunctionElement function) {
+    if (function != null) {
+      (function as FunctionElementImpl).enclosingElement = this;
     }
-    this._initializer = initializer;
+    this._initializer = function;
   }
 
   @override
@@ -10944,20 +10315,18 @@
   bool get isFinal => hasModifier(Modifier.FINAL);
 
   /**
-   * Return `true` if this variable is potentially mutated somewhere in a closure. This
-   * information is only available for local variables (including parameters) and only after the
-   * compilation unit containing the variable has been resolved.
-   *
-   * @return `true` if this variable is potentially mutated somewhere in closure
+   * Return `true` if this variable is potentially mutated somewhere in a
+   * closure. This information is only available for local variables (including
+   * parameters) and only after the compilation unit containing the variable has
+   * been resolved.
    */
   bool get isPotentiallyMutatedInClosure => false;
 
   /**
-   * Return `true` if this variable is potentially mutated somewhere in its scope. This
-   * information is only available for local variables (including parameters) and only after the
-   * compilation unit containing the variable has been resolved.
-   *
-   * @return `true` if this variable is potentially mutated somewhere in its scope
+   * Return `true` if this variable is potentially mutated somewhere in its
+   * scope. This information is only available for local variables (including
+   * parameters) and only after the compilation unit containing the variable has
+   * been resolved.
    */
   bool get isPotentiallyMutatedInScope => false;
 
@@ -10980,17 +10349,13 @@
 }
 
 /**
- * The abstract class `VariableMember` defines the behavior common to members that represent a
- * variable element defined in a parameterized type where the values of the type parameters are
- * known.
+ * A variable element defined in a parameterized type where the values of the
+ * type parameters are known.
  */
 abstract class VariableMember extends Member implements VariableElement {
   /**
-   * Initialize a newly created element to represent an executable element of the given
-   * parameterized type.
-   *
-   * @param baseElement the element on which the parameterized element was created
-   * @param definingType the type in which the element is defined
+   * Initialize a newly created element to represent a constructor, based on the
+   * [baseElement], defined by the [definingType].
    */
   VariableMember(VariableElement baseElement, ParameterizedType definingType)
       : super(baseElement, definingType);
@@ -11030,8 +10395,7 @@
 }
 
 /**
- * The interface `VoidType` defines the behavior of the unique object representing the type
- * `void`.
+ * The type `void`.
  */
 abstract class VoidType implements DartType {
   @override
@@ -11040,7 +10404,7 @@
 }
 
 /**
- * The unique instance of the class `VoidTypeImpl` implements the type `void`.
+ * A concrete implementation of a [VoidType].
  */
 class VoidTypeImpl extends TypeImpl implements VoidType {
   /**
@@ -11050,8 +10414,6 @@
 
   /**
    * Return the unique instance of this class.
-   *
-   * @return the unique instance of this class
    */
   static VoidTypeImpl get instance => _INSTANCE;
 
diff --git a/pkg/analyzer/lib/src/generated/element_handle.dart b/pkg/analyzer/lib/src/generated/element_handle.dart
index 7fd2913..d29787e 100644
--- a/pkg/analyzer/lib/src/generated/element_handle.dart
+++ b/pkg/analyzer/lib/src/generated/element_handle.dart
@@ -12,6 +12,7 @@
 import 'engine.dart';
 import 'java_core.dart';
 import 'java_engine.dart';
+import 'resolver.dart';
 import 'source.dart';
 import 'utilities_dart.dart';
 
@@ -81,9 +82,6 @@
   List<InterfaceType> get mixins => actualElement.mixins;
 
   @override
-  ClassDeclaration get node => actualElement.node;
-
-  @override
   InterfaceType get supertype => actualElement.supertype;
 
   @override
@@ -504,6 +502,9 @@
   List<FunctionElement> get functions => actualElement.functions;
 
   @override
+  bool get isAbstract => actualElement.isAbstract;
+
+  @override
   bool get isAsynchronous => actualElement.isAsynchronous;
 
   @override
@@ -613,6 +614,9 @@
   FunctionElement get actualElement => super.actualElement as FunctionElement;
 
   @override
+  bool get isEntryPoint => actualElement.isEntryPoint;
+
+  @override
   ElementKind get kind => ElementKind.FUNCTION;
 
   @override
@@ -751,6 +755,9 @@
   List<LibraryElement> get exportedLibraries => actualElement.exportedLibraries;
 
   @override
+  Namespace get exportNamespace => actualElement.exportNamespace;
+
+  @override
   List<ExportElement> get exports => actualElement.exports;
 
   @override
@@ -787,6 +794,9 @@
   List<PrefixElement> get prefixes => actualElement.prefixes;
 
   @override
+  Namespace get publicNamespace => actualElement.publicNamespace;
+
+  @override
   List<CompilationUnitElement> get units => actualElement.units;
 
   @override
@@ -846,9 +856,6 @@
   ClassElement get enclosingElement => super.enclosingElement as ClassElement;
 
   @override
-  bool get isAbstract => actualElement.isAbstract;
-
-  @override
   bool get isStatic => actualElement.isStatic;
 
   @override
@@ -945,9 +952,6 @@
       actualElement.correspondingSetter;
 
   @override
-  bool get isAbstract => actualElement.isAbstract;
-
-  @override
   bool get isGetter => actualElement.isGetter;
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 4084137..afdf322 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -15,53 +15,61 @@
 import 'utilities_dart.dart';
 
 /**
- * Instances of the class `ElementResolver` are used by instances of [ResolverVisitor]
- * to resolve references within the AST structure to the elements being referenced. The requirements
- * for the element resolver are:
- * <ol>
- * * Every [SimpleIdentifier] should be resolved to the element to which it refers.
- * Specifically:
- * * An identifier within the declaration of that name should resolve to the element being
- * declared.
- * * An identifier denoting a prefix should resolve to the element representing the import that
- * defines the prefix (an [ImportElement]).
- * * An identifier denoting a variable should resolve to the element representing the variable (a
- * [VariableElement]).
- * * An identifier denoting a parameter should resolve to the element representing the parameter
- * (a [ParameterElement]).
- * * An identifier denoting a field should resolve to the element representing the getter or
- * setter being invoked (a [PropertyAccessorElement]).
- * * An identifier denoting the name of a method or function being invoked should resolve to the
- * element representing the method or function (a [ExecutableElement]).
- * * An identifier denoting a label should resolve to the element representing the label (a
- * [LabelElement]).
- * The identifiers within directives are exceptions to this rule and are covered below.
- * * Every node containing a token representing an operator that can be overridden (
- * [BinaryExpression], [PrefixExpression], [PostfixExpression]) should resolve to
- * the element representing the method invoked by that operator (a [MethodElement]).
- * * Every [FunctionExpressionInvocation] should resolve to the element representing the
- * function being invoked (a [FunctionElement]). This will be the same element as that to
- * which the name is resolved if the function has a name, but is provided for those cases where an
- * unnamed function is being invoked.
- * * Every [LibraryDirective] and [PartOfDirective] should resolve to the element
- * representing the library being specified by the directive (a [LibraryElement]) unless, in
- * the case of a part-of directive, the specified library does not exist.
- * * Every [ImportDirective] and [ExportDirective] should resolve to the element
- * representing the library being specified by the directive unless the specified library does not
- * exist (an [ImportElement] or [ExportElement]).
- * * The identifier representing the prefix in an [ImportDirective] should resolve to the
- * element representing the prefix (a [PrefixElement]).
- * * The identifiers in the hide and show combinators in [ImportDirective]s and
- * [ExportDirective]s should resolve to the elements that are being hidden or shown,
- * respectively, unless those names are not defined in the specified library (or the specified
- * library does not exist).
- * * Every [PartDirective] should resolve to the element representing the compilation unit
- * being specified by the string unless the specified compilation unit does not exist (a
- * [CompilationUnitElement]).
- * </ol>
- * Note that AST nodes that would represent elements that are not defined are not resolved to
- * anything. This includes such things as references to undeclared variables (which is an error) and
- * names in hide and show combinators that are not defined in the imported library (which is not an
+ * An object used by instances of [ResolverVisitor] to resolve references within
+ * the AST structure to the elements being referenced. The requirements for the
+ * element resolver are:
+ *
+ * 1. Every [SimpleIdentifier] should be resolved to the element to which it
+ *    refers. Specifically:
+ *    * An identifier within the declaration of that name should resolve to the
+ *      element being declared.
+ *    * An identifier denoting a prefix should resolve to the element
+ *      representing the import that defines the prefix (an [ImportElement]).
+ *    * An identifier denoting a variable should resolve to the element
+ *      representing the variable (a [VariableElement]).
+ *    * An identifier denoting a parameter should resolve to the element
+ *      representing the parameter (a [ParameterElement]).
+ *    * An identifier denoting a field should resolve to the element
+ *      representing the getter or setter being invoked (a
+ *      [PropertyAccessorElement]).
+ *    * An identifier denoting the name of a method or function being invoked
+ *      should resolve to the element representing the method or function (an
+ *      [ExecutableElement]).
+ *    * An identifier denoting a label should resolve to the element
+ *      representing the label (a [LabelElement]).
+ *    The identifiers within directives are exceptions to this rule and are
+ *    covered below.
+ * 2. Every node containing a token representing an operator that can be
+ *    overridden ( [BinaryExpression], [PrefixExpression], [PostfixExpression])
+ *    should resolve to the element representing the method invoked by that
+ *    operator (a [MethodElement]).
+ * 3. Every [FunctionExpressionInvocation] should resolve to the element
+ *    representing the function being invoked (a [FunctionElement]). This will
+ *    be the same element as that to which the name is resolved if the function
+ *    has a name, but is provided for those cases where an unnamed function is
+ *    being invoked.
+ * 4. Every [LibraryDirective] and [PartOfDirective] should resolve to the
+ *    element representing the library being specified by the directive (a
+ *    [LibraryElement]) unless, in the case of a part-of directive, the
+ *    specified library does not exist.
+ * 5. Every [ImportDirective] and [ExportDirective] should resolve to the
+ *    element representing the library being specified by the directive unless
+ *    the specified library does not exist (an [ImportElement] or
+ *    [ExportElement]).
+ * 6. The identifier representing the prefix in an [ImportDirective] should
+ *    resolve to the element representing the prefix (a [PrefixElement]).
+ * 7. The identifiers in the hide and show combinators in [ImportDirective]s
+ *    and [ExportDirective]s should resolve to the elements that are being
+ *    hidden or shown, respectively, unless those names are not defined in the
+ *    specified library (or the specified library does not exist).
+ * 8. Every [PartDirective] should resolve to the element representing the
+ *    compilation unit being specified by the string unless the specified
+ *    compilation unit does not exist (a [CompilationUnitElement]).
+ *
+ * Note that AST nodes that would represent elements that are not defined are
+ * not resolved to anything. This includes such things as references to
+ * undeclared variables (which is an error) and names in hide and show
+ * combinators that are not defined in the imported library (which is not an
  * error).
  */
 class ElementResolver extends SimpleAstVisitor<Object> {
@@ -81,6 +89,12 @@
   bool _enableHints = false;
 
   /**
+   * A flag indicating whether we should strictly follow the specification when
+   * generating warnings on "call" methods (fixes dartbug.com/21938).
+   */
+  bool _enableStrictCallChecks = false;
+
+  /**
    * The type representing the type 'dynamic'.
    */
   DartType _dynamicType;
@@ -91,7 +105,8 @@
   DartType _typeType;
 
   /**
-   * A utility class for the resolver to answer the question of "what are my subtypes?".
+   * A utility class for the resolver to answer the question of "what are my
+   * subtypes?".
    */
   SubtypeManager _subtypeManager;
 
@@ -101,14 +116,14 @@
   TypePromotionManager _promoteManager;
 
   /**
-   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
-   *
-   * @param resolver the resolver driving this participant
+   * Initialize a newly created visitor to work for the given [_resolver] to
+   * resolve the nodes in a compilation unit.
    */
   ElementResolver(this._resolver) {
     this._definingLibrary = _resolver.definingLibrary;
     AnalysisOptions options = _definingLibrary.context.analysisOptions;
     _enableHints = options.hint;
+    _enableStrictCallChecks = options.enableStrictCallChecks;
     _dynamicType = _resolver.typeProvider.dynamicType;
     _typeType = _resolver.typeProvider.typeType;
     _subtypeManager = new SubtypeManager();
@@ -116,7 +131,8 @@
   }
 
   /**
-   * @return `true` iff current enclosing function is constant constructor declaration.
+   * Return `true` iff the current enclosing function is a constant constructor
+   * declaration.
    */
   bool get isInConstConstructor {
     ExecutableElement function = _resolver.enclosingFunction;
@@ -223,8 +239,7 @@
         simpleIdentifier.staticElement = element;
         if (node.newKeyword != null) {
           if (element is ClassElement) {
-            ConstructorElement constructor =
-                (element as ClassElement).unnamedConstructor;
+            ConstructorElement constructor = element.unnamedConstructor;
             if (constructor == null) {
               // TODO(brianwilkerson) Report this error.
             } else {
@@ -262,14 +277,12 @@
         name.staticElement = element;
         if (node.newKeyword == null) {
           if (element is ClassElement) {
-            Element memberElement = _lookupGetterOrMethod(
-                (element as ClassElement).type, name.name);
+            Element memberElement =
+                _lookupGetterOrMethod(element.type, name.name);
             if (memberElement == null) {
-              memberElement =
-                  (element as ClassElement).getNamedConstructor(name.name);
+              memberElement = element.getNamedConstructor(name.name);
               if (memberElement == null) {
-                memberElement = _lookUpSetter(
-                    prefix, (element as ClassElement).type, name.name);
+                memberElement = _lookUpSetter(prefix, element.type, name.name);
               }
             }
             if (memberElement == null) {
@@ -283,7 +296,7 @@
         } else {
           if (element is ClassElement) {
             ConstructorElement constructor =
-                (element as ClassElement).getNamedConstructor(name.name);
+                element.getNamedConstructor(name.name);
             if (constructor == null) {
               // TODO(brianwilkerson) Report this error.
             } else {
@@ -627,8 +640,7 @@
         // TODO(collinsn): an improvement here is to make the propagated type
         // of the method call the union of the propagated types of all possible
         // calls.
-        if (_lookupMethods(
-                target, propagatedType as UnionType, methodName.name).length >
+        if (_lookupMethods(target, propagatedType, methodName.name).length >
             1) {
           return null;
         }
@@ -665,9 +677,8 @@
     if (identical(
         errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) {
       _resolver.reportErrorForNode(
-          StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName, [
-        methodName.name
-      ]);
+          StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName,
+          [methodName.name]);
     } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) {
       _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_FUNCTION,
           methodName, [methodName.name]);
@@ -695,7 +706,8 @@
             targetType = _getStaticType(target);
           }
         }
-        if (targetType != null &&
+        if (!_enableStrictCallChecks &&
+            targetType != null &&
             targetType.isDartCoreFunction &&
             methodName.name == FunctionElement.CALL_METHOD_NAME) {
           // TODO(brianwilkerson) Can we ever resolve the function being
@@ -707,8 +719,10 @@
         ErrorCode proxyErrorCode = (generatedWithTypePropagation
             ? HintCode.UNDEFINED_METHOD
             : StaticTypeWarningCode.UNDEFINED_METHOD);
-        _recordUndefinedNode(targetType.element, proxyErrorCode,
-            methodName, [methodName.name, targetTypeName]);
+        _recordUndefinedNode(targetType.element, proxyErrorCode, methodName, [
+          methodName.name,
+          targetTypeName
+        ]);
       }
     } else if (identical(
         errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) {
@@ -1083,11 +1097,8 @@
   }
 
   /**
-   * Generate annotation elements for each of the annotations in the given node list and add them to
-   * the given list of elements.
-   *
-   * @param annotationList the list of elements to which new elements are to be added
-   * @param annotations the AST nodes used to generate new elements
+   * Generate annotation elements for each of the annotations in the
+   * [annotationList] and add them to the given list of [annotations].
    */
   void _addAnnotations(List<ElementAnnotationImpl> annotationList,
       NodeList<Annotation> annotations) {
@@ -1105,13 +1116,11 @@
   }
 
   /**
-   * Given that we have found code to invoke the given element, return the error code that should be
-   * reported, or `null` if no error should be reported.
-   *
-   * @param target the target of the invocation, or `null` if there was no target
-   * @param useStaticContext
-   * @param element the element to be invoked
-   * @return the error code that should be reported
+   * Given that we have found code to invoke the given [element], return the
+   * error code that should be reported, or `null` if no error should be
+   * reported. The [target] is the target of the invocation, or `null` if there
+   * was no target. The flag [useStaticContext] should be `true` if the
+   * invocation is in a static constant (does not have access to instance state.
    */
   ErrorCode _checkForInvocationError(
       Expression target, bool useStaticContext, Element element) {
@@ -1196,17 +1205,13 @@
   }
 
   /**
-   * Check that the for some index expression that the method element was resolved, otherwise a
-   * [StaticTypeWarningCode.UNDEFINED_OPERATOR] is generated.
-   *
-   * @param node the index expression to resolve
-   * @param target the target of the expression
-   * @param methodName the name of the operator associated with the context of using of the given
-   *          index expression
-   * @return `true` if and only if an error code is generated on the passed node
+   * Check that the given index [expression] was resolved, otherwise a
+   * [StaticTypeWarningCode.UNDEFINED_OPERATOR] is generated. The [target] is
+   * the target of the expression. The [methodName] is the name of the operator
+   * associated with the context of using of the given index expression.
    */
-  bool _checkForUndefinedIndexOperator(IndexExpression node, Expression target,
-      String methodName, MethodElement staticMethod,
+  bool _checkForUndefinedIndexOperator(IndexExpression expression,
+      Expression target, String methodName, MethodElement staticMethod,
       MethodElement propagatedMethod, DartType staticType,
       DartType propagatedType) {
     bool shouldReportMissingMember_static =
@@ -1219,8 +1224,8 @@
                 propagatedType.element, methodName, true, false);
     if (shouldReportMissingMember_static ||
         shouldReportMissingMember_propagated) {
-      sc.Token leftBracket = node.leftBracket;
-      sc.Token rightBracket = node.rightBracket;
+      sc.Token leftBracket = expression.leftBracket;
+      sc.Token rightBracket = expression.rightBracket;
       ErrorCode errorCode;
       if (shouldReportMissingMember_static) {
         if (target is SuperExpression) {
@@ -1234,13 +1239,17 @@
       DartType type =
           shouldReportMissingMember_static ? staticType : propagatedType;
       if (leftBracket == null || rightBracket == null) {
-        _recordUndefinedNode(
-            type.element, errorCode, node, [methodName, type.displayName]);
+        _recordUndefinedNode(type.element, errorCode, expression, [
+          methodName,
+          type.displayName
+        ]);
       } else {
         int offset = leftBracket.offset;
         int length = rightBracket.offset - offset + 1;
-        _recordUndefinedOffset(type.element, errorCode,
-            offset, length, [methodName, type.displayName]);
+        _recordUndefinedOffset(type.element, errorCode, offset, length, [
+          methodName,
+          type.displayName
+        ]);
       }
       return true;
     }
@@ -1248,13 +1257,10 @@
   }
 
   /**
-   * Given a list of arguments and the element that will be invoked using those argument, compute
-   * the list of parameters that correspond to the list of arguments. Return the parameters that
-   * correspond to the arguments, or `null` if no correspondence could be computed.
-   *
-   * @param argumentList the list of arguments being passed to the element
-   * @param executableElement the element that will be invoked with the arguments
-   * @return the parameters that correspond to the arguments
+   * Given an [argumentList] and the executable [element] that  will be invoked
+   * using those arguments, compute the list of parameters that correspond to
+   * the list of arguments. Return the parameters that correspond to the
+   * arguments, or `null` if no correspondence could be computed.
    */
   List<ParameterElement> _computeCorrespondingParameters(
       ArgumentList argumentList, Element element) {
@@ -1300,11 +1306,8 @@
   }
 
   /**
-   * If the given element is a setter, return the getter associated with it. Otherwise, return the
-   * element unchanged.
-   *
-   * @param element the element to be normalized
-   * @return a non-setter element derived from the given element
+   * If the given [element] is a setter, return the getter associated with it.
+   * Otherwise, return the element unchanged.
    */
   Element _convertSetterToGetter(Element element) {
     // TODO(brianwilkerson) Determine whether and why the element could ever be
@@ -1316,22 +1319,16 @@
   }
 
   /**
-   * Return `true` if the given element is not a proxy.
-   *
-   * @param element the enclosing element. If null, `true` will be returned.
-   * @return `false` iff the passed [Element] is a [ClassElement] that is a proxy
-   *         or inherits proxy
-   * See [ClassElement.isOrInheritsProxy].
+   * Return `true` if the given [element] is not a proxy. See
+   * [ClassElement.isOrInheritsProxy].
    */
   bool _doesntHaveProxy(Element element) =>
       !(element is ClassElement && element.isOrInheritsProxy);
 
   /**
-   * Look for any declarations of the given identifier that are imported using a prefix. Return the
-   * element that was found, or `null` if the name is not imported using a prefix.
-   *
-   * @param identifier the identifier that might have been imported using a prefix
-   * @return the element that was found
+   * Look for any declarations of the given [identifier] that are imported using
+   * a prefix. Return the element that was found, or `null` if the name is not
+   * imported using a prefix.
    */
   Element _findImportWithoutPrefix(SimpleIdentifier identifier) {
     Element element = null;
@@ -1357,11 +1354,8 @@
   }
 
   /**
-   * Assuming that the given expression is a prefix for a deferred import, return the library that
-   * is being imported.
-   *
-   * @param expression the expression representing the deferred import's prefix
-   * @return the library that is being imported by the import associated with the prefix
+   * Assuming that the given [expression] is a prefix for a deferred import,
+   * return the library that is being imported.
    */
   LibraryElement _getImportedLibrary(Expression expression) {
     PrefixElement prefixElement =
@@ -1372,24 +1366,18 @@
   }
 
   /**
-   * Return the name of the method invoked by the given postfix expression.
-   *
-   * @param node the postfix expression being invoked
-   * @return the name of the method invoked by the expression
+   * Return the name of the method invoked by the given postfix [expression].
    */
-  String _getPostfixOperator(PostfixExpression node) =>
-      (node.operator.type == sc.TokenType.PLUS_PLUS)
+  String _getPostfixOperator(PostfixExpression expression) =>
+      (expression.operator.type == sc.TokenType.PLUS_PLUS)
           ? sc.TokenType.PLUS.lexeme
           : sc.TokenType.MINUS.lexeme;
 
   /**
-   * Return the name of the method invoked by the given postfix expression.
-   *
-   * @param node the postfix expression being invoked
-   * @return the name of the method invoked by the expression
+   * Return the name of the method invoked by the given postfix [expression].
    */
-  String _getPrefixOperator(PrefixExpression node) {
-    sc.Token operator = node.operator;
+  String _getPrefixOperator(PrefixExpression expression) {
+    sc.Token operator = expression.operator;
     sc.TokenType operatorType = operator.type;
     if (operatorType == sc.TokenType.PLUS_PLUS) {
       return sc.TokenType.PLUS.lexeme;
@@ -1403,10 +1391,8 @@
   }
 
   /**
-   * Return the propagated type of the given expression that is to be used for type analysis.
-   *
-   * @param expression the expression whose type is to be returned
-   * @return the type of the given expression
+   * Return the propagated type of the given [expression] that is to be used for
+   * type analysis.
    */
   DartType _getPropagatedType(Expression expression) {
     DartType propagatedType = _resolveTypeParameter(expression.propagatedType);
@@ -1421,10 +1407,8 @@
   }
 
   /**
-   * Return the static type of the given expression that is to be used for type analysis.
-   *
-   * @param expression the expression whose type is to be returned
-   * @return the type of the given expression
+   * Return the static type of the given [expression] that is to be used for
+   * type analysis.
    */
   DartType _getStaticType(Expression expression) {
     if (expression is NullLiteral) {
@@ -1442,10 +1426,7 @@
   }
 
   /**
-   * Return `true` if the given expression is a prefix for a deferred import.
-   *
-   * @param expression the expression being tested
-   * @return `true` if the given expression is a prefix for a deferred import
+   * Return `true` if the given [expression] is a prefix for a deferred import.
    */
   bool _isDeferredPrefix(Expression expression) {
     if (expression is! SimpleIdentifier) {
@@ -1465,17 +1446,14 @@
   }
 
   /**
-   * Return `true` if the given type represents an object that could be invoked using the call
-   * operator '()'.
-   *
-   * @param type the type being tested
-   * @return `true` if the given type represents an object that could be invoked
+   * Return `true` if the given [type] represents an object that could be
+   * invoked using the call operator '()'.
    */
   bool _isExecutableType(DartType type) {
-    if (type.isDynamic ||
-        (type is FunctionType) ||
-        type.isDartCoreFunction ||
-        type.isObject) {
+    if (type.isDynamic || type is FunctionType) {
+      return true;
+    } else if (!_enableStrictCallChecks &&
+        (type.isDartCoreFunction || type.isObject)) {
       return true;
     } else if (type is InterfaceType) {
       ClassElement classElement = type.element;
@@ -1495,10 +1473,7 @@
   }
 
   /**
-   * Return `true` if the given element is a static element.
-   *
-   * @param element the element being tested
-   * @return `true` if the given element is a static element
+   * Return `true` if the given [element] is a static element.
    */
   bool _isStatic(Element element) {
     if (element is ExecutableElement) {
@@ -1510,12 +1485,9 @@
   }
 
   /**
-   * Return `true` if the given node can validly be resolved to a prefix:
+   * Return `true` if the given [node] can validly be resolved to a prefix:
    * * it is the prefix in an import directive, or
    * * it is the prefix in a prefixed identifier.
-   *
-   * @param node the node being tested
-   * @return `true` if the given node is the prefix in an import directive
    */
   bool _isValidAsPrefix(SimpleIdentifier node) {
     AstNode parent = node.parent;
@@ -1531,10 +1503,10 @@
 
   /**
    * Return the target of a break or continue statement, and update the static
-   * element of its label (if any).  [parentNode] is the AST node of the break
-   * or continue statement, [labelNode] is the label contained in that
-   * statement (if any), and [isContinue] is true if the node being visited is
-   * a continue statement.
+   * element of its label (if any). The [parentNode] is the AST node of the
+   * break or continue statement. The [labelNode] is the label contained in that
+   * statement (if any). The flag [isContinue] is `true` if the node being
+   * visited is a continue statement.
    */
   AstNode _lookupBreakOrContinueTarget(
       AstNode parentNode, SimpleIdentifier labelNode, bool isContinue) {
@@ -1570,13 +1542,10 @@
   }
 
   /**
-   * Look up the getter with the given name in the given type. Return the element representing the
-   * getter that was found, or `null` if there is no getter with the given name.
-   *
-   * @param target the target of the invocation, or `null` if there is no target
-   * @param type the type in which the getter is defined
-   * @param getterName the name of the getter being looked up
-   * @return the element representing the getter that was found
+   * Look up the getter with the given [getterName] in the given [type]. Return
+   * the element representing the getter that was found, or `null` if there is
+   * no getter with the given name. The [target] is the target of the
+   * invocation, or `null` if there is no target.
    */
   PropertyAccessorElement _lookUpGetter(
       Expression target, DartType type, String getterName) {
@@ -1600,16 +1569,14 @@
   }
 
   /**
-   * Look up the getter with the given name in the interfaces implemented by the given type, either
-   * directly or indirectly. Return the element representing the getter that was found, or
-   * `null` if there is no getter with the given name.
-   *
-   * @param targetType the type in which the getter might be defined
-   * @param includeTargetType `true` if the search should include the target type
-   * @param getterName the name of the getter being looked up
-   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
-   *          to prevent infinite recursion and to optimize the search
-   * @return the element representing the getter that was found
+   * Look up the getter with the given [getterName] in the interfaces
+   * implemented by the given [targetType], either directly or indirectly.
+   * Return the element representing the getter that was found, or `null` if
+   * there is no getter with the given name. The flag [includeTargetType] should
+   * be `true` if the search should include the target type. The
+   * [visitedInterfaces] is a set containing all of the interfaces that have
+   * been examined, used to prevent infinite recursion and to optimize the
+   * search.
    */
   PropertyAccessorElement _lookUpGetterInInterfaces(InterfaceType targetType,
       bool includeTargetType, String getterName,
@@ -1652,13 +1619,9 @@
   }
 
   /**
-   * Look up the method or getter with the given name in the given type. Return the element
-   * representing the method or getter that was found, or `null` if there is no method or
-   * getter with the given name.
-   *
-   * @param type the type in which the method or getter is defined
-   * @param memberName the name of the method or getter being looked up
-   * @return the element representing the method or getter that was found
+   * Look up the method or getter with the given [memberName] in the given
+   * [type]. Return the element representing the method or getter that was
+   * found, or `null` if there is no method or getter with the given name.
    */
   ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) {
     type = _resolveTypeParameter(type);
@@ -1680,16 +1643,14 @@
   }
 
   /**
-   * Look up the method or getter with the given name in the interfaces implemented by the given
-   * type, either directly or indirectly. Return the element representing the method or getter that
-   * was found, or `null` if there is no method or getter with the given name.
-   *
-   * @param targetType the type in which the method or getter might be defined
-   * @param includeTargetType `true` if the search should include the target type
-   * @param memberName the name of the method or getter being looked up
-   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
-   *          to prevent infinite recursion and to optimize the search
-   * @return the element representing the method or getter that was found
+   * Look up the method or getter with the given [memberName] in the interfaces
+   * implemented by the given [targetType], either directly or indirectly.
+   * Return the element representing the method or getter that was found, or
+   * `null` if there is no method or getter with the given name. The flag
+   * [includeTargetType] should be `true` if the search should include the
+   * target type. The [visitedInterfaces] is a set containing all of the
+   * interfaces that have been examined, used to prevent infinite recursion and
+   * to optimize the search.
    */
   ExecutableElement _lookUpGetterOrMethodInInterfaces(InterfaceType targetType,
       bool includeTargetType, String memberName,
@@ -1736,13 +1697,10 @@
   }
 
   /**
-   * Look up the method with the given name in the given type. Return the element representing the
-   * method that was found, or `null` if there is no method with the given name.
-   *
-   * @param target the target of the invocation, or `null` if there is no target
-   * @param type the type in which the method is defined
-   * @param methodName the name of the method being looked up
-   * @return the element representing the method that was found
+   * Look up the method with the given [methodName] in the given [type]. Return
+   * the element representing the method that was found, or `null` if there is
+   * no method with the given name. The [target] is the target of the
+   * invocation, or `null` if there is no target.
    */
   MethodElement _lookUpMethod(
       Expression target, DartType type, String methodName) {
@@ -1773,16 +1731,14 @@
   }
 
   /**
-   * Look up the method with the given name in the interfaces implemented by the given type, either
-   * directly or indirectly. Return the element representing the method that was found, or
-   * `null` if there is no method with the given name.
-   *
-   * @param targetType the type in which the member might be defined
-   * @param includeTargetType `true` if the search should include the target type
-   * @param methodName the name of the method being looked up
-   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
-   *          to prevent infinite recursion and to optimize the search
-   * @return the element representing the method that was found
+   * Look up the method with the given [methodName] in the interfaces
+   * implemented by the given [targetType], either directly or indirectly.
+   * Return the element representing the method that was found, or `null` if
+   * there is no method with the given name. The flag [includeTargetType] should
+   * be `true` if the search should include the target type. The
+   * [visitedInterfaces] is a set containing all of the interfaces that have
+   * been examined, used to prevent infinite recursion and to optimize the
+   * search.
    */
   MethodElement _lookUpMethodInInterfaces(InterfaceType targetType,
       bool includeTargetType, String methodName,
@@ -1825,12 +1781,8 @@
   }
 
   /**
-   * Look up all methods of a given name defined on a union type.
-   *
-   * @param target
-   * @param type
-   * @param methodName
-   * @return all methods named `methodName` defined on the union type `type`.
+   * Look up all methods with the given [methodName] that are defined on the
+   * given union [type].
    */
   Set<ExecutableElement> _lookupMethods(
       Expression target, UnionType type, String methodName) {
@@ -1858,13 +1810,10 @@
   }
 
   /**
-   * Look up the setter with the given name in the given type. Return the element representing the
-   * setter that was found, or `null` if there is no setter with the given name.
-   *
-   * @param target the target of the invocation, or `null` if there is no target
-   * @param type the type in which the setter is defined
-   * @param setterName the name of the setter being looked up
-   * @return the element representing the setter that was found
+   * Look up the setter with the given [setterName] in the given [type]. Return
+   * the element representing the setter that was found, or `null` if there is
+   * no setter with the given name. The [target] is the target of the
+   * invocation, or `null` if there is no target.
    */
   PropertyAccessorElement _lookUpSetter(
       Expression target, DartType type, String setterName) {
@@ -1888,16 +1837,15 @@
   }
 
   /**
-   * Look up the setter with the given name in the interfaces implemented by the given type, either
-   * directly or indirectly. Return the element representing the setter that was found, or
-   * `null` if there is no setter with the given name.
-   *
-   * @param targetType the type in which the setter might be defined
-   * @param includeTargetType `true` if the search should include the target type
-   * @param setterName the name of the setter being looked up
-   * @param visitedInterfaces a set containing all of the interfaces that have been examined, used
-   *          to prevent infinite recursion and to optimize the search
-   * @return the element representing the setter that was found
+   * Look up the setter with the given [setterName] in the interfaces
+   * implemented by the given [targetType], either directly or indirectly.
+   * Return the element representing the setter that was found, or `null` if
+   * there is no setter with the given name. The [targetType] is the type in
+   * which the setter might be defined. The flag [includeTargetType] should be
+   * `true` if the search should include the target type. The
+   * [visitedInterfaces] is a set containing all of the interfaces that have
+   * been examined, used to prevent infinite recursion and to optimize the
+   * search.
    */
   PropertyAccessorElement _lookUpSetterInInterfaces(InterfaceType targetType,
       bool includeTargetType, String setterName,
@@ -1940,17 +1888,12 @@
   }
 
   /**
-   * Given some class element, this method uses [subtypeManager] to find the set of all
-   * subtypes; the subtypes are then searched for a member (method, getter, or setter), that matches
-   * a passed
-   *
-   * @param element the class element to search the subtypes of, if a non-ClassElement element is
-   *          passed, then `false` is returned
-   * @param memberName the member name to search for
-   * @param asMethod `true` if the methods should be searched for in the subtypes
-   * @param asAccessor `true` if the accessors (getters and setters) should be searched for in
-   *          the subtypes
-   * @return `true` if and only if the passed memberName was found in a subtype
+   * Given some class [element], this method uses [_subtypeManager] to find the
+   * set of all subtypes; the subtypes are then searched for a member (method,
+   * getter, or setter), that has the given [memberName]. The flag [asMethod]
+   * should be `true` if the methods should be searched for in the subtypes. The
+   * flag [asAccessor] should be `true` if the accessors (getters and setters)
+   * should be searched for in the subtypes.
    */
   bool _memberFoundInSubclass(
       Element element, String memberName, bool asMethod, bool asAccessor) {
@@ -1972,10 +1915,8 @@
   }
 
   /**
-   * Return the binary operator that is invoked by the given compound assignment operator.
-   *
-   * @param operator the assignment operator being mapped
-   * @return the binary operator that invoked by the given assignment operator
+   * Return the binary operator that is invoked by the given compound assignment
+   * [operator].
    */
   sc.TokenType _operatorFromCompoundAssignment(sc.TokenType operator) {
     while (true) {
@@ -2012,13 +1953,12 @@
   }
 
   /**
-   * Record that the given node is undefined, causing an error to be reported if appropriate.
-   *
-   * @param declaringElement the element inside which no declaration was found. If this element is a
-   *          proxy, no error will be reported. If null, then an error will always be reported.
-   * @param errorCode the error code to report.
-   * @param node the node which is undefined.
-   * @param arguments arguments to the error message.
+   * Record that the given [node] is undefined, causing an error to be reported
+   * if appropriate. The [declaringElement] is the element inside which no
+   * declaration was found. If this element is a proxy, no error will be
+   * reported. If null, then an error will always be reported. The [errorCode]
+   * is the error code to report. The [arguments] are the arguments to the error
+   * message.
    */
   void _recordUndefinedNode(Element declaringElement, ErrorCode errorCode,
       AstNode node, List<Object> arguments) {
@@ -2028,15 +1968,12 @@
   }
 
   /**
-   * Record that the given offset/length is undefined, causing an error to be reported if
-   * appropriate.
-   *
-   * @param declaringElement the element inside which no declaration was found. If this element is a
-   *          proxy, no error will be reported. If null, then an error will always be reported.
-   * @param errorCode the error code to report.
-   * @param offset the offset to the text which is undefined.
-   * @param length the length of the text which is undefined.
-   * @param arguments arguments to the error message.
+   * Record that the given [offset]/[length] is undefined, causing an error to
+   * be reported if appropriate. The [declaringElement] is the element inside
+   * which no declaration was found. If this element is a proxy, no error will
+   * be reported. If null, then an error will always be reported. The
+   * [errorCode] is the error code to report. The [arguments] are arguments to
+   * the error message.
    */
   void _recordUndefinedOffset(Element declaringElement, ErrorCode errorCode,
       int offset, int length, List<Object> arguments) {
@@ -2046,13 +1983,12 @@
   }
 
   /**
-   * Record that the given token is undefined, causing an error to be reported if appropriate.
-   *
-   * @param declaringElement the element inside which no declaration was found. If this element is a
-   *          proxy, no error will be reported. If null, then an error will always be reported.
-   * @param errorCode the error code to report.
-   * @param token the token which is undefined.
-   * @param arguments arguments to the error message.
+   * Record that the given [token] is undefined, causing an error to be reported
+   * if appropriate. The [declaringElement] is the element inside which no
+   * declaration was found. If this element is a proxy, no error will be
+   * reported. If null, then an error will always be reported. The [errorCode]
+   * is the error code to report. The [arguments] are arguments to the error
+   * message.
    */
   void _recordUndefinedToken(Element declaringElement, ErrorCode errorCode,
       sc.Token token, List<Object> arguments) {
@@ -2077,9 +2013,7 @@
   }
 
   /**
-   * Continues resolution of the given [Annotation].
-   *
-   * @param annotation the [Annotation] to resolve
+   * Continues resolution of the given [annotation].
    */
   void _resolveAnnotationElement(Annotation annotation) {
     SimpleIdentifier nameNode1;
@@ -2129,14 +2063,12 @@
       if (element2 is PropertyAccessorElement) {
         nameNode2.staticElement = element2;
         annotation.element = element2;
-        _resolveAnnotationElementGetter(
-            annotation, element2 as PropertyAccessorElement);
+        _resolveAnnotationElementGetter(annotation, element2);
         return;
       }
       // prefix.Class()
       if (element2 is ClassElement) {
-        ClassElement classElement = element2 as ClassElement;
-        constructor = classElement.unnamedConstructor;
+        constructor = element2.unnamedConstructor;
       }
       // Class.constructor(args)
       if (element1 is ClassElement) {
@@ -2201,15 +2133,13 @@
   }
 
   /**
-   * Given a list of arguments and the element that will be invoked using those argument, compute
-   * the list of parameters that correspond to the list of arguments. Return the parameters that
-   * correspond to the arguments, or `null` if no correspondence could be computed.
-   *
-   * @param reportError if `true` then compile-time error should be reported; if `false`
-   *          then compile-time warning
-   * @param argumentList the list of arguments being passed to the element
-   * @param executableElement the element that will be invoked with the arguments
-   * @return the parameters that correspond to the arguments
+   * Given an [argumentList] and the [executableElement] that will be invoked
+   * using those argument, compute the list of parameters that correspond to the
+   * list of arguments. An error will be reported if any of the arguments cannot
+   * be matched to a parameter. The flag [reportError] should be `true` if a
+   * compile-time error should be reported; or `false` if a compile-time warning
+   * should be reported. Return the parameters that correspond to the arguments,
+   * or `null` if no correspondence could be computed.
    */
   List<ParameterElement> _resolveArgumentsToFunction(bool reportError,
       ArgumentList argumentList, ExecutableElement executableElement) {
@@ -2221,15 +2151,13 @@
   }
 
   /**
-   * Given a list of arguments and the parameters related to the element that will be invoked using
-   * those argument, compute the list of parameters that correspond to the list of arguments. Return
-   * the parameters that correspond to the arguments.
-   *
-   * @param reportError if `true` then compile-time error should be reported; if `false`
-   *          then compile-time warning
-   * @param argumentList the list of arguments being passed to the element
-   * @param parameters the of the function that will be invoked with the arguments
-   * @return the parameters that correspond to the arguments
+   * Given an [argumentList] and the [parameters] related to the element that
+   * will be invoked using those arguments, compute the list of parameters that
+   * correspond to the list of arguments. An error will be reported if any of
+   * the arguments cannot be matched to a parameter. The flag [reportError]
+   * should be `true` if a compile-time error should be reported; or `false` if
+   * a compile-time warning should be reported. Return the parameters that
+   * correspond to the arguments.
    */
   List<ParameterElement> _resolveArgumentsToParameters(bool reportError,
       ArgumentList argumentList, List<ParameterElement> parameters) {
@@ -2293,15 +2221,19 @@
       ErrorCode errorCode = (reportError
           ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS
           : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS);
-      _resolver.reportErrorForNode(errorCode, argumentList,
-          [requiredParameters.length, positionalArgumentCount]);
+      _resolver.reportErrorForNode(errorCode, argumentList, [
+        requiredParameters.length,
+        positionalArgumentCount
+      ]);
     } else if (positionalArgumentCount > unnamedParameterCount &&
         noBlankArguments) {
       ErrorCode errorCode = (reportError
           ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS
           : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS);
-      _resolver.reportErrorForNode(errorCode, argumentList,
-          [unnamedParameterCount, positionalArgumentCount]);
+      _resolver.reportErrorForNode(errorCode, argumentList, [
+        unnamedParameterCount,
+        positionalArgumentCount
+      ]);
     }
     return resolvedParameters;
   }
@@ -2345,10 +2277,8 @@
   }
 
   /**
-   * Resolve the names in the given combinators in the scope of the given library.
-   *
-   * @param library the library that defines the names
-   * @param combinators the combinators containing the names to be resolved
+   * Resolve the names in the given [combinators] in the scope of the given
+   * [library].
    */
   void _resolveCombinators(
       LibraryElement library, NodeList<Combinator> combinators) {
@@ -2387,8 +2317,8 @@
   }
 
   /**
-   * Given that we are accessing a property of the given [classElement] with
-   * the given [propertyName], return the element that represents the property.
+   * Given that we are accessing a property of the given [classElement] with the
+   * given [propertyName], return the element that represents the property.
    */
   Element _resolveElement(
       ClassElementImpl classElement, SimpleIdentifier propertyName) {
@@ -2410,13 +2340,12 @@
   }
 
   /**
-   * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the element being invoked. If
-   * the returned element is a method, then the method will be invoked. If the returned element is a
-   * getter, the getter will be invoked without arguments and the result of that invocation will
-   * then be invoked with the arguments.
-   *
-   * @param methodName the name of the method being invoked ('m')
-   * @return the element being invoked
+   * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the
+   * element being invoked. If the returned element is a method, then the method
+   * will be invoked. If the returned element is a getter, the getter will be
+   * invoked without arguments and the result of that invocation will then be
+   * invoked with the arguments. The [methodName] is the name of the method
+   * being invoked ('m').
    */
   Element _resolveInvokedElement(SimpleIdentifier methodName) {
     //
@@ -2446,15 +2375,13 @@
   }
 
   /**
-   * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the element being invoked.
-   * If the returned element is a method, then the method will be invoked. If the returned element
-   * is a getter, the getter will be invoked without arguments and the result of that invocation
-   * will then be invoked with the arguments.
-   *
-   * @param target the target of the invocation ('e')
-   * @param targetType the type of the target
-   * @param methodName the name of the method being invoked ('m')
-   * @return the element being invoked
+   * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the
+   * element being invoked. If the returned element is a method, then the method
+   * will be invoked. If the returned element is a getter, the getter will be
+   * invoked without arguments and the result of that invocation will then be
+   * invoked with the arguments. The [target] is the target of the invocation
+   * ('e'). The [targetType] is the type of the target. The [methodName] is th
+   *  name of the method being invoked ('m').
    */
   Element _resolveInvokedElementWithTarget(
       Expression target, DartType targetType, SimpleIdentifier methodName) {
@@ -2495,13 +2422,9 @@
   }
 
   /**
-   * Given that we are accessing a property of the given type with the given name, return the
-   * element that represents the property.
-   *
-   * @param target the target of the invocation ('e')
-   * @param targetType the type in which the search for the property should begin
-   * @param propertyName the name of the property being accessed
-   * @return the element that represents the property
+   * Given that we are accessing a property of the given [targetType] with the
+   * given [propertyName], return the element that represents the property. The
+   * [target] is the target of the invocation ('e').
    */
   ExecutableElement _resolveProperty(
       Expression target, DartType targetType, SimpleIdentifier propertyName) {
@@ -2579,7 +2502,8 @@
             staticOrPropagatedEnclosingElt is ClassElement) {
           ClassElement classElement = staticOrPropagatedEnclosingElt;
           InterfaceType targetType = classElement.type;
-          if (targetType != null &&
+          if (!_enableStrictCallChecks &&
+              targetType != null &&
               targetType.isDartCoreFunction &&
               propertyName.name == FunctionElement.CALL_METHOD_NAME) {
             // TODO(brianwilkerson) Can we ever resolve the function being
@@ -2588,9 +2512,8 @@
             return;
           } else if (classElement.isEnum && propertyName.name == "_name") {
             _resolver.reportErrorForNode(
-                CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD, propertyName, [
-              propertyName.name
-            ]);
+                CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD, propertyName,
+                [propertyName.name]);
             return;
           }
         }
@@ -2645,24 +2568,20 @@
         ]);
       } else {
         _recordUndefinedNode(declaringElement,
-            StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, [
-          propertyName.name
-        ]);
+            StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName,
+            [propertyName.name]);
       }
     }
   }
 
   /**
-   * Resolve the given simple identifier if possible. Return the element to which it could be
-   * resolved, or `null` if it could not be resolved. This does not record the results of the
-   * resolution.
-   *
-   * @param node the identifier to be resolved
-   * @return the element to which the identifier could be resolved
+   * Resolve the given simple [identifier] if possible. Return the element to
+   * which it could be resolved, or `null` if it could not be resolved. This
+   * does not record the results of the resolution.
    */
-  Element _resolveSimpleIdentifier(SimpleIdentifier node) {
-    Element element = _resolver.nameScope.lookup(node, _definingLibrary);
-    if (element is PropertyAccessorElement && node.inSetterContext()) {
+  Element _resolveSimpleIdentifier(SimpleIdentifier identifier) {
+    Element element = _resolver.nameScope.lookup(identifier, _definingLibrary);
+    if (element is PropertyAccessorElement && identifier.inSetterContext()) {
       PropertyInducingElement variable =
           (element as PropertyAccessorElement).variable;
       if (variable != null) {
@@ -2674,7 +2593,7 @@
           //
           ClassElement enclosingClass = _resolver.enclosingClass;
           if (enclosingClass != null) {
-            setter = _lookUpSetter(null, enclosingClass.type, node.name);
+            setter = _lookUpSetter(null, enclosingClass.type, identifier.name);
           }
         }
         if (setter != null) {
@@ -2682,34 +2601,33 @@
         }
       }
     } else if (element == null &&
-        (node.inSetterContext() || node.parent is CommentReference)) {
+        (identifier.inSetterContext() ||
+            identifier.parent is CommentReference)) {
       element = _resolver.nameScope.lookup(
-          new SyntheticIdentifier("${node.name}=", node), _definingLibrary);
+          new SyntheticIdentifier("${identifier.name}=", identifier),
+          _definingLibrary);
     }
     ClassElement enclosingClass = _resolver.enclosingClass;
     if (element == null && enclosingClass != null) {
       InterfaceType enclosingType = enclosingClass.type;
       if (element == null &&
-          (node.inSetterContext() || node.parent is CommentReference)) {
-        element = _lookUpSetter(null, enclosingType, node.name);
+          (identifier.inSetterContext() ||
+              identifier.parent is CommentReference)) {
+        element = _lookUpSetter(null, enclosingType, identifier.name);
       }
-      if (element == null && node.inGetterContext()) {
-        element = _lookUpGetter(null, enclosingType, node.name);
+      if (element == null && identifier.inGetterContext()) {
+        element = _lookUpGetter(null, enclosingType, identifier.name);
       }
       if (element == null) {
-        element = _lookUpMethod(null, enclosingType, node.name);
+        element = _lookUpMethod(null, enclosingType, identifier.name);
       }
     }
     return element;
   }
 
   /**
-   * If the given type is a type parameter, resolve it to the type that should be used when looking
-   * up members. Otherwise, return the original type.
-   *
-   * @param type the type that is to be resolved if it is a type parameter
-   * @return the type that should be used in place of the argument if it is a type parameter, or the
-   *         original argument if it isn't a type parameter
+   * If the given [type] is a type parameter, resolve it to the type that should
+   * be used when looking up members. Otherwise, return the original type.
    */
   DartType _resolveTypeParameter(DartType type) {
     if (type is TypeParameterType) {
@@ -2723,12 +2641,9 @@
   }
 
   /**
-   * Given a node that can have annotations associated with it and the element to which that node
-   * has been resolved, create the annotations in the element model representing the annotations on
-   * the node.
-   *
-   * @param element the element to which the node has been resolved
-   * @param node the node that can have annotations associated with it
+   * Given a [node] that can have annotations associated with it and the
+   * [element] to which that node has been resolved, create the annotations in
+   * the element model representing the annotations on the node.
    */
   void _setMetadata(Element element, AnnotatedNode node) {
     if (element is! ElementImpl) {
@@ -2755,12 +2670,9 @@
   }
 
   /**
-   * Given a node that can have annotations associated with it and the element to which that node
-   * has been resolved, create the annotations in the element model representing the annotations on
-   * the node.
-   *
-   * @param element the element to which the node has been resolved
-   * @param node the node that can have annotations associated with it
+   * Given a [node] that can have annotations associated with it and the
+   * [element] to which that node has been resolved, create the annotations in
+   * the element model representing the annotations on the node.
    */
   void _setMetadataForParameter(Element element, NormalFormalParameter node) {
     if (element is! ElementImpl) {
@@ -2775,12 +2687,8 @@
   }
 
   /**
-   * Return `true` if we should report an error as a result of looking up a member in the
-   * given type and not finding any member.
-   *
-   * @param type the type in which we attempted to perform the look-up
-   * @param member the result of the look-up
-   * @return `true` if we should report an error
+   * Return `true` if we should report an error as a result of looking up a
+   * [member] in the given [type] and not finding any member.
    */
   bool _shouldReportMissingMember(DartType type, Element member) {
     if (member != null || type == null || type.isDynamic || type.isBottom) {
@@ -2790,11 +2698,9 @@
   }
 
   /**
-   * Checks whether the given expression is a reference to a class. If it is then the
-   * [ClassElement] is returned, otherwise `null` is returned.
-   *
-   * @param expression the expression to evaluate
-   * @return the element representing the class
+   * Checks whether the given [expression] is a reference to a class. If it is
+   * then the element representing the class is returned, otherwise `null` is
+   * returned.
    */
   static ClassElementImpl getTypeReference(Expression expression) {
     if (expression is Identifier) {
@@ -2807,10 +2713,9 @@
   }
 
   /**
-   * Helper function for `maybeMergeExecutableElements` that does the actual merging.
-   *
-   * @param elementArrayToMerge non-empty array of elements to merge.
-   * @return
+   * Helper function for `maybeMergeExecutableElements` that does the actual
+   * merging. The [elementArrayToMerge] is the non-empty list of elements to
+   * merge.
    */
   static ExecutableElement _computeMergedExecutableElement(
       List<ExecutableElement> elementArrayToMerge) {
@@ -2882,9 +2787,8 @@
   }
 
   /**
-   * Return `true` if the given identifier is the return type of a constructor declaration.
-   *
-   * @return `true` if the given identifier is the return type of a constructor declaration.
+   * Return `true` if the given [identifier] is the return type of a constructor
+   * declaration.
    */
   static bool _isConstructorReturnType(SimpleIdentifier identifier) {
     AstNode parent = identifier.parent;
@@ -2895,54 +2799,45 @@
   }
 
   /**
-   * Return `true` if the given identifier is the return type of a factory constructor.
-   *
-   * @return `true` if the given identifier is the return type of a factory constructor
-   *         declaration.
+   * Return `true` if the given [identifier] is the return type of a factory
+   * constructor.
    */
-  static bool _isFactoryConstructorReturnType(SimpleIdentifier node) {
-    AstNode parent = node.parent;
+  static bool _isFactoryConstructorReturnType(SimpleIdentifier identifier) {
+    AstNode parent = identifier.parent;
     if (parent is ConstructorDeclaration) {
       ConstructorDeclaration constructor = parent;
-      return identical(constructor.returnType, node) &&
+      return identical(constructor.returnType, identifier) &&
           constructor.factoryKeyword != null;
     }
     return false;
   }
 
   /**
-   * Return `true` if the given 'super' expression is used in a valid context.
-   *
-   * @param node the 'super' expression to analyze
-   * @return `true` if the 'super' expression is in a valid context
+   * Return `true` if the given 'super' [expression] is used in a valid context.
    */
-  static bool _isSuperInValidContext(SuperExpression node) {
-    for (AstNode n = node; n != null; n = n.parent) {
-      if (n is CompilationUnit) {
+  static bool _isSuperInValidContext(SuperExpression expression) {
+    for (AstNode node = expression; node != null; node = node.parent) {
+      if (node is CompilationUnit) {
         return false;
       }
-      if (n is ConstructorDeclaration) {
-        ConstructorDeclaration constructor = n as ConstructorDeclaration;
-        return constructor.factoryKeyword == null;
+      if (node is ConstructorDeclaration) {
+        return node.factoryKeyword == null;
       }
-      if (n is ConstructorFieldInitializer) {
+      if (node is ConstructorFieldInitializer) {
         return false;
       }
-      if (n is MethodDeclaration) {
-        MethodDeclaration method = n as MethodDeclaration;
-        return !method.isStatic;
+      if (node is MethodDeclaration) {
+        return !node.isStatic;
       }
     }
     return false;
   }
 
   /**
-   * Return a method representing the merge of the given elements. The type of the merged element is
-   * the component-wise union of the types of the given elements. If not all input elements have the
-   * same shape then [null] is returned.
-   *
-   * @param elements the `ExecutableElement`s to merge
-   * @return an `ExecutableElement` representing the merge of `elements`
+   * Return a method representing the merge of the given [elements]. The type of
+   * the merged element is the component-wise union of the types of the given
+   * elements. If not all input elements have the same shape then `null` is
+   * returned.
    */
   static ExecutableElement _maybeMergeExecutableElements(
       Set<ExecutableElement> elements) {
@@ -2959,11 +2854,10 @@
 }
 
 /**
- * A `SyntheticIdentifier` is an identifier that can be used to look up names in
- * the lexical scope when there is no identifier in the AST structure. There is
- * no identifier in the AST when the parser could not distinguish between a
- * method invocation and an invocation of a top-level function imported with a
- * prefix.
+ * An identifier that can be used to look up names in the lexical scope when
+ * there is no identifier in the AST structure. There is no identifier in the
+ * AST when the parser could not distinguish between a method invocation and an
+ * invocation of a top-level function imported with a prefix.
  */
 class SyntheticIdentifier extends Identifier {
   /**
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index bf4be15..f2f12c6 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -35,6 +35,7 @@
 import 'source.dart';
 import 'utilities_collection.dart';
 import 'utilities_general.dart';
+import 'package:analyzer/src/plugin/engine_plugin.dart';
 
 /**
  * Used by [AnalysisOptions] to allow function bodies to be analyzed in some
@@ -58,42 +59,36 @@
 typedef T PendingFutureComputer<T>(SourceEntry sourceEntry);
 
 /**
- * Instances of the class `AnalysisCache` implement an LRU cache of information related to
- * analysis.
+ * An LRU cache of information related to analysis.
  */
 class AnalysisCache {
   /**
-   * A flag used to control whether trace information should be produced when the content of the
-   * cache is modified.
+   * A flag used to control whether trace information should be produced when
+   * the content of the cache is modified.
    */
   static bool _TRACE_CHANGES = false;
 
   /**
-   * An array containing the partitions of which this cache is comprised.
+   * A list containing the partitions of which this cache is comprised.
    */
   final List<CachePartition> _partitions;
 
   /**
-   * Initialize a newly created cache to have the given partitions. The partitions will be searched
-   * in the order in which they appear in the array, so the most specific partition (usually an
-   * [SdkCachePartition]) should be first and the most general (usually a
-   * [UniversalCachePartition]) last.
-   *
-   * @param partitions the partitions for the newly created cache
+   * Initialize a newly created cache to have the given [_partitions]. The
+   * partitions will be searched in the order in which they appear in the list,
+   * so the most specific partition (usually an [SdkCachePartition]) should be
+   * first and the most general (usually a [UniversalCachePartition]) last.
    */
   AnalysisCache(this._partitions);
 
   /**
-   * Return the number of entries in this cache that have an AST associated with them.
-   *
-   * @return the number of entries in this cache that have an AST associated with them
+   * Return the number of entries in this cache that have an AST associated with
+   * them.
    */
   int get astSize => _partitions[_partitions.length - 1].astSize;
 
   /**
    * Return information about each of the partitions in this cache.
-   *
-   * @return information about each of the partitions in this cache
    */
   List<AnalysisContextStatistics_PartitionData> get partitionData {
     int count = _partitions.length;
@@ -108,9 +103,8 @@
   }
 
   /**
-   * Record that the AST associated with the given source was just read from the cache.
-   *
-   * @param source the source whose AST was accessed
+   * Record that the AST associated with the given [source] was just read from
+   * the cache.
    */
   void accessedAst(Source source) {
     int count = _partitions.length;
@@ -123,10 +117,7 @@
   }
 
   /**
-   * Return the entry associated with the given source.
-   *
-   * @param source the source whose entry is to be returned
-   * @return the entry associated with the given source
+   * Return the entry associated with the given [source].
    */
   SourceEntry get(Source source) {
     int count = _partitions.length;
@@ -144,10 +135,7 @@
   }
 
   /**
-   * Return context that owns the given source.
-   *
-   * @param source the source whose context is to be returned
-   * @return the context that owns the partition that contains the source
+   * Return context that owns the given [source].
    */
   InternalAnalysisContext getContextFor(Source source) {
     int count = _partitions.length;
@@ -168,9 +156,8 @@
   }
 
   /**
-   * Return an iterator returning all of the map entries mapping sources to cache entries.
-   *
-   * @return an iterator returning all of the map entries mapping sources to cache entries
+   * Return an iterator returning all of the map entries mapping sources to
+   * cache entries.
    */
   MapIterator<Source, SourceEntry> iterator() {
     int count = _partitions.length;
@@ -182,10 +169,7 @@
   }
 
   /**
-   * Associate the given entry with the given source.
-   *
-   * @param source the source with which the entry is to be associated
-   * @param entry the entry to be associated with the source
+   * Associate the given [entry] with the given [source].
    */
   void put(Source source, SourceEntry entry) {
     entry.fixExceptionState();
@@ -214,9 +198,7 @@
   }
 
   /**
-   * Remove all information related to the given source from this cache.
-   *
-   * @param source the source to be removed
+   * Remove all information related to the given [source] from this cache.
    */
   void remove(Source source) {
     int count = _partitions.length;
@@ -238,9 +220,8 @@
   }
 
   /**
-   * Record that the AST associated with the given source was just removed from the cache.
-   *
-   * @param source the source whose AST was removed
+   * Record that the AST associated with the given [source] was just removed
+   * from the cache.
    */
   void removedAst(Source source) {
     int count = _partitions.length;
@@ -254,8 +235,6 @@
 
   /**
    * Return the number of sources that are mapped to cache entries.
-   *
-   * @return the number of sources that are mapped to cache entries
    */
   int size() {
     int size = 0;
@@ -267,9 +246,8 @@
   }
 
   /**
-   * Record that the AST associated with the given source was just stored to the cache.
-   *
-   * @param source the source whose AST was stored
+   * Record that the AST associated with the given [source] was just stored to
+   * the cache.
    */
   void storedAst(Source source) {
     int count = _partitions.length;
@@ -283,126 +261,113 @@
 }
 
 /**
- * The interface `AnalysisContext` defines the behavior of objects that represent a context in
- * which a single analysis can be performed and incrementally maintained. The context includes such
- * information as the version of the SDK being analyzed against as well as the package-root used to
- * resolve 'package:' URI's. (Both of which are known indirectly through the [SourceFactory
- ].)
+ * A context in which a single analysis can be performed and incrementally
+ * maintained. The context includes such information as the version of the SDK
+ * being analyzed against as well as the package-root used to resolve 'package:'
+ * URI's. (Both of which are known indirectly through the [SourceFactory].)
  *
- * An analysis context also represents the state of the analysis, which includes knowing which
- * sources have been included in the analysis (either directly or indirectly) and the results of the
- * analysis. Sources must be added and removed from the context using the method
- * [applyChanges], which is also used to notify the context when sources have been
- * modified and, consequently, previously known results might have been invalidated.
+ * An analysis context also represents the state of the analysis, which includes
+ * knowing which sources have been included in the analysis (either directly or
+ * indirectly) and the results of the analysis. Sources must be added and
+ * removed from the context using the method [applyChanges], which is also used
+ * to notify the context when sources have been modified and, consequently,
+ * previously known results might have been invalidated.
  *
- * There are two ways to access the results of the analysis. The most common is to use one of the
- * 'get' methods to access the results. The 'get' methods have the advantage that they will always
- * return quickly, but have the disadvantage that if the results are not currently available they
- * will return either nothing or in some cases an incomplete result. The second way to access
- * results is by using one of the 'compute' methods. The 'compute' methods will always attempt to
- * compute the requested results but might block the caller for a significant period of time.
+ * There are two ways to access the results of the analysis. The most common is
+ * to use one of the 'get' methods to access the results. The 'get' methods have
+ * the advantage that they will always return quickly, but have the disadvantage
+ * that if the results are not currently available they will return either
+ * nothing or in some cases an incomplete result. The second way to access
+ * results is by using one of the 'compute' methods. The 'compute' methods will
+ * always attempt to compute the requested results but might block the caller
+ * for a significant period of time.
  *
- * When results have been invalidated, have never been computed (as is the case for newly added
- * sources), or have been removed from the cache, they are <b>not</b> automatically recreated. They
- * will only be recreated if one of the 'compute' methods is invoked.
+ * When results have been invalidated, have never been computed (as is the case
+ * for newly added sources), or have been removed from the cache, they are
+ * <b>not</b> automatically recreated. They will only be recreated if one of the
+ * 'compute' methods is invoked.
  *
- * However, this is not always acceptable. Some clients need to keep the analysis results
- * up-to-date. For such clients there is a mechanism that allows them to incrementally perform
- * needed analysis and get notified of the consequent changes to the analysis results. This
- * mechanism is realized by the method [performAnalysisTask].
+ * However, this is not always acceptable. Some clients need to keep the
+ * analysis results up-to-date. For such clients there is a mechanism that
+ * allows them to incrementally perform needed analysis and get notified of the
+ * consequent changes to the analysis results. This mechanism is realized by the
+ * method [performAnalysisTask].
  *
- * Analysis engine allows for having more than one context. This can be used, for example, to
- * perform one analysis based on the state of files on disk and a separate analysis based on the
- * state of those files in open editors. It can also be used to perform an analysis based on a
- * proposed future state, such as the state after a refactoring.
+ * Analysis engine allows for having more than one context. This can be used,
+ * for example, to perform one analysis based on the state of files on disk and
+ * a separate analysis based on the state of those files in open editors. It can
+ * also be used to perform an analysis based on a proposed future state, such as
+ * the state after a refactoring.
  */
 abstract class AnalysisContext {
-
   /**
    * An empty list of contexts.
    */
   static const List<AnalysisContext> EMPTY_LIST = const <AnalysisContext>[];
 
   /**
-   * Return the set of analysis options controlling the behavior of this context. Clients should not
-   * modify the returned set of options. The options should only be set by invoking the method
-   * [setAnalysisOptions].
-   *
-   * @return the set of analysis options controlling the behavior of this context
+   * Return the set of analysis options controlling the behavior of this
+   * context. Clients should not modify the returned set of options. The options
+   * should only be set by invoking the method [setAnalysisOptions].
    */
   AnalysisOptions get analysisOptions;
 
   /**
-   * Set the set of analysis options controlling the behavior of this context to the given options.
-   * Clients can safely assume that all necessary analysis results have been invalidated.
-   *
-   * @param options the set of analysis options that will control the behavior of this context
+   * Set the set of analysis options controlling the behavior of this context to
+   * the given [options]. Clients can safely assume that all necessary analysis
+   * results have been invalidated.
    */
   void set analysisOptions(AnalysisOptions options);
 
   /**
-   * Set the order in which sources will be analyzed by [performAnalysisTask] to match the
-   * order of the sources in the given list. If a source that needs to be analyzed is not contained
-   * in the list, then it will be treated as if it were at the end of the list. If the list is empty
-   * (or `null`) then no sources will be given priority over other sources.
+   * Set the order in which sources will be analyzed by [performAnalysisTask] to
+   * match the order of the sources in the given list of [sources]. If a source
+   * that needs to be analyzed is not contained in the list, then it will be
+   * treated as if it were at the end of the list. If the list is empty (or
+   * `null`) then no sources will be given priority over other sources.
    *
-   * Changes made to the list after this method returns will <b>not</b> be reflected in the priority
-   * order.
-   *
-   * @param sources the sources to be given priority over other sources
+   * Changes made to the list after this method returns will <b>not</b> be
+   * reflected in the priority order.
    */
   void set analysisPriorityOrder(List<Source> sources);
 
   /**
    * Return the set of declared variables used when computing constant values.
-   *
-   * @return the set of declared variables used when computing constant values
    */
   DeclaredVariables get declaredVariables;
 
   /**
-   * Return an array containing all of the sources known to this context that represent HTML files.
-   * The contents of the array can be incomplete.
-   *
-   * @return the sources known to this context that represent HTML files
+   * Return a list containing all of the sources known to this context that
+   * represent HTML files. The contents of the list can be incomplete.
    */
   List<Source> get htmlSources;
 
   /**
    * Returns `true` if this context was disposed using [dispose].
-   *
-   * @return `true` if this context was disposed
    */
   bool get isDisposed;
 
   /**
-   * Return an array containing all of the sources known to this context that represent the defining
-   * compilation unit of a library that can be run within a browser. The sources that are returned
-   * represent libraries that have a 'main' method and are either referenced by an HTML file or
-   * import, directly or indirectly, a client-only library. The contents of the array can be
+   * Return a list containing all of the sources known to this context that
+   * represent the defining compilation unit of a library that can be run within
+   * a browser. The sources that are returned represent libraries that have a
+   * 'main' method and are either referenced by an HTML file or import, directly
+   * or indirectly, a client-only library. The contents of the list can be
    * incomplete.
-   *
-   * @return the sources known to this context that represent the defining compilation unit of a
-   *         library that can be run within a browser
    */
   List<Source> get launchableClientLibrarySources;
 
   /**
-   * Return an array containing all of the sources known to this context that represent the defining
-   * compilation unit of a library that can be run outside of a browser. The contents of the array
-   * can be incomplete.
-   *
-   * @return the sources known to this context that represent the defining compilation unit of a
-   *         library that can be run outside of a browser
+   * Return a list containing all of the sources known to this context that
+   * represent the defining compilation unit of a library that can be run
+   * outside of a browser. The contents of the list can be incomplete.
    */
   List<Source> get launchableServerLibrarySources;
 
   /**
-   * Return an array containing all of the sources known to this context that represent the defining
-   * compilation unit of a library. The contents of the array can be incomplete.
-   *
-   * @return the sources known to this context that represent the defining compilation unit of a
-   *         library
+   * Return a list containing all of the sources known to this context that
+   * represent the defining compilation unit of a library. The contents of the
+   * list can be incomplete.
    */
   List<Source> get librarySources;
 
@@ -425,157 +390,141 @@
   Stream<SourcesChangedEvent> get onSourcesChanged;
 
   /**
-   * Return an array containing all of the sources known to this context and their resolution state
-   * is not valid or flush. So, these sources are not safe to update during refactoring, because we
-   * may be don't know all the references in them.
-   *
-   * @return the sources known to this context and are not safe for refactoring
+   * Return a list containing all of the sources known to this context whose
+   * state is neither valid or flushed. These sources are not safe to update
+   * during refactoring, because we might not know all the references in them.
    */
   List<Source> get refactoringUnsafeSources;
 
   /**
-   * Return the source factory used to create the sources that can be analyzed in this context.
-   *
-   * @return the source factory used to create the sources that can be analyzed in this context
+   * Return the source factory used to create the sources that can be analyzed
+   * in this context.
    */
   SourceFactory get sourceFactory;
 
   /**
-   * Set the source factory used to create the sources that can be analyzed in this context to the
-   * given source factory. Clients can safely assume that all analysis results have been
-   * invalidated.
-   *
-   * @param factory the source factory used to create the sources that can be analyzed in this
-   *          context
+   * Set the source factory used to create the sources that can be analyzed in
+   * this context to the given source [factory]. Clients can safely assume that
+   * all analysis results have been invalidated.
    */
   void set sourceFactory(SourceFactory factory);
 
   /**
-   * Return an array containing all of the sources known to this context.
-   *
-   * @return all of the sources known to this context
+   * Return a list containing all of the sources known to this context.
    */
   List<Source> get sources;
 
   /**
-   * Returns a type provider for this context or throws [AnalysisException] if
-   * `dart:core` or `dart:async` cannot be resolved.
+   * Return a type provider for this context or throw [AnalysisException] if
+   * either `dart:core` or `dart:async` cannot be resolved.
    */
   TypeProvider get typeProvider;
 
   /**
-   * Add the given listener to the list of objects that are to be notified when various analysis
-   * results are produced in this context.
-   *
-   * @param listener the listener to be added
+   * Add the given [listener] to the list of objects that are to be notified
+   * when various analysis results are produced in this context.
    */
   void addListener(AnalysisListener listener);
 
   /**
-   * Apply the given delta to change the level of analysis that will be performed for the sources
-   * known to this context.
-   *
-   * @param delta a description of the level of analysis that should be performed for some sources
+   * Apply the given [delta] to change the level of analysis that will be
+   * performed for the sources known to this context.
    */
   void applyAnalysisDelta(AnalysisDelta delta);
 
   /**
-   * Apply the changes specified by the given change set to this context. Any analysis results that
-   * have been invalidated by these changes will be removed.
-   *
-   * @param changeSet a description of the changes that are to be applied
+   * Apply the changes specified by the given [changeSet] to this context. Any
+   * analysis results that have been invalidated by these changes will be
+   * removed.
    */
   void applyChanges(ChangeSet changeSet);
 
   /**
-   * Return the documentation comment for the given element as it appears in the original source
-   * (complete with the beginning and ending delimiters) for block documentation comments, or lines
-   * starting with `"///"` and separated with `"\n"` characters for end-of-line
-   * documentation comments, or `null` if the element does not have a documentation comment
-   * associated with it. This can be a long-running operation if the information needed to access
-   * the comment is not cached.
+   * Return the documentation comment for the given [element] as it appears in
+   * the original source (complete with the beginning and ending delimiters) for
+   * block documentation comments, or lines starting with `"///"` and separated
+   * with `"\n"` characters for end-of-line documentation comments, or `null` if
+   * the element does not have a documentation comment associated with it. This
+   * can be a long-running operation if the information needed to access the
+   * comment is not cached.
+   *
+   * Throws an [AnalysisException] if the documentation comment could not be
+   * determined because the analysis could not be performed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param element the element whose documentation comment is to be returned
-   * @return the element's documentation comment
-   * @throws AnalysisException if the documentation comment could not be determined because the
-   *           analysis could not be performed
    */
   String computeDocumentationComment(Element element);
 
   /**
-   * Return an array containing all of the errors associated with the given source. If the errors
-   * are not already known then the source will be analyzed in order to determine the errors
-   * associated with it.
+   * Return a list containing all of the errors associated with the given
+   * [source]. If the errors are not already known then the source will be
+   * analyzed in order to determine the errors associated with it.
+   *
+   * Throws an [AnalysisException] if the errors could not be determined because
+   * the analysis could not be performed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
    *
-   * @param source the source whose errors are to be returned
-   * @return all of the errors associated with the given source
-   * @throws AnalysisException if the errors could not be determined because the analysis could not
-   *           be performed
    * See [getErrors].
    */
   List<AnalysisError> computeErrors(Source source);
 
   /**
-   * Return the element model corresponding to the HTML file defined by the given source. If the
-   * element model does not yet exist it will be created. The process of creating an element model
-   * for an HTML file can be long-running, depending on the size of the file and the number of
-   * libraries that are defined in it (via script tags) that also need to have a model built for
-   * them.
+   * Return the element model corresponding to the HTML file defined by the
+   * given [source]. If the element model does not yet exist it will be created.
+   * The process of creating an element model for an HTML file can be
+   * long-running, depending on the size of the file and the number of libraries
+   * that are defined in it (via script tags) that also need to have a model
+   * built for them.
+   *
+   * Throws AnalysisException if the element model could not be determined
+   * because the analysis could not be performed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
    *
-   * @param source the source defining the HTML file whose element model is to be returned
-   * @return the element model corresponding to the HTML file defined by the given source
-   * @throws AnalysisException if the element model could not be determined because the analysis
-   *           could not be performed
    * See [getHtmlElement].
    */
   HtmlElement computeHtmlElement(Source source);
 
   /**
-   * Return the kind of the given source, computing it's kind if it is not already known. Return
-   * [SourceKind.UNKNOWN] if the source is not contained in this context.
+   * Return the kind of the given [source], computing it's kind if it is not
+   * already known. Return [SourceKind.UNKNOWN] if the source is not contained
+   * in this context.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
    *
-   * @param source the source whose kind is to be returned
-   * @return the kind of the given source
    * See [getKindOf].
    */
   SourceKind computeKindOf(Source source);
 
   /**
-   * Return the element model corresponding to the library defined by the given source. If the
-   * element model does not yet exist it will be created. The process of creating an element model
-   * for a library can long-running, depending on the size of the library and the number of
-   * libraries that are imported into it that also need to have a model built for them.
+   * Return the element model corresponding to the library defined by the given
+   * [source]. If the element model does not yet exist it will be created. The
+   * process of creating an element model for a library can long-running,
+   * depending on the size of the library and the number of libraries that are
+   * imported into it that also need to have a model built for them.
+   *
+   * Throws an [AnalysisException] if the element model could not be determined
+   * because the analysis could not be performed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
    *
-   * @param source the source defining the library whose element model is to be returned
-   * @return the element model corresponding to the library defined by the given source
-   * @throws AnalysisException if the element model could not be determined because the analysis
-   *           could not be performed
    * See [getLibraryElement].
    */
   LibraryElement computeLibraryElement(Source source);
 
   /**
-   * Return the line information for the given source, or `null` if the source is not of a
-   * recognized kind (neither a Dart nor HTML file). If the line information was not previously
-   * known it will be created. The line information is used to map offsets from the beginning of the
-   * source to line and column pairs.
+   * Return the line information for the given [source], or `null` if the source
+   * is not of a recognized kind (neither a Dart nor HTML file). If the line
+   * information was not previously known it will be created. The line
+   * information is used to map offsets from the beginning of the source to line
+   * and column pairs.
+   *
+   * Throws an [AnalysisException] if the line information could not be
+   * determined because the analysis could not be performed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
    *
-   * @param source the source whose line information is to be returned
-   * @return the line information for the given source
-   * @throws AnalysisException if the line information could not be determined because the analysis
-   *           could not be performed
    * See [getLineInfo].
    */
   LineInfo computeLineInfo(Source source);
@@ -600,146 +549,117 @@
   void dispose();
 
   /**
-   * Return `true` if the given source exists.
+   * Return `true` if the given [source] exists.
    *
-   * This method should be used rather than the method [Source.exists] because contexts can
-   * have local overrides of the content of a source that the source is not aware of and a source
-   * with local content is considered to exist even if there is no file on disk.
-   *
-   * @param source the source whose modification stamp is to be returned
-   * @return `true` if the source exists
+   * This method should be used rather than the method [Source.exists] because
+   * contexts can have local overrides of the content of a source that the
+   * source is not aware of and a source with local content is considered to
+   * exist even if there is no file on disk.
    */
   bool exists(Source source);
 
   /**
-   * Return the element model corresponding to the compilation unit defined by the given source in
-   * the library defined by the given source, or `null` if the element model does not
-   * currently exist or if the library cannot be analyzed for some reason.
-   *
-   * @param unitSource the source of the compilation unit
-   * @param librarySource the source of the defining compilation unit of the library containing the
-   *          compilation unit
-   * @return the element model corresponding to the compilation unit defined by the given source
+   * Return the element model corresponding to the compilation unit defined by
+   * the given [unitSource] in the library defined by the given [librarySource],
+   * or `null` if the element model does not currently exist or if the library
+   * cannot be analyzed for some reason.
    */
   CompilationUnitElement getCompilationUnitElement(
       Source unitSource, Source librarySource);
 
   /**
-   * Get the contents and timestamp of the given source.
+   * Return the contents and timestamp of the given [source].
    *
-   * This method should be used rather than the method [Source.getContents] because contexts
-   * can have local overrides of the content of a source that the source is not aware of.
-   *
-   * @param source the source whose content is to be returned
-   * @return the contents and timestamp of the source
-   * @throws Exception if the contents of the source could not be accessed
+   * This method should be used rather than the method [Source.getContents]
+   * because contexts can have local overrides of the content of a source that
+   * the source is not aware of.
    */
   TimestampedData<String> getContents(Source source);
 
   /**
-   * Return the element referenced by the given location, or `null` if the element is not
-   * immediately available or if there is no element with the given location. The latter condition
-   * can occur, for example, if the location describes an element from a different context or if the
-   * element has been removed from this context as a result of some change since it was originally
-   * obtained.
-   *
-   * @param location the reference describing the element to be returned
-   * @return the element referenced by the given location
+   * Return the element referenced by the given [location], or `null` if the
+   * element is not immediately available or if there is no element with the
+   * given location. The latter condition can occur, for example, if the
+   * location describes an element from a different context or if the element
+   * has been removed from this context as a result of some change since it was
+   * originally obtained.
    */
   Element getElement(ElementLocation location);
 
   /**
-   * Return an analysis error info containing the array of all of the errors and the line info
-   * associated with the given source. The array of errors will be empty if the source is not known
-   * to this context or if there are no errors in the source. The errors contained in the array can
-   * be incomplete.
+   * Return an analysis error info containing the list of all of the errors and
+   * the line info associated with the given [source]. The list of errors will
+   * be empty if the source is not known to this context or if there are no
+   * errors in the source. The errors contained in the list can be incomplete.
    *
-   * @param source the source whose errors are to be returned
-   * @return all of the errors associated with the given source and the line info
    * See [computeErrors].
    */
   AnalysisErrorInfo getErrors(Source source);
 
   /**
-   * Return the element model corresponding to the HTML file defined by the given source, or
-   * `null` if the source does not represent an HTML file, the element representing the file
-   * has not yet been created, or the analysis of the HTML file failed for some reason.
+   * Return the element model corresponding to the HTML file defined by the
+   * given [source], or `null` if the source does not represent an HTML file,
+   * the element representing the file has not yet been created, or the analysis
+   * of the HTML file failed for some reason.
    *
-   * @param source the source defining the HTML file whose element model is to be returned
-   * @return the element model corresponding to the HTML file defined by the given source
    * See [computeHtmlElement].
    */
   HtmlElement getHtmlElement(Source source);
 
   /**
-   * Return the sources for the HTML files that reference the given compilation unit. If the source
-   * does not represent a Dart source or is not known to this context, the returned array will be
-   * empty. The contents of the array can be incomplete.
-   *
-   * @param source the source referenced by the returned HTML files
-   * @return the sources for the HTML files that reference the given compilation unit
+   * Return the sources for the HTML files that reference the compilation unit
+   * with the given [source]. If the source does not represent a Dart source or
+   * is not known to this context, the returned list will be empty. The contents
+   * of the list can be incomplete.
    */
   List<Source> getHtmlFilesReferencing(Source source);
 
   /**
-   * Return the kind of the given source, or `null` if the kind is not known to this context.
+   * Return the kind of the given [source], or `null` if the kind is not known
+   * to this context.
    *
-   * @param source the source whose kind is to be returned
-   * @return the kind of the given source
    * See [computeKindOf].
    */
   SourceKind getKindOf(Source source);
 
   /**
-   * Return the sources for the defining compilation units of any libraries of which the given
-   * source is a part. The array will normally contain a single library because most Dart sources
-   * are only included in a single library, but it is possible to have a part that is contained in
-   * multiple identically named libraries. If the source represents the defining compilation unit of
-   * a library, then the returned array will contain the given source as its only element. If the
-   * source does not represent a Dart source or is not known to this context, the returned array
-   * will be empty. The contents of the array can be incomplete.
-   *
-   * @param source the source contained in the returned libraries
-   * @return the sources for the libraries containing the given source
+   * Return the sources for the defining compilation units of any libraries of
+   * which the given [source] is a part. The list will normally contain a single
+   * library because most Dart sources are only included in a single library,
+   * but it is possible to have a part that is contained in multiple identically
+   * named libraries. If the source represents the defining compilation unit of
+   * a library, then the returned list will contain the given source as its only
+   * element. If the source does not represent a Dart source or is not known to
+   * this context, the returned list will be empty. The contents of the list can
+   * be incomplete.
    */
   List<Source> getLibrariesContaining(Source source);
 
   /**
-   * Return the sources for the defining compilation units of any libraries that depend on the given
-   * library. One library depends on another if it either imports or exports that library.
-   *
-   * @param librarySource the source for the defining compilation unit of the library being depended
-   *          on
-   * @return the sources for the libraries that depend on the given library
+   * Return the sources for the defining compilation units of any libraries that
+   * depend on the library defined by the given [librarySource]. One library
+   * depends on another if it either imports or exports that library.
    */
   List<Source> getLibrariesDependingOn(Source librarySource);
 
   /**
-   * Return the sources for the defining compilation units of any libraries that are referenced from
-   * the given HTML file.
-   *
-   * @param htmlSource the source for the HTML file
-   * @return the sources for the libraries that are referenced by the given HTML file
+   * Return the sources for the defining compilation units of any libraries that
+   * are referenced from the HTML file defined by the given [htmlSource].
    */
   List<Source> getLibrariesReferencedFromHtml(Source htmlSource);
 
   /**
-   * Return the element model corresponding to the library defined by the given source, or
-   * `null` if the element model does not currently exist or if the library cannot be analyzed
-   * for some reason.
-   *
-   * @param source the source defining the library whose element model is to be returned
-   * @return the element model corresponding to the library defined by the given source
+   * Return the element model corresponding to the library defined by the given
+   * [source], or `null` if the element model does not currently exist or if the
+   * library cannot be analyzed for some reason.
    */
   LibraryElement getLibraryElement(Source source);
 
   /**
-   * Return the line information for the given source, or `null` if the line information is
-   * not known. The line information is used to map offsets from the beginning of the source to line
-   * and column pairs.
+   * Return the line information for the given [source], or `null` if the line
+   * information is not known. The line information is used to map offsets from
+   * the beginning of the source to line and column pairs.
    *
-   * @param source the source whose line information is to be returned
-   * @return the line information for the given source
    * See [computeLineInfo].
    */
   LineInfo getLineInfo(Source source);
@@ -759,36 +679,29 @@
   int getModificationStamp(Source source);
 
   /**
-   * Return a fully resolved AST for a single compilation unit within the given library, or
-   * `null` if the resolved AST is not already computed.
+   * Return a fully resolved AST for the compilation unit defined by the given
+   * [unitSource] within the given [library], or `null` if the resolved AST is
+   * not already computed.
    *
-   * @param unitSource the source of the compilation unit
-   * @param library the library containing the compilation unit
-   * @return a fully resolved AST for the compilation unit
    * See [resolveCompilationUnit].
    */
   CompilationUnit getResolvedCompilationUnit(
       Source unitSource, LibraryElement library);
 
   /**
-   * Return a fully resolved AST for a single compilation unit within the given library, or
+   * Return a fully resolved AST for the compilation unit defined by the given
+   * [unitSource] within the library defined by the given [librarySource], or
    * `null` if the resolved AST is not already computed.
    *
-   * @param unitSource the source of the compilation unit
-   * @param librarySource the source of the defining compilation unit of the library containing the
-   *          compilation unit
-   * @return a fully resolved AST for the compilation unit
-   * See [resolveCompilationUnit].
+   * See [resolveCompilationUnit2].
    */
   CompilationUnit getResolvedCompilationUnit2(
       Source unitSource, Source librarySource);
 
   /**
-   * Return a fully resolved HTML unit, or `null` if the resolved unit is not already
-   * computed.
+   * Return the fully resolved HTML unit defined by the given [htmlSource], or
+   * `null` if the resolved unit is not already computed.
    *
-   * @param htmlSource the source of the HTML unit
-   * @return a fully resolved HTML unit
    * See [resolveHtmlUnit].
    */
   ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource);
@@ -800,159 +713,133 @@
   List<Source> getSourcesWithFullName(String path);
 
   /**
-   * Return `true` if the given source is known to be the defining compilation unit of a
-   * library that can be run on a client (references 'dart:html', either directly or indirectly).
+   * Return `true` if the given [librarySource] is known to be the defining
+   * compilation unit of a library that can be run on a client (references
+   * 'dart:html', either directly or indirectly).
    *
-   * <b>Note:</b> In addition to the expected case of returning `false` if the source is known
-   * to be a library that cannot be run on a client, this method will also return `false` if
-   * the source is not known to be a library or if we do not know whether it can be run on a client.
-   *
-   * @param librarySource the source being tested
-   * @return `true` if the given source is known to be a library that can be run on a client
+   * <b>Note:</b> In addition to the expected case of returning `false` if the
+   * source is known to be a library that cannot be run on a client, this method
+   * will also return `false` if the source is not known to be a library or if
+   * we do not know whether it can be run on a client.
    */
   bool isClientLibrary(Source librarySource);
 
   /**
-   * Return `true` if the given source is known to be the defining compilation unit of a
-   * library that can be run on the server (does not reference 'dart:html', either directly or
-   * indirectly).
+   * Return `true` if the given [librarySource] is known to be the defining
+   * compilation unit of a library that can be run on the server (does not
+   * reference 'dart:html', either directly or indirectly).
    *
-   * <b>Note:</b> In addition to the expected case of returning `false` if the source is known
-   * to be a library that cannot be run on the server, this method will also return `false` if
-   * the source is not known to be a library or if we do not know whether it can be run on the
-   * server.
-   *
-   * @param librarySource the source being tested
-   * @return `true` if the given source is known to be a library that can be run on the server
+   * <b>Note:</b> In addition to the expected case of returning `false` if the
+   * source is known to be a library that cannot be run on the server, this
+   * method will also return `false` if the source is not known to be a library
+   * or if we do not know whether it can be run on the server.
    */
   bool isServerLibrary(Source librarySource);
 
   /**
-   * Parse a single source to produce an AST structure. The resulting AST structure may or may not
-   * be resolved, and may have a slightly different structure depending upon whether it is resolved.
+   * Parse the content of the given [source] to produce an AST structure. The
+   * resulting AST structure may or may not be resolved, and may have a slightly
+   * different structure depending upon whether it is resolved.
+   *
+   * Throws an [AnalysisException] if the analysis could not be performed
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source to be parsed
-   * @return the AST structure representing the content of the source
-   * @throws AnalysisException if the analysis could not be performed
    */
   CompilationUnit parseCompilationUnit(Source source);
 
   /**
-   * Parse a single HTML source to produce an AST structure. The resulting HTML AST structure may or
-   * may not be resolved, and may have a slightly different structure depending upon whether it is
-   * resolved.
+   * Parse a single HTML [source] to produce an AST structure. The resulting
+   * HTML AST structure may or may not be resolved, and may have a slightly
+   * different structure depending upon whether it is resolved.
+   *
+   * Throws an [AnalysisException] if the analysis could not be performed
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the HTML source to be parsed
-   * @return the parse result (not `null`)
-   * @throws AnalysisException if the analysis could not be performed
    */
   ht.HtmlUnit parseHtmlUnit(Source source);
 
   /**
-   * Perform the next unit of work required to keep the analysis results up-to-date and return
-   * information about the consequent changes to the analysis results. This method can be long
-   * running.
-   *
-   * @return the results of performing the analysis
+   * Perform the next unit of work required to keep the analysis results
+   * up-to-date and return information about the consequent changes to the
+   * analysis results. This method can be long running.
    */
   AnalysisResult performAnalysisTask();
 
   /**
-   * Remove the given listener from the list of objects that are to be notified when various
-   * analysis results are produced in this context.
-   *
-   * @param listener the listener to be removed
+   * Remove the given [listener] from the list of objects that are to be
+   * notified when various analysis results are produced in this context.
    */
   void removeListener(AnalysisListener listener);
 
   /**
-   * Parse and resolve a single source within the given context to produce a fully resolved AST.
+   * Return a fully resolved AST for the compilation unit defined by the given
+   * [unitSource] within the given [library].
+   *
+   * Throws an [AnalysisException] if the analysis could not be performed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
    *
-   * @param unitSource the source to be parsed and resolved
-   * @param library the library containing the source to be resolved
-   * @return the result of resolving the AST structure representing the content of the source in the
-   *         context of the given library
-   * @throws AnalysisException if the analysis could not be performed
    * See [getResolvedCompilationUnit].
    */
   CompilationUnit resolveCompilationUnit(
       Source unitSource, LibraryElement library);
 
   /**
-   * Parse and resolve a single source within the given context to produce a fully resolved AST.
-   * Return the resolved AST structure, or `null` if the source could not be either parsed or
-   * resolved.
+   * Return a fully resolved AST for the compilation unit defined by the given
+   * [unitSource] within the library defined by the given [librarySource].
+   *
+   * Throws an [AnalysisException] if the analysis could not be performed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
    *
-   * @param unitSource the source to be parsed and resolved
-   * @param librarySource the source of the defining compilation unit of the library containing the
-   *          source to be resolved
-   * @return the result of resolving the AST structure representing the content of the source in the
-   *         context of the given library
-   * @throws AnalysisException if the analysis could not be performed
-   * See [getResolvedCompilationUnit].
+   * See [getResolvedCompilationUnit2].
    */
   CompilationUnit resolveCompilationUnit2(
       Source unitSource, Source librarySource);
 
   /**
-   * Parse and resolve a single source within the given context to produce a fully resolved AST.
+   * Parse and resolve a single [htmlSource] within the given context to produce
+   * a fully resolved AST.
+   *
+   * Throws an [AnalysisException] if the analysis could not be performed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param htmlSource the source to be parsed and resolved
-   * @return the result of resolving the AST structure representing the content of the source
-   * @throws AnalysisException if the analysis could not be performed
    */
   ht.HtmlUnit resolveHtmlUnit(Source htmlSource);
 
   /**
-   * Set the contents of the given source to the given contents and mark the source as having
-   * changed. The additional offset and length information is used by the context to determine what
-   * reanalysis is necessary.
-   *
-   * @param source the source whose contents are being overridden
-   * @param contents the text to replace the range in the current contents
-   * @param offset the offset into the current contents
-   * @param oldLength the number of characters in the original contents that were replaced
-   * @param newLength the number of characters in the replacement text
+   * Set the contents of the given [source] to the given [contents] and mark the
+   * source as having changed. The additional [offset] and [length] information
+   * is used by the context to determine what reanalysis is necessary.
    */
   void setChangedContents(
       Source source, String contents, int offset, int oldLength, int newLength);
 
   /**
-   * Set the contents of the given source to the given contents and mark the source as having
-   * changed. This has the effect of overriding the default contents of the source. If the contents
-   * are `null` the override is removed so that the default contents will be returned.
-   *
-   * @param source the source whose contents are being overridden
-   * @param contents the new contents of the source
+   * Set the contents of the given [source] to the given [contents] and mark the
+   * source as having changed. This has the effect of overriding the default
+   * contents of the source. If the contents are `null` the override is removed
+   * so that the default contents will be returned.
    */
   void setContents(Source source, String contents);
 }
 
 /**
- * Instances of the class `AnalysisContextImpl` implement an [AnalysisContext].
+ * An [AnalysisContext].
  */
 class AnalysisContextImpl implements InternalAnalysisContext {
   /**
-   * The difference between the maximum cache size and the maximum priority order size. The priority
-   * list must be capped so that it is less than the cache size. Failure to do so can result in an
-   * infinite loop in performAnalysisTask() because re-caching one AST structure can cause another
-   * priority source's AST structure to be flushed.
+   * The difference between the maximum cache size and the maximum priority
+   * order size. The priority list must be capped so that it is less than the
+   * cache size. Failure to do so can result in an infinite loop in
+   * performAnalysisTask() because re-caching one AST structure can cause
+   * another priority source's AST structure to be flushed.
    */
   static int _PRIORITY_ORDER_SIZE_DELTA = 4;
 
   /**
-   * A flag indicating whether trace output should be produced as analysis tasks are performed. Used
-   * for debugging.
+   * A flag indicating whether trace output should be produced as analysis tasks
+   * are performed. Used for debugging.
    */
   static bool _TRACE_PERFORM_TASK = false;
 
@@ -1000,7 +887,8 @@
   ContentCache _contentCache = new ContentCache();
 
   /**
-   * The source factory used to create the sources that can be analyzed in this context.
+   * The source factory used to create the sources that can be analyzed in this
+   * context.
    */
   SourceFactory _sourceFactory;
 
@@ -1020,17 +908,19 @@
   Source _asyncLibrarySource;
 
   /**
-   * The partition that contains analysis results that are not shared with other contexts.
+   * The partition that contains analysis results that are not shared with other
+   * contexts.
    */
   CachePartition _privatePartition;
 
   /**
-   * A table mapping the sources known to the context to the information known about the source.
+   * A table mapping the sources known to the context to the information known
+   * about the source.
    */
   AnalysisCache _cache;
 
   /**
-   * An array containing sources for which data should not be flushed.
+   * A list containing sources for which data should not be flushed.
    */
   List<Source> _priorityOrder = Source.EMPTY_ARRAY;
 
@@ -1050,14 +940,14 @@
       new HashMap<Source, List<PendingFuture>>();
 
   /**
-   * An array containing sources whose AST structure is needed in order to resolve the next library
-   * to be resolved.
+   * A list containing sources whose AST structure is needed in order to resolve
+   * the next library to be resolved.
    */
   HashSet<Source> _neededForResolution = null;
 
   /**
-   * A table mapping sources to the change notices that are waiting to be returned related to that
-   * source.
+   * A table mapping sources to the change notices that are waiting to be
+   * returned related to that source.
    */
   HashMap<Source, ChangeNoticeImpl> _pendingNotices =
       new HashMap<Source, ChangeNoticeImpl>();
@@ -1068,12 +958,16 @@
   AnalysisContextImpl_AnalysisTaskResultRecorder _resultRecorder;
 
   /**
-   * Cached information used in incremental analysis or `null` if none. Synchronize against
-   * [cacheLock] before accessing this field.
+   * Cached information used in incremental analysis or `null` if none.
    */
   IncrementalAnalysisCache _incrementalAnalysisCache;
 
   /**
+   * The [TypeProvider] for this context, `null` if not yet created.
+   */
+  TypeProvider _typeProvider;
+
+  /**
    * The object used to manage the list of sources that need to be analyzed.
    */
   WorkManager _workManager = new WorkManager();
@@ -1089,22 +983,21 @@
   StreamController<SourcesChangedEvent> _onSourcesChangedController;
 
   /**
-   * The listeners that are to be notified when various analysis results are produced in this
-   * context.
+   * The listeners that are to be notified when various analysis results are
+   * produced in this context.
    */
   List<AnalysisListener> _listeners = new List<AnalysisListener>();
 
   /**
-   * The most recently incrementally resolved [Source].
-   * Is null when it was already validated, or the most recent change was
-   * not incrementally resolved.
+   * The most recently incrementally resolved source, or `null` when it was
+   * already validated, or the most recent change was not incrementally resolved.
    */
   Source incrementalResolutionValidation_lastUnitSource;
 
   /**
-   * The most recently incrementally resolved library [Source].
-   * Is null when it was already validated, or the most recent change was
-   * not incrementally resolved.
+   * The most recently incrementally resolved library source, or `null` when it
+   * was already validated, or the most recent change was not incrementally
+   * resolved.
    */
   Source incrementalResolutionValidation_lastLibrarySource;
 
@@ -1114,10 +1007,14 @@
    */
   CompilationUnit incrementalResolutionValidation_lastUnit;
 
-  /** A factory to override how [ResolverVisitor] is created. */
+  /**
+   * A factory to override how the [ResolverVisitor] is created.
+   */
   ResolverVisitorFactory resolverVisitorFactory;
 
-  /** A factory to override how [TypeResolverVisitor] is created. */
+  /**
+   * A factory to override how the [TypeResolverVisitor] is created.
+   */
   TypeResolverVisitorFactory typeResolverVisitorFactory;
 
   /**
@@ -1145,7 +1042,8 @@
         this._options.generateSdkErrors != options.generateSdkErrors ||
         this._options.dart2jsHint != options.dart2jsHint ||
         (this._options.hint && !options.hint) ||
-        this._options.preserveComments != options.preserveComments;
+        this._options.preserveComments != options.preserveComments ||
+        this._options.enableStrictCallChecks != options.enableStrictCallChecks;
     int cacheSize = options.cacheSize;
     if (this._options.cacheSize != cacheSize) {
       this._options.cacheSize = cacheSize;
@@ -1157,12 +1055,12 @@
       // performAnalysisTask() because re-caching one AST structure
       // can cause another priority source's AST structure to be flushed.
       //
+      // TODO(brianwilkerson) Remove this constraint when the new task model is
+      // implemented.
+      //
       int maxPriorityOrderSize = cacheSize - _PRIORITY_ORDER_SIZE_DELTA;
       if (_priorityOrder.length > maxPriorityOrderSize) {
-        List<Source> newPriorityOrder = new List<Source>(maxPriorityOrderSize);
-        JavaSystem.arraycopy(
-            _priorityOrder, 0, newPriorityOrder, 0, maxPriorityOrderSize);
-        _priorityOrder = newPriorityOrder;
+        _priorityOrder = _priorityOrder.sublist(0, maxPriorityOrderSize);
       }
     }
     this._options.analyzeFunctionBodiesPredicate =
@@ -1170,6 +1068,7 @@
     this._options.generateImplicitErrors = options.generateImplicitErrors;
     this._options.generateSdkErrors = options.generateSdkErrors;
     this._options.dart2jsHint = options.dart2jsHint;
+    this._options.enableStrictCallChecks = options.enableStrictCallChecks;
     this._options.hint = options.hint;
     this._options.incremental = options.incremental;
     this._options.incrementalApi = options.incrementalApi;
@@ -1265,10 +1164,8 @@
   List<Source> get librarySources => _getSources(SourceKind.LIBRARY);
 
   /**
-   * Look through the cache for a task that needs to be performed. Return the task that was found,
-   * or `null` if there is no more work to be done.
-   *
-   * @return the next task that needs to be performed
+   * Look through the cache for a task that needs to be performed. Return the
+   * task that was found, or `null` if there is no more work to be done.
    */
   AnalysisTask get nextAnalysisTask {
     bool hintsEnabled = _options.hint;
@@ -1465,11 +1362,10 @@
   }
 
   /**
-   * Return a list of the sources that would be processed by [performAnalysisTask]. This
-   * method duplicates, and must therefore be kept in sync with, [getNextAnalysisTask].
-   * This method is intended to be used for testing purposes only.
-   *
-   * @return a list of the sources that would be processed by [performAnalysisTask]
+   * Return a list of the sources that would be processed by
+   * [performAnalysisTask]. This method duplicates, and must therefore be kept
+   * in sync with, [getNextAnalysisTask]. This method is intended to be used for
+   * testing purposes only.
    */
   List<Source> get sourcesNeedingProcessing {
     HashSet<Source> sources = new HashSet<Source>();
@@ -1489,8 +1385,8 @@
     WorkManager_WorkIterator iterator = _workManager.iterator();
     while (iterator.hasNext) {
       Source source = iterator.next();
-      _getSourcesNeedingProcessing(source,
-          _cache.get(source), false, hintsEnabled, lintsEnabled, sources);
+      _getSourcesNeedingProcessing(source, _cache.get(source), false,
+          hintsEnabled, lintsEnabled, sources);
     }
     return new List<Source>.from(sources);
   }
@@ -1516,6 +1412,9 @@
 
   @override
   TypeProvider get typeProvider {
+    if (_typeProvider != null) {
+      return _typeProvider;
+    }
     Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
     if (coreSource == null) {
       throw new AnalysisException("Could not create a source for dart:core");
@@ -1532,7 +1431,15 @@
     if (asyncElement == null) {
       throw new AnalysisException("Could not create an element for dart:async");
     }
-    return new TypeProviderImpl(coreElement, asyncElement);
+    _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
+    return _typeProvider;
+  }
+
+  /**
+   * Sets the [TypeProvider] for this context.
+   */
+  void set typeProvider(TypeProvider typeProvider) {
+    _typeProvider = typeProvider;
   }
 
   @override
@@ -1594,8 +1501,8 @@
     changeSet.changedContents.forEach((Source key, String value) {
       _contentsChanged(key, value, false);
     });
-    changeSet.changedRanges.forEach(
-        (Source source, ChangeSet_ContentChange change) {
+    changeSet.changedRanges
+        .forEach((Source source, ChangeSet_ContentChange change) {
       _contentRangeChanged(source, change.contents, change.offset,
           change.oldLength, change.newLength);
     });
@@ -1625,7 +1532,7 @@
     AstNode nameNode = locator.searchWithin(unit);
     while (nameNode != null) {
       if (nameNode is AnnotatedNode) {
-        Comment comment = (nameNode as AnnotatedNode).documentationComment;
+        Comment comment = nameNode.documentationComment;
         if (comment == null) {
           return null;
         }
@@ -1739,7 +1646,7 @@
     } else if (sourceEntry is DartEntry) {
       try {
         return _getDartParseData(source, sourceEntry, DartEntry.SOURCE_KIND);
-      } on AnalysisException catch (exception) {
+      } on AnalysisException {
         return SourceKind.UNKNOWN;
       }
     }
@@ -1803,10 +1710,7 @@
   }
 
   /**
-   * Create an analysis cache based on the given source factory.
-   *
-   * @param factory the source factory containing the information needed to create the cache
-   * @return the cache that was created
+   * Create an analysis cache based on the given source [factory].
    */
   AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
     if (factory == null) {
@@ -1900,7 +1804,7 @@
           }
         }
       }
-    } on _ElementByIdFinderException catch (e) {
+    } on _ElementByIdFinderException {
       return finder.result;
     }
     return null;
@@ -2149,11 +2053,8 @@
   }
 
   /**
-   * Return the cache entry associated with the given source, or `null` if there is no entry
-   * associated with the source.
-   *
-   * @param source the source for which a cache entry is being sought
-   * @return the source cache entry associated with the given source
+   * Return the cache entry associated with the given [source], or `null` if
+   * there is no entry associated with the source.
    */
   SourceEntry getReadableSourceEntryOrNull(Source source) => _cache.get(source);
 
@@ -2395,8 +2296,8 @@
         dartEntry.setValue(DartEntry.SCAN_ERRORS, AnalysisError.NO_ERRORS);
         dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
         dartEntry.setState(DartEntry.TOKEN_STREAM, CacheState.FLUSHED);
-        dartEntry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS,
-            librarySource, AnalysisError.NO_ERRORS);
+        dartEntry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource,
+            AnalysisError.NO_ERRORS);
         dartEntry.setStateInLibrary(
             DartEntry.RESOLVED_UNIT, librarySource, CacheState.FLUSHED);
         dartEntry.setValueInLibrary(DartEntry.VERIFICATION_ERRORS,
@@ -2668,22 +2569,17 @@
   }
 
   /**
-   * Record that we have accessed the AST structure associated with the given source. At the moment,
-   * there is no differentiation between the parsed and resolved forms of the AST.
-   *
-   * @param source the source whose AST structure was accessed
+   * Record that we have accessed the AST structure associated with the given
+   * [source]. At the moment, there is no differentiation between the parsed and
+   * resolved forms of the AST.
    */
   void _accessedAst(Source source) {
     _cache.accessedAst(source);
   }
 
   /**
-   * Add all of the sources contained in the given source container to the given list of sources.
-   *
-   * Note: This method must only be invoked while we are synchronized on [cacheLock].
-   *
-   * @param sources the list to which sources are to be added
-   * @param container the source container containing the sources to be added to the list
+   * Add all of the sources contained in the given source [container] to the
+   * given list of [sources].
    */
   void _addSourcesInContainer(List<Source> sources, SourceContainer container) {
     MapIterator<Source, SourceEntry> iterator = _cache.iterator();
@@ -2696,19 +2592,15 @@
   }
 
   /**
-   * Given a source for a Dart file and the library that contains it, return a cache entry in which
-   * the state of the data represented by the given descriptor is either [CacheState.VALID] or
-   * [CacheStateERROR]. This method assumes that the data can be produced by generating hints
-   * for the library if the data is not already cached.
+   * Given the [unitSource] of a Dart file and the [librarySource] of the
+   * library that contains it, return a cache entry in which the state of the
+   * data represented by the given [descriptor] is either [CacheState.VALID] or
+   * [CacheState.ERROR]. This method assumes that the data can be produced by
+   * generating hints for the library if the data is not already cached. The
+   * [dartEntry] is the cache entry associated with the Dart file.
    *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param unitSource the source representing the Dart file
-   * @param librarySource the source representing the library containing the Dart file
-   * @param dartEntry the cache entry associated with the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return a cache entry containing the required data
-   * @throws AnalysisException if data could not be returned because the source could not be parsed
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be parsed.
    */
   DartEntry _cacheDartHintData(Source unitSource, Source librarySource,
       DartEntry dartEntry, DataDescriptor descriptor) {
@@ -2756,19 +2648,13 @@
   }
 
   /**
-   * Given a source for a Dart file and the library that contains it, return a cache entry in which
-   * the state of the data represented by the given descriptor is either [CacheState.VALID] or
-   * [CacheStateERROR]. This method assumes that the data can be produced by generating lints
-   * for the library if the data is not already cached.
+   * Given a source for a Dart file and the library that contains it, return a
+   * cache entry in which the state of the data represented by the given
+   * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
+   * assumes that the data can be produced by generating lints for the library
+   * if the data is not already cached.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param unitSource the source representing the Dart file
-   * @param librarySource the source representing the library containing the Dart file
-   * @param dartEntry the cache entry associated with the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return a cache entry containing the required data
-   * @throws AnalysisException if data could not be returned because the source could not be parsed
    */
   DartEntry _cacheDartLintData(Source unitSource, Source librarySource,
       DartEntry dartEntry, DataDescriptor descriptor) {
@@ -2817,17 +2703,12 @@
   }
 
   /**
-   * Given a source for a Dart file, return a cache entry in which the state of the data represented
-   * by the given descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This
-   * method assumes that the data can be produced by parsing the source if it is not already cached.
+   * Given a source for a Dart file, return a cache entry in which the state of
+   * the data represented by the given descriptor is either [CacheState.VALID]
+   * or [CacheState.ERROR]. This method assumes that the data can be produced by
+   * parsing the source if it is not already cached.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source representing the Dart file
-   * @param dartEntry the cache entry associated with the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return a cache entry containing the required data
-   * @throws AnalysisException if data could not be returned because the source could not be parsed
    */
   DartEntry _cacheDartParseData(
       Source source, DartEntry dartEntry, DataDescriptor descriptor) {
@@ -2856,19 +2737,13 @@
   }
 
   /**
-   * Given a source for a Dart file and the library that contains it, return a cache entry in which
-   * the state of the data represented by the given descriptor is either [CacheState.VALID] or
-   * [CacheState.ERROR]. This method assumes that the data can be produced by resolving the
-   * source in the context of the library if it is not already cached.
+   * Given a source for a Dart file and the library that contains it, return a
+   * cache entry in which the state of the data represented by the given
+   * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
+   * assumes that the data can be produced by resolving the source in the
+   * context of the library if it is not already cached.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param unitSource the source representing the Dart file
-   * @param librarySource the source representing the library containing the Dart file
-   * @param dartEntry the cache entry associated with the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return a cache entry containing the required data
-   * @throws AnalysisException if data could not be returned because the source could not be parsed
    */
   DartEntry _cacheDartResolutionData(Source unitSource, Source librarySource,
       DartEntry dartEntry, DataDescriptor descriptor) {
@@ -2896,18 +2771,12 @@
   }
 
   /**
-   * Given a source for a Dart file, return a cache entry in which the state of the data represented
-   * by the given descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This
-   * method assumes that the data can be produced by scanning the source if it is not already
-   * cached.
+   * Given a source for a Dart file, return a cache entry in which the state of
+   * the data represented by the given descriptor is either [CacheState.VALID]
+   * or [CacheState.ERROR]. This method assumes that the data can be produced by
+   * scanning the source if it is not already cached.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source representing the Dart file
-   * @param dartEntry the cache entry associated with the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return a cache entry containing the required data
-   * @throws AnalysisException if data could not be returned because the source could not be scanned
    */
   DartEntry _cacheDartScanData(
       Source source, DartEntry dartEntry, DataDescriptor descriptor) {
@@ -2940,19 +2809,13 @@
   }
 
   /**
-   * Given a source for a Dart file and the library that contains it, return a cache entry in which
-   * the state of the data represented by the given descriptor is either [CacheState.VALID] or
-   * [CacheState.ERROR]. This method assumes that the data can be produced by verifying the
-   * source in the given library if the data is not already cached.
+   * Given a source for a Dart file and the library that contains it, return a
+   * cache entry in which the state of the data represented by the given
+   * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
+   * assumes that the data can be produced by verifying the source in the given
+   * library if the data is not already cached.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param unitSource the source representing the Dart file
-   * @param librarySource the source representing the library containing the Dart file
-   * @param dartEntry the cache entry associated with the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return a cache entry containing the required data
-   * @throws AnalysisException if data could not be returned because the source could not be parsed
    */
   DartEntry _cacheDartVerificationData(Source unitSource, Source librarySource,
       DartEntry dartEntry, DataDescriptor descriptor) {
@@ -2979,19 +2842,12 @@
   }
 
   /**
-   * Given a source for an HTML file, return a cache entry in which all of the data represented by
-   * the state of the given descriptors is either [CacheState.VALID] or
-   * [CacheState.ERROR]. This method assumes that the data can be produced by parsing the
-   * source if it is not already cached.
+   * Given a source for an HTML file, return a cache entry in which all of the
+   * data represented by the state of the given descriptors is either
+   * [CacheState.VALID] or [CacheState.ERROR]. This method assumes that the data
+   * can be produced by parsing the source if it is not already cached.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source representing the HTML file
-   * @param htmlEntry the cache entry associated with the HTML file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return a cache entry containing the required data
-   * @throws AnalysisException if data could not be returned because the source could not be
-   *           resolved
    */
   HtmlEntry _cacheHtmlParseData(
       Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
@@ -3030,19 +2886,12 @@
   }
 
   /**
-   * Given a source for an HTML file, return a cache entry in which the state of the data
-   * represented by the given descriptor is either [CacheState.VALID] or
-   * [CacheState.ERROR]. This method assumes that the data can be produced by resolving the
-   * source if it is not already cached.
+   * Given a source for an HTML file, return a cache entry in which the state of
+   * the data represented by the given descriptor is either [CacheState.VALID]
+   * or [CacheState.ERROR]. This method assumes that the data can be produced by
+   * resolving the source if it is not already cached.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source representing the HTML file
-   * @param dartEntry the cache entry associated with the HTML file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return a cache entry containing the required data
-   * @throws AnalysisException if data could not be returned because the source could not be
-   *           resolved
    */
   HtmlEntry _cacheHtmlResolutionData(
       Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
@@ -3080,11 +2929,9 @@
   }
 
   /**
-   * Compute the transitive closure of all libraries that depend on the given library by adding such
-   * libraries to the given collection.
-   *
-   * @param library the library on which the other libraries depend
-   * @param librariesToInvalidate the libraries that depend on the given library
+   * Compute the transitive closure of all libraries that depend on the given
+   * [library] by adding such libraries to the given collection of
+   * [librariesToInvalidate].
    */
   void _computeAllLibrariesDependingOn(
       Source library, HashSet<Source> librariesToInvalidate) {
@@ -3097,11 +2944,8 @@
   }
 
   /**
-   * Compute the priority that should be used when the source associated with the given entry is
-   * added to the work manager.
-   *
-   * @param dartEntry the entry associated with the source
-   * @return the priority that was computed
+   * Return the priority that should be used when the source associated with
+   * the given [dartEntry] is added to the work manager.
    */
   SourcePriority _computePriority(DartEntry dartEntry) {
     SourceKind kind = dartEntry.kind;
@@ -3114,20 +2958,15 @@
   }
 
   /**
-   * Given the encoded form of a source, use the source factory to reconstitute the original source.
-   *
-   * @param encoding the encoded form of a source
-   * @return the source represented by the encoding
+   * Given the encoded form of a source ([encoding]), use the source factory to
+   * reconstitute the original source.
    */
   Source _computeSourceFromEncoding(String encoding) =>
       _sourceFactory.fromEncoding(encoding);
 
   /**
-   * Return `true` if the given array of sources contains the given source.
-   *
-   * @param sources the sources being searched
-   * @param targetSource the source being searched for
-   * @return `true` if the given source is in the array
+   * Return `true` if the given list of [sources] contains the given
+   * [targetSource].
    */
   bool _contains(List<Source> sources, Source targetSource) {
     for (Source source in sources) {
@@ -3139,11 +2978,8 @@
   }
 
   /**
-   * Return `true` if the given array of sources contains any of the given target sources.
-   *
-   * @param sources the sources being searched
-   * @param targetSources the sources being searched for
-   * @return `true` if any of the given target sources are in the array
+   * Return `true` if the given list of [sources] contains any of the given
+   * [targetSources].
    */
   bool _containsAny(List<Source> sources, List<Source> targetSources) {
     for (Source targetSource in targetSources) {
@@ -3155,16 +2991,11 @@
   }
 
   /**
-   * Set the contents of the given source to the given contents and mark the source as having
-   * changed. The additional offset and length information is used by the context to determine what
-   * reanalysis is necessary. [setChangedContents] triggers a source changed event
-   * where as this method does not.
-   *
-   * @param source the source whose contents are being overridden
-   * @param contents the text to replace the range in the current contents
-   * @param offset the offset into the current contents
-   * @param oldLength the number of characters in the original contents that were replaced
-   * @param newLength the number of characters in the replacement text
+   * Set the contents of the given [source] to the given [contents] and mark the
+   * source as having changed. The additional [offset], [oldLength] and
+   * [newLength] information is used by the context to determine what reanalysis
+   * is necessary. The method [setChangedContents] triggers a source changed
+   * event where as this method does not.
    */
   bool _contentRangeChanged(Source source, String contents, int offset,
       int oldLength, int newLength) {
@@ -3196,44 +3027,22 @@
   }
 
   /**
-   * Set the contents of the given source to the given contents and mark the source as having
-   * changed. This has the effect of overriding the default contents of the source. If the contents
-   * are `null` the override is removed so that the default contents will be returned.
-   *
-   * If [notify] is true, a source changed event is triggered.
-   *
-   * @param source the source whose contents are being overridden
-   * @param contents the new contents of the source
+   * Set the contents of the given [source] to the given [contents] and mark the
+   * source as having changed. This has the effect of overriding the default
+   * contents of the source. If the contents are `null` the override is removed
+   * so that the default contents will be returned. If [notify] is true, a
+   * source changed event is triggered.
    */
   void _contentsChanged(Source source, String contents, bool notify) {
     String originalContents = _contentCache.setContents(source, contents);
     handleContentsChanged(source, originalContents, contents, notify);
   }
 
-//  /**
-//   * Create a [BuildUnitElementTask] for the given [source].
-//   */
-//  AnalysisContextImpl_TaskData _createBuildUnitElementTask(Source source,
-//      DartEntry dartEntry, Source librarySource) {
-//    CompilationUnit unit = dartEntry.resolvableCompilationUnit;
-//    if (unit == null) {
-//      return _createParseDartTask(source, dartEntry);
-//    }
-//    return new AnalysisContextImpl_TaskData(
-//        new BuildUnitElementTask(this, source, librarySource, unit),
-//        false);
-//  }
-
   /**
-   * Create a [GenerateDartErrorsTask] for the given source, marking the verification errors
-   * as being in-process. The compilation unit and the library can be the same if the compilation
-   * unit is the defining compilation unit of the library.
-   *
-   * @param unitSource the source for the compilation unit to be verified
-   * @param unitEntry the entry for the compilation unit
-   * @param librarySource the source for the library containing the compilation unit
-   * @param libraryEntry the entry for the library
-   * @return task data representing the created task
+   * Create a [GenerateDartErrorsTask] for the given [unitSource], marking the
+   * verification errors as being in-process. The compilation unit and the
+   * library can be the same if the compilation unit is the defining compilation
+   * unit of the library.
    */
   AnalysisContextImpl_TaskData _createGenerateDartErrorsTask(Source unitSource,
       DartEntry unitEntry, Source librarySource, DartEntry libraryEntry) {
@@ -3260,14 +3069,8 @@
   }
 
   /**
-   * Create a [GenerateDartHintsTask] for the given source, marking the hints as being
-   * in-process.
-   *
-   * @param source the source whose content is to be verified
-   * @param dartEntry the entry for the source
-   * @param librarySource the source for the library containing the source
-   * @param libraryEntry the entry for the library
-   * @return task data representing the created task
+   * Create a [GenerateDartHintsTask] for the given [source], marking the hints
+   * as being in-process.
    */
   AnalysisContextImpl_TaskData _createGenerateDartHintsTask(Source source,
       DartEntry dartEntry, Source librarySource, DartEntry libraryEntry) {
@@ -3299,14 +3102,8 @@
   }
 
   /**
-   * Create a [GenerateDartLintsTask] for the given source, marking the lints as
-   * being in-process.
-   *
-   * @param source the source whose content is to be verified
-   * @param dartEntry the entry for the source
-   * @param librarySource the source for the library containing the source
-   * @param libraryEntry the entry for the library
-   * @return task data representing the created task
+   * Create a [GenerateDartLintsTask] for the given [source], marking the lints
+   * as being in-process.
    */
   AnalysisContextImpl_TaskData _createGenerateDartLintsTask(Source source,
       DartEntry dartEntry, Source librarySource, DartEntry libraryEntry) {
@@ -3339,11 +3136,8 @@
   }
 
   /**
-   * Create a [GetContentTask] for the given source, marking the content as being in-process.
-   *
-   * @param source the source whose content is to be accessed
-   * @param sourceEntry the entry for the source
-   * @return task data representing the created task
+   * Create a [GetContentTask] for the given [source], marking the content as
+   * being in-process.
    */
   AnalysisContextImpl_TaskData _createGetContentTask(
       Source source, SourceEntry sourceEntry) {
@@ -3381,11 +3175,8 @@
   }
 
   /**
-   * Create a [ResolveDartLibraryTask] for the given source, marking ? as being in-process.
-   *
-   * @param source the source whose content is to be resolved
-   * @param dartEntry the entry for the source
-   * @return task data representing the created task
+   * Create a [ResolveDartLibraryTask] for the given [source], marking ? as
+   * being in-process.
    */
   AnalysisContextImpl_TaskData _createResolveDartLibraryTask(
       Source source, DartEntry dartEntry) {
@@ -3412,12 +3203,8 @@
   }
 
   /**
-   * Create a [ResolveHtmlTask] for the given source, marking the resolved unit as being
-   * in-process.
-   *
-   * @param source the source whose content is to be resolved
-   * @param htmlEntry the entry for the source
-   * @return task data representing the created task
+   * Create a [ResolveHtmlTask] for the given [source], marking the resolved
+   * unit as being in-process.
    */
   AnalysisContextImpl_TaskData _createResolveHtmlTask(
       Source source, HtmlEntry htmlEntry) {
@@ -3430,12 +3217,8 @@
   }
 
   /**
-   * Create a [ScanDartTask] for the given source, marking the scan errors as being
-   * in-process.
-   *
-   * @param source the source whose content is to be scanned
-   * @param dartEntry the entry for the source
-   * @return task data representing the created task
+   * Create a [ScanDartTask] for the given [source], marking the scan errors as
+   * being in-process.
    */
   AnalysisContextImpl_TaskData _createScanDartTask(
       Source source, DartEntry dartEntry) {
@@ -3449,12 +3232,8 @@
   }
 
   /**
-   * Create a source information object suitable for the given source. Return the source information
-   * object that was created, or `null` if the source should not be tracked by this context.
-   *
-   * @param source the source for which an information object is being created
-   * @param explicitlyAdded `true` if the source was explicitly added to the context
-   * @return the source information object that was created
+   * Create a source entry for the given [source]. Return the source entry that
+   * was created, or `null` if the source should not be tracked by this context.
    */
   SourceEntry _createSourceEntry(Source source, bool explicitlyAdded) {
     String name = source.shortName;
@@ -3474,12 +3253,9 @@
   }
 
   /**
-   * Return an array containing all of the change notices that are waiting to be returned. If there
-   * are no notices, then return either `null` or an empty array, depending on the value of
-   * the argument.
-   *
-   * @param nullIfEmpty `true` if `null` should be returned when there are no notices
-   * @return the change notices that are waiting to be returned
+   * Return a list containing all of the change notices that are waiting to be
+   * returned. If there are no notices, then return either `null` or an empty
+   * list, depending on the value of [nullIfEmpty].
    */
   List<ChangeNotice> _getChangeNotices(bool nullIfEmpty) {
     if (_pendingNotices.isEmpty) {
@@ -3494,19 +3270,15 @@
   }
 
   /**
-   * Given a source for a Dart file and the library that contains it, return the data represented by
-   * the given descriptor that is associated with that source. This method assumes that the data can
-   * be produced by generating hints for the library if it is not already cached.
+   * Given a source for a Dart file and the library that contains it, return the
+   * data represented by the given descriptor that is associated with that
+   * source. This method assumes that the data can be produced by generating
+   * hints for the library if it is not already cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be resolved.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param unitSource the source representing the Dart file
-   * @param librarySource the source representing the library containing the Dart file
-   * @param dartEntry the entry representing the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be
-   *           resolved
    */
   Object _getDartHintData(Source unitSource, Source librarySource,
       DartEntry dartEntry, DataDescriptor descriptor) {
@@ -3519,19 +3291,15 @@
   }
 
   /**
-   * Given a source for a Dart file and the library that contains it, return the data represented by
-   * the given descriptor that is associated with that source. This method assumes that the data can
-   * be produced by generating lints for the library if it is not already cached.
+   * Given a source for a Dart file and the library that contains it, return the
+   * data represented by the given descriptor that is associated with that
+   * source. This method assumes that the data can be produced by generating
+   * lints for the library if it is not already cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be resolved.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param unitSource the source representing the Dart file
-   * @param librarySource the source representing the library containing the Dart file
-   * @param dartEntry the entry representing the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be
-   *           resolved
    */
   Object _getDartLintData(Source unitSource, Source librarySource,
       DartEntry dartEntry, DataDescriptor descriptor) {
@@ -3544,17 +3312,14 @@
   }
 
   /**
-   * Given a source for a Dart file, return the data represented by the given descriptor that is
-   * associated with that source. This method assumes that the data can be produced by parsing the
-   * source if it is not already cached.
+   * Given a source for a Dart file, return the data represented by the given
+   * descriptor that is associated with that source. This method assumes that
+   * the data can be produced by parsing the source if it is not already cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be parsed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source representing the Dart file
-   * @param dartEntry the cache entry associated with the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be parsed
    */
   Object _getDartParseData(
       Source source, DartEntry dartEntry, DataDescriptor descriptor) {
@@ -3567,17 +3332,15 @@
   }
 
   /**
-   * Given a source for a Dart file, return the data represented by the given descriptor that is
-   * associated with that source, or the given default value if the source is not a Dart file. This
-   * method assumes that the data can be produced by parsing the source if it is not already cached.
+   * Given a source for a Dart file, return the data represented by the given
+   * descriptor that is associated with that source, or the given default value
+   * if the source is not a Dart file. This method assumes that the data can be
+   * produced by parsing the source if it is not already cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be parsed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source representing the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @param defaultValue the value to be returned if the source is not a Dart file
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be parsed
    */
   Object _getDartParseData2(
       Source source, DataDescriptor descriptor, Object defaultValue) {
@@ -3596,19 +3359,15 @@
   }
 
   /**
-   * Given a source for a Dart file and the library that contains it, return the data represented by
-   * the given descriptor that is associated with that source. This method assumes that the data can
-   * be produced by resolving the source in the context of the library if it is not already cached.
+   * Given a source for a Dart file and the library that contains it, return the
+   * data represented by the given descriptor that is associated with that
+   * source. This method assumes that the data can be produced by resolving the
+   * source in the context of the library if it is not already cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be resolved.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param unitSource the source representing the Dart file
-   * @param librarySource the source representing the library containing the Dart file
-   * @param dartEntry the entry representing the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be
-   *           resolved
    */
   Object _getDartResolutionData(Source unitSource, Source librarySource,
       DartEntry dartEntry, DataDescriptor descriptor) {
@@ -3623,20 +3382,16 @@
   }
 
   /**
-   * Given a source for a Dart file and the library that contains it, return the data represented by
-   * the given descriptor that is associated with that source, or the given default value if the
-   * source is not a Dart file. This method assumes that the data can be produced by resolving the
-   * source in the context of the library if it is not already cached.
+   * Given a source for a Dart file and the library that contains it, return the
+   * data represented by the given descriptor that is associated with that
+   * source, or the given default value if the source is not a Dart file. This
+   * method assumes that the data can be produced by resolving the source in the
+   * context of the library if it is not already cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be resolved.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param unitSource the source representing the Dart file
-   * @param librarySource the source representing the library containing the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @param defaultValue the value to be returned if the source is not a Dart file
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be
-   *           resolved
    */
   Object _getDartResolutionData2(Source unitSource, Source librarySource,
       DataDescriptor descriptor, Object defaultValue) {
@@ -3656,17 +3411,15 @@
   }
 
   /**
-   * Given a source for a Dart file, return the data represented by the given descriptor that is
-   * associated with that source. This method assumes that the data can be produced by scanning the
-   * source if it is not already cached.
+   * Given a source for a Dart file, return the data represented by the given
+   * descriptor that is associated with that source. This method assumes that
+   * the data can be produced by scanning the source if it is not already
+   * cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be scanned.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source representing the Dart file
-   * @param dartEntry the cache entry associated with the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be scanned
    */
   Object _getDartScanData(
       Source source, DartEntry dartEntry, DataDescriptor descriptor) {
@@ -3675,18 +3428,15 @@
   }
 
   /**
-   * Given a source for a Dart file, return the data represented by the given descriptor that is
-   * associated with that source, or the given default value if the source is not a Dart file. This
-   * method assumes that the data can be produced by scanning the source if it is not already
-   * cached.
+   * Given a source for a Dart file, return the data represented by the given
+   * descriptor that is associated with that source, or the given default value
+   * if the source is not a Dart file. This method assumes that the data can be
+   * produced by scanning the source if it is not already cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be scanned.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source representing the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @param defaultValue the value to be returned if the source is not a Dart file
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be scanned
    */
   Object _getDartScanData2(
       Source source, DataDescriptor descriptor, Object defaultValue) {
@@ -3705,19 +3455,15 @@
   }
 
   /**
-   * Given a source for a Dart file and the library that contains it, return the data represented by
-   * the given descriptor that is associated with that source. This method assumes that the data can
-   * be produced by verifying the source within the given library if it is not already cached.
+   * Given a source for a Dart file and the library that contains it, return the
+   * data represented by the given descriptor that is associated with that
+   * source. This method assumes that the data can be produced by verifying the
+   * source within the given library if it is not already cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be resolved.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param unitSource the source representing the Dart file
-   * @param librarySource the source representing the library containing the Dart file
-   * @param dartEntry the entry representing the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be
-   *           resolved
    */
   Object _getDartVerificationData(Source unitSource, Source librarySource,
       DartEntry dartEntry, DataDescriptor descriptor) {
@@ -3727,17 +3473,15 @@
   }
 
   /**
-   * Given a source for an HTML file, return the data represented by the given descriptor that is
-   * associated with that source, or the given default value if the source is not an HTML file. This
-   * method assumes that the data can be produced by parsing the source if it is not already cached.
+   * Given a source for an HTML file, return the data represented by the given
+   * descriptor that is associated with that source, or the given default value
+   * if the source is not an HTML file. This method assumes that the data can be
+   * produced by parsing the source if it is not already cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be parsed.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source representing the Dart file
-   * @param descriptor the descriptor representing the data to be returned
-   * @param defaultValue the value to be returned if the source is not an HTML file
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be parsed
    */
   Object _getHtmlParseData(
       Source source, DataDescriptor descriptor, Object defaultValue) {
@@ -3754,19 +3498,15 @@
   }
 
   /**
-   * Given a source for an HTML file, return the data represented by the given descriptor that is
-   * associated with that source, or the given default value if the source is not an HTML file. This
-   * method assumes that the data can be produced by resolving the source if it is not already
-   * cached.
+   * Given a source for an HTML file, return the data represented by the given
+   * descriptor that is associated with that source, or the given default value
+   * if the source is not an HTML file. This method assumes that the data can be
+   * produced by resolving the source if it is not already cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be resolved.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source representing the HTML file
-   * @param descriptor the descriptor representing the data to be returned
-   * @param defaultValue the value to be returned if the source is not an HTML file
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be
-   *           resolved
    */
   Object _getHtmlResolutionData(
       Source source, DataDescriptor descriptor, Object defaultValue) {
@@ -3785,18 +3525,15 @@
   }
 
   /**
-   * Given a source for an HTML file, return the data represented by the given descriptor that is
-   * associated with that source. This method assumes that the data can be produced by resolving the
-   * source if it is not already cached.
+   * Given a source for an HTML file, return the data represented by the given
+   * descriptor that is associated with that source. This method assumes that
+   * the data can be produced by resolving the source if it is not already
+   * cached.
+   *
+   * Throws an [AnalysisException] if data could not be returned because the
+   * source could not be resolved.
    *
    * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * @param source the source representing the HTML file
-   * @param htmlEntry the entry representing the HTML file
-   * @param descriptor the descriptor representing the data to be returned
-   * @return the requested data about the given source
-   * @throws AnalysisException if data could not be returned because the source could not be
-   *           resolved
    */
   Object _getHtmlResolutionData2(
       Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
@@ -3808,18 +3545,9 @@
   }
 
   /**
-   * Look at the given source to see whether a task needs to be performed related to it. Return the
-   * task that should be performed, or `null` if there is no more work to be done for the
-   * source.
-   *
-   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
-   *
-   * @param source the source to be checked
-   * @param sourceEntry the cache entry associated with the source
-   * @param isPriority `true` if the source is a priority source
-   * @param hintsEnabled `true` if hints are currently enabled
-   * @param lintsEnabled `true` if lints are currently enabled
-   * @return the next task that needs to be performed for the given source
+   * Look at the given [source] to see whether a task needs to be performed
+   * related to it. Return the task that should be performed, or `null` if there
+   * is no more work to be done for the source.
    */
   AnalysisContextImpl_TaskData _getNextAnalysisTaskForSource(Source source,
       SourceEntry sourceEntry, bool isPriority, bool hintsEnabled,
@@ -3956,10 +3684,8 @@
   }
 
   /**
-   * Return a change notice for the given source, creating one if one does not already exist.
-   *
-   * @param source the source for which changes are being reported
-   * @return a change notice for the given source
+   * Return a change notice for the given [source], creating one if one does not
+   * already exist.
    */
   ChangeNoticeImpl _getNotice(Source source) {
     ChangeNoticeImpl notice = _pendingNotices[source];
@@ -3971,8 +3697,8 @@
   }
 
   /**
-   * Return the cache entry associated with the given source, or `null` if the source is not a
-   * Dart file.
+   * Return the cache entry associated with the given [source], or `null` if the
+   * source is not a Dart file.
    *
    * @param source the source for which a cache entry is being sought
    * @return the source cache entry associated with the given source
@@ -3983,17 +3709,14 @@
       sourceEntry = _createSourceEntry(source, false);
     }
     if (sourceEntry is DartEntry) {
-      return sourceEntry as DartEntry;
+      return sourceEntry;
     }
     return null;
   }
 
   /**
-   * Return the cache entry associated with the given source, or `null` if the source is not
-   * an HTML file.
-   *
-   * @param source the source for which a cache entry is being sought
-   * @return the source cache entry associated with the given source
+   * Return the cache entry associated with the given [source], or `null` if the
+   * source is not an HTML file.
    */
   HtmlEntry _getReadableHtmlEntry(Source source) {
     SourceEntry sourceEntry = _cache.get(source);
@@ -4001,16 +3724,14 @@
       sourceEntry = _createSourceEntry(source, false);
     }
     if (sourceEntry is HtmlEntry) {
-      return sourceEntry as HtmlEntry;
+      return sourceEntry;
     }
     return null;
   }
 
   /**
-   * Return the cache entry associated with the given source, creating it if necessary.
-   *
-   * @param source the source for which a cache entry is being sought
-   * @return the source cache entry associated with the given source
+   * Return the cache entry associated with the given [source], creating it if
+   * necessary.
    */
   SourceEntry _getReadableSourceEntry(Source source) {
     SourceEntry sourceEntry = _cache.get(source);
@@ -4021,12 +3742,9 @@
   }
 
   /**
-   * Return a resolved compilation unit corresponding to the given element in the given library, or
-   * `null` if the information is not cached.
-   *
-   * @param element the element representing the compilation unit
-   * @param librarySource the source representing the library containing the unit
-   * @return the specified resolved compilation unit
+   * Return a resolved compilation unit corresponding to the given [element] in
+   * the library defined by the given [librarySource], or `null` if the
+   * information is not cached.
    */
   TimestampedData<CompilationUnit> _getResolvedUnit(
       CompilationUnitElement element, Source librarySource) {
@@ -4044,10 +3762,8 @@
   }
 
   /**
-   * Return an array containing all of the sources known to this context that have the given kind.
-   *
-   * @param kind the kind of sources to be returned
-   * @return all of the sources known to this context that have the given kind
+   * Return a list containing all of the sources known to this context that have
+   * the given [kind].
    */
   List<Source> _getSources(SourceKind kind) {
     List<Source> sources = new List<Source>();
@@ -4061,20 +3777,11 @@
   }
 
   /**
-   * Look at the given source to see whether a task needs to be performed related to it. If so, add
-   * the source to the set of sources that need to be processed. This method duplicates, and must
-   * therefore be kept in sync with,
-   * [getNextAnalysisTask]. This method is intended to
-   * be used for testing purposes only.
-   *
-   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
-   *
-   * @param source the source to be checked
-   * @param sourceEntry the cache entry associated with the source
-   * @param isPriority `true` if the source is a priority source
-   * @param hintsEnabled `true` if hints are currently enabled
-   * @param lintsEnabled `true` if lints are currently enabled
-   * @param sources the set to which sources should be added
+   * Look at the given [source] to see whether a task needs to be performed
+   * related to it. If so, add the source to the set of sources that need to be
+   * processed. This method duplicates, and must therefore be kept in sync with,
+   * [_getNextAnalysisTaskForSource]. This method is intended to be used for
+   * testing purposes only.
    */
   void _getSourcesNeedingProcessing(Source source, SourceEntry sourceEntry,
       bool isPriority, bool hintsEnabled, bool lintsEnabled,
@@ -4179,12 +3886,9 @@
   }
 
   /**
-   * Invalidate all of the resolution results computed by this context.
-   *
-   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
-   *
-   * @param invalidateUris `true` if the cached results of converting URIs to source files
-   *          should also be invalidated.
+   * Invalidate all of the resolution results computed by this context. The flag
+   * [invalidateUris] should be `true` if the cached results of converting URIs
+   * to source files should also be invalidated.
    */
   void _invalidateAllLocalResolutionInformation(bool invalidateUris) {
     HashMap<Source, List<Source>> oldPartMap =
@@ -4210,15 +3914,12 @@
   }
 
   /**
-   * In response to a change to at least one of the compilation units in the given library,
-   * invalidate any results that are dependent on the result of resolving that library.
+   * In response to a change to at least one of the compilation units in the
+   * library defined by the given [librarySource], invalidate any results that
+   * are dependent on the result of resolving that library.
    *
-   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
-   *
-   * <b>Note:</b> Any cache entries that were accessed before this method was invoked must be
-   * re-accessed after this method returns.
-   *
-   * @param librarySource the source of the library being invalidated
+   * <b>Note:</b> Any cache entries that were accessed before this method was
+   * invoked must be re-accessed after this method returns.
    */
   void _invalidateLibraryResolution(Source librarySource) {
     // TODO(brianwilkerson) This could be optimized. There's no need to flush
@@ -4241,12 +3942,9 @@
   }
 
   /**
-   * Return `true` if this library is, or depends on, dart:html.
-   *
-   * @param library the library being tested
-   * @param visitedLibraries a collection of the libraries that have been visited, used to prevent
-   *          infinite recursion
-   * @return `true` if this library is, or depends on, dart:html
+   * Return `true` if the given [library] is, or depends on, 'dart:html'. The
+   * [visitedLibraries] is a collection of the libraries that have been visited,
+   * used to prevent infinite recursion.
    */
   bool _isClient(LibraryElement library, Source htmlSource,
       HashSet<LibraryElement> visitedLibraries) {
@@ -4274,9 +3972,7 @@
       false;
 
   /**
-   * Log the given debugging information.
-   *
-   * @param message the message to be added to the log
+   * Log the given debugging [message].
    */
   void _logInformation(String message) {
     AnalysisEngine.instance.logger.logInformation(message);
@@ -4284,8 +3980,6 @@
 
   /**
    * Notify all of the analysis listeners that a task is about to be performed.
-   *
-   * @param taskDescription a human readable description of the task that is about to be performed
    */
   void _notifyAboutToPerformTask(String taskDescription) {
     int count = _listeners.length;
@@ -4295,12 +3989,8 @@
   }
 
   /**
-   * Notify all of the analysis listeners that the errors associated with the given source has been
-   * updated to the given errors.
-   *
-   * @param source the source containing the errors that were computed
-   * @param errors the errors that were computed
-   * @param lineInfo the line information associated with the source
+   * Notify all of the analysis listeners that the errors associated with the
+   * given [source] has been updated to the given [errors].
    */
   void _notifyErrors(
       Source source, List<AnalysisError> errors, LineInfo lineInfo) {
@@ -4452,13 +4142,8 @@
 //  }
 
   /**
-   * Given a cache entry and a library element, record the library element and other information
-   * gleaned from the element in the cache entry.
-   *
-   * @param dartCopy the cache entry in which data is to be recorded
-   * @param library the library element used to record information
-   * @param librarySource the source for the library used to record information
-   * @param htmlSource the source for the HTML library
+   * Given a [dartEntry] and a [library] element, record the library element and
+   * other information gleaned from the element in the cache entry.
    */
   void _recordElementData(DartEntry dartEntry, LibraryElement library,
       Source librarySource, Source htmlSource) {
@@ -4601,11 +4286,8 @@
   }
 
   /**
-   * Record the results produced by performing a [IncrementalAnalysisTask].
-   *
-   * @param task the task that was performed
-   * @return an entry containing the computed results
-   * @throws AnalysisException if the results could not be recorded
+   * Record the results produced by performing a [task] and return the cache
+   * entry associated with the results.
    */
   DartEntry _recordIncrementalAnalysisTaskResults(
       IncrementalAnalysisTask task) {
@@ -4780,13 +4462,8 @@
   }
 
   /**
-   * Remove the given library from the list of containing libraries for all of the parts referenced
-   * by the given entry.
-   *
-   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
-   *
-   * @param librarySource the library to be removed
-   * @param dartEntry the entry containing the list of included parts
+   * Remove the given [librarySource] from the list of containing libraries for
+   * all of the parts referenced by the given [dartEntry].
    */
   void _removeFromParts(Source librarySource, DartEntry dartEntry) {
     List<Source> oldParts = dartEntry.getValue(DartEntry.INCLUDED_PARTS);
@@ -4803,12 +4480,8 @@
   }
 
   /**
-   * Remove the given libraries that are keys in the given map from the list of containing libraries
-   * for each of the parts in the corresponding value.
-   *
-   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
-   *
-   * @param oldPartMap the table containing the parts associated with each library
+   * Remove the given libraries that are keys in the given map from the list of
+   * containing libraries for each of the parts in the corresponding value.
    */
   void _removeFromPartsUsingMap(HashMap<Source, List<Source>> oldPartMap) {
     oldPartMap.forEach((Source librarySource, List<Source> oldParts) {
@@ -4829,9 +4502,7 @@
   }
 
   /**
-   * Remove the given source from the priority order if it is in the list.
-   *
-   * @param source the source to be removed
+   * Remove the given [source] from the priority order if it is in the list.
    */
   void _removeFromPriorityOrder(Source source) {
     int count = _priorityOrder.length;
@@ -4863,9 +4534,6 @@
   /**
    * Create an entry for the newly added [source] and invalidate any sources
    * that referenced the source before it existed.
-   *
-   * <b>Note:</b> This method must only be invoked while we are synchronized on
-   * [cacheLock].
    */
   void _sourceAvailable(Source source) {
     SourceEntry sourceEntry = _cache.get(source);
@@ -4878,16 +4546,13 @@
     if (sourceEntry is HtmlEntry) {
       _workManager.add(source, SourcePriority.HTML);
     } else if (sourceEntry is DartEntry) {
-      _workManager.add(source, _computePriority(sourceEntry as DartEntry));
+      _workManager.add(source, _computePriority(sourceEntry));
     }
   }
 
   /**
    * Invalidate the [source] that was changed and any sources that referenced
    * the source before it existed.
-   *
-   * <b>Note:</b> This method must only be invoked while we are synchronized on
-   * [cacheLock].
    */
   void _sourceChanged(Source source) {
     SourceEntry sourceEntry = _cache.get(source);
@@ -4911,9 +4576,7 @@
   }
 
   /**
-   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
-   *
-   * @param source the source that has been deleted
+   * Record that the give [source] has been deleted.
    */
   void _sourceDeleted(Source source) {
     SourceEntry sourceEntry = _cache.get(source);
@@ -4944,9 +4607,7 @@
   }
 
   /**
-   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
-   *
-   * @param source the source that has been removed
+   * Record that the given [source] has been removed.
    */
   void _sourceRemoved(Source source) {
     SourceEntry sourceEntry = _cache.get(source);
@@ -5031,13 +4692,10 @@
   }
 
   /**
-   * Check the cache for any invalid entries (entries whose modification time does not match the
-   * modification time of the source associated with the entry). Invalid entries will be marked as
-   * invalid so that the source will be re-analyzed.
-   *
-   * <b>Note:</b> This method must only be invoked while we are synchronized on [cacheLock].
-   *
-   * @return `true` if at least one entry was invalid
+   * Check the cache for any invalid entries (entries whose modification time
+   * does not match the modification time of the source associated with the
+   * entry). Invalid entries will be marked as invalid so that the source will
+   * be re-analyzed. Return `true` if at least one entry was invalid.
    */
   bool _validateCacheConsistency() {
     int consistencyCheckStart = JavaSystem.nanoTime();
@@ -5119,8 +4777,7 @@
 }
 
 /**
- * An `AnalysisTaskResultRecorder` is used by an analysis context to record the
- * results of a task.
+ * An object used by an analysis context to record the results of a task.
  */
 class AnalysisContextImpl_AnalysisTaskResultRecorder
     implements AnalysisTaskVisitor<SourceEntry> {
@@ -5217,15 +4874,16 @@
 }
 
 /**
- * Instances of the class `CycleBuilder` are used to construct a list of the libraries that
- * must be resolved together in order to resolve any one of the libraries.
+ * An object used to construct a list of the libraries that must be resolved
+ * together in order to resolve any one of the libraries.
  */
 class AnalysisContextImpl_CycleBuilder {
   final AnalysisContextImpl AnalysisContextImpl_this;
 
   /**
-   * A table mapping the sources of the defining compilation units of libraries to the
-   * representation of the library that has the information needed to resolve the library.
+   * A table mapping the sources of the defining compilation units of libraries
+   * to the representation of the library that has the information needed to
+   * resolve the library.
    */
   HashMap<Source, ResolvableLibrary> _libraryMap =
       new HashMap<Source, ResolvableLibrary>();
@@ -5241,8 +4899,8 @@
   List<ResolvableLibrary> _librariesInCycle;
 
   /**
-   * The analysis task that needs to be performed before the cycle of libraries can be resolved,
-   * or `null` if the libraries are ready to be resolved.
+   * The analysis task that needs to be performed before the cycle of libraries
+   * can be resolved, or `null` if the libraries are ready to be resolved.
    */
   AnalysisContextImpl_TaskData _taskData;
 
@@ -5252,28 +4910,21 @@
   AnalysisContextImpl_CycleBuilder(this.AnalysisContextImpl_this) : super();
 
   /**
-   * Return a list containing the libraries that are ready to be resolved (assuming that
-   * [getTaskData] returns `null`).
-   *
-   * @return the libraries that are ready to be resolved
+   * Return a list containing the libraries that are ready to be resolved
+   * (assuming that [getTaskData] returns `null`).
    */
   List<ResolvableLibrary> get librariesInCycle => _librariesInCycle;
 
   /**
-   * Return a representation of an analysis task that needs to be performed before the cycle of
-   * libraries can be resolved, or `null` if the libraries are ready to be resolved.
-   *
-   * @return the analysis task that needs to be performed before the cycle of libraries can be
-   *         resolved
+   * Return a representation of an analysis task that needs to be performed
+   * before the cycle of libraries can be resolved, or `null` if the libraries
+   * are ready to be resolved.
    */
   AnalysisContextImpl_TaskData get taskData => _taskData;
 
   /**
-   * Compute a list of the libraries that need to be resolved together in order to resolve the
-   * given library.
-   *
-   * @param librarySource the source of the library to be resolved
-   * @throws AnalysisException if the core library cannot be found
+   * Compute a list of the libraries that need to be resolved together in orde
+   *  to resolve the given [librarySource].
    */
   void computeCycleContaining(Source librarySource) {
     //
@@ -5340,12 +4991,12 @@
   }
 
   /**
-   * Recursively traverse the libraries reachable from the given library, creating instances of
-   * the class [Library] to represent them, and record the references in the library
-   * objects.
+   * Recursively traverse the libraries reachable from the given [library],
+   * creating instances of the class [Library] to represent them, and record the
+   * references in the library objects.
    *
-   * @param library the library to be processed to find libraries that have not yet been traversed
-   * @throws AnalysisException if some portion of the library graph could not be traversed
+   * Throws an [AnalysisException] if some portion of the library graph could
+   * not be traversed.
    */
   void _computeLibraryDependencies(ResolvableLibrary library) {
     Source librarySource = library.librarySource;
@@ -5366,15 +5017,12 @@
   }
 
   /**
-   * Recursively traverse the libraries reachable from the given library, creating instances of
-   * the class [Library] to represent them, and record the references in the library
-   * objects.
-   *
-   * @param library the library to be processed to find libraries that have not yet been traversed
-   * @param importedSources an array containing the sources that are imported into the given
-   *          library
-   * @param exportedSources an array containing the sources that are exported from the given
-   *          library
+   * Recursively traverse the libraries reachable from the given [library],
+   * creating instances of the class [Library] to represent them, and record the
+   * references in the library objects. The [importedSources] is a list
+   * containing the sources that are imported into the given library. The
+   * [exportedSources] is a list containing the sources that are exported from
+   * the given library.
    */
   void _computeLibraryDependenciesFromDirectives(ResolvableLibrary library,
       List<Source> importedSources, List<Source> exportedSources) {
@@ -5431,11 +5079,13 @@
   }
 
   /**
-   * Gather the resolvable AST structures for each of the compilation units in each of the
-   * libraries in the cycle. This is done in two phases: first we ensure that we have cached an
-   * AST structure for each compilation unit, then we gather them. We split the work this way
-   * because getting the AST structures can change the state of the cache in such a way that we
-   * would have more work to do if any compilation unit didn't have a resolvable AST structure.
+   * Gather the resolvable AST structures for each of the compilation units in
+   * each of the libraries in the cycle. This is done in two phases: first we
+   * ensure that we have cached an AST structure for each compilation unit, then
+   * we gather them. We split the work this way because getting the AST
+   * structures can change the state of the cache in such a way that we would
+   * have more work to do if any compilation unit didn't have a resolvable AST
+   * structure.
    */
   void _computePartsInCycle(Source librarySource) {
     int count = _librariesInCycle.length;
@@ -5460,11 +5110,8 @@
   }
 
   /**
-   * Gather the resolvable compilation units for each of the compilation units in the specified
-   * library.
-   *
-   * @param libraryPair a holder containing both the library and a list of (source, entry) pairs
-   *          for all of the compilation units in the library
+   * Gather the resolvable compilation units for each of the compilation units
+   * in the library represented by the [libraryPair].
    */
   void _computePartsInLibrary(CycleBuilder_LibraryPair libraryPair) {
     ResolvableLibrary library = libraryPair.library;
@@ -5483,11 +5130,8 @@
   }
 
   /**
-   * Create an object to represent the information about the library defined by the compilation
-   * unit with the given source.
-   *
-   * @param librarySource the source of the library's defining compilation unit
-   * @return the library object that was created
+   * Create an object to represent the information about the library defined by
+   * the compilation unit with the given [librarySource].
    */
   ResolvableLibrary _createLibrary(Source librarySource) {
     ResolvableLibrary library = new ResolvableLibrary(librarySource);
@@ -5505,11 +5149,8 @@
   }
 
   /**
-   * Create an object to represent the information about the library defined by the compilation
-   * unit with the given source.
-   *
-   * @param librarySource the source of the library's defining compilation unit
-   * @return the library object that was created
+   * Create an object to represent the information about the library defined by
+   * the compilation unit with the given [librarySource].
    */
   ResolvableLibrary _createLibraryOrNull(Source librarySource) {
     ResolvableLibrary library = new ResolvableLibrary(librarySource);
@@ -5527,10 +5168,9 @@
   }
 
   /**
-   * Ensure that the given library has an element model built for it. If another task needs to be
-   * executed first in order to build the element model, that task is placed in [taskData].
-   *
-   * @param library the library which needs an element model.
+   * Ensure that the given [library] has an element model built for it. If
+   * another task needs to be executed first in order to build the element
+   * model, that task is placed in [taskData].
    */
   void _ensureElementModel(ResolvableLibrary library) {
     Source librarySource = library.librarySource;
@@ -5548,11 +5188,10 @@
   }
 
   /**
-   * Ensure that all of the libraries that are exported by the given library (but are not
-   * themselves in the cycle) have element models built for them. If another task needs to be
-   * executed first in order to build the element model, that task is placed in [taskData].
-   *
-   * @param library the library being tested
+   * Ensure that all of the libraries that are exported by the given [library]
+   * (but are not themselves in the cycle) have element models built for them.
+   * If another task needs to be executed first in order to build the element
+   * model, that task is placed in [taskData].
    */
   void _ensureExports(
       ResolvableLibrary library, HashSet<Source> visitedLibraries) {
@@ -5575,11 +5214,10 @@
   }
 
   /**
-   * Ensure that all of the libraries that are exported by the given library (but are not
-   * themselves in the cycle) have element models built for them. If another task needs to be
-   * executed first in order to build the element model, that task is placed in [taskData].
-   *
-   * @param library the library being tested
+   * Ensure that all of the libraries that are exported by the given [library]
+   * (but are not themselves in the cycle) have element models built for them.
+   * If another task needs to be executed first in order to build the element
+   * model, that task is placed in [taskData].
    */
   void _ensureImports(ResolvableLibrary library) {
     List<ResolvableLibrary> dependencies = library.imports;
@@ -5597,8 +5235,9 @@
   }
 
   /**
-   * Ensure that all of the libraries that are either imported or exported by libraries in the
-   * cycle (but are not themselves in the cycle) have element models built for them.
+   * Ensure that all of the libraries that are either imported or exported by
+   * libraries in the cycle (but are not themselves in the cycle) have element
+   * models built for them.
    */
   void _ensureImportsAndExports() {
     HashSet<Source> visitedLibraries = new HashSet<Source>();
@@ -5617,11 +5256,8 @@
   }
 
   /**
-   * Ensure that there is a resolvable compilation unit available for all of the compilation units
-   * in the given library.
-   *
-   * @param library the library for which resolvable compilation units must be available
-   * @return a list of (source, entry) pairs for all of the compilation units in the library
+   * Ensure that there is a resolvable compilation unit available for all of the
+   * compilation units in the given [library].
    */
   List<CycleBuilder_SourceEntryPair> _ensurePartsInLibrary(
       ResolvableLibrary library) {
@@ -5663,10 +5299,8 @@
   }
 
   /**
-   * Ensure that there is a resolvable compilation unit available for the given source.
-   *
-   * @param source the source for which a resolvable compilation unit must be available
-   * @param dartEntry the entry associated with the source
+   * Ensure that there is a resolvable compilation unit available for the given
+   * [source].
    */
   void _ensureResolvableCompilationUnit(Source source, DartEntry dartEntry) {
     // The entry will be null if the source represents a non-Dart file.
@@ -5692,12 +5326,7 @@
   }
 
   /**
-   * Return the sources described by the given descriptor.
-   *
-   * @param source the source with which the sources are associated
-   * @param dartEntry the entry corresponding to the source
-   * @param descriptor the descriptor indicating which sources are to be returned
-   * @return the sources described by the given descriptor
+   * Return the sources described by the given [descriptor].
    */
   List<Source> _getSources(Source source, DartEntry dartEntry,
       DataDescriptor<List<Source>> descriptor) {
@@ -5719,15 +5348,16 @@
 }
 
 /**
- * Instances of the class `TaskData` represent information about the next task to be
- * performed. Each data has an implicit associated source: the source that might need to be
- * analyzed. There are essentially three states that can be represented:
+ * Information about the next task to be performed. Each data has an implicit
+ * associated source: the source that might need to be analyzed. There are
+ * essentially three states that can be represented:
+ *
  * * If [getTask] returns a non-`null` value, then that is the task that should
- * be executed to further analyze the associated source.
+ *   be executed to further analyze the associated source.
  * * Otherwise, if [isBlocked] returns `true`, then there is no work that can be
- * done, but analysis for the associated source is not complete.
- * * Otherwise, [getDependentSource] should return a source that needs to be analyzed
- * before the analysis of the associated source can be completed.
+ *   done, but analysis for the associated source is not complete.
+ * * Otherwise, [getDependentSource] should return a source that needs to be
+ *   analyzed before the analysis of the associated source can be completed.
  */
 class AnalysisContextImpl_TaskData {
   /**
@@ -5736,26 +5366,19 @@
   final AnalysisTask task;
 
   /**
-   * A flag indicating whether the associated source is blocked waiting for its contents to be
-   * loaded.
+   * A flag indicating whether the associated source is blocked waiting for its
+   * contents to be loaded.
    */
   final bool _blocked;
 
   /**
    * Initialize a newly created data holder.
-   *
-   * @param task the task that is to be performed
-   * @param blocked `true` if the associated source is blocked waiting for its contents to
-   *          be loaded
    */
   AnalysisContextImpl_TaskData(this.task, this._blocked);
 
   /**
-   * Return `true` if the associated source is blocked waiting for its contents to be
-   * loaded.
-   *
-   * @return `true` if the associated source is blocked waiting for its contents to be
-   *         loaded
+   * Return `true` if the associated source is blocked waiting for its contents
+   * to be loaded.
    */
   bool get isBlocked => _blocked;
 
@@ -5769,8 +5392,7 @@
 }
 
 /**
- * The interface `AnalysisContextStatistics` defines access to statistics about a single
- * [AnalysisContext].
+ * Statistics and information about a single [AnalysisContext].
  */
 abstract class AnalysisContextStatistics {
   /**
@@ -5779,7 +5401,8 @@
   List<AnalysisContextStatistics_CacheRow> get cacheRows;
 
   /**
-   * Return the exceptions that caused some entries to have a state of [CacheState.ERROR].
+   * Return the exceptions that caused some entries to have a state of
+   * [CacheState.ERROR].
    */
   List<CaughtException> get exceptions;
 
@@ -5789,7 +5412,7 @@
   List<AnalysisContextStatistics_PartitionData> get partitionData;
 
   /**
-   * Return an array containing all of the sources in the cache.
+   * Return a list containing all of the sources in the cache.
    */
   List<Source> get sources;
 }
@@ -5850,8 +5473,8 @@
  */
 abstract class AnalysisContextStatistics_PartitionData {
   /**
-   * Return the number of entries in the partition that have an AST structure in one state or
-   * another.
+   * Return the number of entries in the partition that have an AST structure in
+   * one state or another.
    */
   int get astCount;
 
@@ -5978,22 +5601,21 @@
 }
 
 /**
- * Instances of the class `AnalysisDelta` indicate changes to the types of analysis that
- * should be performed.
+ * A representation of changes to the types of analysis that should be
+ * performed.
  */
 class AnalysisDelta {
   /**
-   * A mapping from source to what type of analysis should be performed on that source.
+   * A mapping from source to what type of analysis should be performed on that
+   * source.
    */
   HashMap<Source, AnalysisLevel> _analysisMap =
       new HashMap<Source, AnalysisLevel>();
 
   /**
-   * Return a collection of the sources that have been added. This is equivalent to calling
-   * [getAnalysisLevels] and collecting all sources that do not have an analysis level of
-   * [AnalysisLevel.NONE].
-   *
-   * @return a collection of the sources
+   * Return a collection of the sources that have been added. This is equivalent
+   * to calling [getAnalysisLevels] and collecting all sources that do not have
+   * an analysis level of [AnalysisLevel.NONE].
    */
   List<Source> get addedSources {
     List<Source> result = new List<Source>();
@@ -6006,17 +5628,13 @@
   }
 
   /**
-   * Return a mapping of sources to the level of analysis that should be performed.
-   *
-   * @return the analysis map
+   * Return a mapping of sources to the level of analysis that should be
+   * performed.
    */
   Map<Source, AnalysisLevel> get analysisLevels => _analysisMap;
 
   /**
-   * Record that the specified source should be analyzed at the specified level.
-   *
-   * @param source the source
-   * @param level the level at which the given source should be analyzed
+   * Record that the given [source] should be analyzed at the given [level].
    */
   void setAnalysisLevel(Source source, AnalysisLevel level) {
     _analysisMap[source] = level;
@@ -6033,7 +5651,7 @@
   }
 
   /**
-   * Appendto the given [builder] all sources with the given analysis [level],
+   * Appendto the given [buffer] all sources with the given analysis [level],
    * prefixed with a label and a separator if [needsSeparator] is `true`.
    */
   bool _appendSources(
@@ -6059,43 +5677,43 @@
 }
 
 /**
- * The unique instance of the class `AnalysisEngine` serves as the entry point
- * for the functionality provided by the analysis engine.
+ * The entry point for the functionality provided by the analysis engine. There
+ * is a single instance of this class.
  */
 class AnalysisEngine {
   /**
    * The suffix used for Dart source files.
    */
-  static String SUFFIX_DART = "dart";
+  static const String SUFFIX_DART = "dart";
 
   /**
    * The short suffix used for HTML files.
    */
-  static String SUFFIX_HTM = "htm";
+  static const String SUFFIX_HTM = "htm";
 
   /**
    * The long suffix used for HTML files.
    */
-  static String SUFFIX_HTML = "html";
+  static const String SUFFIX_HTML = "html";
 
   /**
    * The unique instance of this class.
    */
-  static AnalysisEngine _UniqueInstance = new AnalysisEngine();
+  static final AnalysisEngine instance = new AnalysisEngine._();
 
   /**
-   * Return the unique instance of this class.
-   *
-   * @return the unique instance of this class
-   */
-  static AnalysisEngine get instance => _UniqueInstance;
-
-  /**
-   * The logger that should receive information about errors within the analysis engine.
+   * The logger that should receive information about errors within the analysis
+   * engine.
    */
   Logger _logger = Logger.NULL;
 
   /**
+   * The plugin that defines the extension points and extensions that are
+   * inherently defined by the analysis engine.
+   */
+  final EnginePlugin enginePlugin = new EnginePlugin();
+
+  /**
    * The instrumentation service that is to be used by this analysis engine.
    */
   InstrumentationService _instrumentationService =
@@ -6112,11 +5730,13 @@
   bool enableUnionTypes = false;
 
   /**
-   * A flag indicating whether union types should have strict semantics. This option has no effect
-   * when `enabledUnionTypes` is `false`.
+   * A flag indicating whether union types should have strict semantics. This
+   * option has no effect when `enabledUnionTypes` is `false`.
    */
   bool strictUnionTypes = false;
 
+  AnalysisEngine._();
+
   /**
    * Return the instrumentation service that is to be used by this analysis
    * engine.
@@ -6136,45 +5756,37 @@
   }
 
   /**
-   * Return the logger that should receive information about errors within the analysis engine.
-   *
-   * @return the logger that should receive information about errors within the analysis engine
+   * Return the logger that should receive information about errors within the
+   * analysis engine.
    */
   Logger get logger => _logger;
 
   /**
-   * Set the logger that should receive information about errors within the analysis engine to the
-   * given logger.
-   *
-   * @param logger the logger that should receive information about errors within the analysis
-   *          engine
+   * Set the logger that should receive information about errors within the
+   * analysis engine to the given [logger].
    */
   void set logger(Logger logger) {
     this._logger = logger == null ? Logger.NULL : logger;
   }
 
   /**
-   * Clear any caches holding on to analysis results so that a full re-analysis will be performed
-   * the next time an analysis context is created.
+   * Clear any caches holding on to analysis results so that a full re-analysis
+   * will be performed the next time an analysis context is created.
    */
   void clearCaches() {
     partitionManager.clearCache();
   }
 
   /**
-   * Create a new context in which analysis can be performed.
-   *
-   * @return the analysis context that was created
+   * Create and return a new context in which analysis can be performed.
    */
   AnalysisContext createAnalysisContext() {
     return new AnalysisContextImpl();
   }
 
   /**
-   * Return `true` if the given file name is assumed to contain Dart source code.
-   *
-   * @param fileName the name of the file being tested
-   * @return `true` if the given file name is assumed to contain Dart source code
+   * Return `true` if the given [fileName] is assumed to contain Dart source
+   * code.
    */
   static bool isDartFileName(String fileName) {
     if (fileName == null) {
@@ -6185,10 +5797,7 @@
   }
 
   /**
-   * Return `true` if the given file name is assumed to contain HTML.
-   *
-   * @param fileName the name of the file being tested
-   * @return `true` if the given file name is assumed to contain HTML
+   * Return `true` if the given [fileName] is assumed to contain HTML.
    */
   static bool isHtmlFileName(String fileName) {
     if (fileName == null) {
@@ -6201,53 +5810,47 @@
 }
 
 /**
- * The interface `AnalysisErrorInfo` contains the analysis errors and line information for the
- * errors.
+ * The analysis errors and line information for the errors.
  */
 abstract class AnalysisErrorInfo {
   /**
-   * Return the errors that as a result of the analysis, or `null` if there were no errors.
-   *
-   * @return the errors as a result of the analysis
+   * Return the errors that as a result of the analysis, or `null` if there were
+   * no errors.
    */
   List<AnalysisError> get errors;
 
   /**
-   * Return the line information associated with the errors, or `null` if there were no
-   * errors.
-   *
-   * @return the line information associated with the errors
+   * Return the line information associated with the errors, or `null` if there
+   * were no errors.
    */
   LineInfo get lineInfo;
 }
 
 /**
- * Instances of the class `AnalysisErrorInfoImpl` represent the analysis errors and line info
- * associated with a source.
+ * The analysis errors and line info associated with a source.
  */
 class AnalysisErrorInfoImpl implements AnalysisErrorInfo {
   /**
-   * The analysis errors associated with a source, or `null` if there are no errors.
+   * The analysis errors associated with a source, or `null` if there are no
+   * errors.
    */
   final List<AnalysisError> errors;
 
   /**
-   * The line information associated with the errors, or `null` if there are no errors.
+   * The line information associated with the errors, or `null` if there are no
+   * errors.
    */
   final LineInfo lineInfo;
 
   /**
-   * Initialize an newly created error info with the errors and line information
-   *
-   * @param errors the errors as a result of analysis
-   * @param lineinfo the line info for the errors
+   * Initialize an newly created error info with the given [errors] and
+   * [lineInfo].
    */
   AnalysisErrorInfoImpl(this.errors, this.lineInfo);
 }
 
 /**
- * The enumeration `AnalysisLevel` encodes the different levels at which a source can be
- * analyzed.
+ * The levels at which a source can be analyzed.
  */
 class AnalysisLevel extends Enum<AnalysisLevel> {
   /**
@@ -6276,82 +5879,55 @@
 }
 
 /**
- * The interface `AnalysisListener` defines the behavior of objects that are listening for
- * results being produced by an analysis context.
+ * An object that is listening for results being produced by an analysis
+ * context.
  */
 abstract class AnalysisListener {
   /**
-   * Reports that a task is about to be performed by the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param taskDescription a human readable description of the task that is about to be performed
+   * Reports that a task, described by the given [taskDescription] is about to
+   * be performed by the given [context].
    */
   void aboutToPerformTask(AnalysisContext context, String taskDescription);
 
   /**
-   * Reports that the errors associated with the given source in the given context has been updated
-   * to the given errors.
-   *
-   * @param context the context in which the new list of errors was produced
-   * @param source the source containing the errors that were computed
-   * @param errors the errors that were computed
-   * @param lineInfo the line information associated with the source
+   * Reports that the [errors] associated with the given [source] in the given
+   * [context] has been updated to the given errors. The [lineInfo] is the line
+   * information associated with the source.
    */
   void computedErrors(AnalysisContext context, Source source,
       List<AnalysisError> errors, LineInfo lineInfo);
 
   /**
-   * Reports that the given source is no longer included in the set of sources that are being
-   * analyzed by the given analysis context.
-   *
-   * @param context the context in which the source is being analyzed
-   * @param source the source that is no longer being analyzed
+   * Reports that the given [source] is no longer included in the set of sources
+   * that are being analyzed by the given analysis [context].
    */
   void excludedSource(AnalysisContext context, Source source);
 
   /**
-   * Reports that the given source is now included in the set of sources that are being analyzed by
-   * the given analysis context.
-   *
-   * @param context the context in which the source is being analyzed
-   * @param source the source that is now being analyzed
+   * Reports that the given [source] is now included in the set of sources that
+   * are being analyzed by the given analysis [context].
    */
   void includedSource(AnalysisContext context, Source source);
 
   /**
-   * Reports that the given Dart source was parsed in the given context.
-   *
-   * @param context the context in which the source was parsed
-   * @param source the source that was parsed
-   * @param unit the result of parsing the source in the given context
+   * Reports that the given Dart [source] was parsed in the given [context],
+   * producing the given [unit].
    */
   void parsedDart(AnalysisContext context, Source source, CompilationUnit unit);
 
   /**
-   * Reports that the given HTML source was parsed in the given context.
-   *
-   * @param context the context in which the source was parsed
-   * @param source the source that was parsed
-   * @param unit the result of parsing the source in the given context
+   * Reports that the given HTML [source] was parsed in the given [context].
    */
   void parsedHtml(AnalysisContext context, Source source, ht.HtmlUnit unit);
 
   /**
-   * Reports that the given Dart source was resolved in the given context.
-   *
-   * @param context the context in which the source was resolved
-   * @param source the source that was resolved
-   * @param unit the result of resolving the source in the given context
+   * Reports that the given Dart [source] was resolved in the given [context].
    */
   void resolvedDart(
       AnalysisContext context, Source source, CompilationUnit unit);
 
   /**
-   * Reports that the given HTML source was resolved in the given context.
-   *
-   * @param context the context in which the source was resolved
-   * @param source the source that was resolved
-   * @param unit the result of resolving the source in the given context
+   * Reports that the given HTML [source] was resolved in the given [context].
    */
   void resolvedHtml(AnalysisContext context, Source source, ht.HtmlUnit unit);
 }
@@ -6418,6 +5994,12 @@
   bool get enableEnum;
 
   /**
+   * Return `true` to strictly follow the specification when generating
+   * warnings on "call" methods (fixes dartbug.com/21938).
+   */
+  bool get enableStrictCallChecks;
+
+  /**
    * Return `true` if errors, warnings and hints should be generated for sources
    * that are implicitly being analyzed. The default value is `true`.
    */
@@ -6505,6 +6087,12 @@
   bool dart2jsHint = true;
 
   /**
+   * A flag indicating whether analysis is to strictly follow the specification
+   * when generating warnings on "call" methods (fixes dartbug.com/21938).
+   */
+  bool enableStrictCallChecks = false;
+
+  /**
    * A flag indicating whether errors, warnings and hints should be generated
    * for sources that are implicitly being analyzed.
    */
@@ -6563,6 +6151,7 @@
     analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
     cacheSize = options.cacheSize;
     dart2jsHint = options.dart2jsHint;
+    enableStrictCallChecks = options.enableStrictCallChecks;
     generateImplicitErrors = options.generateImplicitErrors;
     generateSdkErrors = options.generateSdkErrors;
     hint = options.hint;
@@ -6644,17 +6233,18 @@
 }
 
 /**
- * Instances of the class `AnalysisResult`
+ *
  */
 class AnalysisResult {
   /**
-   * The change notices associated with this result, or `null` if there were no changes and
-   * there is no more work to be done.
+   * The change notices associated with this result, or `null` if there were no
+   * changes and there is no more work to be done.
    */
   final List<ChangeNotice> _notices;
 
   /**
-   * The number of milliseconds required to determine which task was to be performed.
+   * The number of milliseconds required to determine which task was to be
+   * performed.
    */
   final int getTime;
 
@@ -6669,35 +6259,31 @@
   final int performTime;
 
   /**
-   * Initialize a newly created analysis result to have the given values.
-   *
-   * @param notices the change notices associated with this result
-   * @param getTime the number of milliseconds required to determine which task was to be performed
-   * @param taskClassName the name of the class of the task that was performed
-   * @param performTime the number of milliseconds required to perform the task
+   * Initialize a newly created analysis result to have the given values. The
+   * [notices] is the change notices associated with this result. The [getTime]
+   * is the number of milliseconds required to determine which task was to be
+   * performed. The [taskClassName] is the name of the class of the task that
+   * was performed. The [performTime] is the number of milliseconds required to
+   * perform the task.
    */
   AnalysisResult(
       this._notices, this.getTime, this.taskClassName, this.performTime);
 
   /**
-   * Return the change notices associated with this result, or `null` if there were no changes
-   * and there is no more work to be done.
-   *
-   * @return the change notices associated with this result
+   * Return the change notices associated with this result, or `null` if there
+   * were no changes and there is no more work to be done.
    */
   List<ChangeNotice> get changeNotices => _notices;
 
   /**
-   * Return `true` if there is more to be performed after the task that was performed.
-   *
-   * @return `true` if there is more to be performed after the task that was performed
+   * Return `true` if there is more to be performed after the task that was
+   * performed.
    */
   bool get hasMoreWork => _notices != null;
 }
 
 /**
- * The abstract class `AnalysisTask` defines the behavior of objects used to perform an
- * analysis task.
+ * An analysis task.
  */
 abstract class AnalysisTask {
   /**
@@ -6706,55 +6292,44 @@
   final InternalAnalysisContext context;
 
   /**
-   * The exception that was thrown while performing this task, or `null` if the task completed
-   * successfully.
+   * The exception that was thrown while performing this task, or `null` if the
+   * task completed successfully.
    */
   CaughtException _thrownException;
 
   /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
+   * Initialize a newly created task to perform analysis within the given
+   * [context].
    */
   AnalysisTask(this.context);
 
   /**
-   * Return the exception that was thrown while performing this task, or `null` if the task
-   * completed successfully.
-   *
-   * @return the exception that was thrown while performing this task
+   * Return the exception that was thrown while performing this task, or `null`
+   * if the task completed successfully.
    */
   CaughtException get exception => _thrownException;
 
   /**
    * Return a textual description of this task.
-   *
-   * @return a textual description of this task
    */
   String get taskDescription;
 
   /**
-   * Use the given visitor to visit this task.
-   *
-   * @param visitor the visitor that should be used to visit this task
-   * @return the value returned by the visitor
-   * @throws AnalysisException if the visitor throws the exception
+   * Use the given [visitor] to visit this task. Throws an [AnalysisException]
+   * if the visitor throws the exception.
    */
   accept(AnalysisTaskVisitor visitor);
 
   /**
-   * Perform this analysis task, protected by an exception handler.
-   *
-   * @throws AnalysisException if an exception occurs while performing the task
+   * Perform this analysis task, protected by an exception handler. Throws an
+   * [AnalysisException] if an exception occurs while performing the task.
    */
   void internalPerform();
 
   /**
-   * Perform this analysis task and use the given visitor to visit this task after it has completed.
-   *
-   * @param visitor the visitor used to visit this task after it has completed
-   * @return the value returned by the visitor
-   * @throws AnalysisException if the visitor throws the exception
+   * Perform this analysis task and use the given [visitor] to visit this task
+   * after it has completed. Throws an [AnalysisException] if the visitor throws
+   * the exception.
    */
   Object perform(AnalysisTaskVisitor visitor) {
     try {
@@ -6774,9 +6349,8 @@
 
   /**
    * Perform this analysis task, ensuring that all exceptions are wrapped in an
-   * [AnalysisException].
-   *
-   * @throws AnalysisException if any exception occurs while performing the task
+   * [AnalysisException]. Throws an [AnalysisException] if any exception occurs
+   * while performing the task
    */
   void _safelyPerform() {
     try {
@@ -6787,7 +6361,7 @@
       AnalysisEngine.instance.instrumentationService.logAnalysisTask(
           contextName, taskDescription);
       internalPerform();
-    } on AnalysisException catch (exception) {
+    } on AnalysisException {
       rethrow;
     } catch (exception, stackTrace) {
       throw new AnalysisException(
@@ -6797,7 +6371,7 @@
 }
 
 /**
- * An `AnalysisTaskVisitor` visits tasks. While tasks are not structured in any
+ * An object used to visit tasks. While tasks are not structured in any
  * interesting way, this class provides the ability to dispatch to an
  * appropriate method.
  */
@@ -6909,18 +6483,18 @@
 }
 
 /**
- * Instances of the class `CachePartition` implement a single partition in an LRU cache of
- * information related to analysis.
+ * A single partition in an LRU cache of information related to analysis.
  */
 abstract class CachePartition {
   /**
-   * The context that owns this partition. Multiple contexts can reference a partition, but only one
-   * context can own it.
+   * The context that owns this partition. Multiple contexts can reference a
+   * partition, but only one context can own it.
    */
   final InternalAnalysisContext context;
 
   /**
-   * The maximum number of sources for which AST structures should be kept in the cache.
+   * The maximum number of sources for which AST structures should be kept in
+   * the cache.
    */
   int _maxCacheSize = 0;
 
@@ -6930,27 +6504,24 @@
   final CacheRetentionPolicy _retentionPolicy;
 
   /**
-   * A table mapping the sources belonging to this partition to the information known about those
-   * sources.
+   * A table mapping the sources belonging to this partition to the information
+   * known about those sources.
    */
   HashMap<Source, SourceEntry> _sourceMap = new HashMap<Source, SourceEntry>();
 
   /**
-   * A list containing the most recently accessed sources with the most recently used at the end of
-   * the list. When more sources are added than the maximum allowed then the least recently used
-   * source will be removed and will have it's cached AST structure flushed.
+   * A list containing the most recently accessed sources with the most recently
+   * used at the end of the list. When more sources are added than the maximum
+   * allowed then the least recently used source will be removed and will have
+   * it's cached AST structure flushed.
    */
   List<Source> _recentlyUsed;
 
   /**
-   * Initialize a newly created cache to maintain at most the given number of AST structures in the
-   * cache.
-   *
-   * @param context the context that owns this partition
-   * @param maxCacheSize the maximum number of sources for which AST structures should be kept in
-   *          the cache
-   * @param retentionPolicy the policy used to determine which pieces of data to remove from the
-   *          cache
+   * Initialize a newly created cache to maintain at most [maxCacheSize] AST
+   * structures in the cache. The cache is owned by the give [context], and the
+   * [retentionPolicy] will be used to determine which pieces of data to remove
+   * from the cache.
    */
   CachePartition(this.context, int maxCacheSize, this._retentionPolicy) {
     this._maxCacheSize = maxCacheSize;
@@ -6958,9 +6529,8 @@
   }
 
   /**
-   * Return the number of entries in this partition that have an AST associated with them.
-   *
-   * @return the number of entries in this partition that have an AST associated with them
+   * Return the number of entries in this partition that have an AST associated
+   * with them.
    */
   int get astSize {
     int astSize = 0;
@@ -6982,21 +6552,16 @@
   }
 
   /**
-   * Return a table mapping the sources known to the context to the information known about the
-   * source.
+   * Return a table mapping the sources known to the context to the information
+   * known about the source.
    *
-   * <b>Note:</b> This method is only visible for use by [AnalysisCache] and should not be
-   * used for any other purpose.
-   *
-   * @return a table mapping the sources known to the context to the information known about the
-   *         source
+   * <b>Note:</b> This method is only visible for use by [AnalysisCache] and
+   * should not be used for any other purpose.
    */
   Map<Source, SourceEntry> get map => _sourceMap;
 
   /**
-   * Set the maximum size of the cache to the given size.
-   *
-   * @param size the maximum number of sources for which AST structures should be kept in the cache
+   * Set the maximum size of the cache to the given [size].
    */
   void set maxCacheSize(int size) {
     _maxCacheSize = size;
@@ -7008,9 +6573,8 @@
   }
 
   /**
-   * Record that the AST associated with the given source was just read from the cache.
-   *
-   * @param source the source whose AST was accessed
+   * Record that the AST associated with the given source was just read from the
+   * cache.
    */
   void accessedAst(Source source) {
     if (_recentlyUsed.remove(source)) {
@@ -7026,34 +6590,24 @@
   }
 
   /**
-   * Return `true` if the given source is contained in this partition.
-   *
-   * @param source the source being tested
-   * @return `true` if the source is contained in this partition
+   * Return `true` if the given [source] is contained in this partition.
    */
   bool contains(Source source);
 
   /**
-   * Return the entry associated with the given source.
-   *
-   * @param source the source whose entry is to be returned
-   * @return the entry associated with the given source
+   * Return the entry associated with the given [source].
    */
   SourceEntry get(Source source) => _sourceMap[source];
 
   /**
-   * Return an iterator returning all of the map entries mapping sources to cache entries.
-   *
-   * @return an iterator returning all of the map entries mapping sources to cache entries
+   * Return an iterator returning all of the map entries mapping sources to
+   * cache entries.
    */
   MapIterator<Source, SourceEntry> iterator() =>
       new SingleMapIterator<Source, SourceEntry>(_sourceMap);
 
   /**
-   * Associate the given entry with the given source.
-   *
-   * @param source the source with which the entry is to be associated
-   * @param entry the entry to be associated with the source
+   * Associate the given [entry] with the given [source].
    */
   void put(Source source, SourceEntry entry) {
     entry.fixExceptionState();
@@ -7061,9 +6615,7 @@
   }
 
   /**
-   * Remove all information related to the given source from this cache.
-   *
-   * @param source the source to be removed
+   * Remove all information related to the given [source] from this cache.
    */
   void remove(Source source) {
     _recentlyUsed.remove(source);
@@ -7071,9 +6623,8 @@
   }
 
   /**
-   * Record that the AST associated with the given source was just removed from the cache.
-   *
-   * @param source the source whose AST was removed
+   * Record that the AST associated with the given [source] was just removed
+   * from the cache.
    */
   void removedAst(Source source) {
     _recentlyUsed.remove(source);
@@ -7081,15 +6632,12 @@
 
   /**
    * Return the number of sources that are mapped to cache entries.
-   *
-   * @return the number of sources that are mapped to cache entries
    */
   int size() => _sourceMap.length;
 
   /**
-   * Record that the AST associated with the given source was just stored to the cache.
-   *
-   * @param source the source whose AST was stored
+   * Record that the AST associated with the given [source] was just stored to
+   * the cache.
    */
   void storedAst(Source source) {
     if (_recentlyUsed.contains(source)) {
@@ -7104,9 +6652,8 @@
   }
 
   /**
-   * Attempt to flush one AST structure from the cache.
-   *
-   * @return `true` if a structure was flushed
+   * Attempt to flush one AST structure from the cache. Return `true` if a
+   * structure was flushed.
    */
   bool _flushAstFromCache() {
     Source removedSource = _removeAstToFlush();
@@ -7125,11 +6672,10 @@
   }
 
   /**
-   * Remove and return one source from the list of recently used sources whose AST structure can be
-   * flushed from the cache. The source that will be returned will be the source that has been
-   * unreferenced for the longest period of time but that is not a priority for analysis.
-   *
-   * @return the source that was removed
+   * Remove and return one source from the list of recently used sources whose
+   * AST structure can be flushed from the cache. The source that will be
+   * returned will be the source that has been unreferenced for the longest
+   * period of time but that is not a priority for analysis.
    */
   Source _removeAstToFlush() {
     int sourceToRemove = -1;
@@ -7155,16 +6701,12 @@
 }
 
 /**
- * Instances of the class `CacheRetentionPolicy` define the behavior of objects that determine
- * how important it is for data to be retained in the analysis cache.
+ * An object used to determine how important it is for data to be retained in
+ * the analysis cache.
  */
 abstract class CacheRetentionPolicy {
   /**
-   * Return the priority of retaining the AST structure for the given source.
-   *
-   * @param source the source whose AST structure is being considered for removal
-   * @param sourceEntry the entry representing the source
-   * @return the priority of retaining the AST structure for the given source
+   * Return the priority of retaining the AST structure for the given [source].
    */
   RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry);
 }
@@ -7340,14 +6882,14 @@
 }
 
 /**
- * Instances of the class `ChangeSet` indicate which sources have been added, changed,
- * removed, or deleted. In the case of a changed source, there are multiple ways of indicating the
+ * An indication of which sources have been added, changed, removed, or deleted.
+ * In the case of a changed source, there are multiple ways of indicating the
  * nature of the change.
  *
- * No source should be added to the change set more than once, either with the same or a different
- * kind of change. It does not make sense, for example, for a source to be both added and removed,
- * and it is redundant for a source to be marked as changed in its entirety and changed in some
- * specific range.
+ * No source should be added to the change set more than once, either with the
+ * same or a different kind of change. It does not make sense, for example, for
+ * a source to be both added and removed, and it is redundant for a source to be
+ * marked as changed in its entirety and changed in some specific range.
  */
 class ChangeSet {
   /**
@@ -7361,14 +6903,15 @@
   final List<Source> changedSources = new List<Source>();
 
   /**
-   * A table mapping the sources whose content has been changed to the current content of those
-   * sources.
+   * A table mapping the sources whose content has been changed to the current
+   * content of those sources.
    */
   HashMap<Source, String> _changedContent = new HashMap<Source, String>();
 
   /**
-   * A table mapping the sources whose content has been changed within a single range to the current
-   * content of those sources and information about the affected range.
+   * A table mapping the sources whose content has been changed within a single
+   * range to the current content of those sources and information about the
+   * affected range.
    */
   final HashMap<Source, ChangeSet_ContentChange> changedRanges =
       new HashMap<Source, ChangeSet_ContentChange>();
@@ -7379,7 +6922,8 @@
   final List<Source> removedSources = new List<Source>();
 
   /**
-   * A list containing the source containers specifying additional sources that have been removed.
+   * A list containing the source containers specifying additional sources that
+   * have been removed.
    */
   final List<SourceContainer> removedContainers = new List<SourceContainer>();
 
@@ -7389,18 +6933,13 @@
   final List<Source> deletedSources = new List<Source>();
 
   /**
-   * Return a table mapping the sources whose content has been changed to the current content of
-   * those sources.
-   *
-   * @return a table mapping the sources whose content has been changed to the current content of
-   *         those sources
+   * Return a table mapping the sources whose content has been changed to the
+   * current content of those sources.
    */
   Map<Source, String> get changedContents => _changedContent;
 
   /**
    * Return `true` if this change set does not contain any changes.
-   *
-   * @return `true` if this change set does not contain any changes
    */
   bool get isEmpty => addedSources.isEmpty &&
       changedSources.isEmpty &&
@@ -7411,34 +6950,27 @@
       deletedSources.isEmpty;
 
   /**
-   * Record that the specified source has been added and that its content is the default contents of
-   * the source.
-   *
-   * @param source the source that was added
+   * Record that the specified [source] has been added and that its content is
+   * the default contents of the source.
    */
   void addedSource(Source source) {
     addedSources.add(source);
   }
 
   /**
-   * Record that the specified source has been changed and that its content is the given contents.
-   *
-   * @param source the source that was changed
-   * @param contents the new contents of the source, or `null` if the default contents of the
-   *          source are to be used
+   * Record that the specified [source] has been changed and that its content is
+   * the given [contents].
    */
   void changedContent(Source source, String contents) {
     _changedContent[source] = contents;
   }
 
   /**
-   * Record that the specified source has been changed and that its content is the given contents.
-   *
-   * @param source the source that was changed
-   * @param contents the new contents of the source
-   * @param offset the offset into the current contents
-   * @param oldLength the number of characters in the original contents that were replaced
-   * @param newLength the number of characters in the replacement text
+   * Record that the specified [source] has been changed and that its content is
+   * the given [contents]. The [offset] is the offset into the current contents.
+   * The [oldLength] is the number of characters in the original contents that
+   * were replaced. The [newLength] is the number of characters in the
+   * replacement text.
    */
   void changedRange(Source source, String contents, int offset, int oldLength,
       int newLength) {
@@ -7447,29 +6979,24 @@
   }
 
   /**
-   * Record that the specified source has been changed. If the content of the source was previously
-   * overridden, this has no effect (the content remains overridden). To cancel (or change) the
-   * override, use [changedContent] instead.
-   *
-   * @param source the source that was changed
+   * Record that the specified [source] has been changed. If the content of the
+   * source was previously overridden, this has no effect (the content remains
+   * overridden). To cancel (or change) the override, use [changedContent]
+   * instead.
    */
   void changedSource(Source source) {
     changedSources.add(source);
   }
 
   /**
-   * Record that the specified source has been deleted.
-   *
-   * @param source the source that was deleted
+   * Record that the specified [source] has been deleted.
    */
   void deletedSource(Source source) {
     deletedSources.add(source);
   }
 
   /**
-   * Record that the specified source container has been removed.
-   *
-   * @param container the source container that was removed
+   * Record that the specified source [container] has been removed.
    */
   void removedContainer(SourceContainer container) {
     if (container != null) {
@@ -7478,9 +7005,7 @@
   }
 
   /**
-   * Record that the specified source has been removed.
-   *
-   * @param source the source that was removed
+   * Record that the specified [source] has been removed.
    */
   void removedSource(Source source) {
     if (source != null) {
@@ -7522,14 +7047,9 @@
   }
 
   /**
-   * Append the given sources to the given builder, prefixed with the given label and possibly a
-   * separator.
-   *
-   * @param builder the builder to which the sources are to be appended
-   * @param sources the sources to be appended
-   * @param needsSeparator `true` if a separator is needed before the label
-   * @param label the label used to prefix the sources
-   * @return `true` if future lists of sources will need a separator
+   * Append the given [sources] to the given [buffer], prefixed with the given
+   * [label] and a separator if [needsSeparator] is `true`. Return `true` if
+   * future lists of sources will need a separator.
    */
   bool _appendSources(StringBuffer buffer, List<Source> sources,
       bool needsSeparator, String label) {
@@ -7550,14 +7070,9 @@
   }
 
   /**
-   * Append the given sources to the given builder, prefixed with the given label and possibly a
-   * separator.
-   *
-   * @param builder the builder to which the sources are to be appended
-   * @param sources the sources to be appended
-   * @param needsSeparator `true` if a separator is needed before the label
-   * @param label the label used to prefix the sources
-   * @return `true` if future lists of sources will need a separator
+   * Append the given [sources] to the given [builder], prefixed with the given
+   * [label] and a separator if [needsSeparator] is `true`. Return `true` if
+   * future lists of sources will need a separator.
    */
   bool _appendSources2(StringBuffer buffer, HashMap<Source, dynamic> sources,
       bool needsSeparator, String label) {
@@ -7579,7 +7094,7 @@
 }
 
 /**
- * Instances of the class `ContentChange` represent a change to the content of a source.
+ * A change to the content of a source.
  */
 class ChangeSet_ContentChange {
   /**
@@ -7603,20 +7118,19 @@
   final int newLength;
 
   /**
-   * Initialize a newly created change object to represent a change to the content of a source.
-   *
-   * @param contents the new contents of the source
-   * @param offset the offset into the current contents
-   * @param oldLength the number of characters in the original contents that were replaced
-   * @param newLength the number of characters in the replacement text
+   * Initialize a newly created change object to represent a change to the
+   * content of a source. The [contents] is the new contents of the source. The
+   * [offse] ist the offset into the current contents. The [oldLength] is the
+   * number of characters in the original contents that were replaced. The
+   * [newLength] is the number of characters in the replacement text.
    */
   ChangeSet_ContentChange(
       this.contents, this.offset, this.oldLength, this.newLength);
 }
 
 /**
- * Instances of the class `LibraryPair` hold a library and a list of the (source, entry)
- * pairs for compilation units in the library.
+ * A pair containing a library and a list of the (source, entry) pairs for
+ * compilation units in the library.
  */
 class CycleBuilder_LibraryPair {
   /**
@@ -7625,16 +7139,13 @@
   ResolvableLibrary library;
 
   /**
-   * The (source, entry) pairs representing the compilation units in the library.
+   * The (source, entry) pairs representing the compilation units in the
+   * library.
    */
   List<CycleBuilder_SourceEntryPair> entryPairs;
 
   /**
-   * Initialize a newly created pair.
-   *
-   * @param library the library containing the compilation units
-   * @param entryPairs the (source, entry) pairs representing the compilation units in the
-   *          library
+   * Initialize a newly created pair from the given [library] and [entryPairs].
    */
   CycleBuilder_LibraryPair(ResolvableLibrary library,
       List<CycleBuilder_SourceEntryPair> entryPairs) {
@@ -7644,9 +7155,9 @@
 }
 
 /**
- * Instances of the class `SourceEntryPair` hold a source and the cache entry associated
- * with that source. They are used to reduce the number of times an entry must be looked up in
- * the [cache].
+ * A pair containing a source and the cache entry associated with that source.
+ * They are used to reduce the number of times an entry must be looked up in the
+ * [cache].
  */
 class CycleBuilder_SourceEntryPair {
   /**
@@ -7660,10 +7171,7 @@
   DartEntry entry;
 
   /**
-   * Initialize a newly created pair.
-   *
-   * @param source the source associated with the entry
-   * @param entry the entry associated with the source
+   * Initialize a newly created pair from the given [source] and [entry].
    */
   CycleBuilder_SourceEntryPair(Source source, DartEntry entry) {
     this.source = source;
@@ -7672,8 +7180,7 @@
 }
 
 /**
- * A `DartEntry` maintains the information cached by an analysis context about
- * an individual Dart file.
+ * The information cached by an analysis context about an individual Dart file.
  */
 class DartEntry extends SourceEntry {
   /**
@@ -7870,8 +7377,8 @@
 
   /**
    * Return a valid parsed compilation unit, either an unresolved AST structure
-   * or the result of resolving the AST structure in the context of some library,
-   * or `null` if there is no parsed compilation unit available.
+   * or the result of resolving the AST structure in the context of some
+   * library, or `null` if there is no parsed compilation unit available.
    */
   CompilationUnit get anyParsedCompilationUnit {
     if (getState(PARSED_UNIT) == CacheState.VALID) {
@@ -7910,10 +7417,8 @@
 
   /**
    * Set the list of libraries that contain this compilation unit to contain
-   * only the given source. This method should only be invoked on entries that
-   * represent a library.
-   *
-   * @param librarySource the source of the single library that the list should contain
+   * only the given [librarySource]. This method should only be invoked on
+   * entries that represent a library.
    */
   void set containingLibrary(Source librarySource) {
     _containingLibraries.clear();
@@ -8189,10 +7694,9 @@
   /**
    * Record that an error occurred while attempting to generate hints for the
    * source represented by this entry. This will set the state of all
-   * verification information as being in error.
-   *
-   * @param librarySource the source of the library in which hints were being generated
-   * @param exception the exception that shows where the error occurred
+   * verification information as being in error. The [librarySource] is the
+   * source of the library in which hints were being generated. The [exception]
+   * is the exception that shows where the error occurred.
    */
   void recordHintErrorInLibrary(
       Source librarySource, CaughtException exception) {
@@ -8204,10 +7708,9 @@
   /**
    * Record that an error occurred while attempting to generate lints for the
    * source represented by this entry. This will set the state of all
-   * verification information as being in error.
-   *
-   * @param librarySource the source of the library in which lints were being generated
-   * @param exception the exception that shows where the error occurred
+   * verification information as being in error. The [librarySource] is the
+   * source of the library in which lints were being generated. The [exception]
+   * is the exception that shows where the error occurred.
    */
   void recordLintErrorInLibrary(
       Source librarySource, CaughtException exception) {
@@ -8236,8 +7739,6 @@
    * represented by this entry. This will set the state of all resolution-based
    * information as being in error, but will not change the state of any parse
    * results.
-   *
-   * @param exception the exception that shows where the error occurred
    */
   void recordResolutionError(CaughtException exception) {
     this.exception = exception;
@@ -8249,12 +7750,12 @@
   }
 
   /**
-   * Record that an error occurred while attempting to resolve the source represented by this entry.
-   * This will set the state of all resolution-based information as being in error, but will not
-   * change the state of any parse results.
-   *
-   * @param librarySource the source of the library in which resolution was being performed
-   * @param exception the exception that shows where the error occurred
+   * Record that an error occurred while attempting to resolve the source
+   * represented by this entry. This will set the state of all resolution-based
+   * information as being in error, but will not change the state of any parse
+   * results. The [librarySource] is the source of the library in which
+   * resolution was being performed. The [exception] is the exception that shows
+   * where the error occurred.
    */
   void recordResolutionErrorInLibrary(
       Source librarySource, CaughtException exception) {
@@ -8269,8 +7770,8 @@
 
   /**
    * Record that an [exception] occurred while attempting to scan or parse the
-   * entry represented by this entry. This will set the state of all information,
-   * including any resolution-based information, as being in error.
+   * entry represented by this entry. This will set the state of all
+   * information, including any resolution-based information, as being in error.
    */
   @override
   void recordScanError(CaughtException exception) {
@@ -8283,10 +7784,9 @@
   /**
    * Record that an [exception] occurred while attempting to generate errors and
    * warnings for the source represented by this entry. This will set the state
-   * of all verification information as being in error.
-   *
-   * @param librarySource the source of the library in which verification was being performed
-   * @param exception the exception that shows where the error occurred
+   * of all verification information as being in error. The [librarySource] is
+   * the source of the library in which verification was being performed. The
+   * [exception] is the exception that shows where the error occurred.
    */
   void recordVerificationErrorInLibrary(
       Source librarySource, CaughtException exception) {
@@ -8298,8 +7798,6 @@
   /**
    * Remove the given [library] from the list of libraries that contain this
    * part. This method should only be invoked on entries that represent a part.
-   *
-   * @param librarySource the source of the library to be removed
    */
   void removeContainingLibrary(Source library) {
     _containingLibraries.remove(library);
@@ -8334,46 +7832,36 @@
   }
 
   /**
-   * Set the state of the data represented by the given descriptor in the context of the given
-   * library to the given state.
-   *
-   * @param descriptor the descriptor representing the data whose state is to be set
-   * @param librarySource the source of the defining compilation unit of the library that is the
-   *          context for the data
-   * @param cacheState the new state of the data represented by the given descriptor
+   * Set the state of the data represented by the given [descriptor] in the
+   * context of the given [library] to the given [state].
    */
   void setStateInLibrary(
-      DataDescriptor descriptor, Source librarySource, CacheState cacheState) {
+      DataDescriptor descriptor, Source library, CacheState state) {
     if (!_isValidLibraryDescriptor(descriptor)) {
       throw new ArgumentError("Invalid descriptor: $descriptor");
     }
-    ResolutionState state = _getOrCreateResolutionState(librarySource);
-    state.setState(descriptor, cacheState);
+    ResolutionState resolutionState = _getOrCreateResolutionState(library);
+    resolutionState.setState(descriptor, state);
   }
 
   /**
-   * Set the value of the data represented by the given descriptor in the context of the given
-   * library to the given value, and set the state of that data to [CacheState.VALID].
-   *
-   * @param descriptor the descriptor representing which data is to have its value set
-   * @param librarySource the source of the defining compilation unit of the library that is the
-   *          context for the data
-   * @param value the new value of the data represented by the given descriptor and library
+   * Set the value of the data represented by the given [descriptor] in the
+   * context of the given [library] to the given [value], and set the state of
+   * that data to [CacheState.VALID].
    */
   void setValueInLibrary(
-      DataDescriptor descriptor, Source librarySource, Object value) {
+      DataDescriptor descriptor, Source library, Object value) {
     if (!_isValidLibraryDescriptor(descriptor)) {
       throw new ArgumentError("Invalid descriptor: $descriptor");
     }
-    ResolutionState state = _getOrCreateResolutionState(librarySource);
+    ResolutionState state = _getOrCreateResolutionState(library);
     state.setValue(descriptor, value);
   }
 
   /**
-   * Invalidate all of the resolution information associated with the compilation unit.
-   *
-   * @param invalidateUris true if the cached results of converting URIs to source files should also
-   *          be invalidated.
+   * Invalidate all of the resolution information associated with the
+   * compilation unit. The flag [invalidateUris] should be `true` if the cached
+   * results of converting URIs to source files should also be invalidated.
    */
   void _discardCachedResolutionInformation(bool invalidateUris) {
     setState(ELEMENT, CacheState.INVALID);
@@ -8389,21 +7877,19 @@
   }
 
   /**
-   * Return a resolution state for the specified library, creating one as necessary.
-   *
-   * @param librarySource the library source (not `null`)
-   * @return the resolution state (not `null`)
+   * Return a resolution state for the specified [library], creating one as
+   * necessary.
    */
-  ResolutionState _getOrCreateResolutionState(Source librarySource) {
+  ResolutionState _getOrCreateResolutionState(Source library) {
     ResolutionState state = _resolutionState;
     if (state._librarySource == null) {
-      state._librarySource = librarySource;
+      state._librarySource = library;
       return state;
     }
-    while (state._librarySource != librarySource) {
+    while (state._librarySource != library) {
       if (state._nextState == null) {
         ResolutionState newState = new ResolutionState();
-        newState._librarySource = librarySource;
+        newState._librarySource = library;
         state._nextState = newState;
         return newState;
       }
@@ -8557,8 +8043,7 @@
 }
 
 /**
- * Instances of the class `DataDescriptor` are immutable constants representing data that can
- * be stored in the cache.
+ * An immutable constant representing data that can be stored in the cache.
  */
 class DataDescriptor<E> {
   /**
@@ -8595,9 +8080,9 @@
 }
 
 /**
- * Instances of the class `DefaultRetentionPolicy` implement a retention policy that will keep
- * AST's in the cache if there is analysis information that needs to be computed for a source, where
- * the computation is dependent on having the AST.
+ * A retention policy that will keep AST's in the cache if there is analysis
+ * information that needs to be computed for a source, where the computation is
+ * dependent on having the AST.
  */
 class DefaultRetentionPolicy implements CacheRetentionPolicy {
   /**
@@ -8606,11 +8091,9 @@
   static DefaultRetentionPolicy POLICY = new DefaultRetentionPolicy();
 
   /**
-   * Return `true` if there is analysis information in the given entry that needs to be
-   * computed, where the computation is dependent on having the AST.
-   *
-   * @param dartEntry the entry being tested
-   * @return `true` if there is analysis information that needs to be computed from the AST
+   * Return `true` if there is analysis information in the given [dartEntry]
+   * that needs to be computed, where the computation is dependent on having the
+   * AST.
    */
   bool astIsNeeded(DartEntry dartEntry) =>
       dartEntry.hasInvalidData(DartEntry.HINTS) ||
@@ -8768,7 +8251,7 @@
 class GenerateDartHintsTask extends AnalysisTask {
   /**
    * The compilation units that comprise the library, with the defining compilation unit appearing
-   * first in the array.
+   * first in the list.
    */
   final List<TimestampedData<CompilationUnit>> _units;
 
@@ -8788,7 +8271,7 @@
    *
    * @param context the context in which the task is to be performed
    * @param units the compilation units that comprise the library, with the defining compilation
-   *          unit appearing first in the array
+   *          unit appearing first in the list
    * @param libraryElement the element model for the library being analyzed
    */
   GenerateDartHintsTask(
@@ -8851,7 +8334,7 @@
 class GenerateDartLintsTask extends AnalysisTask {
 
   ///The compilation units that comprise the library, with the defining
-  ///compilation unit appearing first in the array.
+  ///compilation unit appearing first in the list.
   final List<TimestampedData<CompilationUnit>> _units;
 
   /// The element model for the library being analyzed.
@@ -8979,8 +8462,8 @@
       TimestampedData<String> data = context.getContents(source);
       _content = data.data;
       _modificationTime = data.modificationTime;
-      AnalysisEngine.instance.instrumentationService
-          .logFileRead(source.fullName, _modificationTime, _content);
+      AnalysisEngine.instance.instrumentationService.logFileRead(
+          source.fullName, _modificationTime, _content);
     } catch (exception, stackTrace) {
       errors.add(new AnalysisError.con1(
           source, ScannerErrorCode.UNABLE_GET_CONTENT, [exception]));
@@ -8991,8 +8474,7 @@
 }
 
 /**
- * An `HtmlEntry` maintains the information cached by an analysis context about
- * an individual HTML file.
+ * The information cached by an analysis context about an individual HTML file.
  */
 class HtmlEntry extends SourceEntry {
   /**
@@ -9451,7 +8933,7 @@
   TypeProvider get typeProvider {
     try {
       return context.typeProvider;
-    } on AnalysisException catch (exception) {
+    } on AnalysisException {
       return null;
     }
   }
@@ -9474,8 +8956,8 @@
     BooleanErrorListener errorListener = new BooleanErrorListener();
     IncrementalScanner scanner =
         new IncrementalScanner(cache.source, reader, errorListener);
-    scanner.rescan(cache.resolvedUnit.beginToken, cache.offset,
-        cache.oldLength, cache.newLength);
+    scanner.rescan(cache.resolvedUnit.beginToken, cache.offset, cache.oldLength,
+        cache.newLength);
     if (errorListener.errorReported) {
       return;
     }
@@ -9501,8 +8983,8 @@
 }
 
 /**
- * The interface `InternalAnalysisContext` defines additional behavior for an analysis context
- * that is required by internal users of the context.
+ * Additional behavior for an analysis context that is required by internal
+ * users of the context.
  */
 abstract class InternalAnalysisContext implements AnalysisContext {
   /**
@@ -9513,14 +8995,14 @@
   set contentCache(ContentCache value);
 
   /**
-   * Return an array containing all of the sources that have been marked as priority sources.
-   * Clients must not modify the returned array.
-   *
-   * @return the sources that have been marked as priority sources
+   * Return a list containing all of the sources that have been marked as
+   * priority sources. Clients must not modify the returned list.
    */
   List<Source> get prioritySources;
 
-  /** A factory to override how [ResolverVisitor] is created. */
+  /**
+   * A factory to override how [ResolverVisitor] is created.
+   */
   ResolverVisitorFactory get resolverVisitorFactory;
 
   /**
@@ -9529,57 +9011,50 @@
   AnalysisContextStatistics get statistics;
 
   /**
-   * Returns a type provider for this context or throws an exception if dart:core cannot be
-   * resolved.
-   *
-   * @return the type provider (not `null`)
-   * @throws AnalysisException if dart:core cannot be resolved
+   * Sets the [TypeProvider] for this context.
    */
-  TypeProvider get typeProvider;
+  void set typeProvider(TypeProvider typeProvider);
 
-  /** A factory to override how [TypeResolverVisitor] is created. */
+  /**
+   * A factory to override how [TypeResolverVisitor] is created.
+   */
   TypeResolverVisitorFactory get typeResolverVisitorFactory;
 
   /**
-   * Add the given source with the given information to this context.
-   *
-   * @param source the source to be added
-   * @param info the information about the source
+   * Add the given [source] with the given [information] to this context.
    */
-  void addSourceInfo(Source source, SourceEntry info);
+  void addSourceInfo(Source source, SourceEntry information);
 
   /**
-   * Return an array containing the sources of the libraries that are exported by the library with
-   * the given source. The array will be empty if the given source is invalid, if the given source
-   * does not represent a library, or if the library does not export any other libraries.
+   * Return a list containing the sources of the libraries that are exported by
+   * the library with the given [source]. The list will be empty if the given
+   * source is invalid, if the given source does not represent a library, or if
+   * the library does not export any other libraries.
    *
-   * @param source the source representing the library whose exports are to be returned
-   * @return the sources of the libraries that are exported by the given library
-   * @throws AnalysisException if the exported libraries could not be computed
+   * Throws an [AnalysisException] if the exported libraries could not be
+   * computed.
    */
   List<Source> computeExportedLibraries(Source source);
 
   /**
-   * Return an array containing the sources of the libraries that are imported by the library with
-   * the given source. The array will be empty if the given source is invalid, if the given source
-   * does not represent a library, or if the library does not import any other libraries.
+   * Return a list containing the sources of the libraries that are imported by
+   * the library with the given [source]. The list will be empty if the given
+   * source is invalid, if the given source does not represent a library, or if
+   * the library does not import any other libraries.
    *
-   * @param source the source representing the library whose imports are to be returned
-   * @return the sources of the libraries that are imported by the given library
-   * @throws AnalysisException if the imported libraries could not be computed
+   * Throws an [AnalysisException] if the imported libraries could not be
+   * computed.
    */
   List<Source> computeImportedLibraries(Source source);
 
   /**
-   * Return an AST structure corresponding to the given source, but ensure that the structure has
-   * not already been resolved and will not be resolved by any other threads or in any other
-   * library.
+   * Return an AST structure corresponding to the given [source], but ensure
+   * that the structure has not already been resolved and will not be resolved
+   * by any other threads or in any other library.
+   *
+   * Throws an [AnalysisException] if the analysis could not be performed.
    *
    * <b>Note:</b> This method cannot be used in an async environment
-   *
-   * @param source the compilation unit for which an AST structure should be returned
-   * @return the AST structure representing the content of the source
-   * @throws AnalysisException if the analysis could not be performed
    */
   CompilationUnit computeResolvableCompilationUnit(Source source);
 
@@ -9591,19 +9066,13 @@
   List<CompilationUnit> ensureResolvedDartUnits(Source source);
 
   /**
-   * Return context that owns the given source.
-   *
-   * @param source the source whose context is to be returned
-   * @return the context that owns the partition that contains the source
+   * Return context that owns the given [source].
    */
   InternalAnalysisContext getContextFor(Source source);
 
   /**
-   * Return a namespace containing mappings for all of the public names defined by the given
-   * library.
-   *
-   * @param library the library whose public namespace is to be returned
-   * @return the public namespace of the given library
+   * Return a namespace containing mappings for all of the public names defined
+   * by the given [library].
    */
   Namespace getPublicNamespace(LibraryElement library);
 
@@ -9627,11 +9096,9 @@
       Source source, String originalContents, String newContents, bool notify);
 
   /**
-   * Given a table mapping the source for the libraries represented by the corresponding elements to
-   * the elements representing the libraries, record those mappings.
-   *
-   * @param elementMap a table mapping the source for the libraries represented by the elements to
-   *          the elements representing the libraries
+   * Given an [elementMap] mapping the source for the libraries represented by
+   * the corresponding elements to the elements representing the libraries,
+   * record those mappings.
    */
   void recordLibraryElements(Map<Source, LibraryElement> elementMap);
 
@@ -9643,10 +9110,10 @@
 }
 
 /**
- * A `Logger` is an object that can be used to receive information about errors
- * within the analysis engine. Implementations usually write this information to
- * a file, but can also record the information for later use (such as during
- * testing) or even ignore the information.
+ * An object that can be used to receive information about errors within the
+ * analysis engine. Implementations usually write this information to a file,
+ * but can also record the information for later use (such as during testing) or
+ * even ignore the information.
  */
 abstract class Logger {
   /**
@@ -9663,10 +9130,8 @@
   void logError(String message, [CaughtException exception]);
 
   /**
-   * Log the given exception as one representing an error.
-   *
-   * @param message an explanation of why the error occurred or what it means
-   * @param exception the exception being logged
+   * Log the given [exception] as one representing an error. The [message] is an
+   * explanation of why the error occurred or what it means.
    */
   @deprecated
   void logError2(String message, Object exception);
@@ -9679,10 +9144,8 @@
   void logInformation(String message, [CaughtException exception]);
 
   /**
-   * Log the given exception as one representing an informational message.
-   *
-   * @param message an explanation of why the error occurred or what it means
-   * @param exception the exception being logged
+   * Log the given [exception] as one representing an informational message. The
+   * [message] is an explanation of why the error occurred or what it means.
    */
   @deprecated
   void logInformation2(String message, Object exception);
@@ -9706,9 +9169,9 @@
 }
 
 /**
- * Instances of the class `ObsoleteSourceAnalysisException` represent an analysis attempt that
- * failed because a source was deleted between the time the analysis started and the time the
- * results of the analysis were ready to be recorded.
+ * An exception created when an analysis attempt fails because a source was
+ * deleted between the time the analysis started and the time the results of the
+ * analysis were ready to be recorded.
  */
 class ObsoleteSourceAnalysisException extends AnalysisException {
   /**
@@ -9717,9 +9180,8 @@
   Source _source;
 
   /**
-   * Initialize a newly created exception to represent the removal of the given source.
-   *
-   * @param source the source that was removed while it was being analyzed
+   * Initialize a newly created exception to represent the removal of the given
+   * [source].
    */
   ObsoleteSourceAnalysisException(Source source) : super(
           "The source '${source.fullName}' was removed while it was being analyzed") {
@@ -9728,8 +9190,6 @@
 
   /**
    * Return the source that was removed while it was being analyzed.
-   *
-   * @return the source that was removed
    */
   Source get source => _source;
 }
@@ -9809,7 +9269,7 @@
   CompilationUnit get compilationUnit => _unit;
 
   /**
-   * Return the errors that were produced by scanning and parsing the source, or an empty array if
+   * Return the errors that were produced by scanning and parsing the source, or an empty list if
    * the task has not yet been performed or if an exception occurred.
    *
    * @return the errors that were produced by scanning and parsing the source
@@ -9817,10 +9277,10 @@
   List<AnalysisError> get errors => _errors;
 
   /**
-   * Return an array containing the sources referenced by 'export' directives, or an empty array if
+   * Return a list containing the sources referenced by 'export' directives, or an empty list if
    * the task has not yet been performed or if an exception occurred.
    *
-   * @return an array containing the sources referenced by 'export' directives
+   * @return an list containing the sources referenced by 'export' directives
    */
   List<Source> get exportedSources => _toArray(_exportedSources);
 
@@ -9841,18 +9301,18 @@
   bool get hasPartOfDirective => _containsPartOfDirective;
 
   /**
-   * Return an array containing the sources referenced by 'import' directives, or an empty array if
+   * Return a list containing the sources referenced by 'import' directives, or an empty list if
    * the task has not yet been performed or if an exception occurred.
    *
-   * @return an array containing the sources referenced by 'import' directives
+   * @return a list containing the sources referenced by 'import' directives
    */
   List<Source> get importedSources => _toArray(_importedSources);
 
   /**
-   * Return an array containing the sources referenced by 'part' directives, or an empty array if
+   * Return a list containing the sources referenced by 'part' directives, or an empty list if
    * the task has not yet been performed or if an exception occurred.
    *
-   * @return an array containing the sources referenced by 'part' directives
+   * @return a list containing the sources referenced by 'part' directives
    */
   List<Source> get includedSources => _toArray(_includedSources);
 
@@ -9911,10 +9371,7 @@
   }
 
   /**
-   * Efficiently convert the given set of sources to an array.
-   *
-   * @param sources the set to be converted
-   * @return an array containing all of the sources in the given set
+   * Efficiently convert the given set of [sources] to a list.
    */
   List<Source> _toArray(HashSet<Source> sources) {
     int size = sources.length;
@@ -10010,7 +9467,7 @@
   List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
 
   /**
-   * An array containing the sources of the libraries that are referenced within the HTML.
+   * A list containing the sources of the libraries that are referenced within the HTML.
    */
   List<Source> _referencedLibraries = Source.EMPTY_ARRAY;
 
@@ -10062,7 +9519,7 @@
   LineInfo get lineInfo => _lineInfo;
 
   /**
-   * Return an array containing the sources of the libraries that are referenced within the HTML.
+   * Return a list containing the sources of the libraries that are referenced within the HTML.
    *
    * @return the sources of the libraries that are referenced within the HTML
    */
@@ -10141,7 +9598,7 @@
         if (_task.context.exists(librarySource)) {
           libraries.add(librarySource);
         }
-      } on FormatException catch (e) {
+      } on FormatException {
         // ignored - invalid URI reported during resolution phase
       }
     }
@@ -10150,8 +9607,8 @@
 }
 
 /**
- * Instances of the class `PartitionManager` manage the partitions that can be shared between
- * analysis contexts.
+ * An object that manages the partitions that can be shared between analysis
+ * contexts.
  */
 class PartitionManager {
   /**
@@ -10173,10 +9630,8 @@
   }
 
   /**
-   * Return the partition being used for the given SDK, creating the partition
+   * Return the partition being used for the given [sdk], creating the partition
    * if necessary.
-   *
-   * [sdk] - the SDK for which a partition is being requested.
    */
   SdkCachePartition forSdk(DartSdk sdk) {
     // Call sdk.context now, because when it creates a new
@@ -10347,21 +9802,19 @@
 }
 
 /**
- * Instances of the class `RecordingErrorListener` implement an error listener that will
- * record the errors that are reported to it in a way that is appropriate for caching those errors
- * within an analysis context.
+ * An error listener that will record the errors that are reported to it in a
+ * way that is appropriate for caching those errors within an analysis context.
  */
 class RecordingErrorListener implements AnalysisErrorListener {
   /**
-   * A HashMap of lists containing the errors that were collected, keyed by each [Source].
+   * A map of sets containing the errors that were collected, keyed by each
+   * source.
    */
   Map<Source, HashSet<AnalysisError>> _errors =
       new HashMap<Source, HashSet<AnalysisError>>();
 
   /**
-   * Answer the errors collected by the listener.
-   *
-   * @return an array of errors (not `null`, contains no `null`s)
+   * Return the errors collected by the listener.
    */
   List<AnalysisError> get errors {
     int numEntries = _errors.length;
@@ -10376,9 +9829,7 @@
   }
 
   /**
-   * Add all of the errors recorded by the given listener to this listener.
-   *
-   * @param listener the listener that has recorded the errors to be added
+   * Add all of the errors recorded by the given [listener] to this listener.
    */
   void addAll(RecordingErrorListener listener) {
     for (AnalysisError error in listener.errors) {
@@ -10387,11 +9838,7 @@
   }
 
   /**
-   * Answer the errors collected by the listener for some passed [Source].
-   *
-   * @param source some [Source] for which the caller wants the set of [AnalysisError]s
-   *          collected by this listener
-   * @return the errors collected by the listener for the passed [Source]
+   * Return the errors collected by the listener for the given [source].
    */
   List<AnalysisError> getErrorsForSource(Source source) {
     HashSet<AnalysisError> errorsForSource = _errors[source];
@@ -10453,8 +9900,8 @@
 }
 
 /**
- * A `ResolutionEraser` removes any resolution information from an AST
- * structure when used to visit that structure.
+ * An visitor that removes any resolution information from an AST structure when
+ * used to visit that structure.
  */
 class ResolutionEraser extends GeneralizingAstVisitor<Object> {
   @override
@@ -10583,8 +10030,8 @@
 }
 
 /**
- * A `ResolutionState` maintains the information produced by resolving a
- * compilation unit as part of a specific library.
+ * The information produced by resolving a compilation unit as part of a
+ * specific library.
  */
 class ResolutionState {
   /**
@@ -10593,9 +10040,9 @@
   ResolutionState _nextState;
 
   /**
-   * The source for the defining compilation unit of the library that contains this unit. If this
-   * unit is the defining compilation unit for it's library, then this will be the source for this
-   * unit.
+   * The source for the defining compilation unit of the library that contains
+   * this unit. If this unit is the defining compilation unit for it's library,
+   * then this will be the source for this unit.
    */
   Source _librarySource;
 
@@ -10776,12 +10223,11 @@
   }
 
   /**
-   * Write a textual representation of the difference between the old entry and this entry to the
-   * given string builder.
-   *
-   * @param builder the string builder to which the difference is to be written
-   * @param oldEntry the entry that was replaced by this entry
-   * @return `true` if some difference was written
+   * Write a textual representation of the difference between the old entry and
+   * this entry to the given string [buffer]. A separator will be written before
+   * the first difference if [needsSeparator] is `true`. The [oldEntry] is the
+   * entry that was replaced by this entry. Return `true` is a separator is
+   * needed before writing any subsequent differences.
    */
   bool _writeDiffOn(
       StringBuffer buffer, bool needsSeparator, DartEntry oldEntry) {
@@ -10799,10 +10245,8 @@
   }
 
   /**
-   * Write a textual representation of this state to the given builder. The result will only be
-   * used for debugging purposes.
-   *
-   * @param builder the builder to which the text should be written
+   * Write a textual representation of this state to the given [buffer]. The
+   * result will only be used for debugging purposes.
    */
   void _writeOn(StringBuffer buffer) {
     if (_librarySource != null) {
@@ -10859,8 +10303,8 @@
 }
 
 /**
- * A `ResolvableCompilationUnit` is a compilation unit that is not referenced by
- * any other objects. It is used by the [LibraryResolver] to resolve a library.
+ * A compilation unit that is not referenced by any other objects. It is used by
+ * the [LibraryResolver] to resolve a library.
  */
 class ResolvableCompilationUnit {
   /**
@@ -10874,10 +10318,8 @@
   final CompilationUnit compilationUnit;
 
   /**
-   * Initialize a newly created holder to hold the given values.
-   *
-   * @param source the source of the compilation unit
-   * @param unit the AST that was created from the source
+   * Initialize a newly created holder to hold the given [source] and
+   * [compilationUnit].
    */
   ResolvableCompilationUnit(this.source, this.compilationUnit);
 }
@@ -11061,8 +10503,7 @@
 
   @override
   void internalPerform() {
-    TypeProvider typeProvider =
-        (_libraryElement.context as InternalAnalysisContext).typeProvider;
+    TypeProvider typeProvider = _libraryElement.context.typeProvider;
     CompilationUnit unit = context.computeResolvableCompilationUnit(source);
     if (unit == null) {
       throw new AnalysisException(
@@ -11225,26 +10666,27 @@
 }
 
 /**
- * The enumerated type `RetentionPriority` represents the priority of data in the cache in
- * terms of the desirability of retaining some specified data about a specified source.
+ * The priority of data in the cache in terms of the desirability of retaining
+ * some specified data about a specified source.
  */
 class RetentionPriority extends Enum<RetentionPriority> {
   /**
-   * A priority indicating that a given piece of data can be removed from the cache without
-   * reservation.
+   * A priority indicating that a given piece of data can be removed from the
+   * cache without reservation.
    */
   static const RetentionPriority LOW = const RetentionPriority('LOW', 0);
 
   /**
-   * A priority indicating that a given piece of data should not be removed from the cache unless
-   * there are no sources for which the corresponding data has a lower priority. Currently used for
-   * data that is needed in order to finish some outstanding analysis task.
+   * A priority indicating that a given piece of data should not be removed from
+   * the cache unless there are no sources for which the corresponding data has
+   * a lower priority. Currently used for data that is needed in order to finish
+   * some outstanding analysis task.
    */
   static const RetentionPriority MEDIUM = const RetentionPriority('MEDIUM', 1);
 
   /**
-   * A priority indicating that a given piece of data should not be removed from the cache.
-   * Currently used for data related to a priority source.
+   * A priority indicating that a given piece of data should not be removed from
+   * the cache. Currently used for data related to a priority source.
    */
   static const RetentionPriority HIGH = const RetentionPriority('HIGH', 2);
 
@@ -11347,8 +10789,7 @@
 }
 
 /**
- * Instances of the class `SdkAnalysisContext` implement an [AnalysisContext] that only
- * contains sources for a Dart SDK.
+ * An [AnalysisContext] that only contains sources for a Dart SDK.
  */
 class SdkAnalysisContext extends AnalysisContextImpl {
   @override
@@ -11367,16 +10808,13 @@
 }
 
 /**
- * Instances of the class `SdkCachePartition` implement a cache partition that contains all of
- * the sources in the SDK.
+ * A cache partition that contains all of the sources in the SDK.
  */
 class SdkCachePartition extends CachePartition {
   /**
-   * Initialize a newly created partition.
-   *
-   * @param context the context that owns this partition
-   * @param maxCacheSize the maximum number of sources for which AST structures should be kept in
-   *          the cache
+   * Initialize a newly created partition. The [context] is the context that
+   * owns this partition. The [maxCacheSize] is the maximum number of sources
+   * for which AST structures should be kept in the cache.
    */
   SdkCachePartition(InternalAnalysisContext context, int maxCacheSize)
       : super(context, maxCacheSize, DefaultRetentionPolicy.POLICY);
@@ -11386,8 +10824,8 @@
 }
 
 /**
- * A `SourceEntry` maintains the information cached by an analysis context about
- * an individual source, no matter what kind of source it is.
+ * The information cached by an analysis context about an individual source, no
+ * matter what kind of source it is.
  */
 abstract class SourceEntry {
   /**
@@ -11788,14 +11226,15 @@
 }
 
 /**
- * The enumerated type `Priority` defines the priority levels used to return sources in an
- * optimal order. A smaller ordinal value equates to a higher priority.
+ * The priority levels used to return sources in an optimal order. A smaller
+ * ordinal value equates to a higher priority.
  */
 class SourcePriority extends Enum<SourcePriority> {
   /**
-   * Used for a Dart source that is known to be a part contained in a library that was recently
-   * resolved. These parts are given a higher priority because there is a high probability that
-   * their AST structure is still in the cache and therefore would not need to be re-created.
+   * Used for a Dart source that is known to be a part contained in a library
+   * that was recently resolved. These parts are given a higher priority because
+   * there is a high probability that their AST structure is still in the cache
+   * and therefore would not need to be re-created.
    */
   static const SourcePriority PRIORITY_PART =
       const SourcePriority('PRIORITY_PART', 0);
@@ -11811,7 +11250,8 @@
   static const SourcePriority UNKNOWN = const SourcePriority('UNKNOWN', 2);
 
   /**
-   * Used for a Dart source that is known to be a part but whose library has not yet been resolved.
+   * Used for a Dart source that is known to be a part but whose library has not
+   * yet been resolved.
    */
   static const SourcePriority NORMAL_PART =
       const SourcePriority('NORMAL_PART', 3);
@@ -11837,10 +11277,9 @@
  * or whose contents have changed.
  */
 class SourcesChangedEvent {
-
   /**
-   * The internal representation of what has changed.
-   * Clients should not access this field directly.
+   * The internal representation of what has changed. Clients should not access
+   * this field directly.
    */
   final ChangeSet _changeSet;
 
@@ -11893,8 +11332,7 @@
 }
 
 /**
- * Instances of the class `TimestampedData` represent analysis data for which we have a
- * modification time.
+ * Analysis data for which we have a modification time.
  */
 class TimestampedData<E> {
   /**
@@ -11908,27 +11346,23 @@
   final E data;
 
   /**
-   * Initialize a newly created holder to hold the given values.
-   *
-   * @param modificationTime the modification time of the source from which the data was created
-   * @param unit the data that was created from the source
+   * Initialize a newly created holder to associate the given [data] with the
+   * given [modificationTime].
    */
   TimestampedData(this.modificationTime, this.data);
 }
 
 /**
- * Instances of the class `UniversalCachePartition` implement a cache partition that contains
- * all sources not contained in other partitions.
+ * A cache partition that contains all sources not contained in other
+ * partitions.
  */
 class UniversalCachePartition extends CachePartition {
   /**
-   * Initialize a newly created partition.
-   *
-   * @param context the context that owns this partition
-   * @param maxCacheSize the maximum number of sources for which AST structures should be kept in
-   *          the cache
-   * @param retentionPolicy the policy used to determine which pieces of data to remove from the
-   *          cache
+   * Initialize a newly created partition. The [context] is the context that
+   * owns this partition. The [maxCacheSize] is the maximum number of sources
+   * for which AST structures should be kept in the cache. The [retentionPolicy]
+   * is the policy used to determine which pieces of data to remove from the
+   * cache.
    */
   UniversalCachePartition(InternalAnalysisContext context, int maxCacheSize,
       CacheRetentionPolicy retentionPolicy)
@@ -11974,12 +11408,12 @@
 }
 
 /**
- * Instances of the class `WorkManager` manage a list of sources that need to have analysis
- * work performed on them.
+ * An object that manages a list of sources that need to have analysis work
+ * performed on them.
  */
 class WorkManager {
   /**
-   * An array containing the various queues is priority order.
+   * A list containing the various queues is priority order.
    */
   List<List<Source>> _workQueues;
 
@@ -11995,13 +11429,11 @@
   }
 
   /**
-   * Record that the given source needs to be analyzed. The priority level is used to control when
-   * the source will be analyzed with respect to other sources. If the source was previously added
-   * then it's priority is updated. If it was previously added with the same priority then it's
-   * position in the queue is unchanged.
-   *
-   * @param source the source that needs to be analyzed
-   * @param priority the priority level of the source
+   * Record that the given [source] needs to be analyzed. The [priority] level
+   * is used to control when the source will be analyzed with respect to other
+   * sources. If the source was previously added then it's priority is updated.
+   * If it was previously added with the same priority then it's position in the
+   * queue is unchanged.
    */
   void add(Source source, SourcePriority priority) {
     int queueCount = _workQueues.length;
@@ -12019,13 +11451,11 @@
   }
 
   /**
-   * Record that the given source needs to be analyzed. The priority level is used to control when
-   * the source will be analyzed with respect to other sources. If the source was previously added
-   * then it's priority is updated. In either case, it will be analyzed before other sources of the
-   * same priority.
-   *
-   * @param source the source that needs to be analyzed
-   * @param priority the priority level of the source
+   * Record that the given [source] needs to be analyzed. The [priority] level
+   * is used to control when the source will be analyzed with respect to other
+   * sources. If the source was previously added then it's priority is updated.
+   * In either case, it will be analyzed before other sources of the same
+   * priority.
    */
   void addFirst(Source source, SourcePriority priority) {
     int queueCount = _workQueues.length;
@@ -12042,22 +11472,19 @@
   }
 
   /**
-   * Return an iterator that can be used to access the sources to be analyzed in the order in which
-   * they should be analyzed.
+   * Return an iterator that can be used to access the sources to be analyzed in
+   * the order in which they should be analyzed.
    *
-   * <b>Note:</b> As with other iterators, no sources can be added or removed from this work manager
-   * while the iterator is being used. Unlike some implementations, however, the iterator will not
-   * detect when this requirement has been violated; it might work correctly, it might return the
+   * <b>Note:</b> As with other iterators, no sources can be added or removed
+   * from this work manager while the iterator is being used. Unlike some
+   * implementations, however, the iterator will not detect when this
+   * requirement has been violated; it might work correctly, it might return the
    * wrong source, or it might throw an exception.
-   *
-   * @return an iterator that can be used to access the next source to be analyzed
    */
   WorkManager_WorkIterator iterator() => new WorkManager_WorkIterator(this);
 
   /**
    * Record that the given source is fully analyzed.
-   *
-   * @param source the source that is fully analyzed
    */
   void remove(Source source) {
     int queueCount = _workQueues.length;
@@ -12095,8 +11522,8 @@
 }
 
 /**
- * Instances of the class `WorkIterator` implement an iterator that returns the sources in a
- * work manager in the order in which they are to be analyzed.
+ * An iterator that returns the sources in a work manager in the order in which
+ * they are to be analyzed.
  */
 class WorkManager_WorkIterator {
   final WorkManager _manager;
@@ -12112,7 +11539,8 @@
   int _index = -1;
 
   /**
-   * Initialize a newly created iterator to be ready to return the first element in the iteration.
+   * Initialize a newly created iterator to be ready to return the first element
+   * in the iteration.
    */
   WorkManager_WorkIterator(this._manager) {
     _advance();
@@ -12120,16 +11548,12 @@
 
   /**
    * Return `true` if there is another [Source] available for processing.
-   *
-   * @return `true` if there is another [Source] available for processing
    */
   bool get hasNext => _queueIndex < _manager._workQueues.length;
 
   /**
-   * Return the next [Source] available for processing and advance so that the returned
-   * source will not be returned again.
-   *
-   * @return the next [Source] available for processing
+   * Return the next [Source] available for processing and advance so that the
+   * returned source will not be returned again.
    */
   Source next() {
     if (!hasNext) {
@@ -12141,8 +11565,9 @@
   }
 
   /**
-   * Increment the [index] and [queueIndex] so that they are either indicating the
-   * next source to be returned or are indicating that there are no more sources to be returned.
+   * Increment the [index] and [queueIndex] so that they are either indicating
+   * the next source to be returned or are indicating that there are no more
+   * sources to be returned.
    */
   void _advance() {
     _index++;
@@ -12158,7 +11583,7 @@
 }
 
 /**
- * Helper class used to create futures for AnalysisContextImpl.  Using a helper
+ * A helper class used to create futures for AnalysisContextImpl. Using a helper
  * class allows us to preserve the generic parameter T.
  */
 class _AnalysisFutureHelper<T> {
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 6566108..6ba42dc 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -13,8 +13,7 @@
 import 'source.dart';
 
 /**
- * Instances of the class `AnalysisError` represent an error discovered during the analysis of
- * some Dart code.
+ * An error discovered during the analysis of some Dart code.
  *
  * See [AnalysisErrorListener].
  */
@@ -25,15 +24,15 @@
   static const List<AnalysisError> NO_ERRORS = const <AnalysisError>[];
 
   /**
-   * A [Comparator] that sorts by the name of the file that the [AnalysisError] was
-   * found.
+   * A [Comparator] that sorts by the name of the file that the [AnalysisError]
+   * was found.
    */
   static Comparator<AnalysisError> FILE_COMPARATOR = (AnalysisError o1,
       AnalysisError o2) => o1.source.shortName.compareTo(o2.source.shortName);
 
   /**
-   * A [Comparator] that sorts error codes first by their severity (errors first, warnings
-   * second), and then by the the error code type.
+   * A [Comparator] that sorts error codes first by their severity (errors
+   * first, warnings second), and then by the the error code type.
    */
   static Comparator<AnalysisError> ERROR_CODE_COMPARATOR = (AnalysisError o1,
       AnalysisError o2) {
@@ -61,8 +60,8 @@
   String _message;
 
   /**
-   * The correction to be displayed for this error, or `null` if there is no correction
-   * information for this error.
+   * The correction to be displayed for this error, or `null` if there is no
+   * correction information for this error.
    */
   String _correction;
 
@@ -78,37 +77,31 @@
   int offset = 0;
 
   /**
-   * The number of characters from the offset to the end of the source which encompasses the
-   * compilation error.
+   * The number of characters from the offset to the end of the source which
+   * encompasses the compilation error.
    */
   int _length = 0;
 
   /**
-   * A flag indicating whether this error can be shown to be a non-issue because of the result of
-   * type propagation.
+   * A flag indicating whether this error can be shown to be a non-issue because
+   * of the result of type propagation.
    */
   bool isStaticOnly = false;
 
   /**
-   * Initialize a newly created analysis error for the specified source. The error has no location
-   * information.
-   *
-   * @param source the source for which the exception occurred
-   * @param errorCode the error code to be associated with this error
-   * @param arguments the arguments used to build the error message
+   * Initialize a newly created analysis error for the specified [source]. The
+   * error will have the given [errorCode] and the list of [arguments] will be
+   * used to complete the message. The error has no location information.
    */
   AnalysisError.con1(this.source, this.errorCode, [List<Object> arguments]) {
     this._message = formatList(errorCode.message, arguments);
   }
 
   /**
-   * Initialize a newly created analysis error for the specified source at the given location.
-   *
-   * @param source the source for which the exception occurred
-   * @param offset the offset of the location of the error
-   * @param length the length of the location of the error
-   * @param errorCode the error code to be associated with this error
-   * @param arguments the arguments used to build the error message
+   * Initialize a newly created analysis error for the specified [source] at the
+   * given [offset] with the given [length]. The error will have the given
+   * [errorCode] and the list of [arguments] will be used to complete the
+   * message.
    */
   AnalysisError.con2(this.source, this.offset, int length, this.errorCode,
       [List<Object> arguments]) {
@@ -121,10 +114,9 @@
   }
 
   /**
-   * Return the correction to be displayed for this error, or `null` if there is no correction
-   * information for this error. The correction should indicate how the user can fix the error.
-   *
-   * @return the template used to create the correction to be displayed for this error
+   * Return the template used to create the correction to be displayed for this
+   * error, or `null` if there is no correction information for this error. The
+   * correction should indicate how the user can fix the error.
    */
   String get correction => _correction;
 
@@ -137,18 +129,15 @@
   }
 
   /**
-   * Return the number of characters from the offset to the end of the source which encompasses the
-   * compilation error.
-   *
-   * @return the length of the error location
+   * Return the length of the error location, that is, the number of characters
+   * from the offset to the end of the source which encompasses the compilation
+   * error.
    */
   int get length => _length;
 
   /**
-   * Return the message to be displayed for this error. The message should indicate what is wrong
-   * and why it is wrong.
-   *
-   * @return the message to be displayed for this error
+   * Return the message to be displayed for this error. The message should
+   * indicate what is wrong and why it is wrong.
    */
   String get message => _message;
 
@@ -184,11 +173,8 @@
   }
 
   /**
-   * Return the value of the given property, or `null` if the given property is not defined
-   * for this error.
-   *
-   * @param property the property whose value is to be returned
-   * @return the value of the given property
+   * Return the value of the given [property], or `null` if the given property
+   * is not defined for this error.
    */
   Object getProperty(ErrorProperty property) => null;
 
@@ -208,8 +194,8 @@
 }
 
 /**
- * The interface `AnalysisErrorListener` defines the behavior of objects that listen for
- * [AnalysisError] being produced by the analysis engine.
+ * An object that listen for [AnalysisError]s being produced by the analysis
+ * engine.
  */
 abstract class AnalysisErrorListener {
   /**
@@ -219,13 +205,15 @@
       new AnalysisErrorListener_NULL_LISTENER();
 
   /**
-   * This method is invoked when an error has been found by the analysis engine.
-   *
-   * @param error the error that was just found (not `null`)
+   * This method is invoked when an [error] has been found by the analysis
+   * engine.
    */
   void onError(AnalysisError error);
 }
 
+/**
+ * An [AnalysisErrorListener] that ignores error.
+ */
 class AnalysisErrorListener_NULL_LISTENER implements AnalysisErrorListener {
   @override
   void onError(AnalysisError event) {
@@ -234,7 +222,7 @@
 }
 
 /**
- * Instances of the class `AnalysisErrorWithProperties`
+ * An [AnalysisError] that can have arbitrary properties associated with it.
  */
 class AnalysisErrorWithProperties extends AnalysisError {
   /**
@@ -244,39 +232,31 @@
       new HashMap<ErrorProperty, Object>();
 
   /**
-   * Initialize a newly created analysis error for the specified source. The error has no location
-   * information.
-   *
-   * @param source the source for which the exception occurred
-   * @param errorCode the error code to be associated with this error
-   * @param arguments the arguments used to build the error message
+   * Initialize a newly created analysis error for the specified [source]. The
+   * error will have the given [errorCode] and the list of [arguments] will be
+   * used to complete the message. The error has no location information.
    */
-  AnalysisErrorWithProperties.con1(
-      Source source, ErrorCode errorCode, List<Object> arguments)
+  AnalysisErrorWithProperties.con1(Source source, ErrorCode errorCode,
+      [List<Object> arguments])
       : super.con1(source, errorCode, arguments);
 
   /**
-   * Initialize a newly created analysis error for the specified source at the given location.
-   *
-   * @param source the source for which the exception occurred
-   * @param offset the offset of the location of the error
-   * @param length the length of the location of the error
-   * @param errorCode the error code to be associated with this error
-   * @param arguments the arguments used to build the error message
+   * Initialize a newly created analysis error for the specified [source] at the
+   * given [offset] with the given [length]. The error will have the given
+   * [errorCode] and the list of [arguments] will be used to complete the
+   * message.
    */
-  AnalysisErrorWithProperties.con2(Source source, int offset, int length,
-      ErrorCode errorCode, List<Object> arguments)
+  AnalysisErrorWithProperties.con2(
+      Source source, int offset, int length, ErrorCode errorCode,
+      [List<Object> arguments])
       : super.con2(source, offset, length, errorCode, arguments);
 
   @override
   Object getProperty(ErrorProperty property) => _propertyMap[property];
 
   /**
-   * Set the value of the given property to the given value. Using a value of `null` will
-   * effectively remove the property from this error.
-   *
-   * @param property the property whose value is to be returned
-   * @param value the new value of the given property
+   * Set the value of the given [property] to the given [value]. Using a value
+   * of `null` will effectively remove the property from this error.
    */
   void setProperty(ErrorProperty property, Object value) {
     _propertyMap[property] = value;
@@ -284,8 +264,8 @@
 }
 
 /**
- * Instances of the class `BooleanErrorListener` implement a listener that keeps track of
- * whether an error has been reported to it.
+ * An [AnalysisErrorListener] that keeps track of whether any error has been
+ * reported to it.
  */
 class BooleanErrorListener implements AnalysisErrorListener {
   /**
@@ -295,8 +275,6 @@
 
   /**
    * Return `true` if an error has been reported to this listener.
-   *
-   * @return `true` if an error has been reported to this listener
    */
   bool get errorReported => _errorReported;
 
@@ -307,12 +285,12 @@
 }
 
 /**
- * The enumeration `CompileTimeErrorCode` defines the error codes used for
- * compile time errors caused by constant evaluation that would throw an
- * exception when run in checked mode. The client of the analysis engine is
- * responsible for determining how these errors should be presented to the user
- * (for example, a command-line compiler might elect to treat these errors
- * differently depending whether it is compiling it "checked" mode).
+ * The error codes used for compile time errors caused by constant evaluation
+ * that would throw an exception when run in checked mode. The client of the
+ * analysis engine is responsible for determining how these errors should be
+ * presented to the user (for example, a command-line compiler might elect to
+ * treat these errors differently depending whether it is compiling it "checked"
+ * mode).
  */
 class CheckedModeCompileTimeErrorCode extends ErrorCode {
   // TODO(paulberry): improve the text of these error messages so that it's
@@ -348,8 +326,9 @@
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant
    * object results in an uncaught exception being thrown.
    *
-   * @param initializerType the name of the type of the initializer expression
-   * @param fieldType the name of the type of the field
+   * Parameters:
+   * 0: the name of the type of the initializer expression
+   * 1: the name of the type of the field
    */
   static const CheckedModeCompileTimeErrorCode CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE =
       const CheckedModeCompileTimeErrorCode(
@@ -438,11 +417,10 @@
 }
 
 /**
- * The enumeration `CompileTimeErrorCode` defines the error codes used for
- * compile time errors. The convention for this class is for the name of the
- * error code to indicate the problem that caused the error to be generated and
- * for the error message to explain what is wrong and, when appropriate, how the
- * problem can be corrected.
+ * The error codes used for compile time errors. The convention for this class
+ * is for the name of the error code to indicate the problem that caused the
+ * error to be generated and for the error message to explain what is wrong and,
+ * when appropriate, how the problem can be corrected.
  */
 class CompileTimeErrorCode extends ErrorCode {
   /**
@@ -459,11 +437,10 @@
    * of <i>L</i> by more than one export, unless each all exports refer to same
    * declaration for the name N.
    *
-   * @param ambiguousElementName the name of the ambiguous element
-   * @param firstLibraryName the name of the first library that the type is
-   *        found
-   * @param secondLibraryName the name of the second library that the type is
-   *        found
+   * Parameters:
+   * 0: the name of the ambiguous element
+   * 1: the name of the first library that the type is found
+   * 2: the name of the second library that the type is found
    */
   static const CompileTimeErrorCode AMBIGUOUS_EXPORT =
       const CompileTimeErrorCode('AMBIGUOUS_EXPORT',
@@ -473,8 +450,9 @@
    * 12.33 Argument Definition Test: It is a compile time error if <i>v</i> does
    * not denote a formal parameter.
    *
-   * @param the name of the identifier in the argument definition test that is
-   *        not a parameter
+   * Parameters:
+   * 0: the name of the identifier in the argument definition test that is not a
+   *    parameter
    */
   static const CompileTimeErrorCode ARGUMENT_DEFINITION_TEST_NON_PARAMETER =
       const CompileTimeErrorCode(
@@ -713,7 +691,8 @@
    * 5 Variables: A constant variable must be initialized to a compile-time
    * constant (12.1) or a compile-time error occurs.
    *
-   * @param name the name of the uninitialized final variable
+   * Parameters:
+   * 0: the name of the uninitialized final variable
    */
   static const CompileTimeErrorCode CONST_NOT_INITIALIZED =
       const CompileTimeErrorCode('CONST_NOT_INITIALIZED',
@@ -777,9 +756,11 @@
    * &hellip;, U<sub>m</sub>&gt;</i>, let <i>R = S</i>; It is a compile time
    * error if <i>S</i> is not a generic type with <i>m</i> type parameters.
    *
-   * @param typeName the name of the type being referenced (<i>S</i>)
-   * @param parameterCount the number of type parameters that were declared
-   * @param argumentCount the number of type arguments provided
+   * Parameters:
+   * 0: the name of the type being referenced (<i>S</i>)
+   * 1: the number of type parameters that were declared
+   * 2: the number of type arguments provided
+   *
    * See [CompileTimeErrorCode.NEW_WITH_INVALID_TYPE_PARAMETERS], and
    * [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS].
    */
@@ -817,7 +798,8 @@
    * <i>T</i> is not a class accessible in the current scope, optionally
    * followed by type arguments.
    *
-   * @param name the name of the non-type element
+   * Parameters:
+   * 0: the name of the non-type element
    */
   static const CompileTimeErrorCode CONST_WITH_NON_TYPE =
       const CompileTimeErrorCode(
@@ -835,8 +817,9 @@
    * 12.11.2 Const: It is a compile-time error if <i>T.id</i> is not the name of
    * a constant constructor declared by the type <i>T</i>.
    *
-   * @param typeName the name of the type
-   * @param constructorName the name of the requested constant constructor
+   * Parameters:
+   * 0: the name of the type
+   * 1: the name of the requested constant constructor
    */
   static const CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR =
       const CompileTimeErrorCode('CONST_WITH_UNDEFINED_CONSTRUCTOR',
@@ -846,7 +829,8 @@
    * 12.11.2 Const: It is a compile-time error if <i>T.id</i> is not the name of
    * a constant constructor declared by the type <i>T</i>.
    *
-   * @param typeName the name of the type
+   * Parameters:
+   * 0: the name of the type
    */
   static const CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT =
       const CompileTimeErrorCode('CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT',
@@ -891,7 +875,8 @@
    * 3.1 Scoping: It is a compile-time error if there is more than one entity
    * with the same name declared in the same scope.
    *
-   * @param duplicateName the name of the duplicate entity
+   * Parameters:
+   * 0: the name of the duplicate entity
    */
   static const CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_NAME =
       const CompileTimeErrorCode('DUPLICATE_CONSTRUCTOR_NAME',
@@ -907,7 +892,8 @@
    * 7 Classes: It is a compile-time error if a class has an instance member and
    * a static member with the same name.
    *
-   * @param duplicateName the name of the duplicate entity
+   * Parameters:
+   * 0: the name of the duplicate entity
    */
   static const CompileTimeErrorCode DUPLICATE_DEFINITION =
       const CompileTimeErrorCode(
@@ -920,9 +906,10 @@
    * This covers the additional duplicate definition cases where inheritance has
    * to be considered.
    *
-   * @param className the name of the class that has conflicting instance/static
-   *        members
-   * @param name the name of the conflicting members
+   * Parameters:
+   * 0: the name of the class that has conflicting instance/static members
+   * 1: the name of the conflicting members
+   *
    * See [DUPLICATE_DEFINITION].
    */
   static const CompileTimeErrorCode DUPLICATE_DEFINITION_INHERITANCE =
@@ -941,7 +928,8 @@
   /**
    * SDK implementation libraries can be exported only by other SDK libraries.
    *
-   * @param uri the uri pointing to a library
+   * Parameters:
+   * 0: the uri pointing to a library
    */
   static const CompileTimeErrorCode EXPORT_INTERNAL_LIBRARY =
       const CompileTimeErrorCode('EXPORT_INTERNAL_LIBRARY',
@@ -951,7 +939,8 @@
    * 14.2 Exports: It is a compile-time error if the compilation unit found at
    * the specified URI is not a library declaration.
    *
-   * @param uri the uri pointing to a non-library declaration
+   * Parameters:
+   * 0: the uri pointing to a non-library declaration
    */
   static const CompileTimeErrorCode EXPORT_OF_NON_LIBRARY =
       const CompileTimeErrorCode('EXPORT_OF_NON_LIBRARY',
@@ -969,7 +958,8 @@
    * class <i>C</i> includes a type expression that does not denote a class
    * available in the lexical scope of <i>C</i>.
    *
-   * @param typeName the name of the superclass that was not found
+   * Parameters:
+   * 0: the name of the superclass that was not found
    */
   static const CompileTimeErrorCode EXTENDS_NON_CLASS =
       const CompileTimeErrorCode(
@@ -995,7 +985,9 @@
    * 12.5 Strings: It is a compile-time error for a class to attempt to extend
    * or implement String.
    *
-   * @param typeName the name of the type that cannot be extended
+   * Parameters:
+   * 0: the name of the type that cannot be extended
+   *
    * See [IMPLEMENTS_DISALLOWED_CLASS].
    */
   static const CompileTimeErrorCode EXTENDS_DISALLOWED_CLASS =
@@ -1006,7 +998,9 @@
    * 7.9 Superclasses: It is a compile-time error if the extends clause of a
    * class <i>C</i> includes a deferred type expression.
    *
-   * @param typeName the name of the type that cannot be extended
+   * Parameters:
+   * 0: the name of the type that cannot be extended
+   *
    * See [IMPLEMENTS_DEFERRED_CLASS], and [MIXIN_DEFERRED_CLASS].
    */
   static const CompileTimeErrorCode EXTENDS_DEFERRED_CLASS =
@@ -1020,8 +1014,9 @@
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant
    * object results in an uncaught exception being thrown.
    *
-   * @param requiredCount the maximum number of positional arguments
-   * @param argumentCount the actual number of positional arguments given
+   * Parameters:
+   * 0: the maximum number of positional arguments
+   * 1: the actual number of positional arguments given
    */
   static const CompileTimeErrorCode EXTRA_POSITIONAL_ARGUMENTS =
       const CompileTimeErrorCode('EXTRA_POSITIONAL_ARGUMENTS',
@@ -1052,7 +1047,8 @@
    * has is initialized by means of an initializing formal of a constructor is
    * also initialized elsewhere in the same constructor.
    *
-   * @param name the name of the field in question
+   * Parameters:
+   * 0: the name of the field in question
    */
   static const CompileTimeErrorCode FINAL_INITIALIZED_MULTIPLE_TIMES =
       const CompileTimeErrorCode('FINAL_INITIALIZED_MULTIPLE_TIMES',
@@ -1092,7 +1088,8 @@
    * 7.2 Getters: It is a compile-time error if a class has both a getter and a
    * method with the same name.
    *
-   * @param name the conflicting name of the getter and method
+   * Parameters:
+   * 0: the conflicting name of the getter and method
    */
   static const CompileTimeErrorCode GETTER_AND_METHOD_WITH_SAME_NAME =
       const CompileTimeErrorCode('GETTER_AND_METHOD_WITH_SAME_NAME',
@@ -1103,7 +1100,9 @@
    * of a class <i>C</i> specifies a malformed type or deferred type as a
    * superinterface.
    *
-   * @param typeName the name of the type that cannot be extended
+   * Parameters:
+   * 0: the name of the type that cannot be extended
+   *
    * See [EXTENDS_DEFERRED_CLASS], and [MIXIN_DEFERRED_CLASS].
    */
   static const CompileTimeErrorCode IMPLEMENTS_DEFERRED_CLASS =
@@ -1130,7 +1129,9 @@
    * 12.5 Strings: It is a compile-time error for a class to attempt to extend
    * or implement String.
    *
-   * @param typeName the name of the type that cannot be implemented
+   * Parameters:
+   * 0: the name of the type that cannot be implemented
+   *
    * See [EXTENDS_DISALLOWED_CLASS].
    */
   static const CompileTimeErrorCode IMPLEMENTS_DISALLOWED_CLASS =
@@ -1158,7 +1159,8 @@
    * of a class <i>C</i> includes a type expression that does not denote a class
    * available in the lexical scope of <i>C</i>.
    *
-   * @param typeName the name of the interface that was not found
+   * Parameters:
+   * 0: the name of the interface that was not found
    */
   static const CompileTimeErrorCode IMPLEMENTS_NON_CLASS =
       const CompileTimeErrorCode(
@@ -1168,7 +1170,8 @@
    * 7.10 Superinterfaces: It is a compile-time error if a type <i>T</i> appears
    * more than once in the implements clause of a class.
    *
-   * @param className the name of the class that is implemented more than once
+   * Parameters:
+   * 0: the name of the class that is implemented more than once
    */
   static const CompileTimeErrorCode IMPLEMENTS_REPEATED =
       const CompileTimeErrorCode(
@@ -1178,8 +1181,9 @@
    * 7.10 Superinterfaces: It is a compile-time error if the superclass of a
    * class <i>C</i> appears in the implements clause of <i>C</i>.
    *
-   * @param className the name of the class that appears in both "extends" and
-   *        "implements" clauses
+   * Parameters:
+   * 0: the name of the class that appears in both "extends" and "implements"
+   *    clauses
    */
   static const CompileTimeErrorCode IMPLEMENTS_SUPER_CLASS =
       const CompileTimeErrorCode('IMPLEMENTS_SUPER_CLASS',
@@ -1194,7 +1198,8 @@
    * method or variable initializer, or in the initializer of an instance
    * variable.
    *
-   * @param name the name of the type in question
+   * Parameters:
+   * 0: the name of the type in question
    */
   static const CompileTimeErrorCode IMPLICIT_THIS_REFERENCE_IN_INITIALIZER =
       const CompileTimeErrorCode('IMPLICIT_THIS_REFERENCE_IN_INITIALIZER',
@@ -1203,7 +1208,8 @@
   /**
    * SDK implementation libraries can be imported only by other SDK libraries.
    *
-   * @param uri the uri pointing to a library
+   * Parameters:
+   * 0: the uri pointing to a library
    */
   static const CompileTimeErrorCode IMPORT_INTERNAL_LIBRARY =
       const CompileTimeErrorCode('IMPORT_INTERNAL_LIBRARY',
@@ -1213,7 +1219,9 @@
    * 14.1 Imports: It is a compile-time error if the specified URI of an
    * immediate import does not refer to a library declaration.
    *
-   * @param uri the uri pointing to a non-library declaration
+   * Parameters:
+   * 0: the uri pointing to a non-library declaration
+   *
    * See [StaticWarningCode.IMPORT_OF_NON_LIBRARY].
    */
   static const CompileTimeErrorCode IMPORT_OF_NON_LIBRARY =
@@ -1225,9 +1233,9 @@
    * <i>e<sub>k</sub></i> are not instances of the same class <i>C</i>, for all
    * <i>1 &lt;= k &lt;= n</i>.
    *
-   * @param expressionSource the expression source code that is the unexpected
-   *        type
-   * @param expectedType the name of the expected type
+   * Parameters:
+   * 0: the expression source code that is the unexpected type
+   * 1: the name of the expected type
    */
   static const CompileTimeErrorCode INCONSISTENT_CASE_EXPRESSION_TYPES =
       const CompileTimeErrorCode('INCONSISTENT_CASE_EXPRESSION_TYPES',
@@ -1239,8 +1247,10 @@
    * initializer for a variable that is not an instance variable declared in the
    * immediately surrounding class.
    *
-   * @param id the name of the initializing formal that is not an instance
-   *        variable in the immediately enclosing class
+   * Parameters:
+   * 0: the name of the initializing formal that is not an instance variable in
+   *    the immediately enclosing class
+   *
    * See [INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD].
    */
   static const CompileTimeErrorCode INITIALIZER_FOR_NON_EXISTENT_FIELD =
@@ -1253,8 +1263,10 @@
    * initializer for a variable that is not an instance variable declared in the
    * immediately surrounding class.
    *
-   * @param id the name of the initializing formal that is a static variable in
-   *        the immediately enclosing class
+   * Parameters:
+   * 0: the name of the initializing formal that is a static variable in the
+   *    immediately enclosing class
+   *
    * See [INITIALIZING_FORMAL_FOR_STATIC_FIELD].
    */
   static const CompileTimeErrorCode INITIALIZER_FOR_STATIC_FIELD =
@@ -1266,8 +1278,10 @@
    * <i>this.id</i>. It is a compile-time error if <i>id</i> is not the name of
    * an instance variable of the immediately enclosing class.
    *
-   * @param id the name of the initializing formal that is not an instance
-   *        variable in the immediately enclosing class
+   * Parameters:
+   * 0: the name of the initializing formal that is not an instance variable in
+   *    the immediately enclosing class
+   *
    * See [INITIALIZING_FORMAL_FOR_STATIC_FIELD], and
    * [INITIALIZER_FOR_NON_EXISTENT_FIELD].
    */
@@ -1280,8 +1294,10 @@
    * <i>this.id</i>. It is a compile-time error if <i>id</i> is not the name of
    * an instance variable of the immediately enclosing class.
    *
-   * @param id the name of the initializing formal that is a static variable in
-   *        the immediately enclosing class
+   * Parameters:
+   * 0: the name of the initializing formal that is a static variable in the
+   *    immediately enclosing class
+   *
    * See [INITIALIZER_FOR_STATIC_FIELD].
    */
   static const CompileTimeErrorCode INITIALIZING_FORMAL_FOR_STATIC_FIELD =
@@ -1400,7 +1416,8 @@
    * 12.6 Lists: It is a compile time error if the type argument of a constant
    * list literal includes a type parameter.
    *
-   * @name the name of the type parameter
+   * Parameters:
+   * 0: the name of the type parameter
    */
   static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_LIST =
       const CompileTimeErrorCode('INVALID_TYPE_ARGUMENT_IN_CONST_LIST',
@@ -1410,7 +1427,8 @@
    * 12.7 Maps: It is a compile time error if the type arguments of a constant
    * map literal include a type parameter.
    *
-   * @name the name of the type parameter
+   * Parameters:
+   * 0: the name of the type parameter
    */
   static const CompileTimeErrorCode INVALID_TYPE_ARGUMENT_IN_CONST_MAP =
       const CompileTimeErrorCode('INVALID_TYPE_ARGUMENT_IN_CONST_MAP',
@@ -1426,7 +1444,9 @@
    * 14.3 Parts: It is a compile time error if the contents of the URI are not a
    * valid part declaration.
    *
-   * @param uri the URI that is invalid
+   * Parameters:
+   * 0: the URI that is invalid
+   *
    * See [URI_DOES_NOT_EXIST].
    */
   static const CompileTimeErrorCode INVALID_URI =
@@ -1441,7 +1461,8 @@
    * clause <i>s<sub>E</sub></i> exists within the innermost function in which
    * <i>s<sub>c</sub></i> occurs.
    *
-   * @param labelName the name of the unresolvable label
+   * Parameters:
+   * 0: the name of the unresolvable label
    */
   static const CompileTimeErrorCode LABEL_IN_OUTER_SCOPE =
       const CompileTimeErrorCode('LABEL_IN_OUTER_SCOPE',
@@ -1456,7 +1477,8 @@
    * clause <i>s<sub>E</sub></i> exists within the innermost function in which
    * <i>s<sub>c</sub></i> occurs.
    *
-   * @param labelName the name of the unresolvable label
+   * Parameters:
+   * 0: the name of the unresolvable label
    */
   static const CompileTimeErrorCode LABEL_UNDEFINED =
       const CompileTimeErrorCode(
@@ -1474,7 +1496,8 @@
    * 7.2 Getters: It is a compile-time error if a class has both a getter and a
    * method with the same name.
    *
-   * @param name the conflicting name of the getter and method
+   * Parameters:
+   * 0: the conflicting name of the getter and method
    */
   static const CompileTimeErrorCode METHOD_AND_GETTER_WITH_SAME_NAME =
       const CompileTimeErrorCode('METHOD_AND_GETTER_WITH_SAME_NAME',
@@ -1501,9 +1524,11 @@
    * * The static type of <i>e</i> is an enumerated typed with elements
    *   <i>id<sub>1</sub></i>, &hellip;, <i>id<sub>n</sub></i>.
    * * The sets {<i>e<sub>1</sub></i>, &hellip;, <i>e<sub>k</sub></i>} and
-   *   {<i>id<sub>1</sub></i>, &hellip;, <i>id<sub>n</sub></i>} are not the same.
+   *   {<i>id<sub>1</sub></i>, &hellip;, <i>id<sub>n</sub></i>} are not the
+   *   same.
    *
-   * @param constantName the name of the constant that is missing
+   * Parameters:
+   * 0: the name of the constant that is missing
    */
   static const CompileTimeErrorCode MISSING_ENUM_CONSTANT_IN_SWITCH =
       const CompileTimeErrorCode('MISSING_ENUM_CONSTANT_IN_SWITCH',
@@ -1514,7 +1539,8 @@
    * 9 Mixins: It is a compile-time error if a declared or derived mixin
    * explicitly declares a constructor.
    *
-   * @param typeName the name of the mixin that is invalid
+   * Parameters:
+   * 0: the name of the mixin that is invalid
    */
   static const CompileTimeErrorCode MIXIN_DECLARES_CONSTRUCTOR =
       const CompileTimeErrorCode('MIXIN_DECLARES_CONSTRUCTOR',
@@ -1524,7 +1550,9 @@
    * 9.1 Mixin Application: It is a compile-time error if the with clause of a
    * mixin application <i>C</i> includes a deferred type expression.
    *
-   * @param typeName the name of the type that cannot be extended
+   * Parameters:
+   * 0: the name of the type that cannot be extended
+   *
    * See [EXTENDS_DEFERRED_CLASS], and [IMPLEMENTS_DEFERRED_CLASS].
    */
   static const CompileTimeErrorCode MIXIN_DEFERRED_CLASS =
@@ -1547,7 +1575,8 @@
    * 9 Mixins: It is a compile-time error if a mixin is derived from a class
    * whose superclass is not Object.
    *
-   * @param typeName the name of the mixin that is invalid
+   * Parameters:
+   * 0: the name of the mixin that is invalid
    */
   static const CompileTimeErrorCode MIXIN_INHERITS_FROM_NOT_OBJECT =
       const CompileTimeErrorCode('MIXIN_INHERITS_FROM_NOT_OBJECT',
@@ -1572,7 +1601,9 @@
    * 12.5 Strings: It is a compile-time error for a class to attempt to extend
    * or implement String.
    *
-   * @param typeName the name of the type that cannot be extended
+   * Parameters:
+   * 0: the name of the type that cannot be extended
+   *
    * See [IMPLEMENTS_DISALLOWED_CLASS].
    */
   static const CompileTimeErrorCode MIXIN_OF_DISALLOWED_CLASS =
@@ -1827,8 +1858,9 @@
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant
    * object results in an uncaught exception being thrown.
    *
-   * @param requiredCount the expected number of required arguments
-   * @param argumentCount the actual number of positional arguments given
+   * Parameters:
+   * 0: the expected number of required arguments
+   * 1: the actual number of positional arguments given
    */
   static const CompileTimeErrorCode NOT_ENOUGH_REQUIRED_ARGUMENTS =
       const CompileTimeErrorCode('NOT_ENOUGH_REQUIRED_ARGUMENTS',
@@ -1864,7 +1896,8 @@
    * 14.3 Parts: It is a compile time error if the contents of the URI are not a
    * valid part declaration.
    *
-   * @param uri the uri pointing to a non-library declaration
+   * Parameters:
+   * 0: the uri pointing to a non-library declaration
    */
   static const CompileTimeErrorCode PART_OF_NON_PART =
       const CompileTimeErrorCode('PART_OF_NON_PART',
@@ -1926,8 +1959,9 @@
    * 7.9 Superclasses: It is a compile-time error if a class <i>C</i> is a
    * superclass of itself.
    *
-   * @param className the name of the class that implements itself recursively
-   * @param strImplementsPath a string representation of the implements loop
+   * Parameters:
+   * 0: the name of the class that implements itself recursively
+   * 1: a string representation of the implements loop
    */
   static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE =
       const CompileTimeErrorCode('RECURSIVE_INTERFACE_INHERITANCE',
@@ -1943,7 +1977,8 @@
    * 7.9 Superclasses: It is a compile-time error if a class <i>C</i> is a
    * superclass of itself.
    *
-   * @param className the name of the class that implements itself recursively
+   * Parameters:
+   * 0: the name of the class that implements itself recursively
    */
   static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS =
       const CompileTimeErrorCode(
@@ -1960,7 +1995,8 @@
    * 7.9 Superclasses: It is a compile-time error if a class <i>C</i> is a
    * superclass of itself.
    *
-   * @param className the name of the class that implements itself recursively
+   * Parameters:
+   * 0: the name of the class that implements itself recursively
    */
   static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS =
       const CompileTimeErrorCode(
@@ -1977,7 +2013,8 @@
    * 7.9 Superclasses: It is a compile-time error if a class <i>C</i> is a
    * superclass of itself.
    *
-   * @param className the name of the class that implements itself recursively
+   * Parameters:
+   * 0: the name of the class that implements itself recursively
    */
   static const CompileTimeErrorCode RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH =
       const CompileTimeErrorCode(
@@ -2109,10 +2146,11 @@
    * 12.1 Constants: It is a compile-time error if evaluation of a compile-time
    * constant would raise an exception.
    *
-   * @param boundedTypeName the name of the type used in the instance creation
-   *        that should be limited by the bound as specified in the class
-   *        declaration
-   * @param boundingTypeName the name of the bounding type
+   * Parameters:
+   * 0: the name of the type used in the instance creation that should be
+   *    limited by the bound as specified in the class declaration
+   * 1: the name of the bounding type
+   *
    * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
    */
   static const CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS =
@@ -2165,7 +2203,8 @@
    * 12.11.2 Const: It is a compile-time error if evaluation of a constant
    * object results in an uncaught exception being thrown.
    *
-   * @param name the name of the requested named parameter
+   * Parameters:
+   * 0: the name of the requested named parameter
    */
   static const CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER =
       const CompileTimeErrorCode('UNDEFINED_NAMED_PARAMETER',
@@ -2181,7 +2220,9 @@
    * 14.3 Parts: It is a compile time error if the contents of the URI are not a
    * valid part declaration.
    *
-   * @param uri the URI pointing to a non-existent file
+   * Parameters:
+   * 0: the URI pointing to a non-existent file
+   *
    * See [INVALID_URI].
    */
   static const CompileTimeErrorCode URI_DOES_NOT_EXIST =
@@ -2212,10 +2253,10 @@
    * or 1. It is a compile time error if the arity of the user-declared operator
    * ~ is not 0.
    *
-   * @param operatorName the name of the declared operator
-   * @param expectedNumberOfParameters the number of parameters expected
-   * @param actualNumberOfParameters the number of parameters found in the
-   *        operator declaration
+   * Parameters:
+   * 0: the name of the declared operator
+   * 1: the number of parameters expected
+   * 2: the number of parameters found in the operator declaration
    */
   static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR =
       const CompileTimeErrorCode('WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR',
@@ -2225,8 +2266,8 @@
    * 7.1.1 Operators: It is a compile time error if the arity of the
    * user-declared operator - is not 0 or 1.
    *
-   * @param actualNumberOfParameters the number of parameters found in the
-   *        operator declaration
+   * Parameters:
+   * 0: the number of parameters found in the operator declaration
    */
   static const CompileTimeErrorCode WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR_MINUS =
       const CompileTimeErrorCode(
@@ -2274,7 +2315,7 @@
 }
 
 /**
- * An `ErrorCode` represents an error code associated with an [AnalysisError].
+ * An error code associated with an [AnalysisError].
  *
  * Generally, we want to provide messages that consist of three sentences. From
  * the user's perspective these sentences should explain:
@@ -2333,25 +2374,43 @@
 }
 
 /**
- * The enumeration `ErrorProperty` defines the properties that can be associated with an
- * [AnalysisError].
+ * The properties that can be associated with an [AnalysisError].
  */
 class ErrorProperty extends Enum<ErrorProperty> {
   /**
-   * A property whose value is an array of [ExecutableElement] that should
+   * A property whose value is a list of [FieldElement]s that are final, but
+   * not initialized by a constructor.
+   */
+  static const ErrorProperty NOT_INITIALIZED_FIELDS =
+      const ErrorProperty('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.
+   */
+  static const ErrorProperty PARTS_LIBRARY_NAME =
+      const ErrorProperty('PARTS_LIBRARY_NAME', 1);
+
+  /**
+   * A property whose value is a list of [ExecutableElement] that should
    * be but are not implemented by a concrete class.
    */
   static const ErrorProperty UNIMPLEMENTED_METHODS =
-      const ErrorProperty('UNIMPLEMENTED_METHODS', 0);
+      const ErrorProperty('UNIMPLEMENTED_METHODS', 2);
 
-  static const List<ErrorProperty> values = const [UNIMPLEMENTED_METHODS];
+  static const List<ErrorProperty> values = const [
+    NOT_INITIALIZED_FIELDS,
+    PARTS_LIBRARY_NAME,
+    UNIMPLEMENTED_METHODS
+  ];
 
   const ErrorProperty(String name, int ordinal) : super(name, ordinal);
 }
 
 /**
- * Instances of the class `ErrorReporter` wrap an error listener with utility methods used to
- * create the errors being reported.
+ * An object used to create analysis errors and report then to an error
+ * listener.
  */
 class ErrorReporter {
   /**
@@ -2370,10 +2429,9 @@
   Source _source;
 
   /**
-   * Initialize a newly created error reporter that will report errors to the given listener.
-   *
-   * @param errorListener the error listener to which errors will be reported
-   * @param defaultSource the default source to be used when reporting errors
+   * Initialize a newly created error reporter that will report errors to the
+   * given [_errorListener]. Errors will be reported against the
+   * [_defaultSource] unless another source is provided later.
    */
   ErrorReporter(this._errorListener, this._defaultSource) {
     if (_errorListener == null) {
@@ -2387,21 +2445,16 @@
   Source get source => _source;
 
   /**
-   * Set the source to be used when reporting errors. Setting the source to `null` will cause
-   * the default source to be used.
-   *
-   * @param source the source to be used when reporting errors
+   * Set the source to be used when reporting errors to the given [source].
+   * Setting the source to `null` will cause the default source to be used.
    */
   void set source(Source source) {
     this._source = source == null ? _defaultSource : source;
   }
 
   /**
-   * Creates an error with properties with the given error code and arguments.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param node the node specifying the location of the error
-   * @param arguments the arguments to the error, used to compose the error message
+   * Creates an error with properties with the given [errorCode] and
+   * [arguments]. The [node] is used to compute the location of the error.
    */
   AnalysisErrorWithProperties newErrorWithProperties(
           ErrorCode errorCode, AstNode node, List<Object> arguments) =>
@@ -2409,20 +2462,15 @@
           _source, node.offset, node.length, errorCode, arguments);
 
   /**
-   * Report a passed error.
-   *
-   * @param error the error to report
+   * Report the given [error].
    */
   void reportError(AnalysisError error) {
     _errorListener.onError(error);
   }
 
   /**
-   * Report an error with the given error code and arguments.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param element the element which name should be used as the location of the error
-   * @param arguments the arguments to the error, used to compose the error message
+   * Report an error with the given [errorCode] and [arguments]. The [element]
+   * is used to compute the location of the error.
    */
   void reportErrorForElement(
       ErrorCode errorCode, Element element, List<Object> arguments) {
@@ -2431,15 +2479,12 @@
   }
 
   /**
-   * Report an error with the given error code and arguments.
+   * Report an error with the given [errorCode] and [arguments].
+   * The [node] is used to compute the location of the error.
    *
    * If the arguments contain the names of two or more types, the method
    * [reportTypeErrorForNode] should be used and the types
    * themselves (rather than their names) should be passed as arguments.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param node the node specifying the location of the error
-   * @param arguments the arguments to the error, used to compose the error message
    */
   void reportErrorForNode(ErrorCode errorCode, AstNode node,
       [List<Object> arguments]) {
@@ -2447,12 +2492,8 @@
   }
 
   /**
-   * Report an error with the given error code and arguments.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param offset the offset of the location of the error
-   * @param length the length of the location of the error
-   * @param arguments the arguments to the error, used to compose the error message
+   * Report an error with the given [errorCode] and [arguments]. The location of
+   * the error is specified by the given [offset] and [length].
    */
   void reportErrorForOffset(ErrorCode errorCode, int offset, int length,
       [List<Object> arguments]) {
@@ -2461,11 +2502,8 @@
   }
 
   /**
-   * Report an error with the given error code and arguments.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param token the token specifying the location of the error
-   * @param arguments the arguments to the error, used to compose the error message
+   * Report an error with the given [errorCode] and [arguments]. The [token] is
+   * used to compute the location of the error.
    */
   void reportErrorForToken(ErrorCode errorCode, Token token,
       [List<Object> arguments]) {
@@ -2473,17 +2511,15 @@
   }
 
   /**
-   * Report an error with the given error code and arguments. The arguments are expected to contain
-   * two or more types. Convert the types into strings by using the display names of the types,
-   * unless there are two or more types with the same names, in which case the extended display
-   * names of the types will be used in order to clarify the message.
+   * Report an error with the given [errorCode] and [arguments]. The [node] is
+   * used to compute the location of the error. The arguments are expected to
+   * contain two or more types. Convert the types into strings by using the
+   * display names of the types, unless there are two or more types with the
+   * same names, in which case the extended display names of the types will be
+   * used in order to clarify the message.
    *
    * If there are not two or more types in the argument list, the method
    * [reportErrorForNode] should be used instead.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param node the node specifying the location of the error
-   * @param arguments the arguments to the error, used to compose the error message
    */
   void reportTypeErrorForNode(
       ErrorCode errorCode, AstNode node, List<Object> arguments) {
@@ -2492,12 +2528,11 @@
   }
 
   /**
-   * Given an array of arguments that is expected to contain two or more types, convert the types
-   * into strings by using the display names of the types, unless there are two or more types with
-   * the same names, in which case the extended display names of the types will be used in order to
+   * Given an array of [arguments] that is expected to contain two or more
+   * types, convert the types into strings by using the display names of the
+   * types, unless there are two or more types with the same names, in which
+   * case the extended display names of the types will be used in order to
    * clarify the message.
-   *
-   * @param arguments the arguments that are to be converted
    */
   void _convertTypeNames(List<Object> arguments) {
     if (_hasEqualTypeNames(arguments)) {
@@ -2526,12 +2561,8 @@
   }
 
   /**
-   * Return `true` if the given array of arguments contains two or more types with the same
-   * display name.
-   *
-   * @param arguments the arguments being tested
-   * @return `true` if the array of arguments contains two or more types with the same display
-   *         name
+   * Return `true` if the given array of [arguments] contains two or more types
+   * with the same display name.
    */
   bool _hasEqualTypeNames(List<Object> arguments) {
     int count = arguments.length;
@@ -2547,13 +2578,12 @@
 }
 
 /**
- * Instances of the enumeration `ErrorSeverity` represent the severity of an [ErrorCode]
- * .
+ * The severity of an [ErrorCode].
  */
 class ErrorSeverity extends Enum<ErrorSeverity> {
   /**
-   * The severity representing a non-error. This is never used for any error code, but is useful for
-   * clients.
+   * The severity representing a non-error. This is never used for any error
+   * code, but is useful for clients.
    */
   static const ErrorSeverity NONE = const ErrorSeverity('NONE', 0, " ", "none");
 
@@ -2590,8 +2620,9 @@
   /**
    * Initialize a newly created severity with the given names.
    *
-   * @param machineCode the name of the severity used when producing machine output
-   * @param displayName the name of the severity used when producing readable output
+   * Parameters:
+   * 0: the name of the severity used when producing machine output
+   * 1: the name of the severity used when producing readable output
    */
   const ErrorSeverity(
       String name, int ordinal, this.machineCode, this.displayName)
@@ -2599,16 +2630,13 @@
 
   /**
    * Return the severity constant that represents the greatest severity.
-   *
-   * @param severity the severity being compared against
-   * @return the most sever of this or the given severity
    */
   ErrorSeverity max(ErrorSeverity severity) =>
       this.ordinal >= severity.ordinal ? this : severity;
 }
 
 /**
- * Instances of the enumeration `ErrorType` represent the type of an [ErrorCode].
+ * The type of an [ErrorCode].
  */
 class ErrorType extends Enum<ErrorType> {
   /**
@@ -2617,47 +2645,51 @@
   static const ErrorType TODO = const ErrorType('TODO', 0, ErrorSeverity.INFO);
 
   /**
-   * Extra analysis run over the code to follow best practices, which are not in the Dart Language
-   * Specification.
+   * Extra analysis run over the code to follow best practices, which are not in
+   * the Dart Language Specification.
    */
   static const ErrorType HINT = const ErrorType('HINT', 1, ErrorSeverity.INFO);
 
   /**
-   * Compile-time errors are errors that preclude execution. A compile time error must be reported
-   * by a Dart compiler before the erroneous code is executed.
+   * Compile-time errors are errors that preclude execution. A compile time
+   * error must be reported by a Dart compiler before the erroneous code is
+   * executed.
    */
   static const ErrorType COMPILE_TIME_ERROR =
       const ErrorType('COMPILE_TIME_ERROR', 2, ErrorSeverity.ERROR);
 
   /**
-   * Checked mode compile-time errors are errors that preclude execution in checked mode.
+   * Checked mode compile-time errors are errors that preclude execution in
+   * checked mode.
    */
   static const ErrorType CHECKED_MODE_COMPILE_TIME_ERROR = const ErrorType(
       'CHECKED_MODE_COMPILE_TIME_ERROR', 3, ErrorSeverity.ERROR);
 
   /**
-   * Static warnings are those warnings reported by the static checker. They have no effect on
-   * execution. Static warnings must be provided by Dart compilers used during development.
+   * Static warnings are those warnings reported by the static checker. They
+   * have no effect on execution. Static warnings must be provided by Dart
+   * compilers used during development.
    */
   static const ErrorType STATIC_WARNING =
       const ErrorType('STATIC_WARNING', 4, ErrorSeverity.WARNING);
 
   /**
-   * Many, but not all, static warnings relate to types, in which case they are known as static type
-   * warnings.
+   * Many, but not all, static warnings relate to types, in which case they are
+   * known as static type warnings.
    */
   static const ErrorType STATIC_TYPE_WARNING =
       const ErrorType('STATIC_TYPE_WARNING', 5, ErrorSeverity.WARNING);
 
   /**
-   * Syntactic errors are errors produced as a result of input that does not conform to the grammar.
+   * Syntactic errors are errors produced as a result of input that does not
+   * conform to the grammar.
    */
   static const ErrorType SYNTACTIC_ERROR =
       const ErrorType('SYNTACTIC_ERROR', 6, ErrorSeverity.ERROR);
 
   /**
-   * Lint warnings describe style and best practice recommendations that can be used to formalize a project's style
-   * guidelines.
+   * Lint warnings describe style and best practice recommendations that can be
+   * used to formalize a project's style guidelines.
    */
   static const ErrorType LINT = const ErrorType('LINT', 7, ErrorSeverity.INFO);
 
@@ -2678,9 +2710,8 @@
   final ErrorSeverity severity;
 
   /**
-   * Initialize a newly created error type to have the given severity.
-   *
-   * @param severity the severity of this type of error
+   * Initialize a newly created error type to have the given [name] and
+   * [severity].
    */
   const ErrorType(String name, int ordinal, this.severity)
       : super(name, ordinal);
@@ -2689,8 +2720,8 @@
 }
 
 /**
- * The class `HintCode` defines the hints and coding recommendations for best
- * practices which are not mentioned in the Dart Language Specification.
+ * The hints and coding recommendations for best practices which are not
+ * mentioned in the Dart Language Specification.
  */
 class HintCode extends ErrorCode {
   /**
@@ -2698,8 +2729,9 @@
    * [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE] would have been generated,
    * if we used propagated information for the warnings.
    *
-   * @param actualType the name of the actual argument type
-   * @param expectedType the name of the expected type
+   * Parameters:
+   * 0: the name of the actual argument type
+   * 1: the name of the expected type
    */
   static const HintCode ARGUMENT_TYPE_NOT_ASSIGNABLE = const HintCode(
       'ARGUMENT_TYPE_NOT_ASSIGNABLE',
@@ -2724,8 +2756,9 @@
    * user has an on-catch clause such as `on A catch (e)`, where a supertype of
    * `A` was already caught.
    *
-   * @param subtypeName name of the subtype
-   * @param supertypeName name of the supertype
+   * Parameters:
+   * 0: name of the subtype
+   * 1: name of the supertype
    */
   static const HintCode DEAD_CODE_ON_CATCH_SUBTYPE = const HintCode(
       'DEAD_CODE_ON_CATCH_SUBTYPE',
@@ -2734,7 +2767,8 @@
   /**
    * Deprecated members should not be invoked or used.
    *
-   * @param memberName the name of the member
+   * Parameters:
+   * 0: the name of the member
    */
   static const HintCode DEPRECATED_MEMBER_USE =
       const HintCode('DEPRECATED_MEMBER_USE', "'{0}' is deprecated");
@@ -2788,8 +2822,9 @@
    * [StaticTypeWarningCode.INVALID_ASSIGNMENT] would have been generated, if we
    * used propagated information for the warnings.
    *
-   * @param rhsTypeName the name of the right hand side type
-   * @param lhsTypeName the name of the left hand side type
+   * Parameters:
+   * 0: the name of the right hand side type
+   * 1: the name of the left hand side type
    */
   static const HintCode INVALID_ASSIGNMENT = const HintCode(
       'INVALID_ASSIGNMENT',
@@ -2801,7 +2836,8 @@
    * or functions with no return, Dart implicitly returns `null`, avoiding these
    * implicit returns is considered a best practice.
    *
-   * @param returnType the name of the declared return type
+   * Parameters:
+   * 0: the name of the declared return type
    */
   static const HintCode MISSING_RETURN = const HintCode('MISSING_RETURN',
       "This function declares a return type of '{0}', but does not end with a return statement",
@@ -2831,7 +2867,8 @@
   /**
    * Hint for classes that override equals, but not hashCode.
    *
-   * @param className the name of the current class
+   * Parameters:
+   * 0: the name of the current class
    */
   static const HintCode OVERRIDE_EQUALS_BUT_NOT_HASH_CODE = const HintCode(
       'OVERRIDE_EQUALS_BUT_NOT_HASH_CODE',
@@ -2856,9 +2893,9 @@
    * [StaticWarningCode.UNDEFINED_GETTER] would have been generated, if we used
    * propagated information for the warnings.
    *
-   * @param getterName the name of the getter
-   * @param enclosingType the name of the enclosing type where the getter is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the getter
+   * 1: the name of the enclosing type where the getter is being looked for
    */
   static const HintCode UNDEFINED_GETTER = const HintCode('UNDEFINED_GETTER',
       "The getter '{0}' is not defined for the class '{1}'");
@@ -2868,9 +2905,9 @@
    * [StaticTypeWarningCode.UNDEFINED_METHOD] would have been generated, if we
    * used propagated information for the warnings.
    *
-   * @param methodName the name of the method that is undefined
-   * @param typeName the resolved type name that the method lookup is happening
-   *        on
+   * Parameters:
+   * 0: the name of the method that is undefined
+   * 1: the resolved type name that the method lookup is happening on
    */
   static const HintCode UNDEFINED_METHOD = const HintCode('UNDEFINED_METHOD',
       "The method '{0}' is not defined for the class '{1}'");
@@ -2880,9 +2917,9 @@
    * [StaticTypeWarningCode.UNDEFINED_OPERATOR] would have been generated, if we
    * used propagated information for the warnings.
    *
-   * @param operator the name of the operator
-   * @param enclosingType the name of the enclosing type where the operator is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the operator
+   * 1: the name of the enclosing type where the operator is being looked for
    */
   static const HintCode UNDEFINED_OPERATOR = const HintCode(
       'UNDEFINED_OPERATOR',
@@ -2894,9 +2931,9 @@
    * [StaticWarningCode.UNDEFINED_SETTER] would have been generated, if we used
    * propagated information for the warnings.
    *
-   * @param setterName the name of the setter
-   * @param enclosingType the name of the enclosing type where the setter is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the setter
+   * 1: the name of the enclosing type where the setter is being looked for
    */
   static const HintCode UNDEFINED_SETTER = const HintCode('UNDEFINED_SETTER',
       "The setter '{0}' is not defined for the class '{1}'");
@@ -2940,6 +2977,20 @@
       const HintCode('UNUSED_IMPORT', "Unused import");
 
   /**
+   * Unused catch exception variables.
+   */
+  static const HintCode UNUSED_CATCH_CLAUSE = const HintCode(
+      'UNUSED_CATCH_CLAUSE',
+      "The exception variable '{0}' is not used, so the 'catch' clause can be removed");
+
+  /**
+   * Unused catch stack trace variables.
+   */
+  static const HintCode UNUSED_CATCH_STACK = const HintCode(
+      'UNUSED_CATCH_STACK',
+      "The stack trace variable '{0}' is not used and can be removed");
+
+  /**
    * Unused local variables are local varaibles which are never read.
    */
   static const HintCode UNUSED_LOCAL_VARIABLE = const HintCode(
@@ -2950,7 +3001,8 @@
    * Hint for cases where the source expects a method or function to return a
    * non-void result, but the method or function signature returns void.
    *
-   * @param name the name of the method or function that returns void
+   * Parameters:
+   * 0: the name of the method or function that returns void
    */
   static const HintCode USE_OF_VOID_RESULT = const HintCode(
       'USE_OF_VOID_RESULT',
@@ -3005,18 +3057,18 @@
 }
 
 /**
- * The enumeration `HtmlWarningCode` defines the error codes used for warnings
- * in HTML files. The convention for this class is for the name of the error
- * code to indicate the problem that caused the error to be generated and for
- * the error message to explain what is wrong and, when appropriate, how the
- * problem can be corrected.
+ * The error codes used for warnings in HTML files. The convention for this
+ * class is for the name of the error code to indicate the problem that caused
+ * the error to be generated and for the error message to explain what is wrong
+ * and, when appropriate, how the problem can be corrected.
  */
 class HtmlWarningCode extends ErrorCode {
   /**
    * An error code indicating that the value of the 'src' attribute of a Dart
    * script tag is not a valid URI.
    *
-   * @param uri the URI that is invalid
+   * Parameters:
+   * 0: the URI that is invalid
    */
   static const HtmlWarningCode INVALID_URI =
       const HtmlWarningCode('INVALID_URI', "Invalid URI syntax: '{0}'");
@@ -3025,7 +3077,8 @@
    * An error code indicating that the value of the 'src' attribute of a Dart
    * script tag references a file that does not exist.
    *
-   * @param uri the URI pointing to a non-existent file
+   * Parameters:
+   * 0: the URI pointing to a non-existent file
    */
   static const HtmlWarningCode URI_DOES_NOT_EXIST = const HtmlWarningCode(
       'URI_DOES_NOT_EXIST', "Target of URI does not exist: '{0}'");
@@ -3049,8 +3102,9 @@
 /**
  * Defines style and best practice recommendations.
  *
- * Unlike [HintCode]s, which are akin to traditional static warnings from a compiler, lint recommendations focus on
- * matters of style and practices that might aggregated to define a project's style guide.
+ * Unlike [HintCode]s, which are akin to traditional static warnings from a
+ * compiler, lint recommendations focus on matters of style and practices that
+ * might aggregated to define a project's style guide.
  */
 class LintCode extends ErrorCode {
   const LintCode(String name, String message, [String correction])
@@ -3064,18 +3118,18 @@
 }
 
 /**
- * The class `StaticTypeWarningCode` defines the error codes used for static
- * type warnings. The convention for this class is for the name of the error
- * code to indicate the problem that caused the error to be generated and for
- * the error message to explain what is wrong and, when appropriate, how the
- * problem can be corrected.
+ * The error codes used for static type warnings. The convention for this class
+ * is for the name of the error code to indicate the problem that caused the
+ * error to be generated and for the error message to explain what is wrong and,
+ * when appropriate, how the problem can be corrected.
  */
 class StaticTypeWarningCode extends ErrorCode {
   /**
    * 12.7 Lists: A fresh instance (7.6.1) <i>a</i>, of size <i>n</i>, whose
    * class implements the built-in class <i>List&lt;E></i> is allocated.
    *
-   * @param numTypeArgument the number of provided type arguments
+   * Parameters:
+   * 0: the number of provided type arguments
    */
   static const StaticTypeWarningCode EXPECTED_ONE_LIST_TYPE_ARGUMENTS =
       const StaticTypeWarningCode('EXPECTED_ONE_LIST_TYPE_ARGUMENTS',
@@ -3085,7 +3139,8 @@
    * 12.8 Maps: A fresh instance (7.6.1) <i>m</i>, of size <i>n</i>, whose class
    * implements the built-in class <i>Map&lt;K, V></i> is allocated.
    *
-   * @param numTypeArgument the number of provided type arguments
+   * Parameters:
+   * 0: the number of provided type arguments
    */
   static const StaticTypeWarningCode EXPECTED_TWO_MAP_TYPE_ARGUMENTS =
       const StaticTypeWarningCode('EXPECTED_TWO_MAP_TYPE_ARGUMENTS',
@@ -3161,7 +3216,9 @@
    * 12.15.1 Ordinary Invocation: It is a static type warning if <i>T</i> does
    * not have an accessible (3.2) instance member named <i>m</i>.
    *
-   * @param memberName the name of the static member
+   * Parameters:
+   * 0: the name of the static member
+   *
    * See [UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER].
    */
   static const StaticTypeWarningCode INSTANCE_ACCESS_TO_STATIC_MEMBER =
@@ -3181,8 +3238,9 @@
    * It is a static type warning if the static type of <i>e<sub>2</sub></i> may
    * not be assigned to <i>T</i>.
    *
-   * @param rhsTypeName the name of the right hand side type
-   * @param lhsTypeName the name of the left hand side type
+   * Parameters:
+   * 0: the name of the right hand side type
+   * 1: the name of the left hand side type
    */
   static const StaticTypeWarningCode INVALID_ASSIGNMENT =
       const StaticTypeWarningCode('INVALID_ASSIGNMENT',
@@ -3209,8 +3267,8 @@
    * <i>S.m</i> exists, it is a static warning if the type <i>F</i> of
    * <i>S.m</i> may not be assigned to a function type.
    *
-   * @param nonFunctionIdentifier the name of the identifier that is not a
-   *        function type
+   * Parameters:
+   * 0: the name of the identifier that is not a function type
    */
   static const StaticTypeWarningCode INVOCATION_OF_NON_FUNCTION =
       const StaticTypeWarningCode(
@@ -3270,7 +3328,8 @@
    * static types of both of <i>e<sub>1</sub></i> and <i>e<sub>2</sub></i> may
    * not be assigned to bool.
    *
-   * @param operator the lexeme of the logical operator
+   * Parameters:
+   * 0: the lexeme of the logical operator
    */
   static const StaticTypeWarningCode NON_BOOL_OPERAND =
       const StaticTypeWarningCode('NON_BOOL_OPERAND',
@@ -3289,9 +3348,10 @@
    * be assigned to the declared return type of the immediately enclosing
    * function.
    *
-   * @param actualReturnType the return type as declared in the return statement
-   * @param expectedReturnType the expected return type as defined by the method
-   * @param methodName the name of the method
+   * Parameters:
+   * 0: the return type as declared in the return statement
+   * 1: the expected return type as defined by the method
+   * 2: the name of the method
    */
   static const StaticTypeWarningCode RETURN_OF_INVALID_TYPE =
       const StaticTypeWarningCode('RETURN_OF_INVALID_TYPE',
@@ -3318,10 +3378,11 @@
    * to <i>k'</i> are not subtypes of the bounds of the corresponding formal
    * type parameters of type.
    *
-   * @param boundedTypeName the name of the type used in the instance creation
-   *        that should be limited by the bound as specified in the class
-   *        declaration
-   * @param boundingTypeName the name of the bounding type
+   * Parameters:
+   * 0: the name of the type used in the instance creation that should be
+   *    limited by the bound as specified in the class declaration
+   * 1: the name of the bounding type
+   *
    * See [TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND].
    */
   static const StaticTypeWarningCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS =
@@ -3332,7 +3393,9 @@
    * 10 Generics: It is a static type warning if a type parameter is a supertype
    * of its upper bound.
    *
-   * @param typeParameterName the name of the type parameter
+   * Parameters:
+   * 0: the name of the type parameter
+   *
    * See [TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
    */
   static const StaticTypeWarningCode TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND =
@@ -3344,9 +3407,9 @@
    * <i>C</i> in the enclosing lexical scope of <i>i</i>, or if <i>C</i> does
    * not declare, implicitly or explicitly, a getter named <i>m</i>.
    *
-   * @param constantName the name of the enumeration constant that is not
-   *        defined
-   * @param enumName the name of the enumeration used to access the constant
+   * Parameters:
+   * 0: the name of the enumeration constant that is not defined
+   * 1: the name of the enumeration used to access the constant
    */
   static const StaticTypeWarningCode UNDEFINED_ENUM_CONSTANT =
       const StaticTypeWarningCode('UNDEFINED_ENUM_CONSTANT',
@@ -3361,7 +3424,8 @@
    * <i>x<sub>n+1</sub></i> : <i>a<sub>n+1</sub></i>, ...,
    * <i>x<sub>n+k</sub></i> : <i>a<sub>n+k</sub></i>).
    *
-   * @param methodName the name of the method that is undefined
+   * Parameters:
+   * 0: the name of the method that is undefined
    */
   static const StaticTypeWarningCode UNDEFINED_FUNCTION =
       const StaticTypeWarningCode(
@@ -3371,9 +3435,9 @@
    * 12.17 Getter Invocation: Let <i>T</i> be the static type of <i>e</i>. It is
    * a static type warning if <i>T</i> does not have a getter named <i>m</i>.
    *
-   * @param getterName the name of the getter
-   * @param enclosingType the name of the enclosing type where the getter is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the getter
+   * 1: the name of the enclosing type where the getter is being looked for
    */
   static const StaticTypeWarningCode UNDEFINED_GETTER =
       const StaticTypeWarningCode('UNDEFINED_GETTER',
@@ -3384,9 +3448,9 @@
    * It is a static type warning if <i>T</i> does not have an accessible
    * instance member named <i>m</i>.
    *
-   * @param methodName the name of the method that is undefined
-   * @param typeName the resolved type name that the method lookup is happening
-   *        on
+   * Parameters:
+   * 0: the name of the method that is undefined
+   * 1: the resolved type name that the method lookup is happening on
    */
   static const StaticTypeWarningCode UNDEFINED_METHOD =
       const StaticTypeWarningCode('UNDEFINED_METHOD',
@@ -3408,9 +3472,9 @@
    * It is a static type warning if <i>T</i> does not have an accessible
    * instance member named <i>m</i>.
    *
-   * @param operator the name of the operator
-   * @param enclosingType the name of the enclosing type where the operator is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the operator
+   * 1: the name of the enclosing type where the operator is being looked for
    */
   static const StaticTypeWarningCode UNDEFINED_OPERATOR =
       const StaticTypeWarningCode('UNDEFINED_OPERATOR',
@@ -3421,9 +3485,10 @@
    * It is a static type warning if <i>T</i> does not have an accessible
    * instance setter named <i>v=</i>.
    *
-   * @param setterName the name of the setter
-   * @param enclosingType the name of the enclosing type where the setter is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the setter
+   * 1: the name of the enclosing type where the setter is being looked for
+   *
    * See [INACCESSIBLE_SETTER].
    */
   static const StaticTypeWarningCode UNDEFINED_SETTER =
@@ -3434,9 +3499,9 @@
    * 12.17 Getter Invocation: Let <i>T</i> be the static type of <i>e</i>. It is
    * a static type warning if <i>T</i> does not have a getter named <i>m</i>.
    *
-   * @param getterName the name of the getter
-   * @param enclosingType the name of the enclosing type where the getter is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the getter
+   * 1: the name of the enclosing type where the getter is being looked for
    */
   static const StaticTypeWarningCode UNDEFINED_SUPER_GETTER =
       const StaticTypeWarningCode('UNDEFINED_SUPER_GETTER',
@@ -3449,9 +3514,9 @@
    * static type warning if <i>S</i> does not have an accessible instance member
    * named <i>m</i>.
    *
-   * @param methodName the name of the method that is undefined
-   * @param typeName the resolved type name that the method lookup is happening
-   *        on
+   * Parameters:
+   * 0: the name of the method that is undefined
+   * 1: the resolved type name that the method lookup is happening on
    */
   static const StaticTypeWarningCode UNDEFINED_SUPER_METHOD =
       const StaticTypeWarningCode('UNDEFINED_SUPER_METHOD',
@@ -3473,9 +3538,9 @@
    * It is a static type warning if <i>T</i> does not have an accessible
    * instance member named <i>m</i>.
    *
-   * @param operator the name of the operator
-   * @param enclosingType the name of the enclosing type where the operator is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the operator
+   * 1: the name of the enclosing type where the operator is being looked for
    */
   static const StaticTypeWarningCode UNDEFINED_SUPER_OPERATOR =
       const StaticTypeWarningCode('UNDEFINED_SUPER_OPERATOR',
@@ -3486,9 +3551,10 @@
    * It is a static type warning if <i>T</i> does not have an accessible
    * instance setter named <i>v=</i>.
    *
-   * @param setterName the name of the setter
-   * @param enclosingType the name of the enclosing type where the setter is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the setter
+   * 1: the name of the enclosing type where the setter is being looked for
+   *
    * See [INACCESSIBLE_SETTER].
    */
   static const StaticTypeWarningCode UNDEFINED_SUPER_SETTER =
@@ -3512,9 +3578,11 @@
    * 15.8 Parameterized Types: It is a static type warning if <i>G</i> is not a
    * generic type with exactly <i>n</i> type parameters.
    *
-   * @param typeName the name of the type being referenced (<i>G</i>)
-   * @param parameterCount the number of type parameters that were declared
-   * @param argumentCount the number of type arguments provided
+   * Parameters:
+   * 0: the name of the type being referenced (<i>G</i>)
+   * 1: the number of type parameters that were declared
+   * 2: the number of type arguments provided
+   *
    * See [CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS], and
    * [CompileTimeErrorCode.NEW_WITH_INVALID_TYPE_PARAMETERS].
    */
@@ -3561,11 +3629,10 @@
 }
 
 /**
- * The enumeration `StaticWarningCode` defines the error codes used for static
- * warnings. The convention for this class is for the name of the error code to
- * indicate the problem that caused the error to be generated and for the error
- * message to explain what is wrong and, when appropriate, how the problem can
- * be corrected.
+ * The error codes used for static warnings. The convention for this class is
+ * for the name of the error code to indicate the problem that caused the error
+ * to be generated and for the error message to explain what is wrong and, when
+ * appropriate, how the problem can be corrected.
  */
 class StaticWarningCode extends ErrorCode {
   /**
@@ -3577,11 +3644,10 @@
    *    <i>NoSuchMethodError</i> is raised.
    * 3. If <i>N</i> is referenced as a type, it is treated as a malformed type.
    *
-   * @param ambiguousTypeName the name of the ambiguous type
-   * @param firstLibraryName the name of the first library that the type is
-   *        found
-   * @param secondLibraryName the name of the second library that the type is
-   *        found
+   * Parameters:
+   * 0: the name of the ambiguous type
+   * 1: the name of the first library that the type is found
+   * 2: the name of the second library that the type is found
    */
   static const StaticWarningCode AMBIGUOUS_IMPORT = const StaticWarningCode(
       'AMBIGUOUS_IMPORT', "The name '{0}' is defined in the libraries {1}",
@@ -3613,8 +3679,9 @@
    * assigned to <i>S<sub>r</sub></i>, where <i>r = q<sub>j</sub>, 1 &lt;= j
    * &lt;= l</i>.
    *
-   * @param actualType the name of the actual argument type
-   * @param expectedType the name of the expected type
+   * Parameters:
+   * 0: the name of the actual argument type
+   * 1: the name of the expected type
    */
   static const StaticWarningCode ARGUMENT_TYPE_NOT_ASSIGNABLE =
       const StaticWarningCode('ARGUMENT_TYPE_NOT_ASSIGNABLE',
@@ -3699,11 +3766,10 @@
    * * The import from <i>dart:</i> is implicitly extended by a hide N clause.
    * * A static warning is issued.
    *
-   * @param ambiguousName the ambiguous name
-   * @param sdkLibraryName the name of the dart: library that the element is
-   *        found
-   * @param otherLibraryName the name of the non-dart: library that the element
-   *        is found
+   * Parameters:
+   * 0: the ambiguous name
+   * 1: the name of the dart: library in which the element is found
+   * 1: the name of the non-dart: library in which the element is found
    */
   static const StaticWarningCode CONFLICTING_DART_IMPORT =
       const StaticWarningCode('CONFLICTING_DART_IMPORT',
@@ -3714,7 +3780,8 @@
    * instance getter named <i>v</i> and an accessible static member named
    * <i>v</i> or <i>v=</i> is declared in a superclass of <i>C</i>.
    *
-   * @param superName the name of the super class declaring a static member
+   * Parameters:
+   * 0: the name of the super class declaring a static member
    */
   static const StaticWarningCode CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER =
       const StaticWarningCode(
@@ -3742,7 +3809,8 @@
    * instance setter named <i>v=</i> and an accessible static member named
    * <i>v=</i> or <i>v</i> is declared in a superclass of <i>C</i>.
    *
-   * @param superName the name of the super class declaring a static member
+   * Parameters:
+   * 0: the name of the super class declaring a static member
    */
   static const StaticWarningCode CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER =
       const StaticWarningCode(
@@ -3786,9 +3854,10 @@
    * 14.2 Exports: It is a static warning to export two different libraries with
    * the same name.
    *
-   * @param uri1 the uri pointing to a first library
-   * @param uri2 the uri pointing to a second library
-   * @param name the shared name of the exported libraries
+   * Parameters:
+   * 0: the uri pointing to a first library
+   * 1: the uri pointing to a second library
+   * 2:e the shared name of the exported libraries
    */
   static const StaticWarningCode EXPORT_DUPLICATED_LIBRARY_NAMED =
       const StaticWarningCode('EXPORT_DUPLICATED_LIBRARY_NAMED',
@@ -3798,8 +3867,9 @@
    * 14.2 Exports: It is a static warning to export two different libraries with
    * the same name.
    *
-   * @param uri1 the uri pointing to a first library
-   * @param uri2 the uri pointing to a second library
+   * Parameters:
+   * 0: the uri pointing to a first library
+   * 1: the uri pointing to a second library
    */
   static const StaticWarningCode EXPORT_DUPLICATED_LIBRARY_UNNAMED =
       const StaticWarningCode('EXPORT_DUPLICATED_LIBRARY_UNNAMED',
@@ -3809,8 +3879,10 @@
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt;
    * h</i> or if <i>m &gt; n</i>.
    *
-   * @param requiredCount the maximum number of positional arguments
-   * @param argumentCount the actual number of positional arguments given
+   * Parameters:
+   * 0: the maximum number of positional arguments
+   * 1: the actual number of positional arguments given
+   *
    * See [NOT_ENOUGH_REQUIRED_ARGUMENTS].
    */
   static const StaticWarningCode EXTRA_POSITIONAL_ARGUMENTS =
@@ -3832,7 +3904,8 @@
    * been initialized at its point of declaration is also initialized in a
    * constructor.
    *
-   * @param name the name of the field in question
+   * Parameters:
+   * 0: the name of the field in question
    */
   static const StaticWarningCode FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR =
       const StaticWarningCode(
@@ -3852,8 +3925,9 @@
    * warning if <i>T<sub>j</sub></i> may not be assigned to <i>S<sub>j</sub>, 1
    * &lt;= j &lt;= m</i>.
    *
-   * @param initializerType the name of the type of the initializer expression
-   * @param fieldType the name of the type of the field
+   * Parameters:
+   * 0: the name of the type of the initializer expression
+   * 1: the name of the type of the field
    */
   static const StaticWarningCode FIELD_INITIALIZER_NOT_ASSIGNABLE =
       const StaticWarningCode('FIELD_INITIALIZER_NOT_ASSIGNABLE',
@@ -3864,8 +3938,9 @@
    * <i>this.id</i>. It is a static warning if the static type of <i>id</i> is
    * not assignable to <i>T<sub>id</sub></i>.
    *
-   * @param parameterType the name of the type of the field formal parameter
-   * @param fieldType the name of the type of the field
+   * Parameters:
+   * 0: the name of the type of the field formal parameter
+   * 1: the name of the type of the field
    */
   static const StaticWarningCode FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE =
       const StaticWarningCode('FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE',
@@ -3876,6 +3951,14 @@
    * <i>v</i> is final and <i>v</i> is not initialized at its point of
    * declaration.
    *
+   * Parameters:
+   * 0: the name of the uninitialized final variable
+   */
+  static const StaticWarningCode FINAL_NOT_INITIALIZED =
+      const StaticWarningCode('FINAL_NOT_INITIALIZED',
+          "The final variable '{0}' must be initialized");
+
+  /**
    * 7.6.1 Generative Constructors: Each final instance variable <i>f</i>
    * declared in the immediately enclosing class must have an initializer in
    * <i>k</i>'s initializer list unless it has already been initialized by one
@@ -3884,13 +3967,49 @@
    * * Initialization by means of an initializing formal of <i>k</i>.
    * or a static warning occurs.
    *
-   * @param name the name of the uninitialized final variable
+   * Parameters:
+   * 0: the name of the uninitialized final variable
    */
-  static const StaticWarningCode FINAL_NOT_INITIALIZED =
-      const StaticWarningCode('FINAL_NOT_INITIALIZED',
+  static const StaticWarningCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 =
+      const StaticWarningCode('FINAL_NOT_INITIALIZED_CONSTRUCTOR_1',
           "The final variable '{0}' must be initialized");
 
   /**
+   * 7.6.1 Generative Constructors: Each final instance variable <i>f</i>
+   * declared in the immediately enclosing class must have an initializer in
+   * <i>k</i>'s initializer list unless it has already been initialized by one
+   * of the following means:
+   * * Initialization at the declaration of <i>f</i>.
+   * * Initialization by means of an initializing formal of <i>k</i>.
+   * or a static warning occurs.
+   *
+   * Parameters:
+   * 0: the name of the uninitialized final variable
+   * 1: the name of the uninitialized final variable
+   */
+  static const StaticWarningCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 =
+      const StaticWarningCode('FINAL_NOT_INITIALIZED_CONSTRUCTOR_2',
+          "The final variables '{0}' and '{1}' must be initialized");
+
+  /**
+   * 7.6.1 Generative Constructors: Each final instance variable <i>f</i>
+   * declared in the immediately enclosing class must have an initializer in
+   * <i>k</i>'s initializer list unless it has already been initialized by one
+   * of the following means:
+   * * Initialization at the declaration of <i>f</i>.
+   * * Initialization by means of an initializing formal of <i>k</i>.
+   * or a static warning occurs.
+   *
+   * Parameters:
+   * 0: the name of the uninitialized final variable
+   * 1: the name of the uninitialized final variable
+   * 2: the number of additional not initialized variables that aren't listed
+   */
+  static const StaticWarningCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS =
+      const StaticWarningCode('FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
+          "The final variables '{0}', '{1}' and '{2}' more must be initialized");
+
+  /**
    * 15.5 Function Types: It is a static warning if a concrete class implements
    * Function and does not have a concrete method named call().
    */
@@ -3902,9 +4021,10 @@
    * 14.1 Imports: It is a static warning to import two different libraries with
    * the same name.
    *
-   * @param uri1 the uri pointing to a first library
-   * @param uri2 the uri pointing to a second library
-   * @param name the shared name of the imported libraries
+   * Parameters:
+   * 0: the uri pointing to a first library
+   * 1: the uri pointing to a second library
+   * 2: the shared name of the imported libraries
    */
   static const StaticWarningCode IMPORT_DUPLICATED_LIBRARY_NAMED =
       const StaticWarningCode('IMPORT_DUPLICATED_LIBRARY_NAMED',
@@ -3914,8 +4034,9 @@
    * 14.1 Imports: It is a static warning to import two different libraries with
    * the same name.
    *
-   * @param uri1 the uri pointing to a first library
-   * @param uri2 the uri pointing to a second library
+   * Parameters:
+   * 0: the uri pointing to a first library
+   * 1: the uri pointing to a second library
    */
   static const StaticWarningCode IMPORT_DUPLICATED_LIBRARY_UNNAMED =
       const StaticWarningCode('IMPORT_DUPLICATED_LIBRARY_UNNAMED',
@@ -3925,7 +4046,9 @@
    * 14.1 Imports: It is a static warning if the specified URI of a deferred
    * import does not refer to a library declaration.
    *
-   * @param uri the uri pointing to a non-library declaration
+   * Parameters:
+   * 0: the uri pointing to a non-library declaration
+   *
    * See [CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY].
    */
   static const StaticWarningCode IMPORT_OF_NON_LIBRARY =
@@ -3953,9 +4076,9 @@
    * an instance method named <i>n</i> and an accessible static member named
    * <i>n</i> is declared in a superclass of <i>C</i>.
    *
-   * @param memberName the name of the member with the name conflict
-   * @param superclassName the name of the enclosing class that has the static
-   *        member
+   * Parameters:
+   * 0: the name of the member with the name conflict
+   * 1: the name of the enclosing class that has the static member
    */
   static const StaticWarningCode INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC =
       const StaticWarningCode(
@@ -3967,11 +4090,12 @@
    * getter <i>m2</i> and the type of <i>m1</i> is not a subtype of the type of
    * <i>m2</i>.
    *
-   * @param actualReturnTypeName the name of the expected return type
-   * @param expectedReturnType the name of the actual return type, not
-   *        assignable to the actualReturnTypeName
-   * @param className the name of the class where the overridden getter is
-   *        declared
+   * Parameters:
+   * 0: the name of the actual return type
+   * 1: the name of the expected return type, not assignable to the actual
+   *    return type
+   * 2: the name of the class where the overridden getter is declared
+   *
    * See [INVALID_METHOD_OVERRIDE_RETURN_TYPE].
    */
   static const StaticWarningCode INVALID_GETTER_OVERRIDE_RETURN_TYPE =
@@ -3983,11 +4107,11 @@
    * <i>m1</i> overrides an instance method <i>m2</i> and the type of <i>m1</i>
    * is not a subtype of the type of <i>m2</i>.
    *
-   * @param actualParamTypeName the name of the expected parameter type
-   * @param expectedParamType the name of the actual parameter type, not
-   *        assignable to the actualParamTypeName
-   * @param className the name of the class where the overridden method is
-   *        declared
+   * Parameters:
+   * 0: the name of the actual parameter type
+   * 1: the name of the expected parameter type, not assignable to the actual
+   *    parameter type
+   * 2: the name of the class where the overridden method is declared
    */
   static const StaticWarningCode INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE =
       const StaticWarningCode('INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE',
@@ -3998,11 +4122,11 @@
    * <i>m1</i> overrides an instance method <i>m2</i> and the type of <i>m1</i>
    * is not a subtype of the type of <i>m2</i>.
    *
-   * @param actualParamTypeName the name of the expected parameter type
-   * @param expectedParamType the name of the actual parameter type, not
-   *        assignable to the actualParamTypeName
-   * @param className the name of the class where the overridden method is
-   *        declared
+   * Parameters:
+   * 0: the name of the actual parameter type
+   * 1: the name of the expected parameter type, not assignable to the actual
+   *    parameter type
+   * 2: the name of the class where the overridden method is declared
    * See [INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE].
    */
   static const StaticWarningCode INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE =
@@ -4014,11 +4138,11 @@
    * <i>m1</i> overrides an instance method <i>m2</i> and the type of <i>m1</i>
    * is not a subtype of the type of <i>m2</i>.
    *
-   * @param actualParamTypeName the name of the expected parameter type
-   * @param expectedParamType the name of the actual parameter type, not
-   *        assignable to the actualParamTypeName
-   * @param className the name of the class where the overridden method is
-   *        declared
+   * Parameters:
+   * 0: the name of the actual parameter type
+   * 1: the name of the expected parameter type, not assignable to the actual
+   *    parameter type
+   * 2: the name of the class where the overridden method is declared
    */
   static const StaticWarningCode INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE =
       const StaticWarningCode('INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE',
@@ -4029,11 +4153,12 @@
    * <i>m1</i> overrides an instance method <i>m2</i> and the type of <i>m1</i>
    * is not a subtype of the type of <i>m2</i>.
    *
-   * @param actualReturnTypeName the name of the expected return type
-   * @param expectedReturnType the name of the actual return type, not
-   *        assignable to the actualReturnTypeName
-   * @param className the name of the class where the overridden method is
-   *        declared
+   * Parameters:
+   * 0: the name of the actual return type
+   * 1: the name of the expected return type, not assignable to the actual
+   *    return type
+   * 2: the name of the class where the overridden method is declared
+   *
    * See [INVALID_GETTER_OVERRIDE_RETURN_TYPE].
    */
   static const StaticWarningCode INVALID_METHOD_OVERRIDE_RETURN_TYPE =
@@ -4068,8 +4193,9 @@
    * <i>m1</i> overrides an instance member <i>m2</i> and <i>m1</i> does not
    * declare all the named parameters declared by <i>m2</i>.
    *
-   * @param paramCount the number of named parameters in the overridden member
-   * @param className the name of the class from the overridden method
+   * Parameters:
+   * 0: the number of named parameters in the overridden member
+   * 1: the name of the class from the overridden method
    */
   static const StaticWarningCode INVALID_OVERRIDE_NAMED = const StaticWarningCode(
       'INVALID_OVERRIDE_NAMED',
@@ -4080,9 +4206,9 @@
    * <i>m1</i> overrides an instance member <i>m2</i> and <i>m1</i> has fewer
    * positional parameters than <i>m2</i>.
    *
-   * @param paramCount the number of positional parameters in the overridden
-   *        member
-   * @param className the name of the class from the overridden method
+   * Parameters:
+   * 0: the number of positional parameters in the overridden member
+   * 1: the name of the class from the overridden method
    */
   static const StaticWarningCode INVALID_OVERRIDE_POSITIONAL =
       const StaticWarningCode('INVALID_OVERRIDE_POSITIONAL',
@@ -4093,9 +4219,9 @@
    * <i>m1</i> overrides an instance member <i>m2</i> and <i>m1</i> has a
    * greater number of required parameters than <i>m2</i>.
    *
-   * @param paramCount the number of required parameters in the overridden
-   *        member
-   * @param className the name of the class from the overridden method
+   * Parameters:
+   * 0: the number of required parameters in the overridden member
+   * 1: the name of the class from the overridden method
    */
   static const StaticWarningCode INVALID_OVERRIDE_REQUIRED =
       const StaticWarningCode('INVALID_OVERRIDE_REQUIRED',
@@ -4106,11 +4232,12 @@
    * setter <i>m2</i> and the type of <i>m1</i> is not a subtype of the type of
    * <i>m2</i>.
    *
-   * @param actualParamTypeName the name of the expected parameter type
-   * @param expectedParamType the name of the actual parameter type, not
-   *        assignable to the actualParamTypeName
-   * @param className the name of the class where the overridden setter is
-   *        declared
+   * Parameters:
+   * 0: the name of the actual parameter type
+   * 1: the name of the expected parameter type, not assignable to the actual
+   * parameter type
+   * 2: the name of the class where the overridden setter is declared
+   *
    * See [INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE].
    */
   static const StaticWarningCode INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE =
@@ -4212,9 +4339,11 @@
    * 15.8 Parameterized Types: Any use of a malbounded type gives rise to a
    * static warning.
    *
-   * @param typeName the name of the type being referenced (<i>S</i>)
-   * @param parameterCount the number of type parameters that were declared
-   * @param argumentCount the number of type arguments provided
+   * Parameters:
+   * 0: the name of the type being referenced (<i>S</i>)
+   * 1: the number of type parameters that were declared
+   * 2: the number of type arguments provided
+   *
    * See [CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS], and
    * [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS].
    */
@@ -4226,7 +4355,8 @@
    * 12.11.1 New: It is a static warning if <i>T</i> is not a class accessible
    * in the current scope, optionally followed by type arguments.
    *
-   * @param name the name of the non-type element
+   * Parameters:
+   * 0: the name of the non-type element
    */
   static const StaticWarningCode NEW_WITH_NON_TYPE = const StaticWarningCode(
       'NEW_WITH_NON_TYPE', "The name '{0}' is not a class");
@@ -4278,12 +4408,12 @@
    * is declared or inherited in a concrete class unless that member overrides a
    * concrete one.
    *
-   * @param memberName the name of the first member
-   * @param memberName the name of the second member
-   * @param memberName the name of the third member
-   * @param memberName the name of the fourth member
-   * @param additionalCount the number of additional missing members that aren't
-   *        listed
+   * Parameters:
+   * 0: the name of the first member
+   * 1: the name of the second member
+   * 2: the name of the third member
+   * 3: the name of the fourth member
+   * 4: the number of additional missing members that aren't listed
    */
   static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS =
       const StaticWarningCode(
@@ -4304,10 +4434,11 @@
    * is declared or inherited in a concrete class unless that member overrides a
    * concrete one.
    *
-   * @param memberName the name of the first member
-   * @param memberName the name of the second member
-   * @param memberName the name of the third member
-   * @param memberName the name of the fourth member
+   * Parameters:
+   * 0: the name of the first member
+   * 1: the name of the second member
+   * 2: the name of the third member
+   * 3: the name of the fourth member
    */
   static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR =
       const StaticWarningCode(
@@ -4328,7 +4459,8 @@
    * is declared or inherited in a concrete class unless that member overrides a
    * concrete one.
    *
-   * @param memberName the name of the member
+   * Parameters:
+   * 0: the name of the member
    */
   static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE =
       const StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
@@ -4348,9 +4480,10 @@
    * is declared or inherited in a concrete class unless that member overrides a
    * concrete one.
    *
-   * @param memberName the name of the first member
-   * @param memberName the name of the second member
-   * @param memberName the name of the third member
+   * Parameters:
+   * 0: the name of the first member
+   * 1: the name of the second member
+   * 2: the name of the third member
    */
   static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE =
       const StaticWarningCode(
@@ -4371,8 +4504,9 @@
    * is declared or inherited in a concrete class unless that member overrides a
    * concrete one.
    *
-   * @param memberName the name of the first member
-   * @param memberName the name of the second member
+   * Parameters:
+   * 0: the name of the first member
+   * 1: the name of the second member
    */
   static const StaticWarningCode NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO =
       const StaticWarningCode('NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
@@ -4385,7 +4519,8 @@
    * <i>T</i> does not denote a type available in the lexical scope of the
    * catch clause.
    *
-   * @param name the name of the non-type element
+   * Parameters:
+   * 0: the name of the non-type element
    */
   static const StaticWarningCode NON_TYPE_IN_CATCH_CLAUSE =
       const StaticWarningCode('NON_TYPE_IN_CATCH_CLAUSE',
@@ -4419,7 +4554,8 @@
    *
    * Any use of a malformed type gives rise to a static warning.
    *
-   * @param nonTypeName the name that is not a type
+   * Parameters:
+   * 0: the name that is not a type
    */
   static const StaticWarningCode NOT_A_TYPE =
       const StaticWarningCode('NOT_A_TYPE', "{0} is not a type");
@@ -4428,8 +4564,10 @@
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt;
    * h</i> or if <i>m &gt; n</i>.
    *
-   * @param requiredCount the expected number of required arguments
-   * @param argumentCount the actual number of positional arguments given
+   * Parameters:
+   * 0: the expected number of required arguments
+   * 1: the actual number of positional arguments given
+   *
    * See [EXTRA_POSITIONAL_ARGUMENTS].
    */
   static const StaticWarningCode NOT_ENOUGH_REQUIRED_ARGUMENTS =
@@ -4441,9 +4579,9 @@
    * <i>p</i> names a library other than the current library as the library to
    * which <i>p</i> belongs.
    *
-   * @param expectedLibraryName the name of expected library name
-   * @param actualLibraryName the non-matching actual library name from the
-   *        "part of" declaration
+   * Parameters:
+   * 0: the name of expected library name
+   * 1: the non-matching actual library name from the "part of" declaration
    */
   static const StaticWarningCode PART_OF_DIFFERENT_LIBRARY =
       const StaticWarningCode('PART_OF_DIFFERENT_LIBRARY',
@@ -4453,8 +4591,9 @@
    * 7.6.2 Factories: It is a static warning if the function type of <i>k'</i>
    * is not a subtype of the type of <i>k</i>.
    *
-   * @param redirectedName the name of the redirected constructor
-   * @param redirectingName the name of the redirecting constructor
+   * Parameters:
+   * 0: the name of the redirected constructor
+   * 1: the name of the redirecting constructor
    */
   static const StaticWarningCode REDIRECT_TO_INVALID_FUNCTION_TYPE =
       const StaticWarningCode('REDIRECT_TO_INVALID_FUNCTION_TYPE',
@@ -4464,8 +4603,9 @@
    * 7.6.2 Factories: It is a static warning if the function type of <i>k'</i>
    * is not a subtype of the type of <i>k</i>.
    *
-   * @param redirectedName the name of the redirected constructor return type
-   * @param redirectingName the name of the redirecting constructor return type
+   * Parameters:
+   * 0: the name of the redirected constructor return type
+   * 1: the name of the redirecting constructor return type
    */
   static const StaticWarningCode REDIRECT_TO_INVALID_RETURN_TYPE =
       const StaticWarningCode('REDIRECT_TO_INVALID_RETURN_TYPE',
@@ -4505,7 +4645,8 @@
    * 12.16.3 Static Invocation: It is a static warning if <i>C</i> does not
    * declare a static method or getter <i>m</i>.
    *
-   * @param memberName the name of the instance member
+   * Parameters:
+   * 0: the name of the instance member
    */
   static const StaticWarningCode STATIC_ACCESS_TO_INSTANCE_MEMBER =
       const StaticWarningCode('STATIC_ACCESS_TO_INSTANCE_MEMBER',
@@ -4523,8 +4664,9 @@
    * 15.1 Static Types: It is a static warning to use a deferred type in a type
    * annotation.
    *
-   * @param name the name of the type that is deferred and being used in a type
-   *        annotation
+   * Parameters:
+   * 0: the name of the type that is deferred and being used in a type
+   *    annotation
    */
   static const StaticWarningCode TYPE_ANNOTATION_DEFERRED_CLASS =
       const StaticWarningCode('TYPE_ANNOTATION_DEFERRED_CLASS',
@@ -4564,7 +4706,8 @@
    * a<sub>n+1</sub>, &hellip; x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. It is a
    * static warning if <i>C</i> does not denote a class in the current scope.
    *
-   * @param undefinedClassName the name of the undefined class
+   * Parameters:
+   * 0: the name of the undefined class
    */
   static const StaticWarningCode UNDEFINED_CLASS =
       const StaticWarningCode('UNDEFINED_CLASS', "Undefined class '{0}'");
@@ -4581,9 +4724,9 @@
    * <i>C</i> in the enclosing lexical scope of <i>i</i>, or if <i>C</i> does
    * not declare, implicitly or explicitly, a getter named <i>m</i>.
    *
-   * @param getterName the name of the getter
-   * @param enclosingType the name of the enclosing type where the getter is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the getter
+   * 1: the name of the enclosing type where the getter is being looked for
    */
   static const StaticWarningCode UNDEFINED_GETTER = const StaticWarningCode(
       'UNDEFINED_GETTER',
@@ -4596,7 +4739,8 @@
    * initializer and there is no declaration <i>d</i> with name <i>id</i> in the
    * lexical scope enclosing the expression.
    *
-   * @param name the name of the identifier
+   * Parameters:
+   * 0: the name of the identifier
    */
   static const StaticWarningCode UNDEFINED_IDENTIFIER =
       const StaticWarningCode('UNDEFINED_IDENTIFIER', "Undefined name '{0}'");
@@ -4607,7 +4751,8 @@
    * {<i>p<sub>n+1</sub></i> &hellip; <i>p<sub>n+k</sub></i>} or a static
    * warning occurs.
    *
-   * @param name the name of the requested named parameter
+   * Parameters:
+   * 0: the name of the requested named parameter
    */
   static const StaticWarningCode UNDEFINED_NAMED_PARAMETER =
       const StaticWarningCode('UNDEFINED_NAMED_PARAMETER',
@@ -4624,9 +4769,9 @@
    * the enclosing lexical scope of the assignment, or if <i>C</i> does not
    * declare, implicitly or explicitly, a setter <i>v=</i>.
    *
-   * @param setterName the name of the getter
-   * @param enclosingType the name of the enclosing type where the setter is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the getter
+   * 1: the name of the enclosing type where the setter is being looked for
    */
   static const StaticWarningCode UNDEFINED_SETTER = const StaticWarningCode(
       'UNDEFINED_SETTER',
@@ -4636,9 +4781,9 @@
    * 12.16.3 Static Invocation: It is a static warning if <i>C</i> does not
    * declare a static method or getter <i>m</i>.
    *
-   * @param methodName the name of the method
-   * @param enclosingType the name of the enclosing type where the method is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the method
+   * 1: the name of the enclosing type where the method is being looked for
    */
   static const StaticWarningCode UNDEFINED_STATIC_METHOD_OR_GETTER =
       const StaticWarningCode('UNDEFINED_STATIC_METHOD_OR_GETTER',
@@ -4649,9 +4794,9 @@
    * <i>C</i> in the enclosing lexical scope of <i>i</i>, or if <i>C</i> does
    * not declare, implicitly or explicitly, a getter named <i>m</i>.
    *
-   * @param getterName the name of the getter
-   * @param enclosingType the name of the enclosing type where the getter is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the getter
+   * 1: the name of the enclosing type where the getter is being looked for
    */
   static const StaticWarningCode UNDEFINED_SUPER_GETTER =
       const StaticWarningCode('UNDEFINED_SUPER_GETTER',
@@ -4668,9 +4813,9 @@
    * the enclosing lexical scope of the assignment, or if <i>C</i> does not
    * declare, implicitly or explicitly, a setter <i>v=</i>.
    *
-   * @param setterName the name of the getter
-   * @param enclosingType the name of the enclosing type where the setter is
-   *        being looked for
+   * Parameters:
+   * 0: the name of the getter
+   * 1: the name of the enclosing type where the setter is being looked for
    */
   static const StaticWarningCode UNDEFINED_SUPER_SETTER =
       const StaticWarningCode('UNDEFINED_SUPER_SETTER',
@@ -4700,7 +4845,8 @@
 }
 
 /**
- * The class `TodoCode` defines the single TODO error code.
+ * The error code indicating a marker in code for work that needs to be finished
+ * or revisited.
  */
 class TodoCode extends ErrorCode {
   /**
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index f0f7053..74c14ae 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -22,14 +22,14 @@
 import 'utilities_dart.dart';
 
 /**
- * Instances of the class `ErrorVerifier` traverse an AST structure looking for additional
- * errors and warnings not covered by the parser and resolver.
+ * A visitor used to traverse an AST structure looking for additional errors and
+ * warnings not covered by the parser and resolver.
  */
 class ErrorVerifier extends RecursiveAstVisitor<Object> {
   /**
    * Static final string with value `"getter "` used in the construction of the
-   * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and similar, error
-   * code messages.
+   * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and
+   * similar, error code messages.
    *
    * See [_checkForNonAbstractClassInheritsAbstractMember].
    */
@@ -37,8 +37,8 @@
 
   /**
    * Static final string with value `"setter "` used in the construction of the
-   * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and similar, error
-   * code messages.
+   * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], and
+   * similar, error code messages.
    *
    * See [_checkForNonAbstractClassInheritsAbstractMember].
    */
@@ -75,158 +75,164 @@
   final InheritanceManager _inheritanceManager;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting children nodes of a
-   * [ConstructorDeclaration] and the constructor is 'const'.
+   * A flag indicating whether the visitor is currently within a constructor
+   * declaration that is 'const'.
    *
    * See [visitConstructorDeclaration].
    */
   bool _isEnclosingConstructorConst = false;
 
   /**
-   * A flag indicating whether we are currently within a function body marked as being asynchronous.
+   * A flag indicating whether we are currently within a function body marked as
+   * being asynchronous.
    */
   bool _inAsync = false;
 
   /**
-   * A flag indicating whether we are currently within a function body marked as being a generator.
+   * A flag indicating whether we are currently within a function body marked a
+   *  being a generator.
    */
   bool _inGenerator = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting children nodes of a
-   * [CatchClause].
+   * A flag indicating whether the visitor is currently within a catch clause.
    *
    * See [visitCatchClause].
    */
   bool _isInCatchClause = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting children nodes of an
-   * [Comment].
+   * A flag indicating whether the visitor is currently within a comment.
    */
   bool _isInComment = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting children nodes of an
-   * [InstanceCreationExpression].
+   * A flag indicating whether the visitor is currently within an instance
+   * creation expression.
    */
   bool _isInConstInstanceCreation = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting children nodes of a native
-   * [ClassDeclaration].
+   * A flag indicating whether the visitor is currently within a native class
+   * declaration.
    */
   bool _isInNativeClass = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting a static variable
+   * A flag indicating whether the visitor is currently within a static variable
    * declaration.
    */
   bool _isInStaticVariableDeclaration = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting an instance variable
-   * declaration.
+   * A flag indicating whether the visitor is currently within an instance
+   * variable declaration.
    */
   bool _isInInstanceVariableDeclaration = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting an instance variable
-   * initializer.
+   * A flag indicating whether the visitor is currently within an instance
+   * variable initializer.
    */
   bool _isInInstanceVariableInitializer = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting a
-   * [ConstructorInitializer].
+   * A flag indicating whether the visitor is currently within a constructor
+   * initializer.
    */
   bool _isInConstructorInitializer = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting a
-   * [FunctionTypedFormalParameter].
+   * This is set to `true` iff the visitor is currently within a function typed
+   * formal parameter.
    */
   bool _isInFunctionTypedFormalParameter = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting a static method. By "method"
-   * here getter, setter and operator declarations are also implied since they are all represented
-   * with a [MethodDeclaration] in the AST structure.
+   * A flag indicating whether the visitor is currently within a static method.
+   * By "method" here getter, setter and operator declarations are also implied
+   * since they are all represented with a [MethodDeclaration] in the AST
+   * structure.
    */
   bool _isInStaticMethod = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting a factory constructor.
+   * A flag indicating whether the visitor is currently within a factory
+   * constructor.
    */
   bool _isInFactory = false;
 
   /**
-   * This is set to `true` iff the visitor is currently visiting code in the SDK.
+   * A flag indicating whether the visitor is currently within code in the SDK.
    */
   bool _isInSystemLibrary = false;
 
   /**
-   * A flag indicating whether the current library contains at least one import directive with a URI
-   * that uses the "dart-ext" scheme.
+   * A flag indicating whether the current library contains at least one import
+   * directive with a URI that uses the "dart-ext" scheme.
    */
   bool _hasExtUri = false;
 
   /**
-   * This is set to `false` on the entry of every [BlockFunctionBody], and is restored
-   * to the enclosing value on exit. The value is used in
-   * [checkForMixedReturns] to prevent both
-   * [StaticWarningCode.MIXED_RETURN_TYPES] and [StaticWarningCode.RETURN_WITHOUT_VALUE]
-   * from being generated in the same function body.
+   * This is set to `false` on the entry of every [BlockFunctionBody], and is
+   * restored to the enclosing value on exit. The value is used in
+   * [_checkForMixedReturns] to prevent both
+   * [StaticWarningCode.MIXED_RETURN_TYPES] and
+   * [StaticWarningCode.RETURN_WITHOUT_VALUE] from being generated in the same
+   * function body.
    */
   bool _hasReturnWithoutValue = false;
 
   /**
-   * The class containing the AST nodes being visited, or `null` if we are not in the scope of
-   * a class.
+   * The class containing the AST nodes being visited, or `null` if we are not
+   * in the scope of a class.
    */
   ClassElement _enclosingClass;
 
   /**
-   * The method or function that we are currently visiting, or `null` if we are not inside a
-   * method or function.
+   * The method or function that we are currently visiting, or `null` if we are
+   * not inside a method or function.
    */
   ExecutableElement _enclosingFunction;
 
   /**
-   * The return statements found in the method or function that we are currently visiting that have
-   * a return value.
+   * The return statements found in the method or function that we are currently
+   * visiting that have a return value.
    */
   List<ReturnStatement> _returnsWith = new List<ReturnStatement>();
 
   /**
-   * The return statements found in the method or function that we are currently visiting that do
-   * not have a return value.
+   * The return statements found in the method or function that we are currently
+   * visiting that do not have a return value.
    */
   List<ReturnStatement> _returnsWithout = new List<ReturnStatement>();
 
   /**
-   * This map is initialized when visiting the contents of a class declaration. If the visitor is
-   * not in an enclosing class declaration, then the map is set to `null`.
+   * This map is initialized when visiting the contents of a class declaration.
+   * If the visitor is not in an enclosing class declaration, then the map is
+   * set to `null`.
    *
    * When set the map maps the set of [FieldElement]s in the class to an
-   * [INIT_STATE.NOT_INIT] or [INIT_STATE.INIT_IN_DECLARATION]. <code>checkFor*</code>
-   * methods, specifically [checkForAllFinalInitializedErrorCodes],
-   * can make a copy of the map to compute error code states. <code>checkFor*</code> methods should
-   * only ever make a copy, or read from this map after it has been set in
-   * [visitClassDeclaration].
+   * [INIT_STATE.NOT_INIT] or [INIT_STATE.INIT_IN_DECLARATION]. The `checkFor*`
+   * methods, specifically [_checkForAllFinalInitializedErrorCodes], can make a
+   * copy of the map to compute error code states. The `checkFor*` methods
+   * should only ever make a copy, or read from this map after it has been set
+   * in [visitClassDeclaration].
    *
    * See [visitClassDeclaration], and [_checkForAllFinalInitializedErrorCodes].
    */
   HashMap<FieldElement, INIT_STATE> _initialFieldElementsMap;
 
   /**
-   * A table mapping name of the library to the export directive which export this library.
+   * A table mapping name of the library to the export directive which export
+   * this library.
    */
   HashMap<String, LibraryElement> _nameToExportElement =
       new HashMap<String, LibraryElement>();
 
   /**
-   * A table mapping name of the library to the import directive which import this library.
+   * A table mapping name of the library to the import directive which import
+   * this library.
    */
   HashMap<String, LibraryElement> _nameToImportElement =
       new HashMap<String, LibraryElement>();
@@ -243,13 +249,13 @@
       new HashSet<String>();
 
   /**
-   * A list of types used by the [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS] and
-   * [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS] error codes.
+   * A list of types used by the [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]
+   * and [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS] error codes.
    */
   List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT;
 
   /**
-   * Initialize the [ErrorVerifier] visitor.
+   * Initialize a newly created error verifier.
    */
   ErrorVerifier(this._errorReporter, this._currentLibrary, this._typeProvider,
       this._inheritanceManager) {
@@ -440,7 +446,7 @@
    * Implementation of this method should be synchronized with
    * [visitClassDeclaration].
    */
-  visitClassDeclarationIncrementally(ClassDeclaration node) {
+  void visitClassDeclarationIncrementally(ClassDeclaration node) {
     _isInNativeClass = node.nativeClause != null;
     _enclosingClass = node.element;
     // initialize initialFieldElementsMap
@@ -1091,10 +1097,9 @@
   }
 
   /**
-   * This verifies if the passed map literal has type arguments then there is exactly two.
+   * Verify that the given list of [typeArguments] contains exactly two
+   * elements.
    *
-   * @param typeArguments the type arguments, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS].
    */
   bool _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) {
@@ -1105,26 +1110,25 @@
     }
     // report problem
     _errorReporter.reportErrorForNode(
-        StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArguments, [
-      num
-    ]);
+        StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArguments,
+        [num]);
     return true;
   }
 
   /**
-   * This verifies that the passed constructor declaration does not violate any of the error codes
-   * relating to the initialization of fields in the enclosing class.
+   * Verify that the given [constructor] declaration does not violate any of the
+   * error codes relating to the initialization of fields in the enclosing
+   * class.
    *
-   * @param node the [ConstructorDeclaration] to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [_initialFieldElementsMap],
-   * [StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR],
-   * and [CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES].
+   * [StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR], and
+   * [CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES].
    */
-  bool _checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) {
-    if (node.factoryKeyword != null ||
-        node.redirectedConstructor != null ||
-        node.externalKeyword != null) {
+  bool _checkForAllFinalInitializedErrorCodes(
+      ConstructorDeclaration constructor) {
+    if (constructor.factoryKeyword != null ||
+        constructor.redirectedConstructor != null ||
+        constructor.externalKeyword != null) {
       return false;
     }
     // Ignore if native class.
@@ -1135,7 +1139,8 @@
     HashMap<FieldElement, INIT_STATE> fieldElementsMap =
         new HashMap<FieldElement, INIT_STATE>.from(_initialFieldElementsMap);
     // Visit all of the field formal parameters
-    NodeList<FormalParameter> formalParameters = node.parameters.parameters;
+    NodeList<FormalParameter> formalParameters =
+        constructor.parameters.parameters;
     for (FormalParameter formalParameter in formalParameters) {
       FormalParameter parameter = formalParameter;
       if (parameter is DefaultFormalParameter) {
@@ -1165,7 +1170,7 @@
       }
     }
     // Visit all of the initializers
-    NodeList<ConstructorInitializer> initializers = node.initializers;
+    NodeList<ConstructorInitializer> initializers = constructor.initializers;
     for (ConstructorInitializer constructorInitializer in initializers) {
       if (constructorInitializer is RedirectingConstructorInvocation) {
         return false;
@@ -1201,36 +1206,63 @@
         }
       }
     }
+    // Prepare a list of not initialized fields.
+    List<FieldElement> notInitFinalFields = <FieldElement>[];
+    fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) {
+      if (state == INIT_STATE.NOT_INIT) {
+        if (fieldElement.isFinal) {
+          notInitFinalFields.add(fieldElement);
+        }
+      }
+    });
     // Visit all of the states in the map to ensure that none were never
     // initialized.
     fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) {
       if (state == INIT_STATE.NOT_INIT) {
         if (fieldElement.isConst) {
           _errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.CONST_NOT_INITIALIZED, node.returnType, [
-            fieldElement.name
-          ]);
-          foundError = true;
-        } else if (fieldElement.isFinal) {
-          _errorReporter.reportErrorForNode(
-              StaticWarningCode.FINAL_NOT_INITIALIZED, node.returnType, [
-            fieldElement.name
-          ]);
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED,
+              constructor.returnType, [fieldElement.name]);
           foundError = true;
         }
       }
     });
+    if (notInitFinalFields.isNotEmpty) {
+      foundError = true;
+      AnalysisErrorWithProperties analysisError;
+      if (notInitFinalFields.length == 1) {
+        analysisError = _errorReporter.newErrorWithProperties(
+            StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1,
+            constructor.returnType, [notInitFinalFields[0].name]);
+      } else if (notInitFinalFields.length == 2) {
+        analysisError = _errorReporter.newErrorWithProperties(
+            StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2,
+            constructor.returnType, [
+          notInitFinalFields[0].name,
+          notInitFinalFields[1].name
+        ]);
+      } else {
+        analysisError = _errorReporter.newErrorWithProperties(
+            StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS,
+            constructor.returnType, [
+          notInitFinalFields[0].name,
+          notInitFinalFields[1].name,
+          notInitFinalFields.length - 2
+        ]);
+      }
+      analysisError.setProperty(
+          ErrorProperty.NOT_INITIALIZED_FIELDS, notInitFinalFields);
+      _errorReporter.reportError(analysisError);
+    }
     return foundError;
   }
 
   /**
-   * This checks the passed executable element against override-error codes.
+   * Check the given [executableElement] against override-error codes. The
+   * [overriddenExecutable] is the element that the executable element is
+   * overriding. The [parameters] is the parameters of the executable element.
+   * The [errorNameTarget] is the node to report problems on.
    *
-   * @param executableElement a non-null [ExecutableElement] to evaluate
-   * @param overriddenExecutable the element that the executableElement is overriding
-   * @param parameters the parameters of the executable element
-   * @param errorNameTarget the node to report problems on
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC],
    * [CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED],
    * [CompileTimeErrorCode.INVALID_OVERRIDE_POSITIONAL],
@@ -1389,9 +1421,9 @@
     }
     // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES
     //
-    // Create three arrays: an array of the optional parameter ASTs
-    // (FormalParameters), an array of the optional parameters elements from our
-    // method, and finally an array of the optional parameter elements from the
+    // Create three lists: a list of the optional parameter ASTs
+    // (FormalParameters), a list of the optional parameters elements from our
+    // method, and finally a list of the optional parameter elements from the
     // method we are overriding.
     //
     bool foundError = false;
@@ -1499,16 +1531,13 @@
   }
 
   /**
-   * This checks the passed executable element against override-error codes. This method computes
-   * the passed executableElement is overriding and calls
-   * [checkForAllInvalidOverrideErrorCodes]
-   * when the [InheritanceManager] returns a [MultiplyInheritedExecutableElement], this
-   * method loops through the array in the [MultiplyInheritedExecutableElement].
-   *
-   * @param executableElement a non-null [ExecutableElement] to evaluate
-   * @param parameters the parameters of the executable element
-   * @param errorNameTarget the node to report problems on
-   * @return `true` if and only if an error code is generated on the passed node
+   * Check the given [executableElement] against override-error codes. This
+   * method computes the given executableElement is overriding and calls
+   * [_checkForAllInvalidOverrideErrorCodes] when the [InheritanceManager]
+   * returns a [MultiplyInheritedExecutableElement], this method loops through
+   * the list in the [MultiplyInheritedExecutableElement]. The [parameters] are
+   * the parameters of the executable element. The [errorNameTarget] is the node
+   * to report problems on.
    */
   bool _checkForAllInvalidOverrideErrorCodesForExecutable(
       ExecutableElement executableElement, List<ParameterElement> parameters,
@@ -1532,18 +1561,17 @@
   }
 
   /**
-   * This checks the passed field declaration against override-error codes.
+   * Check the given field [declaration] against override-error codes.
    *
-   * @param node the [MethodDeclaration] to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [_checkForAllInvalidOverrideErrorCodes].
    */
-  bool _checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) {
-    if (_enclosingClass == null || node.isStatic) {
+  bool _checkForAllInvalidOverrideErrorCodesForField(
+      FieldDeclaration declaration) {
+    if (_enclosingClass == null || declaration.isStatic) {
       return false;
     }
     bool hasProblems = false;
-    VariableDeclarationList fields = node.fields;
+    VariableDeclarationList fields = declaration.fields;
     for (VariableDeclaration field in fields.variables) {
       FieldElement element = field.element as FieldElement;
       if (element == null) {
@@ -1569,27 +1597,26 @@
   }
 
   /**
-   * This checks the passed method declaration against override-error codes.
+   * Check the given [method] declaration against override-error codes.
    *
-   * @param node the [MethodDeclaration] to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [_checkForAllInvalidOverrideErrorCodes].
    */
-  bool _checkForAllInvalidOverrideErrorCodesForMethod(MethodDeclaration node) {
+  bool _checkForAllInvalidOverrideErrorCodesForMethod(
+      MethodDeclaration method) {
     if (_enclosingClass == null ||
-        node.isStatic ||
-        node.body is NativeFunctionBody) {
+        method.isStatic ||
+        method.body is NativeFunctionBody) {
       return false;
     }
-    ExecutableElement executableElement = node.element;
+    ExecutableElement executableElement = method.element;
     if (executableElement == null) {
       return false;
     }
-    SimpleIdentifier methodName = node.name;
+    SimpleIdentifier methodName = method.name;
     if (methodName.isSynthetic) {
       return false;
     }
-    FormalParameterList formalParameterList = node.parameters;
+    FormalParameterList formalParameterList = method.parameters;
     NodeList<FormalParameter> parameterList =
         formalParameterList != null ? formalParameterList.parameters : null;
     List<AstNode> parameters =
@@ -1599,10 +1626,8 @@
   }
 
   /**
-   * This verifies that all classes of the passed 'with' clause are valid.
+   * Verify that all classes of the given [withClause] are valid.
    *
-   * @param node the 'with' clause to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR],
    * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT], and
    * [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER].
@@ -1641,19 +1666,18 @@
   }
 
   /**
-   * This checks error related to the redirected constructors.
+   * Check for errors related to the redirected constructors.
    *
-   * @param node the constructor declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE],
    * [StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE], and
    * [StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR].
    */
-  bool _checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) {
+  bool _checkForAllRedirectConstructorErrorCodes(
+      ConstructorDeclaration declaration) {
     //
     // Prepare redirected constructor node
     //
-    ConstructorName redirectedConstructor = node.redirectedConstructor;
+    ConstructorName redirectedConstructor = declaration.redirectedConstructor;
     if (redirectedConstructor == null) {
       return false;
     }
@@ -1678,11 +1702,13 @@
         if (redirectedConstructor.name != null) {
           constructorStrName += ".${redirectedConstructor.name.name}";
         }
-        ErrorCode errorCode = (node.constKeyword != null
+        ErrorCode errorCode = (declaration.constKeyword != null
             ? CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR
             : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR);
-        _errorReporter.reportErrorForNode(errorCode, redirectedConstructor,
-            [constructorStrName, redirectedType.displayName]);
+        _errorReporter.reportErrorForNode(errorCode, redirectedConstructor, [
+          constructorStrName,
+          redirectedType.displayName
+        ]);
         return true;
       }
       return false;
@@ -1692,7 +1718,7 @@
     //
     // Report specific problem when return type is incompatible
     //
-    FunctionType constructorType = node.element.type;
+    FunctionType constructorType = declaration.element.type;
     DartType constructorReturnType = constructorType.returnType;
     if (!redirectedReturnType.isAssignableTo(constructorReturnType)) {
       _errorReporter.reportErrorForNode(
@@ -1713,29 +1739,27 @@
   }
 
   /**
-   * This checks that the return statement of the form <i>return e;</i> is not in a generative
-   * constructor.
+   * Check that the return [statement] of the form <i>return e;</i> is not in a
+   * generative constructor.
    *
-   * This checks that return statements without expressions are not in a generative constructor and
-   * the return type is not assignable to `null`; that is, we don't have `return;` if
-   * the enclosing method has a return type.
+   * Check that return statements without expressions are not in a generative
+   * constructor and the return type is not assignable to `null`; that is, we
+   * don't have `return;` if the enclosing method has a return type.
    *
-   * This checks that the return type matches the type of the declared return type in the enclosing
-   * method or function.
+   * Check that the return type matches the type of the declared return type in
+   * the enclosing method or function.
    *
-   * @param node the return statement to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR],
    * [StaticWarningCode.RETURN_WITHOUT_VALUE], and
    * [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE].
    */
-  bool _checkForAllReturnStatementErrorCodes(ReturnStatement node) {
+  bool _checkForAllReturnStatementErrorCodes(ReturnStatement statement) {
     FunctionType functionType =
         _enclosingFunction == null ? null : _enclosingFunction.type;
     DartType expectedReturnType = functionType == null
         ? DynamicTypeImpl.instance
         : functionType.returnType;
-    Expression returnExpression = node.expression;
+    Expression returnExpression = statement.expression;
     // RETURN_IN_GENERATIVE_CONSTRUCTOR
     bool isGenerativeConstructor = _enclosingFunction is ConstructorElement &&
         !(_enclosingFunction as ConstructorElement).isFactory;
@@ -1756,30 +1780,28 @@
         return false;
       }
       _hasReturnWithoutValue = true;
-      _errorReporter
-          .reportErrorForNode(StaticWarningCode.RETURN_WITHOUT_VALUE, node);
+      _errorReporter.reportErrorForNode(
+          StaticWarningCode.RETURN_WITHOUT_VALUE, statement);
       return true;
     } else if (_inGenerator) {
       // RETURN_IN_GENERATOR
-      _errorReporter
-          .reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATOR, node);
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.RETURN_IN_GENERATOR, statement);
     }
     // RETURN_OF_INVALID_TYPE
     return _checkForReturnOfInvalidType(returnExpression, expectedReturnType);
   }
 
   /**
-   * This verifies that the export namespace of the passed export directive does not export any name
-   * already exported by other export directive.
+   * Verify that the export namespace of the given export [directive] does not
+   * export any name already exported by another export directive. The
+   * [exportElement] is the [ExportElement] retrieved from the node. If the
+   * element in the node was `null`, then this method is not called. The
+   * [exportedLibrary] is the library element containing the exported element.
    *
-   * @param node the export directive node to report problem on
-   * @param exportElement the [ExportElement] retrieved from the node, if the element in the
-   *          node was `null`, then this method is not called
-   * @param exportedLibrary the library element containing the exported element
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.AMBIGUOUS_EXPORT].
    */
-  bool _checkForAmbiguousExport(ExportDirective node,
+  bool _checkForAmbiguousExport(ExportDirective directive,
       ExportElement exportElement, LibraryElement exportedLibrary) {
     if (exportedLibrary == null) {
       return false;
@@ -1793,7 +1815,7 @@
       Element prevElement = _exportedElements[name];
       if (element != null && prevElement != null && prevElement != element) {
         _errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_EXPORT,
-            node, [
+            directive, [
           name,
           prevElement.library.definingCompilationUnit.displayName,
           element.library.definingCompilationUnit.displayName
@@ -1807,17 +1829,14 @@
   }
 
   /**
-   * This verifies that the passed expression can be assigned to its corresponding parameters.
+   * Verify that the given [expression] can be assigned to its corresponding
+   * parameters. The [expectedStaticType] is the expected static type of the
+   * parameter. The [actualStaticType] is the actual static type of the
+   * argument.
    *
-   * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAssignable.
+   * This method corresponds to
+   * [BestPracticesVerifier.checkForArgumentTypeNotAssignable].
    *
-   * @param expression the expression to evaluate
-   * @param expectedStaticType the expected static type of the parameter
-   * @param actualStaticType the actual static type of the argument
-   * @param expectedPropagatedType the expected propagated type of the parameter, may be
-   *          `null`
-   * @param actualPropagatedType the expected propagated type of the parameter, may be `null`
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE],
    * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
    * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
@@ -1843,12 +1862,12 @@
   }
 
   /**
-   * This verifies that the passed argument can be assigned to its corresponding parameter.
+   * Verify that the given [argument] can be assigned to its corresponding
+   * parameter.
    *
-   * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument.
+   * This method corresponds to
+   * [BestPracticesVerifier.checkForArgumentTypeNotAssignableForArgument].
    *
-   * @param argument the argument to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
    */
   bool _checkForArgumentTypeNotAssignableForArgument(Expression argument) {
@@ -1863,15 +1882,12 @@
   }
 
   /**
-   * This verifies that the passed expression can be assigned to its corresponding parameters.
+   * Verify that the given [expression] can be assigned to its corresponding
+   * parameters. The [expectedStaticType] is the expected static type.
    *
    * This method corresponds to
-   * BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes.
+   * [BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes].
    *
-   * @param expression the expression to evaluate
-   * @param expectedStaticType the expected static type
-   * @param expectedPropagatedType the expected propagated type, may be `null`
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE],
    * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
    * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE],
@@ -1886,12 +1902,12 @@
           expression, expectedStaticType, getStaticType(expression), errorCode);
 
   /**
-   * This verifies that the passed arguments can be assigned to their corresponding parameters.
+   * Verify that the arguments in the given [argumentList] can be assigned to
+   * their corresponding parameters.
    *
-   * This method corresponds to BestPracticesVerifier.checkForArgumentTypesNotAssignableInList.
+   * This method corresponds to
+   * [BestPracticesVerifier.checkForArgumentTypesNotAssignableInList].
    *
-   * @param node the arguments to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
    */
   bool _checkForArgumentTypesNotAssignableInList(ArgumentList argumentList) {
@@ -1908,14 +1924,11 @@
   }
 
   /**
-   * Check that the static type of the given expression is assignable to the given type. If it
-   * isn't, report an error with the given error code.
-   *
-   * @param expression the expression being tested
-   * @param type the type that the expression must be assignable to
-   * @param errorCode the error code to be reported
-   * @param arguments the arguments to pass in when creating the error
-   * @return `true` if an error was reported
+   * Check that the static type of the given expression is assignable to the
+   * given type. If it isn't, report an error with the given error code. The
+   * [type] is the type that the expression must be assignable to. The
+   * [errorCode] is the error code to be reported. The [arguments] are the
+   * arguments to pass in when creating the error.
    */
   bool _checkForAssignability(Expression expression, InterfaceType type,
       ErrorCode errorCode, List<Object> arguments) {
@@ -1934,10 +1947,8 @@
   }
 
   /**
-   * This verifies that the passed expression is not final.
+   * Verify that the given [expression] is not final.
    *
-   * @param node the expression to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.ASSIGNMENT_TO_CONST],
    * [StaticWarningCode.ASSIGNMENT_TO_FINAL], and
    * [StaticWarningCode.ASSIGNMENT_TO_METHOD].
@@ -1962,23 +1973,22 @@
       element = accessor.variable;
     }
     if (element is VariableElement) {
-      VariableElement variable = element as VariableElement;
-      if (variable.isConst) {
+      if (element.isConst) {
         _errorReporter.reportErrorForNode(
             StaticWarningCode.ASSIGNMENT_TO_CONST, expression);
         return true;
       }
-      if (variable.isFinal) {
-        if (variable is FieldElementImpl &&
-            variable.setter == null &&
-            variable.isSynthetic) {
+      if (element.isFinal) {
+        if (element is FieldElementImpl &&
+            element.setter == null &&
+            element.isSynthetic) {
           _errorReporter.reportErrorForNode(
               StaticWarningCode.ASSIGNMENT_TO_FINAL_NO_SETTER, highlightedNode,
-              [variable.name, variable.enclosingElement.displayName]);
+              [element.name, element.enclosingElement.displayName]);
           return true;
         }
         _errorReporter.reportErrorForNode(StaticWarningCode.ASSIGNMENT_TO_FINAL,
-            highlightedNode, [variable.name]);
+            highlightedNode, [element.name]);
         return true;
       }
       return false;
@@ -1997,16 +2007,9 @@
   }
 
   /**
-   * This verifies that the passed identifier is not a keyword, and generates the passed error code
-   * on the identifier if it is a keyword.
+   * Verify that the given [identifier] is not a keyword, and generates the
+   * given [errorCode] on the identifier if it is a keyword.
    *
-   * @param identifier the identifier to check to ensure that it is not a keyword
-   * @param errorCode if the passed identifier is a keyword then this error code is created on the
-   *          identifier, the error code will be one of
-   *          [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME],
-   *          [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME] or
-   *          [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME]
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME],
    * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME], and
    * [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME].
@@ -2023,22 +2026,20 @@
   }
 
   /**
-   * This verifies that the given switch case is terminated with 'break', 'continue', 'return' or
-   * 'throw'.
+   * Verify that the given [switchCase] is terminated with 'break', 'continue',
+   * 'return' or 'throw'.
    *
-   * @param node the switch case to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * see [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED].
    */
-  bool _checkForCaseBlockNotTerminated(SwitchCase node) {
-    NodeList<Statement> statements = node.statements;
+  bool _checkForCaseBlockNotTerminated(SwitchCase switchCase) {
+    NodeList<Statement> statements = switchCase.statements;
     if (statements.isEmpty) {
       // fall-through without statements at all
-      AstNode parent = node.parent;
+      AstNode parent = switchCase.parent;
       if (parent is SwitchStatement) {
         SwitchStatement switchStatement = parent;
         NodeList<SwitchMember> members = switchStatement.members;
-        int index = members.indexOf(node);
+        int index = members.indexOf(switchCase);
         if (index != -1 && index < members.length - 1) {
           return false;
         }
@@ -2062,21 +2063,19 @@
     }
     // report error
     _errorReporter.reportErrorForToken(
-        StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, node.keyword);
+        StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, switchCase.keyword);
     return true;
   }
 
   /**
-   * This verifies that the switch cases in the given switch statement is terminated with 'break',
-   * 'continue', 'return' or 'throw'.
+   * Verify that the switch cases in the given switch [statement] are terminated
+   * with 'break', 'continue', 'return' or 'throw'.
    *
-   * @param node the switch statement containing the cases to be checked
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED].
    */
-  bool _checkForCaseBlocksNotTerminated(SwitchStatement node) {
+  bool _checkForCaseBlocksNotTerminated(SwitchStatement statement) {
     bool foundError = false;
-    NodeList<SwitchMember> members = node.members;
+    NodeList<SwitchMember> members = statement.members;
     int lastMember = members.length - 1;
     for (int i = 0; i < lastMember; i++) {
       SwitchMember member = members[i];
@@ -2088,24 +2087,22 @@
   }
 
   /**
-   * This verifies that the passed method declaration is abstract only if the enclosing class is
-   * also abstract.
+   * Verify that the given [method] declaration is abstract only if the
+   * enclosing class is also abstract.
    *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER].
    */
-  bool _checkForConcreteClassWithAbstractMember(MethodDeclaration node) {
-    if (node.isAbstract &&
+  bool _checkForConcreteClassWithAbstractMember(MethodDeclaration method) {
+    if (method.isAbstract &&
         _enclosingClass != null &&
         !_enclosingClass.isAbstract) {
-      SimpleIdentifier nameNode = node.name;
+      SimpleIdentifier nameNode = method.name;
       String memberName = nameNode.name;
       ExecutableElement overriddenMember;
-      if (node.isGetter) {
+      if (method.isGetter) {
         overriddenMember = _enclosingClass.lookUpInheritedConcreteGetter(
             memberName, _currentLibrary);
-      } else if (node.isSetter) {
+      } else if (method.isSetter) {
         overriddenMember = _enclosingClass.lookUpInheritedConcreteSetter(
             memberName, _currentLibrary);
       } else {
@@ -2125,20 +2122,19 @@
   }
 
   /**
-   * This verifies all possible conflicts of the constructor name with other constructors and
-   * members of the same class.
+   * Verify all possible conflicts of the given [constructor]'s name with other
+   * constructors and members of the same class. The [constructorElement] is the
+   * constructor's element.
    *
-   * @param node the constructor declaration to evaluate
-   * @param constructorElement the constructor element
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT],
    * [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME],
    * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD], and
    * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD].
    */
   bool _checkForConflictingConstructorNameAndMember(
-      ConstructorDeclaration node, ConstructorElement constructorElement) {
-    SimpleIdentifier constructorName = node.name;
+      ConstructorDeclaration constructor,
+      ConstructorElement constructorElement) {
+    SimpleIdentifier constructorName = constructor.name;
     String name = constructorElement.name;
     ClassElement classElement = constructorElement.enclosingElement;
     // constructors
@@ -2150,10 +2146,11 @@
       if (name == otherConstructor.name) {
         if (name == null || name.length == 0) {
           _errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, node);
+              CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, constructor);
         } else {
           _errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME, node, [name]);
+              CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME, constructor,
+              [name]);
         }
         return true;
       }
@@ -2166,17 +2163,16 @@
       FieldElement field = classElement.getField(name);
       if (field != null) {
         _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, [
-          name
-        ]);
+            CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD,
+            constructor, [name]);
         return true;
       }
       // methods
       MethodElement method = classElement.getMethod(name);
       if (method != null) {
         _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node,
-            [name]);
+            CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD,
+            constructor, [name]);
         return true;
       }
     }
@@ -2184,10 +2180,9 @@
   }
 
   /**
-   * This verifies that the [enclosingClass] does not have a method and getter pair with the
-   * same name on, via inheritance.
+   * Verify that the [_enclosingClass] does not have a method and getter pair
+   * with the same name on, via inheritance.
    *
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD], and
    * [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER].
    */
@@ -2242,12 +2237,10 @@
   }
 
   /**
-   * This verifies that the superclass of the [enclosingClass] does not declare accessible
-   * static members with the same name as the instance getters/setters declared in
-   * [enclosingClass].
+   * Verify that the superclass of the [_enclosingClass] does not declare
+   * accessible static members with the same name as the instance
+   * getters/setters declared in [_enclosingClass].
    *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER], and
    * [StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER].
    */
@@ -2311,18 +2304,17 @@
   }
 
   /**
-   * This verifies that the enclosing class does not have a setter with the same name as the passed
-   * instance method declaration.
+   * Verify that the enclosing class does not have a setter with the same name
+   * as the given instance method declaration.
    *
-   * TODO(jwren) add other "conflicting" error codes into algorithm/ data structure
+   * TODO(jwren) add other "conflicting" error codes into algorithm/ data
+   * structure.
    *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER].
    */
-  bool _checkForConflictingInstanceMethodSetter(ClassDeclaration node) {
+  bool _checkForConflictingInstanceMethodSetter(ClassDeclaration declaration) {
     // Reference all of the class members in this class.
-    NodeList<ClassMember> classMembers = node.members;
+    NodeList<ClassMember> classMembers = declaration.members;
     if (classMembers.isEmpty) {
       return false;
     }
@@ -2386,8 +2378,10 @@
               !conflictingMethod.isGetter) {
             // report problem
             _errorReporter.reportErrorForNode(
-                StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2, name,
-                [_enclosingClass.displayName, name.name]);
+                StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2, name, [
+              _enclosingClass.displayName,
+              name.name
+            ]);
             foundError = true;
             addThisMemberToTheMap = false;
           }
@@ -2406,20 +2400,18 @@
   }
 
   /**
-   * This verifies that the enclosing class does not have an instance member with the same name as
-   * the passed static getter method declaration.
+   * Verify that the enclosing class does not have an instance member with the
+   * same name as the given static [method] declaration.
    *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER].
    */
   bool _checkForConflictingStaticGetterAndInstanceSetter(
-      MethodDeclaration node) {
-    if (!node.isStatic) {
+      MethodDeclaration method) {
+    if (!method.isStatic) {
       return false;
     }
     // prepare name
-    SimpleIdentifier nameNode = node.name;
+    SimpleIdentifier nameNode = method.name;
     if (nameNode == null) {
       return false;
     }
@@ -2450,20 +2442,18 @@
   }
 
   /**
-   * This verifies that the enclosing class does not have an instance member with the same name as
-   * the passed static getter method declaration.
+   * Verify that the enclosing class does not have an instance member with the
+   * same name as the given static [method] declaration.
    *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER].
    */
   bool _checkForConflictingStaticSetterAndInstanceMember(
-      MethodDeclaration node) {
-    if (!node.isStatic) {
+      MethodDeclaration method) {
+    if (!method.isStatic) {
       return false;
     }
     // prepare name
-    SimpleIdentifier nameNode = node.name;
+    SimpleIdentifier nameNode = method.name;
     if (nameNode == null) {
       return false;
     }
@@ -2500,14 +2490,14 @@
   }
 
   /**
-   * This verifies all conflicts between type variable and enclosing class. TODO(scheglov)
+   * Verify all conflicts between type variable and enclosing class.
+   * TODO(scheglov)
    *
-   * @param node the class declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS], and
    * [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER].
    */
-  bool _checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) {
+  bool _checkForConflictingTypeVariableErrorCodes(
+      ClassDeclaration declaration) {
     bool problemReported = false;
     for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) {
       String name = typeParameter.name;
@@ -2532,29 +2522,29 @@
   }
 
   /**
-   * This verifies that if the passed constructor declaration is 'const' then there are no
-   * invocations of non-'const' super constructors.
+   * Verify that if the given [constructor] declaration is 'const' then there
+   * are no invocations of non-'const' super constructors.
    *
-   * @param node the constructor declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER].
    */
-  bool _checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) {
+  bool _checkForConstConstructorWithNonConstSuper(
+      ConstructorDeclaration constructor) {
     if (!_isEnclosingConstructorConst) {
       return false;
     }
     // OK, const factory, checked elsewhere
-    if (node.factoryKeyword != null) {
+    if (constructor.factoryKeyword != null) {
       return false;
     }
     // check for mixins
     if (_enclosingClass.mixins.length != 0) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN, node.returnType);
+          CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN,
+          constructor.returnType);
       return true;
     }
     // try to find and check super constructor invocation
-    for (ConstructorInitializer initializer in node.initializers) {
+    for (ConstructorInitializer initializer in constructor.initializers) {
       if (initializer is SuperConstructorInvocation) {
         SuperConstructorInvocation superInvocation = initializer;
         ConstructorElement element = superInvocation.staticElement;
@@ -2586,21 +2576,20 @@
     // default constructor is not 'const', report problem
     _errorReporter.reportErrorForNode(
         CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
-        node.returnType, [supertype.displayName]);
+        constructor.returnType, [supertype.displayName]);
     return true;
   }
 
   /**
-   * This verifies that if the passed constructor declaration is 'const' then there are no non-final
-   * instance variable.
+   * Verify that if the given [constructor] declaration is 'const' then there
+   * are no non-final instance variable. The [constructorElement] is the
+   * constructor element.
    *
-   * @param node the constructor declaration to evaluate
-   * @param constructorElement the constructor element
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD].
    */
   bool _checkForConstConstructorWithNonFinalField(
-      ConstructorDeclaration node, ConstructorElement constructorElement) {
+      ConstructorDeclaration constructor,
+      ConstructorElement constructorElement) {
     if (!_isEnclosingConstructorConst) {
       return false;
     }
@@ -2611,83 +2600,77 @@
     }
     // report problem
     _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, node);
+        CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
+        constructor);
     return true;
   }
 
   /**
-   * This verifies that the passed 'const' instance creation expression is not creating a deferred
-   * type.
+   * Verify that the given 'const' instance creation [expression] is not
+   * creating a deferred type. The [constructorName] is the constructor name,
+   * always non-`null`. The [typeName] is the name of the type defining the
+   * constructor, always non-`null`.
    *
-   * @param node the instance creation expression to evaluate
-   * @param constructorName the constructor name, always non-`null`
-   * @param typeName the name of the type defining the constructor, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONST_DEFERRED_CLASS].
    */
-  bool _checkForConstDeferredClass(InstanceCreationExpression node,
+  bool _checkForConstDeferredClass(InstanceCreationExpression expression,
       ConstructorName constructorName, TypeName typeName) {
     if (typeName.isDeferred) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.CONST_DEFERRED_CLASS, constructorName, [
-        typeName.name.name
-      ]);
+          CompileTimeErrorCode.CONST_DEFERRED_CLASS, constructorName,
+          [typeName.name.name]);
       return true;
     }
     return false;
   }
 
   /**
-   * This verifies that the passed throw expression is not enclosed in a 'const' constructor
-   * declaration.
+   * Verify that the given throw [expression] is not enclosed in a 'const'
+   * constructor declaration.
    *
-   * @param node the throw expression expression to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION].
    */
-  bool _checkForConstEvalThrowsException(ThrowExpression node) {
+  bool _checkForConstEvalThrowsException(ThrowExpression expression) {
     if (_isEnclosingConstructorConst) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, node);
+          CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, expression);
       return true;
     }
     return false;
   }
 
   /**
-   * This verifies that the passed normal formal parameter is not 'const'.
+   * Verify that the given normal formal [parameter] is not 'const'.
    *
-   * @param node the normal formal parameter to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONST_FORMAL_PARAMETER].
    */
-  bool _checkForConstFormalParameter(NormalFormalParameter node) {
-    if (node.isConst) {
+  bool _checkForConstFormalParameter(NormalFormalParameter parameter) {
+    if (parameter.isConst) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.CONST_FORMAL_PARAMETER, node);
+          CompileTimeErrorCode.CONST_FORMAL_PARAMETER, parameter);
       return true;
     }
     return false;
   }
 
   /**
-   * This verifies that the passed instance creation expression is not being invoked on an abstract
-   * class.
+   * Verify that the given instance creation [expression] is not being invoked
+   * on an abstract class. The [typeName] is the [TypeName] of the
+   * [ConstructorName] from the [InstanceCreationExpression], this is the AST
+   * node that the error is attached to. The [type] is the type being
+   * constructed with this [InstanceCreationExpression].
    *
-   * @param node the instance creation expression to evaluate
-   * @param typeName the [TypeName] of the [ConstructorName] from the
-   *          [InstanceCreationExpression], this is the AST node that the error is attached to
-   * @param type the type being constructed with this [InstanceCreationExpression]
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.CONST_WITH_ABSTRACT_CLASS], and
    * [StaticWarningCode.NEW_WITH_ABSTRACT_CLASS].
    */
   bool _checkForConstOrNewWithAbstractClass(
-      InstanceCreationExpression node, TypeName typeName, InterfaceType type) {
+      InstanceCreationExpression expression, TypeName typeName,
+      InterfaceType type) {
     if (type.element.isAbstract) {
-      ConstructorElement element = node.staticElement;
+      ConstructorElement element = expression.staticElement;
       if (element != null && !element.isFactory) {
-        if ((node.keyword as sc.KeywordToken).keyword == sc.Keyword.CONST) {
+        if ((expression.keyword as sc.KeywordToken).keyword ==
+            sc.Keyword.CONST) {
           _errorReporter.reportErrorForNode(
               StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName);
         } else {
@@ -2701,17 +2684,16 @@
   }
 
   /**
-   * This verifies that the passed instance creation expression is not being invoked on an enum.
+   * Verify that the given instance creation [expression] is not being invoked
+   * on an enum. The [typeName] is the [TypeName] of the [ConstructorName] from
+   * the [InstanceCreationExpression], this is the AST node that the error is
+   * attached to. The [type] is the type being constructed with this
+   * [InstanceCreationExpression].
    *
-   * @param node the instance creation expression to verify
-   * @param typeName the [TypeName] of the [ConstructorName] from the
-   *          [InstanceCreationExpression], this is the AST node that the error is attached to
-   * @param type the type being constructed with this [InstanceCreationExpression]
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.INSTANTIATE_ENUM].
    */
-  bool _checkForConstOrNewWithEnum(
-      InstanceCreationExpression node, TypeName typeName, InterfaceType type) {
+  bool _checkForConstOrNewWithEnum(InstanceCreationExpression expression,
+      TypeName typeName, InterfaceType type) {
     if (type.element.isEnum) {
       _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.INSTANTIATE_ENUM, typeName);
@@ -2721,30 +2703,27 @@
   }
 
   /**
-   * This verifies that the passed 'const' instance creation expression is not being invoked on a
-   * constructor that is not 'const'.
+   * Verify that the given 'const' instance creation [expression] is not being
+   * invoked on a constructor that is not 'const'.
    *
-   * This method assumes that the instance creation was tested to be 'const' before being called.
+   * This method assumes that the instance creation was tested to be 'const'
+   * before being called.
    *
-   * @param node the instance creation expression to verify
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONST_WITH_NON_CONST].
    */
-  bool _checkForConstWithNonConst(InstanceCreationExpression node) {
-    ConstructorElement constructorElement = node.staticElement;
+  bool _checkForConstWithNonConst(InstanceCreationExpression expression) {
+    ConstructorElement constructorElement = expression.staticElement;
     if (constructorElement != null && !constructorElement.isConst) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.CONST_WITH_NON_CONST, node);
+          CompileTimeErrorCode.CONST_WITH_NON_CONST, expression);
       return true;
     }
     return false;
   }
 
   /**
-   * This verifies that the passed type name does not reference any type parameters.
+   * Verify that the given [typeName] does not reference any type parameters.
    *
-   * @param typeName the type name to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS].
    */
   bool _checkForConstWithTypeParameters(TypeName typeName) {
@@ -2777,22 +2756,22 @@
   }
 
   /**
-   * This verifies that if the passed 'const' instance creation expression is being invoked on the
-   * resolved constructor.
+   * Verify that if the given 'const' instance creation [expression] is being
+   * invoked on the resolved constructor. The [constructorName] is the
+   * constructor name, always non-`null`. The [typeName] is the name of the type
+   * defining the constructor, always non-`null`.
    *
-   * This method assumes that the instance creation was tested to be 'const' before being called.
+   * This method assumes that the instance creation was tested to be 'const'
+   * before being called.
    *
-   * @param node the instance creation expression to evaluate
-   * @param constructorName the constructor name, always non-`null`
-   * @param typeName the name of the type defining the constructor, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR], and
    * [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT].
    */
-  bool _checkForConstWithUndefinedConstructor(InstanceCreationExpression node,
-      ConstructorName constructorName, TypeName typeName) {
+  bool _checkForConstWithUndefinedConstructor(
+      InstanceCreationExpression expression, ConstructorName constructorName,
+      TypeName typeName) {
     // OK if resolved
-    if (node.staticElement != null) {
+    if (expression.staticElement != null) {
       return false;
     }
     DartType type = typeName.type;
@@ -2821,22 +2800,21 @@
   }
 
   /**
-   * This verifies that there are no default parameters in the passed function type alias.
+   * Verify that there are no default parameters in the given function type
+   * [alias].
    *
-   * @param node the function type alias to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS].
    */
-  bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) {
+  bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias alias) {
     bool result = false;
-    FormalParameterList formalParameterList = node.parameters;
+    FormalParameterList formalParameterList = alias.parameters;
     NodeList<FormalParameter> parameters = formalParameterList.parameters;
     for (FormalParameter formalParameter in parameters) {
       if (formalParameter is DefaultFormalParameter) {
         DefaultFormalParameter defaultFormalParameter = formalParameter;
         if (defaultFormalParameter.defaultValue != null) {
           _errorReporter.reportErrorForNode(
-              CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, node);
+              CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, alias);
           result = true;
         }
       }
@@ -2845,39 +2823,37 @@
   }
 
   /**
-   * This verifies that the given default formal parameter is not part of a function typed
-   * parameter.
+   * Verify that the given default formal [parameter] is not part of a function
+   * typed parameter.
    *
-   * @param node the default formal parameter to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER].
    */
   bool _checkForDefaultValueInFunctionTypedParameter(
-      DefaultFormalParameter node) {
+      DefaultFormalParameter parameter) {
     // OK, not in a function typed parameter.
     if (!_isInFunctionTypedFormalParameter) {
       return false;
     }
     // OK, no default value.
-    if (node.defaultValue == null) {
+    if (parameter.defaultValue == null) {
       return false;
     }
     // Report problem.
     _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, node);
+        CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER,
+        parameter);
     return true;
   }
 
   /**
-   * This verifies that any deferred imports in the given compilation unit have a unique prefix.
+   * Verify that any deferred imports in the given compilation [unit] have a
+   * unique prefix.
    *
-   * @param node the compilation unit containing the imports to be checked
-   * @return `true` if an error was generated
    * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX].
    */
-  bool _checkForDeferredPrefixCollisions(CompilationUnit node) {
+  bool _checkForDeferredPrefixCollisions(CompilationUnit unit) {
     bool foundError = false;
-    NodeList<Directive> directives = node.directives;
+    NodeList<Directive> directives = unit.directives;
     int count = directives.length;
     if (count > 0) {
       HashMap<PrefixElement, List<ImportDirective>> prefixToDirectivesMap =
@@ -2912,10 +2888,9 @@
   }
 
   /**
-   * This verifies that the enclosing class does not have an instance member with the given name of
-   * the static member.
+   * Verify that the enclosing class does not have an instance member with the
+   * given name of the static member.
    *
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE].
    */
   bool _checkForDuplicateDefinitionInheritance() {
@@ -2937,11 +2912,9 @@
   }
 
   /**
-   * This verifies that the enclosing class does not have an instance member with the given name of
-   * the static member.
+   * Verify that the enclosing class does not have an instance member with the
+   * given name of the [staticMember].
    *
-   * @param staticMember the static member to check conflict for
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.DUPLICATE_DEFINITION_INHERITANCE].
    */
   bool _checkForDuplicateDefinitionOfMember(ExecutableElement staticMember) {
@@ -2977,15 +2950,13 @@
   }
 
   /**
-   * This verifies if the passed list literal has type arguments then there is exactly one.
+   * Verify that if the given list [literal] has type arguments then there is
+   * exactly one. The [typeArguments] are the type arguments.
    *
-   * @param node the list literal to evaluate
-   * @param typeArguments the type arguments, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS].
    */
   bool _checkForExpectedOneListTypeArgument(
-      ListLiteral node, TypeArgumentList typeArguments) {
+      ListLiteral literal, TypeArgumentList typeArguments) {
     // check number of type arguments
     int num = typeArguments.arguments.length;
     if (num == 1) {
@@ -2993,23 +2964,21 @@
     }
     // report problem
     _errorReporter.reportErrorForNode(
-        StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, [
-      num
-    ]);
+        StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments,
+        [num]);
     return true;
   }
 
   /**
-   * This verifies the passed import has unique name among other exported libraries.
+   * Verify that the given export [directive] has a unique name among other
+   * exported libraries. The [exportElement] is the [ExportElement] retrieved
+   * from the node, if the element in the node was `null`, then this method is
+   * not called. The [exportedLibrary] is the library element containing the
+   * exported element.
    *
-   * @param node the export directive to evaluate
-   * @param exportElement the [ExportElement] retrieved from the node, if the element in the
-   *          node was `null`, then this method is not called
-   * @param exportedLibrary the library element containing the exported element
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.EXPORT_DUPLICATED_LIBRARY_NAME].
    */
-  bool _checkForExportDuplicateLibraryName(ExportDirective node,
+  bool _checkForExportDuplicateLibraryName(ExportDirective directive,
       ExportElement exportElement, LibraryElement exportedLibrary) {
     if (exportedLibrary == null) {
       return false;
@@ -3021,13 +2990,13 @@
       if (prevLibrary != exportedLibrary) {
         if (name.isEmpty) {
           _errorReporter.reportErrorForNode(
-              StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_UNNAMED, node, [
+              StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_UNNAMED, directive, [
             prevLibrary.definingCompilationUnit.displayName,
             exportedLibrary.definingCompilationUnit.displayName
           ]);
         } else {
           _errorReporter.reportErrorForNode(
-              StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAMED, node, [
+              StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAMED, directive, [
             prevLibrary.definingCompilationUnit.displayName,
             exportedLibrary.definingCompilationUnit.displayName,
             name
@@ -3043,17 +3012,15 @@
   }
 
   /**
-   * Check that if the visiting library is not system, then any passed library should not be SDK
-   * internal library.
+   * Check that if the visiting library is not system, then any given library
+   * should not be SDK internal library. The [exportElement] is the
+   * [ExportElement] retrieved from the node, if the element in the node was
+   * `null`, then this method is not called.
    *
-   * @param node the export directive to evaluate
-   * @param exportElement the [ExportElement] retrieved from the node, if the element in the
-   *          node was `null`, then this method is not called
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY].
    */
   bool _checkForExportInternalLibrary(
-      ExportDirective node, ExportElement exportElement) {
+      ExportDirective directive, ExportElement exportElement) {
     if (_isInSystemLibrary) {
       return false;
     }
@@ -3069,76 +3036,69 @@
     }
     // report problem
     _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, node, [node.uri]);
+        CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, directive,
+        [directive.uri]);
     return true;
   }
 
   /**
-   * This verifies that the passed extends clause does not extend a deferred class.
+   * Verify that the given extends [clause] does not extend a deferred class.
    *
-   * @param node the extends clause to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS].
    */
-  bool _checkForExtendsDeferredClass(ExtendsClause node) {
-    if (node == null) {
+  bool _checkForExtendsDeferredClass(ExtendsClause clause) {
+    if (clause == null) {
       return false;
     }
     return _checkForExtendsOrImplementsDeferredClass(
-        node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS);
+        clause.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS);
   }
 
   /**
-   * This verifies that the passed type alias does not extend a deferred class.
+   * Verify that the given type [alias] does not extend a deferred class.
    *
-   * @param node the extends clause to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS].
    */
-  bool _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias node) {
-    if (node == null) {
+  bool _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias alias) {
+    if (alias == null) {
       return false;
     }
     return _checkForExtendsOrImplementsDeferredClass(
-        node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS);
+        alias.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS);
   }
 
   /**
-   * This verifies that the passed extends clause does not extend classes such as num or String.
+   * Verify that the given extends [clause] does not extend classes such as
+   * 'num' or 'String'.
    *
-   * @param node the extends clause to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS].
    */
-  bool _checkForExtendsDisallowedClass(ExtendsClause node) {
-    if (node == null) {
+  bool _checkForExtendsDisallowedClass(ExtendsClause clause) {
+    if (clause == null) {
       return false;
     }
     return _checkForExtendsOrImplementsDisallowedClass(
-        node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS);
+        clause.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS);
   }
 
   /**
-   * This verifies that the passed type alias does not extend classes such as num or String.
+   * Verify that the given type [alias] does not extend classes such as 'num' or
+   * 'String'.
    *
-   * @param node the extends clause to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS].
    */
-  bool _checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias node) {
-    if (node == null) {
+  bool _checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias alias) {
+    if (alias == null) {
       return false;
     }
     return _checkForExtendsOrImplementsDisallowedClass(
-        node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS);
+        alias.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS);
   }
 
   /**
-   * This verifies that the passed type name does not extend, implement or mixin classes that are
-   * deferred.
+   * Verify that the given [typeName] does not extend, implement or mixin
+   * classes that are deferred.
    *
-   * @param node the type name to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [_checkForExtendsDeferredClass],
    * [_checkForExtendsDeferredClassInTypeAlias],
    * [_checkForImplementsDeferredClass],
@@ -3161,11 +3121,9 @@
   }
 
   /**
-   * This verifies that the passed type name does not extend, implement or mixin classes such as
-   * 'num' or 'String'.
+   * Verify that the given [typeName] does not extend, implement or mixin
+   * classes such as 'num' or 'String'.
    *
-   * @param node the type name to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [_checkForExtendsDisallowedClass],
    * [_checkForExtendsDisallowedClassInTypeAlias],
    * [_checkForImplementsDisallowedClass],
@@ -3212,18 +3170,15 @@
   }
 
   /**
-   * This verifies that the passed constructor field initializer has compatible field and
-   * initializer expression types.
+   * Verify that the given constructor field [initializer] has compatible field
+   * and initializer expression types. The [staticElement] is the static element
+   * from the name in the [ConstructorFieldInitializer].
    *
-   * @param node the constructor field initializer to test
-   * @param staticElement the static element from the name in the
-   *          [ConstructorFieldInitializer]
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and
    * [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE].
    */
   bool _checkForFieldInitializerNotAssignable(
-      ConstructorFieldInitializer node, Element staticElement) {
+      ConstructorFieldInitializer initializer, Element staticElement) {
     // prepare field element
     if (staticElement is! FieldElement) {
       return false;
@@ -3232,7 +3187,7 @@
     // prepare field type
     DartType fieldType = fieldElement.type;
     // prepare expression type
-    Expression expression = node.expression;
+    Expression expression = initializer.expression;
     if (expression == null) {
       return false;
     }
@@ -3283,25 +3238,26 @@
   }
 
   /**
-   * This verifies that the passed field formal parameter is in a constructor declaration.
+   * Verify that the given field formal [parameter] is in a constructor
+   * declaration.
    *
-   * @param node the field formal parameter to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR].
    */
   bool _checkForFieldInitializingFormalRedirectingConstructor(
-      FieldFormalParameter node) {
+      FieldFormalParameter parameter) {
     ConstructorDeclaration constructor =
-        node.getAncestor((node) => node is ConstructorDeclaration);
+        parameter.getAncestor((node) => node is ConstructorDeclaration);
     if (constructor == null) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, node);
+          CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
+          parameter);
       return true;
     }
     // constructor cannot be a factory
     if (constructor.factoryKeyword != null) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, node);
+          CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR,
+          parameter);
       return true;
     }
     // constructor cannot have a redirection
@@ -3309,7 +3265,7 @@
       if (initializer is RedirectingConstructorInvocation) {
         _errorReporter.reportErrorForNode(
             CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR,
-            node);
+            parameter);
         return true;
       }
     }
@@ -3318,36 +3274,29 @@
   }
 
   /**
-   * This verifies that the passed variable declaration list has only initialized variables if the
-   * list is final or const. This method is called by
-   * [checkForFinalNotInitializedInClass],
-   * [visitTopLevelVariableDeclaration] and
-   * [visitVariableDeclarationStatement].
+   * Verify that the given variable declaration [list] has only initialized
+   * variables if the list is final or const.
    *
-   * @param node the class declaration to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and
    * [StaticWarningCode.FINAL_NOT_INITIALIZED].
    */
-  bool _checkForFinalNotInitialized(VariableDeclarationList node) {
+  bool _checkForFinalNotInitialized(VariableDeclarationList list) {
     if (_isInNativeClass) {
       return false;
     }
     bool foundError = false;
-    if (!node.isSynthetic) {
-      NodeList<VariableDeclaration> variables = node.variables;
+    if (!list.isSynthetic) {
+      NodeList<VariableDeclaration> variables = list.variables;
       for (VariableDeclaration variable in variables) {
         if (variable.initializer == null) {
-          if (node.isConst) {
+          if (list.isConst) {
             _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, [
-              variable.name.name
-            ]);
-          } else if (node.isFinal) {
+                CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name,
+                [variable.name.name]);
+          } else if (list.isFinal) {
             _errorReporter.reportErrorForNode(
-                StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, [
-              variable.name.name
-            ]);
+                StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name,
+                [variable.name.name]);
           }
           foundError = true;
         }
@@ -3357,17 +3306,16 @@
   }
 
   /**
-   * This verifies that final fields that are declared, without any constructors in the enclosing
-   * class, are initialized. Cases in which there is at least one constructor are handled at the end
-   * of [checkForAllFinalInitializedErrorCodes].
+   * Verify that final fields in the given clas [declaration] that are declared,
+   * without any constructors in the enclosing class, are initialized. Cases in
+   * which there is at least one constructor are handled at the end of
+   * [_checkForAllFinalInitializedErrorCodes].
    *
-   * @param node the class declaration to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and
    * [StaticWarningCode.FINAL_NOT_INITIALIZED].
    */
-  bool _checkForFinalNotInitializedInClass(ClassDeclaration node) {
-    NodeList<ClassMember> classMembers = node.members;
+  bool _checkForFinalNotInitializedInClass(ClassDeclaration declaration) {
+    NodeList<ClassMember> classMembers = declaration.members;
     for (ClassMember classMember in classMembers) {
       if (classMember is ConstructorDeclaration) {
         return false;
@@ -3386,10 +3334,10 @@
   /**
    * If the current function is async, async*, or sync*, verify that its
    * declared return type is assignable to Future, Stream, or Iterable,
-   * respectively.  If not, report the error using [node].
+   * respectively.  If not, report the error using [returnType].
    */
-  void _checkForIllegalReturnType(TypeName node) {
-    if (node == null) {
+  void _checkForIllegalReturnType(TypeName returnType) {
+    if (returnType == null) {
       // No declared return type, so the return type must be dynamic, which is
       // assignable to everything.
       return;
@@ -3399,37 +3347,38 @@
         if (!_enclosingFunction.returnType
             .isAssignableTo(_typeProvider.streamDynamicType)) {
           _errorReporter.reportErrorForNode(
-              StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE, node);
+              StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE,
+              returnType);
         }
       } else {
         if (!_enclosingFunction.returnType
             .isAssignableTo(_typeProvider.futureDynamicType)) {
           _errorReporter.reportErrorForNode(
-              StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, node);
+              StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, returnType);
         }
       }
     } else if (_enclosingFunction.isGenerator) {
       if (!_enclosingFunction.returnType
           .isAssignableTo(_typeProvider.iterableDynamicType)) {
         _errorReporter.reportErrorForNode(
-            StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, node);
+            StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE,
+            returnType);
       }
     }
   }
 
   /**
-   * This verifies that the passed implements clause does not implement classes that are deferred.
+   * Verify that the given implements [clause] does not implement classes that
+   * are deferred.
    *
-   * @param node the implements clause to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS].
    */
-  bool _checkForImplementsDeferredClass(ImplementsClause node) {
-    if (node == null) {
+  bool _checkForImplementsDeferredClass(ImplementsClause clause) {
+    if (clause == null) {
       return false;
     }
     bool foundError = false;
-    for (TypeName type in node.interfaces) {
+    for (TypeName type in clause.interfaces) {
       if (_checkForExtendsOrImplementsDeferredClass(
           type, CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) {
         foundError = true;
@@ -3439,19 +3388,17 @@
   }
 
   /**
-   * This verifies that the passed implements clause does not implement classes such as 'num' or
-   * 'String'.
+   * Verify that the given implements [clause] does not implement classes such
+   * as 'num' or 'String'.
    *
-   * @param node the implements clause to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS].
    */
-  bool _checkForImplementsDisallowedClass(ImplementsClause node) {
-    if (node == null) {
+  bool _checkForImplementsDisallowedClass(ImplementsClause clause) {
+    if (clause == null) {
       return false;
     }
     bool foundError = false;
-    for (TypeName type in node.interfaces) {
+    for (TypeName type in clause.interfaces) {
       if (_checkForExtendsOrImplementsDisallowedClass(
           type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) {
         foundError = true;
@@ -3461,16 +3408,15 @@
   }
 
   /**
-   * This verifies that if the passed identifier is part of constructor initializer, then it does
-   * not reference implicitly 'this' expression.
+   * Verify that if the given [identifier] is part of a constructor initializer,
+   * then it does not implicitly reference 'this' expression.
    *
-   * @param node the simple identifier to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER], and
    * [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC].
    * TODO(scheglov) rename thid method
    */
-  bool _checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) {
+  bool _checkForImplicitThisReferenceInInitializer(
+      SimpleIdentifier identifier) {
     if (!_isInConstructorInitializer &&
         !_isInStaticMethod &&
         !_isInFactory &&
@@ -3479,7 +3425,7 @@
       return false;
     }
     // prepare element
-    Element element = node.staticElement;
+    Element element = identifier.staticElement;
     if (!(element is MethodElement || element is PropertyAccessorElement)) {
       return false;
     }
@@ -3494,14 +3440,14 @@
       return false;
     }
     // comment
-    AstNode parent = node.parent;
+    AstNode parent = identifier.parent;
     if (parent is CommentReference) {
       return false;
     }
     // qualified method invocation
     if (parent is MethodInvocation) {
       MethodInvocation invocation = parent;
-      if (identical(invocation.methodName, node) &&
+      if (identical(invocation.methodName, identifier) &&
           invocation.realTarget != null) {
         return false;
       }
@@ -3509,41 +3455,42 @@
     // qualified property access
     if (parent is PropertyAccess) {
       PropertyAccess access = parent;
-      if (identical(access.propertyName, node) && access.realTarget != null) {
+      if (identical(access.propertyName, identifier) &&
+          access.realTarget != null) {
         return false;
       }
     }
     if (parent is PrefixedIdentifier) {
       PrefixedIdentifier prefixed = parent;
-      if (identical(prefixed.identifier, node)) {
+      if (identical(prefixed.identifier, identifier)) {
         return false;
       }
     }
     // report problem
     if (_isInStaticMethod) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, node);
+          CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, identifier);
     } else if (_isInFactory) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, node);
+          CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, identifier);
     } else {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, node);
+          CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
+          identifier);
     }
     return true;
   }
 
   /**
-   * This verifies the passed import has unique name among other imported libraries.
+   * Verify that the given import [directive] has a unique name among other
+   * imported libraries. The [importElement] is the [ImportElement] retrieved
+   * from the node, if the element in the node was `null`, then this method is
+   * not called.
    *
-   * @param node the import directive to evaluate
-   * @param importElement the [ImportElement] retrieved from the node, if the element in the
-   *          node was `null`, then this method is not called
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.IMPORT_DUPLICATED_LIBRARY_NAME].
    */
   bool _checkForImportDuplicateLibraryName(
-      ImportDirective node, ImportElement importElement) {
+      ImportDirective directive, ImportElement importElement) {
     // prepare imported library
     LibraryElement nodeLibrary = importElement.importedLibrary;
     if (nodeLibrary == null) {
@@ -3556,13 +3503,13 @@
       if (prevLibrary != nodeLibrary) {
         if (name.isEmpty) {
           _errorReporter.reportErrorForNode(
-              StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_UNNAMED, node, [
+              StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_UNNAMED, directive, [
             prevLibrary.definingCompilationUnit.displayName,
             nodeLibrary.definingCompilationUnit.displayName
           ]);
         } else {
           _errorReporter.reportErrorForNode(
-              StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED, node, [
+              StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED, directive, [
             prevLibrary.definingCompilationUnit.displayName,
             nodeLibrary.definingCompilationUnit.displayName,
             name
@@ -3578,17 +3525,15 @@
   }
 
   /**
-   * Check that if the visiting library is not system, then any passed library should not be SDK
-   * internal library.
+   * Check that if the visiting library is not system, then any given library
+   * should not be SDK internal library. The [importElement] is the
+   * [ImportElement] retrieved from the node, if the element in the node was
+   * `null`, then this method is not called
    *
-   * @param node the import directive to evaluate
-   * @param importElement the [ImportElement] retrieved from the node, if the element in the
-   *          node was `null`, then this method is not called
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY].
    */
   bool _checkForImportInternalLibrary(
-      ImportDirective node, ImportElement importElement) {
+      ImportDirective directive, ImportElement importElement) {
     if (_isInSystemLibrary) {
       return false;
     }
@@ -3604,15 +3549,15 @@
     }
     // report problem
     _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, node, [node.uri]);
+        CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, directive,
+        [directive.uri]);
     return true;
   }
 
   /**
-   * For each class declaration, this method is called which verifies that all inherited members are
-   * inherited consistently.
+   * For each class declaration, this method is called which verifies that all
+   * inherited members are inherited consistently.
    *
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE].
    */
   bool _checkForInconsistentMethodInheritance() {
@@ -3632,14 +3577,9 @@
   }
 
   /**
-   * This checks the given "typeReference" is not a type reference and that then the "name" is
-   * reference to an instance member.
+   * Check that the given [typeReference] is not a type reference and that then
+   * the [name] is reference to an instance member.
    *
-   * @param typeReference the resolved [ClassElement] of the left hand side of the expression,
-   *          or `null`, aka, the class element of 'C' in 'C.x', see
-   *          [getTypeReference]
-   * @param name the accessed name to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER].
    */
   bool _checkForInstanceAccessToStaticMember(
@@ -3668,19 +3608,17 @@
     }
     // report problem
     _errorReporter.reportErrorForNode(
-        StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, [
-      name.name
-    ]);
+        StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name,
+        [name.name]);
     return true;
   }
 
   /**
-   * This checks whether the given [executableElement] collides with the name of a static
-   * method in one of its superclasses, and reports the appropriate warning if it does.
+   * Check whether the given [executableElement] collides with the name of a
+   * static method in one of its superclasses, and reports the appropriate
+   * warning if it does. The [errorNameTarget] is the node to report problems
+   * on.
    *
-   * @param executableElement the method to check.
-   * @param errorNameTarget the node to report problems on.
-   * @return `true` if and only if a warning was generated.
    * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC].
    */
   bool _checkForInstanceMethodNameCollidesWithSuperclassStatic(
@@ -3750,12 +3688,10 @@
   }
 
   /**
-   * This verifies that an 'int' can be assigned to the parameter corresponding to the given
-   * expression. This is used for prefix and postfix expressions where the argument value is
-   * implicit.
+   * Verify that an 'int' can be assigned to the parameter corresponding to the
+   * given [argument]. This is used for prefix and postfix expressions where
+   * the argument value is implicit.
    *
-   * @param argument the expression to which the operator is being applied
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
    */
   bool _checkForIntNotAssignable(Expression argument) {
@@ -3770,19 +3706,17 @@
   }
 
   /**
-   * This verifies that the passed [Annotation] isn't defined in a deferred library.
+   * Verify that the given [annotation] isn't defined in a deferred library.
    *
-   * @param node the [Annotation]
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY].
    */
-  bool _checkForInvalidAnnotationFromDeferredLibrary(Annotation node) {
-    Identifier nameIdentifier = node.name;
+  bool _checkForInvalidAnnotationFromDeferredLibrary(Annotation annotation) {
+    Identifier nameIdentifier = annotation.name;
     if (nameIdentifier is PrefixedIdentifier) {
       if (nameIdentifier.isDeferred) {
         _errorReporter.reportErrorForNode(
             CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY,
-            node.name);
+            annotation.name);
         return true;
       }
     }
@@ -3790,11 +3724,9 @@
   }
 
   /**
-   * This verifies that the passed left hand side and right hand side represent a valid assignment.
+   * Verify that the given left hand side ([lhs]) and right hand side ([rhs])
+   * represent a valid assignment.
    *
-   * @param lhs the left hand side expression
-   * @param rhs the right hand side expression
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.INVALID_ASSIGNMENT].
    */
   bool _checkForInvalidAssignment(Expression lhs, Expression rhs) {
@@ -3818,17 +3750,14 @@
   }
 
   /**
-   * Given an assignment using a compound assignment operator, this verifies that the given
-   * assignment is valid.
+   * Given an [assignment] using a compound assignment operator, this verifies
+   * that the given assignment is valid. The [lhs] is the left hand side
+   * expression. The [rhs] is the right hand side expression.
    *
-   * @param node the assignment expression being tested
-   * @param lhs the left hand side expression
-   * @param rhs the right hand side expression
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.INVALID_ASSIGNMENT].
    */
   bool _checkForInvalidCompoundAssignment(
-      AssignmentExpression node, Expression lhs, Expression rhs) {
+      AssignmentExpression assignment, Expression lhs, Expression rhs) {
     if (lhs == null) {
       return false;
     }
@@ -3836,7 +3765,7 @@
     DartType leftType = (leftVariableElement == null)
         ? getStaticType(lhs)
         : leftVariableElement.type;
-    MethodElement invokedMethod = node.staticElement;
+    MethodElement invokedMethod = assignment.staticElement;
     if (invokedMethod == null) {
       return false;
     }
@@ -3853,44 +3782,35 @@
   }
 
   /**
-   * Check the given initializer to ensure that the field being initialized is a valid field.
-   *
-   * @param node the field initializer being checked
-   * @param fieldName the field name from the [ConstructorFieldInitializer]
-   * @param staticElement the static element from the name in the
-   *          [ConstructorFieldInitializer]
+   * Check the given [initializer] to ensure that the field being initialized is
+   * a valid field. The [fieldName] is the field name from the
+   * [ConstructorFieldInitializer]. The [staticElement] is the static element
+   * from the name in the [ConstructorFieldInitializer].
    */
-  void _checkForInvalidField(ConstructorFieldInitializer node,
+  void _checkForInvalidField(ConstructorFieldInitializer initializer,
       SimpleIdentifier fieldName, Element staticElement) {
     if (staticElement is FieldElement) {
       FieldElement fieldElement = staticElement;
       if (fieldElement.isSynthetic) {
         _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, [
-          fieldName
-        ]);
+            CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD,
+            initializer, [fieldName]);
       } else if (fieldElement.isStatic) {
         _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [
-          fieldName
-        ]);
+            CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, initializer,
+            [fieldName]);
       }
     } else {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, [
-        fieldName
-      ]);
+          CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, initializer,
+          [fieldName]);
       return;
     }
   }
 
   /**
-   * Check to see whether the given function body has a modifier associated with it, and report it
-   * as an error if it does.
-   *
-   * @param body the function body being checked
-   * @param errorCode the error code to be reported if a modifier is found
-   * @return `true` if an error was reported
+   * Check to see whether the given function [body] has a modifier associated
+   * with it, and report it as an error if it does.
    */
   bool _checkForInvalidModifierOnBody(
       FunctionBody body, CompileTimeErrorCode errorCode) {
@@ -3903,30 +3823,24 @@
   }
 
   /**
-   * This verifies that the usage of the passed 'this' is valid.
+   * Verify that the usage of the given 'this' is valid.
    *
-   * @param node the 'this' expression to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS].
    */
-  bool _checkForInvalidReferenceToThis(ThisExpression node) {
-    if (!_isThisInValidContext(node)) {
+  bool _checkForInvalidReferenceToThis(ThisExpression expression) {
+    if (!_isThisInValidContext(expression)) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, node);
+          CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, expression);
       return true;
     }
     return false;
   }
 
   /**
-   * Checks to ensure that the passed [ListLiteral] or [MapLiteral] does not have a type
-   * parameter as a type argument.
-   *
-   * @param arguments a non-`null`, non-empty [TypeName] node list from the respective
-   *          [ListLiteral] or [MapLiteral]
-   * @param errorCode either [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or
-   *          [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]
-   * @return `true` if and only if an error code is generated on the passed node
+   * Checks to ensure that the given list of type [arguments] does not have a
+   * type parameter as a type argument. The [errorCode] is either
+   * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or
+   * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP].
    */
   bool _checkForInvalidTypeArgumentInConstTypedLiteral(
       NodeList<TypeName> arguments, ErrorCode errorCode) {
@@ -3941,17 +3855,14 @@
   }
 
   /**
-   * This verifies that the elements given [ListLiteral] are subtypes of the specified element
-   * type.
+   * Verify that the elements given list [literal] are subtypes of the specified
+   * element type. The [typeArguments] are the type arguments.
    *
-   * @param node the list literal to evaluate
-   * @param typeArguments the type arguments, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and
    * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE].
    */
   bool _checkForListElementTypeNotAssignable(
-      ListLiteral node, TypeArgumentList typeArguments) {
+      ListLiteral literal, TypeArgumentList typeArguments) {
     NodeList<TypeName> typeNames = typeArguments.arguments;
     if (typeNames.length < 1) {
       return false;
@@ -3959,8 +3870,8 @@
     DartType listElementType = typeNames[0].type;
     // Check every list element.
     bool hasProblems = false;
-    for (Expression element in node.elements) {
-      if (node.constKeyword != null) {
+    for (Expression element in literal.elements) {
+      if (literal.constKeyword != null) {
         // TODO(paulberry): this error should be based on the actual type of the
         // list element, not the static type.  See dartbug.com/21119.
         if (_checkForArgumentTypeNotAssignableWithExpectedTypes(element,
@@ -3979,19 +3890,17 @@
   }
 
   /**
-   * This verifies that the key/value of entries of the given [MapLiteral] are subtypes of the
-   * key/value types specified in the type arguments.
+   * Verify that the key/value of entries of the given map [literal] are
+   * subtypes of the key/value types specified in the type arguments. The
+   * [typeArguments] are the type arguments.
    *
-   * @param node the map literal to evaluate
-   * @param typeArguments the type arguments, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE],
    * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE],
    * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and
    * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE].
    */
   bool _checkForMapTypeNotAssignable(
-      MapLiteral node, TypeArgumentList typeArguments) {
+      MapLiteral literal, TypeArgumentList typeArguments) {
     // Prepare maps key/value types.
     NodeList<TypeName> typeNames = typeArguments.arguments;
     if (typeNames.length < 2) {
@@ -4001,11 +3910,11 @@
     DartType valueType = typeNames[1].type;
     // Check every map entry.
     bool hasProblems = false;
-    NodeList<MapLiteralEntry> entries = node.entries;
+    NodeList<MapLiteralEntry> entries = literal.entries;
     for (MapLiteralEntry entry in entries) {
       Expression key = entry.key;
       Expression value = entry.value;
-      if (node.constKeyword != null) {
+      if (literal.constKeyword != null) {
         // TODO(paulberry): this error should be based on the actual type of the
         // list element, not the static type.  See dartbug.com/21119.
         if (_checkForArgumentTypeNotAssignableWithExpectedTypes(key, keyType,
@@ -4031,10 +3940,9 @@
   }
 
   /**
-   * This verifies that the [enclosingClass] does not define members with the same name as
-   * the enclosing class.
+   * Verify that the [_enclosingClass] does not define members with the same name
+   * as the enclosing class.
    *
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME].
    */
   bool _checkForMemberWithClassName() {
@@ -4061,11 +3969,9 @@
   }
 
   /**
-   * Check to make sure that all similarly typed accessors are of the same type (including inherited
-   * accessors).
+   * Check to make sure that all similarly typed accessors are of the same type
+   * (including inherited accessors).
    *
-   * @param node the accessor currently being visited
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES], and
    * [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE].
    */
@@ -4155,11 +4061,9 @@
   }
 
   /**
-   * Check to make sure that switch statements whose static type is an enum type either have a
-   * default case or include all of the enum constants.
-   *
-   * @param statement the switch statement to check
-   * @return `true` if and only if an error code is generated on the passed node
+   * Check to make sure that the given switch [statement] whose static type is
+   * an enum type either have a default case or include all of the enum
+   * constants.
    */
   bool _checkForMissingEnumConstantInSwitch(SwitchStatement statement) {
     // TODO(brianwilkerson) This needs to be checked after constant values have
@@ -4204,22 +4108,19 @@
     }
     for (int i = 0; i < nameCount; i++) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, statement, [
-        constantNames[i]
-      ]);
+          CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, statement,
+          [constantNames[i]]);
     }
     return true;
   }
 
   /**
-   * This verifies that the given function body does not contain return statements that both have
-   * and do not have return values.
+   * Verify that the given function [body] does not contain return statements
+   * that both have and do not have return values.
    *
-   * @param node the function body being tested
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.MIXED_RETURN_TYPES].
    */
-  bool _checkForMixedReturns(BlockFunctionBody node) {
+  bool _checkForMixedReturns(BlockFunctionBody body) {
     if (_hasReturnWithoutValue) {
       return false;
     }
@@ -4240,11 +4141,10 @@
   }
 
   /**
-   * This verifies that the passed mixin does not have an explicitly declared constructor.
+   * Verify that the given mixin does not have an explicitly declared
+   * constructor. The [mixinName] is the node to report problem on. The
+   * [mixinElement] is the mixing to evaluate.
    *
-   * @param mixinName the node to report problem on
-   * @param mixinElement the mixing to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR].
    */
   bool _checkForMixinDeclaresConstructor(
@@ -4252,9 +4152,8 @@
     for (ConstructorElement constructor in mixinElement.constructors) {
       if (!constructor.isSynthetic && !constructor.isFactory) {
         _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName, [
-          mixinElement.name
-        ]);
+            CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName,
+            [mixinElement.name]);
         return true;
       }
     }
@@ -4262,11 +4161,10 @@
   }
 
   /**
-   * This verifies that the passed mixin has the 'Object' superclass.
+   * Verify that the given mixin has the 'Object' superclass. The [mixinName] is
+   * the node to report problem on. The [mixinElement] is the mixing to
+   * evaluate.
    *
-   * @param mixinName the node to report problem on
-   * @param mixinElement the mixing to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT].
    */
   bool _checkForMixinInheritsNotFromObject(
@@ -4276,9 +4174,8 @@
       if (!mixinSupertype.isObject ||
           !mixinElement.isTypedef && mixinElement.mixins.length != 0) {
         _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName, [
-          mixinElement.name
-        ]);
+            CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName,
+            [mixinElement.name]);
         return true;
       }
     }
@@ -4286,34 +4183,30 @@
   }
 
   /**
-   * This verifies that the passed mixin does not reference 'super'.
+   * Verify that the given mixin does not reference 'super'. The [mixinName] is
+   * the node to report problem on. The [mixinElement] is the mixing to
+   * evaluate.
    *
-   * @param mixinName the node to report problem on
-   * @param mixinElement the mixing to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER].
    */
   bool _checkForMixinReferencesSuper(
       TypeName mixinName, ClassElement mixinElement) {
     if (mixinElement.hasReferenceToSuper) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName, [
-        mixinElement.name
-      ]);
+          CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName,
+          [mixinElement.name]);
     }
     return false;
   }
 
   /**
-   * This verifies that the passed constructor has at most one 'super' initializer.
+   * Verify that the given [constructor] has at most one 'super' initializer.
    *
-   * @param node the constructor declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS].
    */
-  bool _checkForMultipleSuperInitializers(ConstructorDeclaration node) {
+  bool _checkForMultipleSuperInitializers(ConstructorDeclaration constructor) {
     int numSuperInitializers = 0;
-    for (ConstructorInitializer initializer in node.initializers) {
+    for (ConstructorInitializer initializer in constructor.initializers) {
       if (initializer is SuperConstructorInvocation) {
         numSuperInitializers++;
         if (numSuperInitializers > 1) {
@@ -4326,36 +4219,34 @@
   }
 
   /**
-   * Checks to ensure that native function bodies can only in SDK code.
+   * Checks to ensure that the given native function [body] is in SDK code.
    *
-   * @param node the native function body to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE].
    */
-  bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) {
+  bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody body) {
     if (!_isInSystemLibrary && !_hasExtUri) {
       _errorReporter.reportErrorForNode(
-          ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, node);
+          ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, body);
       return true;
     }
     return false;
   }
 
   /**
-   * This verifies that the passed 'new' instance creation expression invokes existing constructor.
+   * Verify that the given instance creation [expression] invokes an existing
+   * constructor. The [constructorName] is the constructor name. The [typeName]
+   * is the name of the type defining the constructor.
    *
-   * This method assumes that the instance creation was tested to be 'new' before being called.
+   * This method assumes that the instance creation was tested to be 'new'
+   * before being called.
    *
-   * @param node the instance creation expression to evaluate
-   * @param constructorName the constructor name, always non-`null`
-   * @param typeName the name of the type defining the constructor, always non-`null`
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR].
    */
-  bool _checkForNewWithUndefinedConstructor(InstanceCreationExpression node,
-      ConstructorName constructorName, TypeName typeName) {
+  bool _checkForNewWithUndefinedConstructor(
+      InstanceCreationExpression expression, ConstructorName constructorName,
+      TypeName typeName) {
     // OK if resolved
-    if (node.staticElement != null) {
+    if (expression.staticElement != null) {
       return false;
     }
     DartType type = typeName.type;
@@ -4385,14 +4276,14 @@
   }
 
   /**
-   * This checks that if the passed class declaration implicitly calls default constructor of its
-   * superclass, there should be such default constructor - implicit or explicit.
+   * Check that if the given class [declaration] implicitly calls default
+   * constructor of its superclass, there should be such default constructor -
+   * implicit or explicit.
    *
-   * @param node the [ClassDeclaration] to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT].
    */
-  bool _checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) {
+  bool _checkForNoDefaultSuperConstructorImplicit(
+      ClassDeclaration declaration) {
     // do nothing if mixin errors have already been reported for this class.
     ClassElementImpl enclosingClass = _enclosingClass;
     if (enclosingClass.mixinErrorsReported) {
@@ -4415,9 +4306,8 @@
     if (superUnnamedConstructor != null) {
       if (superUnnamedConstructor.isFactory) {
         _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.name, [
-          superUnnamedConstructor
-        ]);
+            CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, declaration.name,
+            [superUnnamedConstructor]);
         return true;
       }
       if (superUnnamedConstructor.isDefaultConstructor &&
@@ -4428,19 +4318,17 @@
     }
     // report problem
     _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, [
-      superType.displayName
-    ]);
+        CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
+        declaration.name, [superType.displayName]);
     return true;
   }
 
   /**
-   * This checks that passed class declaration overrides all members required by its superclasses
-   * and interfaces.
+   * Check that the given class declaration overrides all members required by
+   * its superclasses and interfaces. The [classNameNode] is the
+   * [SimpleIdentifier] to be used if there is a violation, this is either the
+   * named from the [ClassDeclaration] or from the [ClassTypeAlias].
    *
-   * @param classNameNode the [SimpleIdentifier] to be used if there is a violation, this is
-   *          either the named from the [ClassDeclaration] or from the [ClassTypeAlias].
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE],
    * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO],
    * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE],
@@ -4613,11 +4501,9 @@
   }
 
   /**
-   * Checks to ensure that the expressions that need to be of type bool, are. Otherwise an error is
-   * reported on the expression.
+   * Check to ensure that the [condition] is of type bool, are. Otherwise an
+   * error is reported on the expression.
    *
-   * @param condition the conditional expression to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.NON_BOOL_CONDITION].
    */
   bool _checkForNonBoolCondition(Expression condition) {
@@ -4631,14 +4517,13 @@
   }
 
   /**
-   * This verifies that the passed assert statement has either a 'bool' or '() -> bool' input.
+   * Verify that the given assert [statement] has either a 'bool' or
+   * '() -> bool' input.
    *
-   * @param node the assert statement to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.NON_BOOL_EXPRESSION].
    */
-  bool _checkForNonBoolExpression(AssertStatement node) {
-    Expression expression = node.condition;
+  bool _checkForNonBoolExpression(AssertStatement statement) {
+    Expression expression = statement.condition;
     DartType type = getStaticType(expression);
     if (type is InterfaceType) {
       if (!type.isAssignableTo(_boolType)) {
@@ -4659,10 +4544,8 @@
   }
 
   /**
-   * Checks to ensure that the given expression is assignable to bool.
+   * Checks to ensure that the given [expression] is assignable to bool.
    *
-   * @param expression the expression expression to test
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.NON_BOOL_NEGATION_EXPRESSION].
    */
   bool _checkForNonBoolNegationExpression(Expression expression) {
@@ -4676,56 +4559,52 @@
   }
 
   /**
-   * This verifies the passed map literal either:
+   * Verify the given map [literal] either:
    * * has `const modifier`
    * * has explicit type arguments
    * * is not start of the statement
    *
-   * @param node the map literal to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT].
    */
-  bool _checkForNonConstMapAsExpressionStatement(MapLiteral node) {
+  bool _checkForNonConstMapAsExpressionStatement(MapLiteral literal) {
     // "const"
-    if (node.constKeyword != null) {
+    if (literal.constKeyword != null) {
       return false;
     }
     // has type arguments
-    if (node.typeArguments != null) {
+    if (literal.typeArguments != null) {
       return false;
     }
     // prepare statement
     Statement statement =
-        node.getAncestor((node) => node is ExpressionStatement);
+        literal.getAncestor((node) => node is ExpressionStatement);
     if (statement == null) {
       return false;
     }
     // OK, statement does not start with map
-    if (!identical(statement.beginToken, node.beginToken)) {
+    if (!identical(statement.beginToken, literal.beginToken)) {
       return false;
     }
     // report problem
     _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, node);
+        CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, literal);
     return true;
   }
 
   /**
-   * This verifies the passed method declaration of operator `[]=`, has `void` return
-   * type.
+   * Verify that the given method [declaration] of operator `[]=`, has `void`
+   * return type.
    *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR].
    */
-  bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration node) {
+  bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration declaration) {
     // check that []= operator
-    SimpleIdentifier name = node.name;
+    SimpleIdentifier name = declaration.name;
     if (name.name != "[]=") {
       return false;
     }
     // check return type
-    TypeName typeName = node.returnType;
+    TypeName typeName = declaration.returnType;
     if (typeName != null) {
       DartType type = typeName.type;
       if (type != null && !type.isVoid) {
@@ -4738,10 +4617,9 @@
   }
 
   /**
-   * This verifies the passed setter has no return type or the `void` return type.
+   * Verify the [typeName], used as the return type of a setter, is valid
+   * (either `null` or the type 'void').
    *
-   * @param typeName the type name to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER].
    */
   bool _checkForNonVoidReturnTypeForSetter(TypeName typeName) {
@@ -4756,17 +4634,14 @@
   }
 
   /**
-   * This verifies the passed operator-method declaration, does not have an optional parameter.
+   * Verify the given operator-method [declaration], does not have an optional
+   * parameter. This method assumes that the method declaration was tested to be
+   * an operator declaration before being called.
    *
-   * This method assumes that the method declaration was tested to be an operator declaration before
-   * being called.
-   *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR].
    */
-  bool _checkForOptionalParameterInOperator(MethodDeclaration node) {
-    FormalParameterList parameterList = node.parameters;
+  bool _checkForOptionalParameterInOperator(MethodDeclaration declaration) {
+    FormalParameterList parameterList = declaration.parameters;
     if (parameterList == null) {
       return false;
     }
@@ -4784,46 +4659,42 @@
   }
 
   /**
-   * This checks for named optional parameters that begin with '_'.
+   * Check that the given named optional [parameter] does not begin with '_'.
    *
-   * @param node the default formal parameter to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER].
    */
-  bool _checkForPrivateOptionalParameter(FormalParameter node) {
+  bool _checkForPrivateOptionalParameter(FormalParameter parameter) {
     // should be named parameter
-    if (node.kind != ParameterKind.NAMED) {
+    if (parameter.kind != ParameterKind.NAMED) {
       return false;
     }
     // name should start with '_'
-    SimpleIdentifier name = node.identifier;
+    SimpleIdentifier name = parameter.identifier;
     if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) {
       return false;
     }
     // report problem
     _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, node);
+        CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, parameter);
     return true;
   }
 
   /**
-   * This checks if the passed constructor declaration is the redirecting generative constructor and
-   * references itself directly or indirectly.
+   * Check whether the given constructor [declaration] is the redirecting
+   * generative constructor and references itself directly or indirectly. The
+   * [constructorElement] is the constructor element.
    *
-   * @param node the constructor declaration to evaluate
-   * @param constructorElement the constructor element
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT].
    */
-  bool _checkForRecursiveConstructorRedirect(
-      ConstructorDeclaration node, ConstructorElement constructorElement) {
+  bool _checkForRecursiveConstructorRedirect(ConstructorDeclaration declaration,
+      ConstructorElement constructorElement) {
     // we check generative constructor here
-    if (node.factoryKeyword != null) {
+    if (declaration.factoryKeyword != null) {
       return false;
     }
     // try to find redirecting constructor invocation and analyzer it for
     // recursion
-    for (ConstructorInitializer initializer in node.initializers) {
+    for (ConstructorInitializer initializer in declaration.initializers) {
       if (initializer is RedirectingConstructorInvocation) {
         // OK if no cycle
         if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) {
@@ -4840,23 +4711,22 @@
   }
 
   /**
-   * This checks if the passed constructor declaration has redirected constructor and references
-   * itself directly or indirectly.
+   * Check whether the given constructor [declaration] has redirected
+   * constructor and references itself directly or indirectly. The
+   * constructor [element] is the element introduced by the declaration.
    *
-   * @param node the constructor declaration to evaluate
-   * @param constructorElement the constructor element
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT].
    */
   bool _checkForRecursiveFactoryRedirect(
-      ConstructorDeclaration node, ConstructorElement constructorElement) {
+      ConstructorDeclaration declaration, ConstructorElement element) {
     // prepare redirected constructor
-    ConstructorName redirectedConstructorNode = node.redirectedConstructor;
+    ConstructorName redirectedConstructorNode =
+        declaration.redirectedConstructor;
     if (redirectedConstructorNode == null) {
       return false;
     }
     // OK if no cycle
-    if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) {
+    if (!_hasRedirectingFactoryConstructorCycle(element)) {
       return false;
     }
     // report error
@@ -4867,42 +4737,40 @@
   }
 
   /**
-   * This checks the class declaration is not a superinterface to itself.
+   * Check that the class [element] is not a superinterface to itself.
    *
-   * @param classElt the class element to test
-   * @return `true` if and only if an error code is generated on the passed element
    * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE],
    * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], and
    * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS].
    */
-  bool _checkForRecursiveInterfaceInheritance(ClassElement classElt) {
-    if (classElt == null) {
+  bool _checkForRecursiveInterfaceInheritance(ClassElement element) {
+    if (element == null) {
       return false;
     }
     return _safeCheckForRecursiveInterfaceInheritance(
-        classElt, new List<ClassElement>());
+        element, new List<ClassElement>());
   }
 
   /**
-   * This checks the passed constructor declaration has a valid combination of redirected
-   * constructor invocation(s), super constructor invocations and field initializers.
+   * Check that the given constructor [declaration] has a valid combination of
+   * redirected constructor invocation(s), super constructor invocations and
+   * field initializers.
    *
-   * @param node the constructor declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR],
    * [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR],
    * [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS],
    * [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR], and
    * [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR].
    */
-  bool _checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) {
+  bool _checkForRedirectingConstructorErrorCodes(
+      ConstructorDeclaration declaration) {
     bool errorReported = false;
     //
     // Check for default values in the parameters
     //
-    ConstructorName redirectedConstructor = node.redirectedConstructor;
+    ConstructorName redirectedConstructor = declaration.redirectedConstructor;
     if (redirectedConstructor != null) {
-      for (FormalParameter parameter in node.parameters.parameters) {
+      for (FormalParameter parameter in declaration.parameters.parameters) {
         if (parameter is DefaultFormalParameter &&
             parameter.defaultValue != null) {
           _errorReporter.reportErrorForNode(
@@ -4914,7 +4782,7 @@
     }
     // check if there are redirected invocations
     int numRedirections = 0;
-    for (ConstructorInitializer initializer in node.initializers) {
+    for (ConstructorInitializer initializer in declaration.initializers) {
       if (initializer is RedirectingConstructorInvocation) {
         if (numRedirections > 0) {
           _errorReporter.reportErrorForNode(
@@ -4922,7 +4790,7 @@
               initializer);
           errorReported = true;
         }
-        if (node.factoryKeyword == null) {
+        if (declaration.factoryKeyword == null) {
           RedirectingConstructorInvocation invocation = initializer;
           ConstructorElement redirectingElement = invocation.staticElement;
           if (redirectingElement == null) {
@@ -4947,7 +4815,7 @@
     }
     // check for other initializers
     if (numRedirections > 0) {
-      for (ConstructorInitializer initializer in node.initializers) {
+      for (ConstructorInitializer initializer in declaration.initializers) {
         if (initializer is SuperConstructorInvocation) {
           _errorReporter.reportErrorForNode(
               CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR,
@@ -4967,32 +4835,30 @@
   }
 
   /**
-   * This checks if the passed constructor declaration has redirected constructor and references
-   * itself directly or indirectly.
+   * Check whether the given constructor [declaration] has redirected
+   * constructor and references itself directly or indirectly. The
+   * constructor [element] is the element introduced by the declaration.
    *
-   * @param node the constructor declaration to evaluate
-   * @param constructorElement the constructor element
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR].
    */
   bool _checkForRedirectToNonConstConstructor(
-      ConstructorDeclaration node, ConstructorElement constructorElement) {
+      ConstructorDeclaration declaration, ConstructorElement element) {
     // prepare redirected constructor
-    ConstructorName redirectedConstructorNode = node.redirectedConstructor;
+    ConstructorName redirectedConstructorNode =
+        declaration.redirectedConstructor;
     if (redirectedConstructorNode == null) {
       return false;
     }
     // prepare element
-    if (constructorElement == null) {
+    if (element == null) {
       return false;
     }
     // OK, it is not 'const'
-    if (!constructorElement.isConst) {
+    if (!element.isConst) {
       return false;
     }
     // prepare redirected constructor
-    ConstructorElement redirectedConstructor =
-        constructorElement.redirectedConstructor;
+    ConstructorElement redirectedConstructor = element.redirectedConstructor;
     if (redirectedConstructor == null) {
       return false;
     }
@@ -5008,36 +4874,33 @@
   }
 
   /**
-   * This checks that the rethrow is inside of a catch clause.
+   * Check that the given rethrow [expression] is inside of a catch clause.
    *
-   * @param node the rethrow expression to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH].
    */
-  bool _checkForRethrowOutsideCatch(RethrowExpression node) {
+  bool _checkForRethrowOutsideCatch(RethrowExpression expression) {
     if (!_isInCatchClause) {
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, node);
+          CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, expression);
       return true;
     }
     return false;
   }
 
   /**
-   * This checks that if the the given constructor declaration is generative, then it does not have
-   * an expression function body.
+   * Check that if the the given constructor [declaration] is generative, then
+   * it does not have an expression function body.
    *
-   * @param node the constructor to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR].
    */
-  bool _checkForReturnInGenerativeConstructor(ConstructorDeclaration node) {
+  bool _checkForReturnInGenerativeConstructor(
+      ConstructorDeclaration declaration) {
     // ignore factory
-    if (node.factoryKeyword != null) {
+    if (declaration.factoryKeyword != null) {
       return false;
     }
     // block body (with possible return statement) is checked elsewhere
-    FunctionBody body = node.body;
+    FunctionBody body = declaration.body;
     if (body is! ExpressionFunctionBody) {
       return false;
     }
@@ -5048,15 +4911,12 @@
   }
 
   /**
-   * This checks that a type mis-match between the return type and the expressed return type by the
-   * enclosing method or function.
+   * Check that a type mis-match between the type of the [returnExpression] and
+   * the [expectedReturnType] by the enclosing method or function.
    *
-   * This method is called both by [checkForAllReturnStatementErrorCodes]
+   * This method is called both by [_checkForAllReturnStatementErrorCodes]
    * and [visitExpressionFunctionBody].
    *
-   * @param returnExpression the returned expression to evaluate
-   * @param expectedReturnType the expressed return type by the enclosing method or function
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE].
    */
   bool _checkForReturnOfInvalidType(
@@ -5112,14 +4972,9 @@
   }
 
   /**
-   * This checks the given "typeReference" and that the "name" is not the reference to an instance
-   * member.
+   * Check the given [typeReference] and that the [name] is not the reference to
+   * an instance member.
    *
-   * @param typeReference the resolved [ClassElement] of the left hand side of the expression,
-   *          or `null`, aka, the class element of 'C' in 'C.x', see
-   *          [getTypeReference]
-   * @param name the accessed name to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER].
    */
   bool _checkForStaticAccessToInstanceMember(
@@ -5145,22 +5000,20 @@
   }
 
   /**
-   * This checks that the type of the passed 'switch' expression is assignable to the type of the
-   * 'case' members.
+   * Check that the type of the expression in the given 'switch' [statement] is
+   * assignable to the type of the 'case' members.
    *
-   * @param node the 'switch' statement to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE].
    */
-  bool _checkForSwitchExpressionNotAssignable(SwitchStatement node) {
+  bool _checkForSwitchExpressionNotAssignable(SwitchStatement statement) {
     // prepare 'switch' expression type
-    Expression expression = node.expression;
+    Expression expression = statement.expression;
     DartType expressionType = getStaticType(expression);
     if (expressionType == null) {
       return false;
     }
     // compare with type of the first 'case'
-    NodeList<SwitchMember> members = node.members;
+    NodeList<SwitchMember> members = statement.members;
     for (SwitchMember switchMember in members) {
       if (switchMember is! SwitchCase) {
         continue;
@@ -5185,51 +5038,47 @@
   }
 
   /**
-   * This verifies that the passed function type alias does not reference itself directly.
+   * Verify that the given function type [alias] does not reference itself
+   * directly.
    *
-   * @param node the function type alias to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF].
    */
   bool _checkForTypeAliasCannotReferenceItself_function(
-      FunctionTypeAlias node) {
-    FunctionTypeAliasElement element = node.element;
+      FunctionTypeAlias alias) {
+    FunctionTypeAliasElement element = alias.element;
     if (!_hasTypedefSelfReference(element)) {
       return false;
     }
     _errorReporter.reportErrorForNode(
-        CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node);
+        CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, alias);
     return true;
   }
 
   /**
-   * This verifies that the passed type name is not a deferred type.
+   * Verify that the given type [name] is not a deferred type.
    *
-   * @param expression the expression to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS].
    */
-  bool _checkForTypeAnnotationDeferredClass(TypeName node) {
-    if (node != null && node.isDeferred) {
+  bool _checkForTypeAnnotationDeferredClass(TypeName name) {
+    if (name != null && name.isDeferred) {
       _errorReporter.reportErrorForNode(
-          StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, node, [node.name]);
+          StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, name, [name.name]);
     }
     return false;
   }
 
   /**
-   * This verifies that the type arguments in the passed type name are all within their bounds.
+   * Verify that the type arguments in the given [typeName] are all within
+   * their bounds.
    *
-   * @param node the [TypeName] to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
    */
-  bool _checkForTypeArgumentNotMatchingBounds(TypeName node) {
-    if (node.typeArguments == null) {
+  bool _checkForTypeArgumentNotMatchingBounds(TypeName typeName) {
+    if (typeName.typeArguments == null) {
       return false;
     }
     // prepare Type
-    DartType type = node.type;
+    DartType type = typeName.type;
     if (type == null) {
       return false;
     }
@@ -5243,7 +5092,7 @@
     List<DartType> typeParameters = classElement.type.typeArguments;
     List<TypeParameterElement> boundingElts = classElement.typeParameters;
     // iterate over each bounded type parameter and corresponding argument
-    NodeList<TypeName> typeNameArgList = node.typeArguments.arguments;
+    NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments;
     List<DartType> typeArguments = (type as InterfaceType).typeArguments;
     int loopThroughIndex =
         math.min(typeNameArgList.length, boundingElts.length);
@@ -5274,19 +5123,17 @@
   }
 
   /**
-   * This checks that if the passed type name is a type parameter being used to define a static
-   * member.
+   * Check whether the given type [name] is a type parameter being used to
+   * define a static member.
    *
-   * @param node the type name to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC].
    */
-  bool _checkForTypeParameterReferencedByStatic(TypeName node) {
+  bool _checkForTypeParameterReferencedByStatic(TypeName name) {
     if (_isInStaticMethod || _isInStaticVariableDeclaration) {
-      DartType type = node.type;
+      DartType type = name.type;
       if (type is TypeParameterType) {
         _errorReporter.reportErrorForNode(
-            StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, node);
+            StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, name);
         return true;
       }
     }
@@ -5294,14 +5141,12 @@
   }
 
   /**
-   * This checks that if the passed type parameter is a supertype of its bound.
+   * Check whether the given type [parameter] is a supertype of its bound.
    *
-   * @param node the type parameter to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND].
    */
-  bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter node) {
-    TypeParameterElement element = node.element;
+  bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter parameter) {
+    TypeParameterElement element = parameter.element;
     // prepare bound
     DartType bound = element.bound;
     if (bound == null) {
@@ -5313,25 +5158,22 @@
     }
     // report problem
     _errorReporter.reportErrorForNode(
-        StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, node, [
-      element.displayName
-    ]);
+        StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, parameter,
+        [element.displayName]);
     return true;
   }
 
   /**
-   * This checks that if the passed generative constructor has neither an explicit super constructor
-   * invocation nor a redirecting constructor invocation, that the superclass has a default
-   * generative constructor.
+   * Check that if the given generative [constructor] has neither an explicit
+   * super constructor invocation nor a redirecting constructor invocation, that
+   * the superclass has a default generative constructor.
    *
-   * @param node the constructor declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT],
    * [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and
    * [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT].
    */
   bool _checkForUndefinedConstructorInInitializerImplicit(
-      ConstructorDeclaration node) {
+      ConstructorDeclaration constructor) {
     if (_enclosingClass == null) {
       return false;
     }
@@ -5343,14 +5185,15 @@
     //
     // Ignore if the constructor is not generative.
     //
-    if (node.factoryKeyword != null) {
+    if (constructor.factoryKeyword != null) {
       return false;
     }
     //
     // Ignore if the constructor has either an implicit super constructor
     // invocation or a redirecting constructor invocation.
     //
-    for (ConstructorInitializer constructorInitializer in node.initializers) {
+    for (ConstructorInitializer constructorInitializer
+        in constructor.initializers) {
       if (constructorInitializer is SuperConstructorInvocation ||
           constructorInitializer is RedirectingConstructorInvocation) {
         return false;
@@ -5370,9 +5213,8 @@
     if (superUnnamedConstructor != null) {
       if (superUnnamedConstructor.isFactory) {
         _errorReporter.reportErrorForNode(
-            CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.returnType, [
-          superUnnamedConstructor
-        ]);
+            CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR,
+            constructor.returnType, [superUnnamedConstructor]);
         return true;
       }
       if (!superUnnamedConstructor.isDefaultConstructor ||
@@ -5381,8 +5223,8 @@
         int offset;
         int length;
         {
-          Identifier returnType = node.returnType;
-          SimpleIdentifier name = node.name;
+          Identifier returnType = constructor.returnType;
+          SimpleIdentifier name = constructor.name;
           offset = returnType.offset;
           length = (name != null ? name.end : returnType.end) - offset;
         }
@@ -5394,16 +5236,14 @@
     }
     _errorReporter.reportErrorForNode(
         CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
-        node.returnType, [superElement.name]);
+        constructor.returnType, [superElement.name]);
     return true;
   }
 
   /**
-   * This checks that if the given name is a reference to a static member it is defined in the
-   * enclosing class rather than in a superclass.
+   * Check that if the given [name] is a reference to a static member it is
+   * defined in the enclosing class rather than in a superclass.
    *
-   * @param name the name to be evaluated
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER].
    */
   bool _checkForUnqualifiedReferenceToNonLocalStaticMember(
@@ -5429,16 +5269,16 @@
     return true;
   }
 
-  void _checkForValidField(FieldFormalParameter node) {
-    ParameterElement element = node.element;
+  void _checkForValidField(FieldFormalParameter parameter) {
+    ParameterElement element = parameter.element;
     if (element is FieldFormalParameterElement) {
       FieldElement fieldElement = element.field;
       if (fieldElement == null || fieldElement.isSynthetic) {
         _errorReporter.reportErrorForNode(
             CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
-            node, [node.identifier.name]);
+            parameter, [parameter.identifier.name]);
       } else {
-        ParameterElement parameterElement = node.element;
+        ParameterElement parameterElement = parameter.element;
         if (parameterElement is FieldFormalParameterElementImpl) {
           FieldFormalParameterElementImpl fieldFormal = parameterElement;
           DartType declaredType = fieldFormal.type;
@@ -5446,27 +5286,27 @@
           if (fieldElement.isSynthetic) {
             _errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
-                node, [node.identifier.name]);
+                parameter, [parameter.identifier.name]);
           } else if (fieldElement.isStatic) {
             _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node,
-                [node.identifier.name]);
+                CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD,
+                parameter, [parameter.identifier.name]);
           } else if (declaredType != null &&
               fieldType != null &&
               !declaredType.isAssignableTo(fieldType)) {
             _errorReporter.reportTypeErrorForNode(
                 StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE,
-                node, [declaredType, fieldType]);
+                parameter, [declaredType, fieldType]);
           }
         } else {
           if (fieldElement.isSynthetic) {
             _errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD,
-                node, [node.identifier.name]);
+                parameter, [parameter.identifier.name]);
           } else if (fieldElement.isStatic) {
             _errorReporter.reportErrorForNode(
-                CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node,
-                [node.identifier.name]);
+                CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD,
+                parameter, [parameter.identifier.name]);
           }
         }
       }
@@ -5478,14 +5318,12 @@
   }
 
   /**
-   * This verifies that the given getter does not have a return type of 'void'.
+   * Verify that the given [getter] does not have a return type of 'void'.
    *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.VOID_RETURN_FOR_GETTER].
    */
-  bool _checkForVoidReturnType(MethodDeclaration node) {
-    TypeName returnType = node.returnType;
+  bool _checkForVoidReturnType(MethodDeclaration getter) {
+    TypeName returnType = getter.returnType;
     if (returnType == null || returnType.name.name != "void") {
       return false;
     }
@@ -5495,24 +5333,24 @@
   }
 
   /**
-   * This verifies the passed operator-method declaration, has correct number of parameters.
+   * Verify the given operator-method [declaration], has correct number of
+   * parameters.
    *
-   * This method assumes that the method declaration was tested to be an operator declaration before
-   * being called.
+   * This method assumes that the method declaration was tested to be an
+   * operator declaration before being called.
    *
-   * @param node the method declaration to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR].
    */
-  bool _checkForWrongNumberOfParametersForOperator(MethodDeclaration node) {
+  bool _checkForWrongNumberOfParametersForOperator(
+      MethodDeclaration declaration) {
     // prepare number of parameters
-    FormalParameterList parameterList = node.parameters;
+    FormalParameterList parameterList = declaration.parameters;
     if (parameterList == null) {
       return false;
     }
     int numParameters = parameterList.parameters.length;
     // prepare operator name
-    SimpleIdentifier nameNode = node.name;
+    SimpleIdentifier nameNode = declaration.name;
     if (nameNode == null) {
       return false;
     }
@@ -5559,13 +5397,13 @@
   }
 
   /**
-   * This verifies if the passed setter parameter list have only one required parameter.
+   * Verify that the given setter [parameterList] has only one required
+   * parameter. The [setterName] is the name of the setter to report problems
+   * on.
    *
-   * This method assumes that the method declaration was tested to be a setter before being called.
+   * This method assumes that the method declaration was tested to be a setter
+   * before being called.
    *
-   * @param setterName the name of the setter to report problems on
-   * @param parameterList the parameter list to evaluate
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER].
    */
   bool _checkForWrongNumberOfParametersForSetter(
@@ -5642,17 +5480,16 @@
   }
 
   /**
-   * This verifies that if the given class declaration implements the class Function that it has a
-   * concrete implementation of the call method.
+   * Verify that if the given class [declaration] implements the class Function
+   * that it has a concrete implementation of the call method.
    *
-   * @return `true` if and only if an error code is generated on the passed node
    * See [StaticWarningCode.FUNCTION_WITHOUT_CALL].
    */
-  bool _checkImplementsFunctionWithoutCall(ClassDeclaration node) {
-    if (node.isAbstract) {
+  bool _checkImplementsFunctionWithoutCall(ClassDeclaration declaration) {
+    if (declaration.isAbstract) {
       return false;
     }
-    ClassElement classElement = node.element;
+    ClassElement classElement = declaration.element;
     if (classElement == null) {
       return false;
     }
@@ -5665,33 +5502,32 @@
         null) {
       return false;
     }
-    ExecutableElement callMethod =
-        _inheritanceManager.lookupMember(classElement, "call");
+    ExecutableElement callMethod = _inheritanceManager.lookupMember(
+        classElement, FunctionElement.CALL_METHOD_NAME);
     if (callMethod == null ||
         callMethod is! MethodElement ||
         (callMethod as MethodElement).isAbstract) {
       _errorReporter.reportErrorForNode(
-          StaticWarningCode.FUNCTION_WITHOUT_CALL, node.name);
+          StaticWarningCode.FUNCTION_WITHOUT_CALL, declaration.name);
       return true;
     }
     return false;
   }
 
   /**
-   * This verifies that the given class declaration does not have the same class in the 'extends'
-   * and 'implements' clauses.
+   * Verify that the given class [declaration] does not have the same class in
+   * the 'extends' and 'implements' clauses.
    *
-   * @return `true` if and only if an error code is generated on the passed node
    * See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS].
    */
-  bool _checkImplementsSuperClass(ClassDeclaration node) {
+  bool _checkImplementsSuperClass(ClassDeclaration declaration) {
     // prepare super type
     InterfaceType superType = _enclosingClass.supertype;
     if (superType == null) {
       return false;
     }
     // prepare interfaces
-    ImplementsClause implementsClause = node.implementsClause;
+    ImplementsClause implementsClause = declaration.implementsClause;
     if (implementsClause == null) {
       return false;
     }
@@ -5730,17 +5566,15 @@
   }
 
   /**
-   * Return the error code that should be used when the given class references itself directly.
-   *
-   * @param classElt the class that references itself
-   * @return the error code that should be used
+   * Return the error code that should be used when the given class [element]
+   * references itself directly.
    */
-  ErrorCode _getBaseCaseErrorCode(ClassElement classElt) {
-    InterfaceType supertype = classElt.supertype;
+  ErrorCode _getBaseCaseErrorCode(ClassElement element) {
+    InterfaceType supertype = element.supertype;
     if (supertype != null && _enclosingClass == supertype.element) {
       return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS;
     }
-    List<InterfaceType> mixins = classElt.mixins;
+    List<InterfaceType> mixins = element.mixins;
     for (int i = 0; i < mixins.length; i++) {
       if (_enclosingClass == mixins[i].element) {
         return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH;
@@ -5750,11 +5584,8 @@
   }
 
   /**
-   * Given an expression in a switch case whose value is expected to be an enum constant, return the
-   * name of the constant.
-   *
-   * @param expression the expression from the switch case
-   * @return the name of the constant referenced by the expression
+   * Given an [expression] in a switch case whose value is expected to be an
+   * enum constant, return the name of the constant.
    */
   String _getConstantName(Expression expression) {
     // TODO(brianwilkerson) Convert this to return the element representing the
@@ -5770,13 +5601,10 @@
   }
 
   /**
-   * Returns the Type (return type) for a given getter.
-   *
-   * @param propertyAccessorElement
-   * @return The type of the given getter.
+   * Return the return type of the given [getter].
    */
-  DartType _getGetterType(PropertyAccessorElement propertyAccessorElement) {
-    FunctionType functionType = propertyAccessorElement.type;
+  DartType _getGetterType(PropertyAccessorElement getter) {
+    FunctionType functionType = getter.type;
     if (functionType != null) {
       return functionType.returnType;
     } else {
@@ -5785,15 +5613,11 @@
   }
 
   /**
-   * Returns the Type (first and only parameter) for a given setter.
-   *
-   * @param propertyAccessorElement
-   * @return The type of the given setter.
+   * Return the type of the first and only parameter of the given [setter].
    */
-  DartType _getSetterType(PropertyAccessorElement propertyAccessorElement) {
+  DartType _getSetterType(PropertyAccessorElement setter) {
     // Get the parameters for MethodDeclaration or FunctionDeclaration
-    List<ParameterElement> setterParameters =
-        propertyAccessorElement.parameters;
+    List<ParameterElement> setterParameters = setter.parameters;
     // If there are no setter parameters, return no type.
     if (setterParameters.length == 0) {
       return null;
@@ -5802,11 +5626,9 @@
   }
 
   /**
-   * Given a list of directives that have the same prefix, generate an error if there is more than
-   * one import and any of those imports is deferred.
+   * Given a list of [directives] that have the same prefix, generate an error
+   * if there is more than one import and any of those imports is deferred.
    *
-   * @param directives the list of directives that have the same prefix
-   * @return `true` if an error was generated
    * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX].
    */
   bool _hasDeferredPrefixCollision(List<ImportDirective> directives) {
@@ -5826,14 +5648,15 @@
   }
 
   /**
-   * @return `true` if the given constructor redirects to itself, directly or indirectly
+   * Return `true` if the given [constructor] redirects to itself, directly or
+   * indirectly.
    */
-  bool _hasRedirectingFactoryConstructorCycle(ConstructorElement element) {
+  bool _hasRedirectingFactoryConstructorCycle(ConstructorElement constructor) {
     Set<ConstructorElement> constructors = new HashSet<ConstructorElement>();
-    ConstructorElement current = element;
+    ConstructorElement current = constructor;
     while (current != null) {
       if (constructors.contains(current)) {
-        return identical(current, element);
+        return identical(current, constructor);
       }
       constructors.add(current);
       current = current.redirectedConstructor;
@@ -5845,16 +5668,16 @@
   }
 
   /**
-   * @return <code>true</code> if given [Element] has direct or indirect reference to itself
-   *         from anywhere except [ClassElement] or type parameter bounds.
+   * Return `true` if the given [element] has direct or indirect reference to
+   * itself from anywhere except a class element or type parameter bounds.
    */
-  bool _hasTypedefSelfReference(Element target) {
+  bool _hasTypedefSelfReference(Element element) {
     Set<Element> checked = new HashSet<Element>();
     List<Element> toCheck = new List<Element>();
     GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference elementVisitor =
         new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(
             toCheck);
-    toCheck.add(target);
+    toCheck.add(element);
     bool firstIteration = true;
     while (true) {
       Element current;
@@ -5866,7 +5689,7 @@
         }
         // try to get next element
         current = toCheck.removeAt(toCheck.length - 1);
-        if (target == current) {
+        if (element == current) {
           if (firstIteration) {
             firstIteration = false;
             break;
@@ -5898,47 +5721,44 @@
   }
 
   /**
-   * Return `true` iff the passed [ClassElement] has a method, getter or setter that
-   * matches the name of the passed [ExecutableElement] in either the class itself, or one of
-   * its' mixins that is concrete.
+   * Return `true` iff the given [classElement] has a concrete method, getter or
+   * setter that matches the name of the given [executableElement] in either the
+   * class itself, or one of its' mixins.
    *
-   * By "match", only the name of the member is tested to match, it does not have to equal or be a
-   * subtype of the passed executable element, this is due to the specific use where this method is
-   * used in [checkForNonAbstractClassInheritsAbstractMember].
-   *
-   * @param executableElt the executable to search for in the passed class element
-   * @param classElt the class method to search through the members of
-   * @return `true` iff the passed member is found in the passed class element
+   * By "match", only the name of the member is tested to match, it does not
+   * have to equal or be a subtype of the given executable element, this is due
+   * to the specific use where this method is used in
+   * [_checkForNonAbstractClassInheritsAbstractMember].
    */
   bool _isMemberInClassOrMixin(
-      ExecutableElement executableElt, ClassElement classElt) {
+      ExecutableElement executableElement, ClassElement classElement) {
     ExecutableElement foundElt = null;
-    String executableName = executableElt.name;
-    if (executableElt is MethodElement) {
-      foundElt = classElt.getMethod(executableName);
+    String executableName = executableElement.name;
+    if (executableElement is MethodElement) {
+      foundElt = classElement.getMethod(executableName);
       if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
         return true;
       }
-      List<InterfaceType> mixins = classElt.mixins;
+      List<InterfaceType> mixins = classElement.mixins;
       for (int i = 0; i < mixins.length && foundElt == null; i++) {
         foundElt = mixins[i].getMethod(executableName);
       }
       if (foundElt != null && !(foundElt as MethodElement).isAbstract) {
         return true;
       }
-    } else if (executableElt is PropertyAccessorElement) {
-      PropertyAccessorElement propertyAccessorElement = executableElt;
+    } else if (executableElement is PropertyAccessorElement) {
+      PropertyAccessorElement propertyAccessorElement = executableElement;
       if (propertyAccessorElement.isGetter) {
-        foundElt = classElt.getGetter(executableName);
+        foundElt = classElement.getGetter(executableName);
       }
       if (foundElt == null && propertyAccessorElement.isSetter) {
-        foundElt = classElt.getSetter(executableName);
+        foundElt = classElement.getSetter(executableName);
       }
       if (foundElt != null &&
           !(foundElt as PropertyAccessorElement).isAbstract) {
         return true;
       }
-      List<InterfaceType> mixins = classElt.mixins;
+      List<InterfaceType> mixins = classElement.mixins;
       for (int i = 0; i < mixins.length && foundElt == null; i++) {
         foundElt = mixins[i].getGetter(executableName);
         if (foundElt == null) {
@@ -5954,53 +5774,47 @@
   }
 
   /**
-   * @param node the 'this' expression to analyze
-   * @return `true` if the given 'this' expression is in the valid context
+   * Return `true` if the given 'this' [expression] is in a valid context.
    */
-  bool _isThisInValidContext(ThisExpression node) {
-    for (AstNode n = node; n != null; n = n.parent) {
-      if (n is CompilationUnit) {
+  bool _isThisInValidContext(ThisExpression expression) {
+    for (AstNode node = expression.parent; node != null; node = node.parent) {
+      if (node is CompilationUnit) {
         return false;
       }
-      if (n is ConstructorDeclaration) {
-        ConstructorDeclaration constructor = n as ConstructorDeclaration;
-        return constructor.factoryKeyword == null;
+      if (node is ConstructorDeclaration) {
+        return node.factoryKeyword == null;
       }
-      if (n is ConstructorInitializer) {
+      if (node is ConstructorInitializer) {
         return false;
       }
-      if (n is MethodDeclaration) {
-        MethodDeclaration method = n as MethodDeclaration;
-        return !method.isStatic;
+      if (node is MethodDeclaration) {
+        return !node.isStatic;
       }
     }
     return false;
   }
 
   /**
-   * Return `true` if the given identifier is in a location where it is allowed to resolve to
-   * a static member of a supertype.
-   *
-   * @param node the node being tested
-   * @return `true` if the given identifier is in a location where it is allowed to resolve to
-   *         a static member of a supertype
+   * Return `true` if the given [identifier] is in a location where it is
+   * allowed to resolve to a static member of a supertype.
    */
   bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed(
-      SimpleIdentifier node) {
-    if (node.inDeclarationContext()) {
+      SimpleIdentifier identifier) {
+    if (identifier.inDeclarationContext()) {
       return true;
     }
-    AstNode parent = node.parent;
+    AstNode parent = identifier.parent;
     if (parent is ConstructorName ||
         parent is MethodInvocation ||
         parent is PropertyAccess ||
         parent is SuperConstructorInvocation) {
       return true;
     }
-    if (parent is PrefixedIdentifier && identical(parent.identifier, node)) {
+    if (parent is PrefixedIdentifier &&
+        identical(parent.identifier, identifier)) {
       return true;
     }
-    if (parent is Annotation && identical(parent.constructorName, node)) {
+    if (parent is Annotation && identical(parent.constructorName, identifier)) {
       return true;
     }
     if (parent is CommentReference) {
@@ -6016,23 +5830,21 @@
       (result.value != null && result.value.isUserDefinedObject);
 
   /**
-   * This checks the class declaration is not a superinterface to itself.
+   * Check that the given class [element] is not a superinterface to itself. The
+   * [path] is a list containing the potentially cyclic implements path.
    *
-   * @param classElt the class element to test
-   * @param path a list containing the potentially cyclic implements path
-   * @return `true` if and only if an error code is generated on the passed element
    * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE],
    * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS],
-   * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS], and
-   * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH].
+   * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS],
+   * and [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH].
    */
   bool _safeCheckForRecursiveInterfaceInheritance(
-      ClassElement classElt, List<ClassElement> path) {
+      ClassElement element, List<ClassElement> path) {
     // Detect error condition.
     int size = path.length;
     // If this is not the base case (size > 0), and the enclosing class is the
-    // passed class element then an error an error.
-    if (size > 0 && _enclosingClass == classElt) {
+    // given class element then an error an error.
+    if (size > 0 && _enclosingClass == element) {
       String enclosingClassName = _enclosingClass.displayName;
       if (size > 1) {
         // Construct a string showing the cyclic implements path:
@@ -6043,7 +5855,7 @@
           buffer.write(path[i].displayName);
           buffer.write(separator);
         }
-        buffer.write(classElt.displayName);
+        buffer.write(element.displayName);
         _errorReporter.reportErrorForOffset(
             CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
             _enclosingClass.nameOffset, enclosingClassName.length, [
@@ -6055,31 +5867,30 @@
         // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or
         // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or
         // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH
-        _errorReporter.reportErrorForOffset(_getBaseCaseErrorCode(classElt),
-            _enclosingClass.nameOffset, enclosingClassName.length, [
-          enclosingClassName
-        ]);
+        _errorReporter.reportErrorForOffset(_getBaseCaseErrorCode(element),
+            _enclosingClass.nameOffset, enclosingClassName.length,
+            [enclosingClassName]);
         return true;
       }
     }
-    if (path.indexOf(classElt) > 0) {
+    if (path.indexOf(element) > 0) {
       return false;
     }
-    path.add(classElt);
+    path.add(element);
     // n-case
-    InterfaceType supertype = classElt.supertype;
+    InterfaceType supertype = element.supertype;
     if (supertype != null &&
         _safeCheckForRecursiveInterfaceInheritance(supertype.element, path)) {
       return true;
     }
-    List<InterfaceType> interfaceTypes = classElt.interfaces;
+    List<InterfaceType> interfaceTypes = element.interfaces;
     for (InterfaceType interfaceType in interfaceTypes) {
       if (_safeCheckForRecursiveInterfaceInheritance(
           interfaceType.element, path)) {
         return true;
       }
     }
-    List<InterfaceType> mixinTypes = classElt.mixins;
+    List<InterfaceType> mixinTypes = element.mixins;
     for (InterfaceType mixinType in mixinTypes) {
       if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) {
         return true;
@@ -6090,10 +5901,8 @@
   }
 
   /**
-   * Return the static type of the given expression that is to be used for type analysis.
-   *
-   * @param expression the expression whose type is to be returned
-   * @return the static type of the given expression
+   * Return the static type of the given [expression] that is to be used for
+   * type analysis.
    */
   static DartType getStaticType(Expression expression) {
     DartType type = expression.staticType;
@@ -6105,11 +5914,8 @@
   }
 
   /**
-   * Return the variable element represented by the given expression, or `null` if there is no
-   * such element.
-   *
-   * @param expression the expression whose element is to be returned
-   * @return the variable element represented by the expression
+   * Return the variable element represented by the given [expression], or
+   * `null` if there is no such element.
    */
   static VariableElement getVariableElement(Expression expression) {
     if (expression is Identifier) {
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 5832ef8..ea6aac7 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -103,7 +103,7 @@
       _captureEnclosingElements(element);
       _gatherElements(element);
       node.accept(this);
-    } on _DeclarationMismatchException catch (exception) {
+    } on _DeclarationMismatchException {
       return DeclarationMatchKind.MISMATCH;
     } finally {
       logger.exit();
@@ -268,7 +268,7 @@
     _assertSameType(node.returnType, element.returnType);
     _assertCompatibleParameters(
         node.functionExpression.parameters, element.parameters);
-    _assertBodyModifiers(node.functionExpression.body, element);
+    _assertBody(node.functionExpression.body, element);
     // matches, update the existing element
     ExecutableElement newElement = node.element;
     node.name.staticElement = element;
@@ -342,12 +342,12 @@
       _assertEquals(node.isStatic, element.isStatic);
       _assertSameType(node.returnType, element.returnType);
       _assertCompatibleParameters(node.parameters, element.parameters);
-      _assertBodyModifiers(node.body, element);
+      _assertBody(node.body, element);
       _removedElements.remove(element);
       // matches, update the existing element
       node.name.staticElement = element;
       _setLocalElements(element, newElement);
-    } on _DeclarationMismatchException catch (e) {
+    } on _DeclarationMismatchException {
       _addedElements.add(newElement);
       _removeElement(element);
       // add new element
@@ -420,12 +420,18 @@
   }
 
   /**
-   * Asserts that [body] has async / generator modifiers compatible with the
-   * given [element].
+   * Assert that the given [body] is compatible with the given [element].
+   * It should not be empty if the [element] is not an abstract class member.
+   * If it is present, it should have the same async / generator modifiers.
    */
-  void _assertBodyModifiers(FunctionBody body, ExecutableElementImpl element) {
-    _assertEquals(body.isSynchronous, element.isSynchronous);
-    _assertEquals(body.isGenerator, element.isGenerator);
+  void _assertBody(FunctionBody body, ExecutableElementImpl element) {
+    if (body is EmptyFunctionBody) {
+      _assertTrue(element.isAbstract);
+    } else {
+      _assertFalse(element.isAbstract);
+      _assertEquals(body.isSynchronous, element.isSynchronous);
+      _assertEquals(body.isGenerator, element.isGenerator);
+    }
   }
 
   void _assertCombinators(List<Combinator> nodeCombinators,
@@ -637,19 +643,19 @@
         element is CompilationUnitElement ? element : element.enclosingElement;
     while (parent != null) {
       if (parent is CompilationUnitElement) {
-        _enclosingUnit = parent as CompilationUnitElement;
+        _enclosingUnit = parent;
         _enclosingLibrary = element.library;
       } else if (parent is ClassElement) {
         if (_enclosingClass == null) {
-          _enclosingClass = parent as ClassElement;
+          _enclosingClass = parent;
         }
       } else if (parent is FunctionTypeAliasElement) {
         if (_enclosingAlias == null) {
-          _enclosingAlias = parent as FunctionTypeAliasElement;
+          _enclosingAlias = parent;
         }
       } else if (parent is ParameterElement) {
         if (_enclosingParameter == null) {
-          _enclosingParameter = parent as ParameterElement;
+          _enclosingParameter = parent;
         }
       }
       parent = parent.enclosingElement;
diff --git a/pkg/analyzer/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart
index 04ef61c..4f67072 100644
--- a/pkg/analyzer/lib/src/generated/java_core.dart
+++ b/pkg/analyzer/lib/src/generated/java_core.dart
@@ -279,6 +279,7 @@
 }
 
 class JavaSystem {
+  @deprecated
   static void arraycopy(
       List src, int srcPos, List dest, int destPos, int length) {
     for (int i = 0; i < length; i++) {
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index e918ed8..4a4823f 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -427,8 +427,7 @@
 }
 
 /**
- * Instances of the class `CommentAndMetadata` implement a simple data-holder for a method
- * that needs to return multiple values.
+ * A simple data-holder for a method that needs to return multiple values.
  */
 class CommentAndMetadata {
   /**
@@ -442,17 +441,13 @@
   final List<Annotation> metadata;
 
   /**
-   * Initialize a newly created holder with the given data.
-   *
-   * @param comment the documentation comment that was parsed
-   * @param metadata the metadata that was parsed
+   * Initialize a newly created holder with the given [comment] and [metadata].
    */
   CommentAndMetadata(this.comment, this.metadata);
 }
 
 /**
- * Instances of the class `FinalConstVarOrType` implement a simple data-holder for a method
- * that needs to return multiple values.
+ * A simple data-holder for a method that needs to return multiple values.
  */
 class FinalConstVarOrType {
   /**
@@ -466,20 +461,17 @@
   final TypeName type;
 
   /**
-   * Initialize a newly created holder with the given data.
-   *
-   * @param keyword the 'final', 'const' or 'var' keyword
-   * @param type the type
+   * Initialize a newly created holder with the given [keyword] and [type].
    */
   FinalConstVarOrType(this.keyword, this.type);
 }
 
 /**
- * Instances of the class `IncrementalParseDispatcher` implement a dispatcher that will invoke
- * the right parse method when re-parsing a specified child of the visited node. All of the methods
- * in this class assume that the parser is positioned to parse the replacement for the node. All of
- * the methods will throw an [IncrementalParseException] if the node could not be parsed for
- * some reason.
+ * A dispatcher that will invoke the right parse method when re-parsing a
+ * specified child of the visited node. All of the methods in this class assume
+ * that the parser is positioned to parse the replacement for the node. All of
+ * the methods will throw an [IncrementalParseException] if the node could not
+ * be parsed for some reason.
  */
 class IncrementalParseDispatcher implements AstVisitor<AstNode> {
   /**
@@ -493,10 +485,8 @@
   final AstNode _oldNode;
 
   /**
-   * Initialize a newly created dispatcher to parse a single node that will replace the given node.
-   *
-   * @param parser the parser used to parse the replacement for the node
-   * @param oldNode the node that is to be replaced
+   * Initialize a newly created dispatcher to parse a single node that will
+   * use the [_parser] to replace the [_oldNode].
    */
   IncrementalParseDispatcher(this._parser, this._oldNode);
 
@@ -1566,68 +1556,60 @@
   }
 
   /**
-   * Return `true` if the given assignment expression can have a cascade expression on the
-   * right-hand side.
-   *
-   * @param node the assignment expression being tested
-   * @return `true` if the right-hand side can be a cascade expression
+   * Return `true` if the given assignment [expression] can have a cascade
+   * expression on the right-hand side.
    */
-  bool _isCascadeAllowedInAssignment(AssignmentExpression node) {
+  bool _isCascadeAllowedInAssignment(AssignmentExpression expression) {
     // TODO(brianwilkerson) Implement this method.
     throw new InsufficientContextException();
   }
 
   /**
-   * Return `true` if the given throw expression can have a cascade expression.
-   *
-   * @param node the throw expression being tested
-   * @return `true` if the expression can be a cascade expression
+   * Return `true` if the given throw [expression] can have a cascade
+   * expression.
    */
-  bool _isCascadeAllowedInThrow(ThrowExpression node) {
+  bool _isCascadeAllowedInThrow(ThrowExpression expression) {
     // TODO(brianwilkerson) Implement this method.
     throw new InsufficientContextException();
   }
 
   /**
-   * Throw an exception indicating that the visited node was not the parent of the node to be
-   * replaced.
-   *
-   * @param visitedNode the visited node that should have been the parent of the node to be replaced
+   * Throw an exception indicating that the visited [node] was not the parent of
+   * the node to be replaced.
    */
-  AstNode _notAChild(AstNode visitedNode) {
+  AstNode _notAChild(AstNode node) {
     throw new IncrementalParseException.con1(
-        "Internal error: the visited node (a ${visitedNode.runtimeType}) was not the parent of the node to be replaced (a ${_oldNode.runtimeType})");
+        "Internal error: the visited node (a ${node.runtimeType}) was not the parent of the node to be replaced (a ${_oldNode.runtimeType})");
   }
 }
 
 /**
- * Instances of the class `IncrementalParseException` represent an exception that occurred
- * while attempting to parse a replacement for a specified node in an existing AST structure.
+ * An exception that occurred while attempting to parse a replacement for a
+ * specified node in an existing AST structure.
  */
 class IncrementalParseException extends RuntimeException {
   /**
-   * Initialize a newly created exception to have no message and to be its own cause.
+   * Initialize a newly created exception to have no message and to be its own
+   * cause.
    */
   IncrementalParseException() : super();
 
   /**
-   * Initialize a newly created exception to have the given message and to be its own cause.
-   *
-   * @param message the message describing the reason for the exception
+   * Initialize a newly created exception to have the given [message] and to be
+   * its own cause.
    */
   IncrementalParseException.con1(String message) : super(message: message);
 
   /**
-   * Initialize a newly created exception to have no message and to have the given cause.
-   *
-   * @param cause the exception that caused this exception
+   * Initialize a newly created exception to have no message and to have the
+   * given [cause].
    */
   IncrementalParseException.con2(Exception cause) : super(cause: cause);
 }
 
 /**
- * Instances of the class `IncrementalParser` re-parse a single AST structure within a larger
- * AST structure.
+ * An object used to re-parse a single AST structure within a larger AST
+ * structure.
  */
 class IncrementalParser {
   /**
@@ -1641,7 +1623,8 @@
   final TokenMap _tokenMap;
 
   /**
-   * The error listener that will be informed of any errors that are found during the parse.
+   * The error listener that will be informed of any errors that are found
+   * during the parse.
    */
   final AnalysisErrorListener _errorListener;
 
@@ -1651,34 +1634,31 @@
   AstNode _updatedNode;
 
   /**
-   * Initialize a newly created incremental parser to parse a portion of the content of the given
-   * source.
-   *
-   * @param source the source being parsed
-   * @param tokenMap a map from old tokens to new tokens used during the cloning process
-   * @param errorListener the error listener that will be informed of any errors that are found
-   *          during the parse
+   * Initialize a newly created incremental parser to parse a portion of the
+   * content of the given [_source]. The [_tokenMap] is a map from old tokens to
+   * new tokens that is used during the cloning process. The [_errorListener]
+   * will be informed of any errors that are found during the parse.
    */
   IncrementalParser(this._source, this._tokenMap, this._errorListener);
 
   /**
    * Return the node in the AST structure that contains the revised content.
-   *
-   * @return the updated node
    */
   AstNode get updatedNode => _updatedNode;
 
   /**
-   * Given a range of tokens that were re-scanned, re-parse the minimum number of tokens to produce
-   * a consistent AST structure. The range is represented by the first and last tokens in the range.
-   * The tokens are assumed to be contained in the same token stream.
+   * Given a range of tokens that were re-scanned, re-parse the minimum number
+   * of tokens to produce a consistent AST structure. The range is represented
+   * by the first and last tokens in the range.
    *
-   * @param leftToken the token in the new token stream immediately to the left of the range of
-   *          tokens that were inserted
-   * @param rightToken the token in the new token stream immediately to the right of the range of
-   *          tokens that were inserted
-   * @param originalStart the offset in the original source of the first character that was modified
-   * @param originalEnd the offset in the original source of the last character that was modified
+   * More specifically, the [leftToken] is the token in the new token stream
+   * immediately to the left of the range of tokens that were inserted and the
+   * [rightToken] is the token in the new token stream immediately to the right
+   * of the range of tokens that were inserted. The [originalStart] and
+   * [originalEnd] are the offsets in the original source of the first and last
+   * characters that were modified.
+   *
+   * The tokens are assumed to be contained in the same token stream.
    */
   AstNode reparse(AstNode originalStructure, Token leftToken, Token rightToken,
       int originalStart, int originalEnd) {
@@ -1742,7 +1722,7 @@
             newNode.offset != oldNode.offset) {
           advanceToParent = true;
         }
-      } on InsufficientContextException catch (exception) {
+      } on InsufficientContextException {
         advanceToParent = true;
       } catch (exception) {
         return null;
@@ -1773,10 +1753,8 @@
   }
 
   /**
-   * Return the first (non-EOF) token in the token stream containing the given token.
-   *
-   * @param firstToken the token from which the search is to begin
-   * @return the first token in the token stream containing the given token
+   * Return the first (non-EOF) token in the token stream containing the
+   * [firstToken].
    */
   Token _findFirstToken(Token firstToken) {
     while (firstToken.type != TokenType.EOF) {
@@ -1786,12 +1764,8 @@
   }
 
   /**
-   * Find the token at or before the given token with the given offset, or `null` if there is
-   * no such token.
-   *
-   * @param firstToken the token from which the search is to begin
-   * @param offset the offset of the token to be returned
-   * @return the token with the given offset
+   * Find the token at or before the [firstToken] with the given [offset], or
+   * `null` if there is no such token.
    */
   Token _findTokenAt(Token firstToken, int offset) {
     while (firstToken.offset > offset && firstToken.type != TokenType.EOF) {
@@ -1802,18 +1776,18 @@
 }
 
 /**
- * Visitor capable of inferring the correct parser state for incremental
+ * A visitor capable of inferring the correct parser state for incremental
  * parsing.  This visitor visits each parent/child relationship in the chain of
  * ancestors of the node to be replaced (starting with the root of the parse
  * tree), updating the parser to the correct state for parsing the child of the
  * given parent.  Once it has visited all of these relationships, the parser
  * will be in the correct state for reparsing the node to be replaced.
- *
- * TODO(paulberry): add support for other pieces of parser state (_inAsync,
- * _inGenerator, _inLoop, and _inSwitch).  Note that _inLoop and _inSwitch only
- * affect error message generation.
  */
 class IncrementalParseStateBuilder extends SimpleAstVisitor {
+  // TODO(paulberry): add support for other pieces of parser state (_inAsync,
+  // _inGenerator, _inLoop, and _inSwitch).  Note that _inLoop and _inSwitch
+  // only affect error message generation.
+
   /**
    * The parser whose state should be built.
    */
@@ -1896,33 +1870,33 @@
 }
 
 /**
- * Instances of the class `InsufficientContextException` represent a situation in which an AST
- * node cannot be re-parsed because there is not enough context to know how to re-parse the node.
- * Clients can attempt to re-parse the parent of the node.
+ * An exception indicating that an AST node cannot be re-parsed because there is
+ * not enough context to know how to re-parse the node. Clients can attempt to
+ * re-parse the parent of the node.
  */
 class InsufficientContextException extends IncrementalParseException {
   /**
-   * Initialize a newly created exception to have no message and to be its own cause.
+   * Initialize a newly created exception to have no message and to be its own
+   * cause.
    */
   InsufficientContextException() : super();
 
   /**
-   * Initialize a newly created exception to have the given message and to be its own cause.
-   *
-   * @param message the message describing the reason for the exception
+   * Initialize a newly created exception to have the given [message] and to be
+   * its own cause.
    */
   InsufficientContextException.con1(String message) : super.con1(message);
 
   /**
-   * Initialize a newly created exception to have no message and to have the given cause.
-   *
-   * @param cause the exception that caused this exception
+   * Initialize a newly created exception to have no message and to have the
+   * given [cause].
    */
   InsufficientContextException.con2(Exception cause) : super.con2(cause);
 }
 
 /**
- * Wrapper around [Function] which should be called with "target" and "arguments".
+ * Wrapper around [Function] which should be called with "target" and
+ * "arguments".
  */
 class MethodTrampoline {
   int parameterCount;
@@ -1952,42 +1926,48 @@
 }
 
 /**
- * Instances of the class `Modifiers` implement a simple data-holder for a method that needs
- * to return multiple values.
+ * A simple data-holder for a method that needs to return multiple values.
  */
 class Modifiers {
   /**
-   * The token representing the keyword 'abstract', or `null` if the keyword was not found.
+   * The token representing the keyword 'abstract', or `null` if the keyword was
+   * not found.
    */
   Token abstractKeyword;
 
   /**
-   * The token representing the keyword 'const', or `null` if the keyword was not found.
+   * The token representing the keyword 'const', or `null` if the keyword was
+   * not found.
    */
   Token constKeyword;
 
   /**
-   * The token representing the keyword 'external', or `null` if the keyword was not found.
+   * The token representing the keyword 'external', or `null` if the keyword was
+   * not found.
    */
   Token externalKeyword;
 
   /**
-   * The token representing the keyword 'factory', or `null` if the keyword was not found.
+   * The token representing the keyword 'factory', or `null` if the keyword was
+   * not found.
    */
   Token factoryKeyword;
 
   /**
-   * The token representing the keyword 'final', or `null` if the keyword was not found.
+   * The token representing the keyword 'final', or `null` if the keyword was
+   * not found.
    */
   Token finalKeyword;
 
   /**
-   * The token representing the keyword 'static', or `null` if the keyword was not found.
+   * The token representing the keyword 'static', or `null` if the keyword was
+   * not found.
    */
   Token staticKeyword;
 
   /**
-   * The token representing the keyword 'var', or `null` if the keyword was not found.
+   * The token representing the keyword 'var', or `null` if the keyword was not
+   * found.
    */
   Token varKeyword;
 
@@ -2005,13 +1985,9 @@
   }
 
   /**
-   * If the given keyword is not `null`, append it to the given builder, prefixing it with a
-   * space if needed.
-   *
-   * @param builder the builder to which the keyword will be appended
-   * @param needsSpace `true` if the keyword needs to be prefixed with a space
-   * @param keyword the keyword to be appended
-   * @return `true` if subsequent keywords need to be prefixed with a space
+   * If the given [keyword] is not `null`, append it to the given [builder],
+   * prefixing it with a space if [needsSpace] is `true`. Return `true` if
+   * subsequent keywords need to be prefixed with a space.
    */
   bool _appendKeyword(StringBuffer buffer, bool needsSpace, Token keyword) {
     if (keyword != null) {
@@ -2026,7 +2002,7 @@
 }
 
 /**
- * Instances of the class `Parser` are used to parse tokens into an AST structure.
+ * A parser used to parse tokens into an AST structure.
  */
 class Parser {
   static String ASYNC = "async";
@@ -2053,7 +2029,8 @@
   final Source _source;
 
   /**
-   * The error listener that will be informed of any errors that are found during the parse.
+   * The error listener that will be informed of any errors that are found
+   * during the parse.
    */
   final AnalysisErrorListener _errorListener;
 
@@ -2073,12 +2050,14 @@
   Token _currentToken;
 
   /**
-   * A flag indicating whether the parser is currently in a function body marked as being 'async'.
+   * A flag indicating whether the parser is currently in a function body marked
+   * as being 'async'.
    */
   bool _inAsync = false;
 
   /**
-   * A flag indicating whether the parser is currently in a function body marked as being 'async'.
+   * A flag indicating whether the parser is currently in a function body marked
+   * as being 'async'.
    */
   bool _inGenerator = false;
 
@@ -2093,17 +2072,15 @@
   bool _inSwitch = false;
 
   /**
-   * A flag indicating whether the parser is currently in a constructor field initializer, with no
-   * intervening parens, braces, or brackets.
+   * A flag indicating whether the parser is currently in a constructor field
+   * initializer, with no intervening parens, braces, or brackets.
    */
   bool _inInitializer = false;
 
   /**
-   * Initialize a newly created parser.
-   *
-   * @param source the source being parsed
-   * @param errorListener the error listener that will be informed of any errors that are found
-   *          during the parse
+   * Initialize a newly created parser to parse the content of the given
+   * [_source] and to report any errors that are found to the given
+   * [_errorListener].
    */
   Parser(this._source, this._errorListener);
 
@@ -2112,13 +2089,10 @@
   }
 
   /**
-   * Return `true` if the current token is the first token of a return type that is followed
-   * by an identifier, possibly followed by a list of type parameters, followed by a
-   * left-parenthesis. This is used by parseTypeAlias to determine whether or not to parse a return
-   * type.
-   *
-   * @return `true` if we can successfully parse the rest of a type alias if we first parse a
-   *         return type.
+   * Return `true` if the current token is the first token of a return type that
+   * is followed by an identifier, possibly followed by a list of type
+   * parameters, followed by a left-parenthesis. This is used by
+   * [_parseTypeAlias] to determine whether or not to parse a return type.
    */
   bool get hasReturnTypeInTypeAlias {
     Token next = _skipReturnType(_currentToken);
@@ -2130,35 +2104,30 @@
 
   /**
    * Set whether the parser is to parse the async support.
-   *
-   * @param parseAsync `true` if the parser is to parse the async support
    */
+  @deprecated
   void set parseAsync(bool parseAsync) {
     // Async support cannot be disabled
   }
 
   /**
    * Set whether the parser is to parse deferred libraries.
-   *
-   * @param parseDeferredLibraries `true` if the parser is to parse deferred libraries
    */
+  @deprecated
   void set parseDeferredLibraries(bool parseDeferredLibraries) {
     // Deferred libraries support cannot be disabled
   }
 
   /**
    * Set whether the parser is to parse enum declarations.
-   *
-   * @param parseEnum `true` if the parser is to parse enum declarations
    */
+  @deprecated
   void set parseEnum(bool parseEnum) {
     // Enum support cannot be disabled
   }
 
   /**
    * Set whether parser is to parse function bodies.
-   *
-   * @param parseFunctionBodies `true` if parser is to parse function bodies
    */
   void set parseFunctionBodies(bool parseFunctionBodies) {
     this._parseFunctionBodies = parseFunctionBodies;
@@ -2175,14 +2144,11 @@
   }
 
   /**
-   * Parse an annotation.
+   * Parse an annotation. Return the annotation that was parsed.
    *
-   * <pre>
-   * annotation ::=
-   *     '@' qualified ('.' identifier)? arguments?
-   * </pre>
+   *     annotation ::=
+   *         '@' qualified ('.' identifier)? arguments?
    *
-   * @return the annotation that was parsed
    */
   Annotation parseAnnotation() {
     Token atSign = _expect(TokenType.AT);
@@ -2201,18 +2167,14 @@
   }
 
   /**
-   * Parse an argument.
+   * Parse an argument. Return the argument that was parsed.
    *
-   * <pre>
-   * argument ::=
-   *     namedArgument
-   *   | expression
+   *     argument ::=
+   *         namedArgument
+   *       | expression
    *
-   * namedArgument ::=
-   *     label expression
-   * </pre>
-   *
-   * @return the argument that was parsed
+   *     namedArgument ::=
+   *         label expression
    */
   Expression parseArgument() {
     //
@@ -2227,18 +2189,14 @@
   }
 
   /**
-   * Parse a list of arguments.
+   * Parse a list of arguments. Return the argument list that was parsed.
    *
-   * <pre>
-   * arguments ::=
-   *     '(' argumentList? ')'
+   *     arguments ::=
+   *         '(' argumentList? ')'
    *
-   * argumentList ::=
-   *     namedArgument (',' namedArgument)*
-   *   | expressionList (',' namedArgument)*
-   * </pre>
-   *
-   * @return the argument list that was parsed
+   *     argumentList ::=
+   *         namedArgument (',' namedArgument)*
+   *       | expressionList (',' namedArgument)*
    */
   ArgumentList parseArgumentList() {
     Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
@@ -2261,8 +2219,8 @@
         argument = parseArgument();
         arguments.add(argument);
         if (foundNamedArgument) {
-          bool blankArgument = argument is SimpleIdentifier &&
-              (argument as SimpleIdentifier).name.isEmpty;
+          bool blankArgument =
+              argument is SimpleIdentifier && argument.name.isEmpty;
           if (!generatedError &&
               !(argument is NamedExpression && !blankArgument)) {
             // Report the error, once, but allow the arguments to be in any
@@ -2286,15 +2244,12 @@
   }
 
   /**
-   * Parse a bitwise or expression.
+   * Parse a bitwise or expression. Return the bitwise or expression that was
+   * parsed.
    *
-   * <pre>
-   * bitwiseOrExpression ::=
-   *     bitwiseXorExpression ('|' bitwiseXorExpression)*
-   *   | 'super' ('|' bitwiseXorExpression)+
-   * </pre>
-   *
-   * @return the bitwise or expression that was parsed
+   *     bitwiseOrExpression ::=
+   *         bitwiseXorExpression ('|' bitwiseXorExpression)*
+   *       | 'super' ('|' bitwiseXorExpression)+
    */
   Expression parseBitwiseOrExpression() {
     Expression expression;
@@ -2313,14 +2268,10 @@
   }
 
   /**
-   * Parse a block.
+   * Parse a block. Return the block that was parsed.
    *
-   * <pre>
-   * block ::=
-   *     '{' statements '}'
-   * </pre>
-   *
-   * @return the block that was parsed
+   *     block ::=
+   *         '{' statements '}'
    */
   Block parseBlock() {
     Token leftBracket = _expect(TokenType.OPEN_CURLY_BRACKET);
@@ -2345,17 +2296,13 @@
   }
 
   /**
-   * Parse a class member.
+   * Parse a class member. The [className] is the name of the class containing
+   * the member being parsed. Return the class member that was parsed, or `null`
+   * if what was found was not a valid class member.
    *
-   * <pre>
-   * classMemberDefinition ::=
-   *     declaration ';'
-   *   | methodSignature functionBody
-   * </pre>
-   *
-   * @param className the name of the class containing the member being parsed
-   * @return the class member that was parsed, or `null` if what was found was not a valid
-   *         class member
+   *     classMemberDefinition ::=
+   *         declaration ';'
+   *       | methodSignature functionBody
    */
   ClassMember parseClassMember(String className) {
     CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata();
@@ -2613,14 +2560,12 @@
   }
 
   /**
-   * Parse a single import combinator.  If no combinator is found, return
-   * `null`.
+   * Parse a single combinator. Return the combinator that was parsed, or `null`
+   * if no combinator is found.
    *
-   * <pre>
-   * combinator ::=
-   *     'show' identifier (',' identifier)*
-   *   | 'hide' identifier (',' identifier)*
-   * </pre>
+   *     combinator ::=
+   *         'show' identifier (',' identifier)*
+   *       | 'hide' identifier (',' identifier)*
    */
   Combinator parseCombinator() {
     if (_matchesString(_SHOW) || _matchesString(_HIDE)) {
@@ -2636,10 +2581,8 @@
   }
 
   /**
-   * Parse a compilation unit, starting with the given token.
-   *
-   * @param token the first token of the compilation unit
-   * @return the compilation unit that was parsed
+   * Parse a compilation unit, starting with the given [token]. Return the
+   * compilation unit that was parsed.
    */
   CompilationUnit parseCompilationUnit(Token token) {
     _currentToken = token;
@@ -2647,26 +2590,21 @@
   }
 
   /**
-   * Parse a compilation unit.
+   * Parse a compilation unit. Return the compilation unit that was parsed.
    *
    * Specified:
    *
-   * <pre>
-   * compilationUnit ::=
-   *     scriptTag? directive* topLevelDeclaration*
-   * </pre>
+   *     compilationUnit ::=
+   *         scriptTag? directive* topLevelDeclaration*
+   *
    * Actual:
    *
-   * <pre>
-   * compilationUnit ::=
-   *     scriptTag? topLevelElement*
+   *     compilationUnit ::=
+   *         scriptTag? topLevelElement*
    *
-   * topLevelElement ::=
-   *     directive
-   *   | topLevelDeclaration
-   * </pre>
-   *
-   * @return the compilation unit that was parsed
+   *     topLevelElement ::=
+   *         directive
+   *       | topLevelDeclaration
    */
   CompilationUnit parseCompilationUnit2() {
     Token firstToken = _currentToken;
@@ -2698,8 +2636,8 @@
           !_tokenMatches(_peek(), TokenType.OPEN_PAREN)) {
         Directive directive = _parseDirective(commentAndMetadata);
         if (declarations.length > 0 && !directiveFoundAfterDeclaration) {
-          _reportErrorForToken(
-              ParserErrorCode.DIRECTIVE_AFTER_DECLARATION, directive.beginToken);
+          _reportErrorForToken(ParserErrorCode.DIRECTIVE_AFTER_DECLARATION,
+              directive.beginToken);
           directiveFoundAfterDeclaration = true;
         }
         if (directive is LibraryDirective) {
@@ -2747,9 +2685,8 @@
         }
         directives.add(directive);
       } else if (_matches(TokenType.SEMICOLON)) {
-        _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [
-          _currentToken.lexeme
-        ]);
+        _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken,
+            [_currentToken.lexeme]);
         _advance();
       } else {
         CompilationUnitMember member =
@@ -2759,9 +2696,8 @@
         }
       }
       if (identical(_currentToken, memberStart)) {
-        _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [
-          _currentToken.lexeme
-        ]);
+        _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken,
+            [_currentToken.lexeme]);
         _advance();
         while (!_matches(TokenType.EOF) &&
             !_couldBeStartOfCompilationUnitMember()) {
@@ -2775,14 +2711,11 @@
   }
 
   /**
-   * Parse a conditional expression.
+   * Parse a conditional expression. Return the conditional expression that was
+   * parsed.
    *
-   * <pre>
-   * conditionalExpression ::=
-   *     logicalOrExpression ('?' expressionWithoutCascade ':' expressionWithoutCascade)?
-   * </pre>
-   *
-   * @return the conditional expression that was parsed
+   *     conditionalExpression ::=
+   *         logicalOrExpression ('?' expressionWithoutCascade ':' expressionWithoutCascade)?
    */
   Expression parseConditionalExpression() {
     Expression condition = parseLogicalOrExpression();
@@ -2798,14 +2731,11 @@
   }
 
   /**
-   * Parse the name of a constructor.
+   * Parse the name of a constructor. Return the constructor name that was
+   * parsed.
    *
-   * <pre>
-   * constructorName:
-   *     type ('.' identifier)?
-   * </pre>
-   *
-   * @return the constructor name that was parsed
+   *     constructorName:
+   *         type ('.' identifier)?
    */
   ConstructorName parseConstructorName() {
     TypeName type = parseTypeName();
@@ -2819,12 +2749,11 @@
   }
 
   /**
-   * Parse the script tag and directives in a compilation unit, starting with the given token, until
-   * the first non-directive is encountered. The remainder of the compilation unit will not be
-   * parsed. Specifically, if there are directives later in the file, they will not be parsed.
-   *
-   * @param token the first token of the compilation unit
-   * @return the compilation unit that was parsed
+   * Parse the script tag and directives in a compilation unit, starting with
+   * the given [token], until the first non-directive is encountered. The
+   * remainder of the compilation unit will not be parsed. Specifically, if
+   * there are directives later in the file, they will not be parsed. Return the
+   * compilation unit that was parsed.
    */
   CompilationUnit parseDirectives(Token token) {
     _currentToken = token;
@@ -2832,11 +2761,9 @@
   }
 
   /**
-   * Parse an expression, starting with the given token.
-   *
-   * @param token the first token of the expression
-   * @return the expression that was parsed, or `null` if the tokens do not represent a
-   *         recognizable expression
+   * Parse an expression, starting with the given [token]. Return the expression
+   * that was parsed, or `null` if the tokens do not represent a recognizable
+   * expression.
    */
   Expression parseExpression(Token token) {
     _currentToken = token;
@@ -2844,16 +2771,13 @@
   }
 
   /**
-   * Parse an expression that might contain a cascade.
+   * Parse an expression that might contain a cascade. Return the expression
+   * that was parsed.
    *
-   * <pre>
-   * expression ::=
-   *     assignableExpression assignmentOperator expression
-   *   | conditionalExpression cascadeSection*
-   *   | throwExpression
-   * </pre>
-   *
-   * @return the expression that was parsed
+   *     expression ::=
+   *         assignableExpression assignmentOperator expression
+   *       | conditionalExpression cascadeSection*
+   *       | throwExpression
    */
   Expression parseExpression2() {
     if (_matchesKeyword(Keyword.THROW)) {
@@ -2889,16 +2813,13 @@
   }
 
   /**
-   * Parse an expression that does not contain any cascades.
+   * Parse an expression that does not contain any cascades. Return the
+   * expression that was parsed.
    *
-   * <pre>
-   * expressionWithoutCascade ::=
-   *     assignableExpression assignmentOperator expressionWithoutCascade
-   *   | conditionalExpression
-   *   | throwExpressionWithoutCascade
-   * </pre>
-   *
-   * @return the expression that was parsed
+   *     expressionWithoutCascade ::=
+   *         assignableExpression assignmentOperator expressionWithoutCascade
+   *       | conditionalExpression
+   *       | throwExpressionWithoutCascade
    */
   Expression parseExpressionWithoutCascade() {
     if (_matchesKeyword(Keyword.THROW)) {
@@ -2923,14 +2844,11 @@
   }
 
   /**
-   * Parse a class extends clause.
+   * Parse a class extends clause. Return the class extends clause that was
+   * parsed.
    *
-   * <pre>
-   * classExtendsClause ::=
-   *     'extends' type
-   * </pre>
-   *
-   * @return the class extends clause that was parsed
+   *     classExtendsClause ::=
+   *         'extends' type
    */
   ExtendsClause parseExtendsClause() {
     Token keyword = _expectKeyword(Keyword.EXTENDS);
@@ -2939,29 +2857,26 @@
   }
 
   /**
-   * Parse a list of formal parameters.
+   * Parse a list of formal parameters. Return the formal parameters that were
+   * parsed.
    *
-   * <pre>
-   * formalParameterList ::=
-   *     '(' ')'
-   *   | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
-   *   | '(' optionalFormalParameters ')'
+   *     formalParameterList ::=
+   *         '(' ')'
+   *       | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
+   *       | '(' optionalFormalParameters ')'
    *
-   * normalFormalParameters ::=
-   *     normalFormalParameter (',' normalFormalParameter)*
+   *     normalFormalParameters ::=
+   *         normalFormalParameter (',' normalFormalParameter)*
    *
-   * optionalFormalParameters ::=
-   *     optionalPositionalFormalParameters
-   *   | namedFormalParameters
+   *     optionalFormalParameters ::=
+   *         optionalPositionalFormalParameters
+   *       | namedFormalParameters
    *
-   * optionalPositionalFormalParameters ::=
-   *     '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
+   *     optionalPositionalFormalParameters ::=
+   *         '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
    *
-   * namedFormalParameters ::=
-   *     '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
-   * </pre>
-   *
-   * @return the formal parameters that were parsed
+   *     namedFormalParameters ::=
+   *         '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
    */
   FormalParameterList parseFormalParameterList() {
     Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
@@ -3065,9 +2980,8 @@
             rightSquareBracket = null;
           } else {
             _reportErrorForCurrentToken(
-                ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP, [
-              "["
-            ]);
+                ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP,
+                ["["]);
           }
         }
         kind = ParameterKind.REQUIRED;
@@ -3082,9 +2996,8 @@
             rightCurlyBracket = null;
           } else {
             _reportErrorForCurrentToken(
-                ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP, [
-              "{"
-            ]);
+                ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP,
+                ["{"]);
           }
         }
         kind = ParameterKind.REQUIRED;
@@ -3117,14 +3030,11 @@
   }
 
   /**
-   * Parse a function expression.
+   * Parse a function expression. Return the function expression that was
+   * parsed.
    *
-   * <pre>
-   * functionExpression ::=
-   *     formalParameterList functionExpressionBody
-   * </pre>
-   *
-   * @return the function expression that was parsed
+   *     functionExpression ::=
+   *         formalParameterList functionExpressionBody
    */
   FunctionExpression parseFunctionExpression() {
     FormalParameterList parameters = parseFormalParameterList();
@@ -3135,14 +3045,10 @@
   }
 
   /**
-   * Parse an implements clause.
+   * Parse an implements clause. Return the implements clause that was parsed.
    *
-   * <pre>
-   * implementsClause ::=
-   *     'implements' type (',' type)*
-   * </pre>
-   *
-   * @return the implements clause that was parsed
+   *     implementsClause ::=
+   *         'implements' type (',' type)*
    */
   ImplementsClause parseImplementsClause() {
     Token keyword = _expectKeyword(Keyword.IMPLEMENTS);
@@ -3155,14 +3061,10 @@
   }
 
   /**
-   * Parse a label.
+   * Parse a label. Return the label that was parsed.
    *
-   * <pre>
-   * label ::=
-   *     identifier ':'
-   * </pre>
-   *
-   * @return the label that was parsed
+   *     label ::=
+   *         identifier ':'
    */
   Label parseLabel() {
     SimpleIdentifier label = parseSimpleIdentifier();
@@ -3171,14 +3073,10 @@
   }
 
   /**
-   * Parse a library identifier.
+   * Parse a library identifier. Return the library identifier that was parsed.
    *
-   * <pre>
-   * libraryIdentifier ::=
-   *     identifier ('.' identifier)*
-   * </pre>
-   *
-   * @return the library identifier that was parsed
+   *     libraryIdentifier ::=
+   *         identifier ('.' identifier)*
    */
   LibraryIdentifier parseLibraryIdentifier() {
     List<SimpleIdentifier> components = new List<SimpleIdentifier>();
@@ -3191,14 +3089,11 @@
   }
 
   /**
-   * Parse a logical or expression.
+   * Parse a logical or expression. Return the logical or expression that was
+   * parsed.
    *
-   * <pre>
-   * logicalOrExpression ::=
-   *     logicalAndExpression ('||' logicalAndExpression)*
-   * </pre>
-   *
-   * @return the logical or expression that was parsed
+   *     logicalOrExpression ::=
+   *         logicalAndExpression ('||' logicalAndExpression)*
    */
   Expression parseLogicalOrExpression() {
     Expression expression = _parseLogicalAndExpression();
@@ -3211,14 +3106,10 @@
   }
 
   /**
-   * Parse a map literal entry.
+   * Parse a map literal entry. Return the map literal entry that was parsed.
    *
-   * <pre>
-   * mapLiteralEntry ::=
-   *     expression ':' expression
-   * </pre>
-   *
-   * @return the map literal entry that was parsed
+   *     mapLiteralEntry ::=
+   *         expression ':' expression
    */
   MapLiteralEntry parseMapLiteralEntry() {
     Expression key = parseExpression2();
@@ -3228,25 +3119,23 @@
   }
 
   /**
-   * Parse a normal formal parameter and return the normal formal parameter that
+   * Parse a normal formal parameter. Return the normal formal parameter that
    * was parsed.
    *
-   * <pre>
-   * normalFormalParameter ::=
-   *     functionSignature
-   *   | fieldFormalParameter
-   *   | simpleFormalParameter
+   *     normalFormalParameter ::=
+   *         functionSignature
+   *       | fieldFormalParameter
+   *       | simpleFormalParameter
    *
-   * functionSignature:
-   *     metadata returnType? identifier formalParameterList
+   *     functionSignature:
+   *         metadata returnType? identifier formalParameterList
    *
-   * fieldFormalParameter ::=
-   *     metadata finalConstVarOrType? 'this' '.' identifier
+   *     fieldFormalParameter ::=
+   *         metadata finalConstVarOrType? 'this' '.' identifier
    *
-   * simpleFormalParameter ::=
-   *     declaredIdentifier
-   *   | metadata identifier
-   * </pre>
+   *     simpleFormalParameter ::=
+   *         declaredIdentifier
+   *       | metadata identifier
    */
   NormalFormalParameter parseNormalFormalParameter() {
     CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata();
@@ -3293,14 +3182,11 @@
   }
 
   /**
-   * Parse a prefixed identifier.
+   * Parse a prefixed identifier. Return the prefixed identifier that was
+   * parsed.
    *
-   * <pre>
-   * prefixedIdentifier ::=
-   *     identifier ('.' identifier)?
-   * </pre>
-   *
-   * @return the prefixed identifier that was parsed
+   *     prefixedIdentifier ::=
+   *         identifier ('.' identifier)?
    */
   Identifier parsePrefixedIdentifier() {
     SimpleIdentifier qualifier = parseSimpleIdentifier();
@@ -3313,15 +3199,11 @@
   }
 
   /**
-   * Parse a return type.
+   * Parse a return type. Return the return type that was parsed.
    *
-   * <pre>
-   * returnType ::=
-   *     'void'
-   *   | type
-   * </pre>
-   *
-   * @return the return type that was parsed
+   *     returnType ::=
+   *         'void'
+   *       | type
    */
   TypeName parseReturnType() {
     if (_matchesKeyword(Keyword.VOID)) {
@@ -3332,14 +3214,10 @@
   }
 
   /**
-   * Parse a simple identifier.
+   * Parse a simple identifier. Return the simple identifier that was parsed.
    *
-   * <pre>
-   * identifier ::=
-   *     IDENTIFIER
-   * </pre>
-   *
-   * @return the simple identifier that was parsed
+   *     identifier ::=
+   *         IDENTIFIER
    */
   SimpleIdentifier parseSimpleIdentifier() {
     if (_matchesIdentifier()) {
@@ -3356,11 +3234,9 @@
   }
 
   /**
-   * Parse a statement, starting with the given token.
-   *
-   * @param token the first token of the statement
-   * @return the statement that was parsed, or `null` if the tokens do not represent a
-   *         recognizable statement
+   * Parse a statement, starting with the given [token]. Return the statement
+   * that was parsed, or `null` if the tokens do not represent a recognizable
+   * statement.
    */
   Statement parseStatement(Token token) {
     _currentToken = token;
@@ -3368,14 +3244,10 @@
   }
 
   /**
-   * Parse a statement.
+   * Parse a statement. Return the statement that was parsed.
    *
-   * <pre>
-   * statement ::=
-   *     label* nonLabeledStatement
-   * </pre>
-   *
-   * @return the statement that was parsed
+   *     statement ::=
+   *         label* nonLabeledStatement
    */
   Statement parseStatement2() {
     List<Label> labels = new List<Label>();
@@ -3390,11 +3262,9 @@
   }
 
   /**
-   * Parse a sequence of statements, starting with the given token.
-   *
-   * @param token the first token of the sequence of statement
-   * @return the statements that were parsed, or `null` if the tokens do not represent a
-   *         recognizable sequence of statements
+   * Parse a sequence of statements, starting with the given [token]. Return the
+   * statements that were parsed, or `null` if the tokens do not represent a
+   * recognizable sequence of statements.
    */
   List<Statement> parseStatements(Token token) {
     _currentToken = token;
@@ -3402,15 +3272,11 @@
   }
 
   /**
-   * Parse a string literal.
+   * Parse a string literal. Return the string literal that was parsed.
    *
-   * <pre>
-   * stringLiteral ::=
-   *     MULTI_LINE_STRING+
-   *   | SINGLE_LINE_STRING+
-   * </pre>
-   *
-   * @return the string literal that was parsed
+   *     stringLiteral ::=
+   *         MULTI_LINE_STRING+
+   *       | SINGLE_LINE_STRING+
    */
   StringLiteral parseStringLiteral() {
     List<StringLiteral> strings = new List<StringLiteral>();
@@ -3435,17 +3301,14 @@
   }
 
   /**
-   * Parse a list of type arguments.
+   * Parse a list of type arguments. Return the type argument list that was
+   * parsed.
    *
-   * <pre>
-   * typeArguments ::=
-   *     '<' typeList '>'
+   *     typeArguments ::=
+   *         '<' typeList '>'
    *
-   * typeList ::=
-   *     type (',' type)*
-   * </pre>
-   *
-   * @return the type argument list that was parsed
+   *     typeList ::=
+   *         type (',' type)*
    */
   TypeArgumentList parseTypeArgumentList() {
     Token leftBracket = _expect(TokenType.LT);
@@ -3459,14 +3322,10 @@
   }
 
   /**
-   * Parse a type name.
+   * Parse a type name. Return the type name that was parsed.
    *
-   * <pre>
-   * type ::=
-   *     qualified typeArguments?
-   * </pre>
-   *
-   * @return the type name that was parsed
+   *     type ::=
+   *         qualified typeArguments?
    */
   TypeName parseTypeName() {
     Identifier typeName;
@@ -3487,14 +3346,10 @@
   }
 
   /**
-   * Parse a type parameter.
+   * Parse a type parameter. Return the type parameter that was parsed.
    *
-   * <pre>
-   * typeParameter ::=
-   *     metadata name ('extends' bound)?
-   * </pre>
-   *
-   * @return the type parameter that was parsed
+   *     typeParameter ::=
+   *         metadata name ('extends' bound)?
    */
   TypeParameter parseTypeParameter() {
     CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata();
@@ -3510,14 +3365,11 @@
   }
 
   /**
-   * Parse a list of type parameters.
+   * Parse a list of type parameters. Return the list of type parameters that
+   * were parsed.
    *
-   * <pre>
-   * typeParameterList ::=
-   *     '<' typeParameter (',' typeParameter)* '>'
-   * </pre>
-   *
-   * @return the list of type parameters that were parsed
+   *     typeParameterList ::=
+   *         '<' typeParameter (',' typeParameter)* '>'
    */
   TypeParameterList parseTypeParameterList() {
     Token leftBracket = _expect(TokenType.LT);
@@ -3531,14 +3383,10 @@
   }
 
   /**
-   * Parse a with clause.
+   * Parse a with clause. Return the with clause that was parsed.
    *
-   * <pre>
-   * withClause ::=
-   *     'with' typeName (',' typeName)*
-   * </pre>
-   *
-   * @return the with clause that was parsed
+   *     withClause ::=
+   *         'with' typeName (',' typeName)*
    */
   WithClause parseWithClause() {
     Token with2 = _expectKeyword(Keyword.WITH);
@@ -3558,15 +3406,11 @@
   }
 
   /**
-   * Append the character equivalent of the given scalar value to the given builder. Use the start
-   * and end indices to report an error, and don't append anything to the builder, if the scalar
-   * value is invalid.
-   *
-   * @param builder the builder to which the scalar value is to be appended
-   * @param escapeSequence the escape sequence that was parsed to produce the scalar value
-   * @param scalarValue the value to be appended
-   * @param startIndex the index of the first character representing the scalar value
-   * @param endIndex the index of the last character representing the scalar value
+   * Append the character equivalent of the given [scalarValue] to the given
+   * [builder]. Use the [startIndex] and [endIndex] to report an error, and
+   * don't append anything to the builder, if the scalar value is invalid. The
+   * [escapeSequence] is the escape sequence that was parsed to produce the
+   * scalar value (used for error reporting).
    */
   void _appendScalarValue(StringBuffer buffer, String escapeSequence,
       int scalarValue, int startIndex, int endIndex) {
@@ -3585,12 +3429,10 @@
   }
 
   /**
-   * Compute the content of a string with the given literal representation.
-   *
-   * @param lexeme the literal representation of the string
-   * @param first `true` if this is the first token in a string literal
-   * @param last `true` if this is the last token in a string literal
-   * @return the actual value of the string
+   * Return the content of a string with the given literal representation. The
+   * [lexeme] is the literal representation of the string. The flag [first] is
+   * `true` if this is the first token in a string literal. The flag [last] is
+   * `true` if this is the last token in a string literal.
    */
   String _computeStringValue(String lexeme, bool first, bool last) {
     bool isRaw = false;
@@ -3639,11 +3481,9 @@
   }
 
   /**
-   * Convert the given method declaration into the nearest valid top-level function declaration.
-   *
-   * @param method the method to be converted
-   * @return the function declaration that most closely captures the components of the given method
-   *         declaration
+   * Convert the given [method] declaration into the nearest valid top-level
+   * function declaration (that is, the function declaration that most closely
+   * captures the components of the given method declaration).
    */
   FunctionDeclaration _convertToFunctionDeclaration(MethodDeclaration method) =>
       new FunctionDeclaration(method.documentationComment, method.metadata,
@@ -3651,11 +3491,10 @@
           method.name, new FunctionExpression(method.parameters, method.body));
 
   /**
-   * Return `true` if the current token could be the start of a compilation unit member. This
-   * method is used for recovery purposes to decide when to stop skipping tokens after finding an
-   * error while parsing a compilation unit member.
-   *
-   * @return `true` if the current token could be the start of a compilation unit member
+   * Return `true` if the current token could be the start of a compilation unit
+   * member. This method is used for recovery purposes to decide when to stop
+   * skipping tokens after finding an error while parsing a compilation unit
+   * member.
    */
   bool _couldBeStartOfCompilationUnitMember() {
     if ((_matchesKeyword(Keyword.IMPORT) ||
@@ -3700,9 +3539,7 @@
   }
 
   /**
-   * Create a synthetic identifier.
-   *
-   * @return the synthetic identifier that was created
+   * Return a synthetic identifier.
    */
   SimpleIdentifier _createSyntheticIdentifier() {
     Token syntheticToken;
@@ -3721,25 +3558,19 @@
   }
 
   /**
-   * Create a synthetic token representing the given keyword.
-   *
-   * @return the synthetic token that was created
+   * Return a synthetic token representing the given [keyword].
    */
   Token _createSyntheticKeyword(Keyword keyword) => _injectToken(
       new Parser_SyntheticKeywordToken(keyword, _currentToken.offset));
 
   /**
-   * Create a synthetic string literal.
-   *
-   * @return the synthetic string literal that was created
+   * Return a synthetic string literal.
    */
   SimpleStringLiteral _createSyntheticStringLiteral() =>
       new SimpleStringLiteral(_createSyntheticToken(TokenType.STRING), "");
 
   /**
-   * Create a synthetic token with the given type.
-   *
-   * @return the synthetic token that was created
+   * Return a synthetic token with the given [type].
    */
   Token _createSyntheticToken(TokenType type) =>
       _injectToken(new StringToken(type, "", _currentToken.offset));
@@ -3763,20 +3594,17 @@
   }
 
   /**
-   * Check that the given expression is assignable and report an error if it isn't.
+   * Check that the given [expression] is assignable and report an error if it
+   * isn't.
    *
-   * <pre>
-   * assignableExpression ::=
-   *     primary (arguments* assignableSelector)+
-   *   | 'super' assignableSelector
-   *   | identifier
+   *     assignableExpression ::=
+   *         primary (arguments* assignableSelector)+
+   *       | 'super' assignableSelector
+   *       | identifier
    *
-   * assignableSelector ::=
-   *     '[' expression ']'
-   *   | '.' identifier
-   * </pre>
-   *
-   * @param expression the expression being checked
+   *     assignableSelector ::=
+   *         '[' expression ']'
+   *       | '.' identifier
    */
   void _ensureAssignable(Expression expression) {
     if (expression != null && !expression.isAssignable) {
@@ -3818,10 +3646,9 @@
   }
 
   /**
-   * If the current token has the type [TokenType.GT], return it after advancing to the next
-   * token. Otherwise report an error and return the current token without advancing.
-   *
-   * @return the token that matched the given type
+   * If the current token has the type [TokenType.GT], return it after advancing
+   * to the next token. Otherwise report an error and return the current token
+   * without advancing.
    */
   Token _expectGt() {
     if (_matchesGt()) {
@@ -3833,11 +3660,9 @@
   }
 
   /**
-   * If the current token is a keyword matching the given string, return it after advancing to the
-   * next token. Otherwise report an error and return the current token without advancing.
-   *
-   * @param keyword the keyword that is expected
-   * @return the token that matched the given type
+   * If the current token is a keyword matching the given [keyword], return it
+   * after advancing to the next token. Otherwise report an error and return the
+   * current token without advancing.
    */
   Token _expectKeyword(Keyword keyword) {
     if (_matchesKeyword(keyword)) {
@@ -3851,12 +3676,11 @@
   }
 
   /**
-   * If [currentToken] is a semicolon, returns it; otherwise reports error and creates a
-   * synthetic one.
-   *
-   * TODO(scheglov) consider pushing this into [expect]
+   * If the current token is a semicolon, return it after advancing to the next
+   * token. Otherwise report an error and create a synthetic semicolon.
    */
   Token _expectSemicolon() {
+    // TODO(scheglov) consider pushing this behavior into [_expect]
     if (_matches(TokenType.SEMICOLON)) {
       return getAndAdvance();
     } else {
@@ -3867,12 +3691,9 @@
   }
 
   /**
-   * Search the given list of ranges for a range that contains the given index. Return the range
-   * that was found, or `null` if none of the ranges contain the index.
-   *
-   * @param ranges the ranges to be searched
-   * @param index the index contained in the returned range
-   * @return the range that was found
+   * Search the given list of [ranges] for a range that contains the given
+   * [index]. Return the range that was found, or `null` if none of the ranges
+   * contain the index.
    */
   List<int> _findRange(List<List<int>> ranges, int index) {
     int rangeCount = ranges.length;
@@ -3888,11 +3709,8 @@
   }
 
   /**
-   * Return a list of the ranges of characters in the given comment string that should be treated as
-   * code blocks.
-   *
-   * @param comment the comment being processed
-   * @return the ranges of characters that should be treated as code blocks
+   * Return a list of the ranges of characters in the given [comment] that
+   * should be treated as code blocks.
    */
   List<List<int>> _getCodeBlockRanges(String comment) {
     List<List<int>> ranges = new List<List<int>>();
@@ -3946,11 +3764,9 @@
   }
 
   /**
-   * Return the end token associated with the given begin token, or `null` if either the given
-   * token is not a begin token or it does not have an end token associated with it.
-   *
-   * @param beginToken the token that is expected to have an end token associated with it
-   * @return the end token associated with the begin token
+   * Return the end token associated with the given [beginToken], or `null` if
+   * either the given token is not a begin token or it does not have an end
+   * token associated with it.
    */
   Token _getEndToken(Token beginToken) {
     if (beginToken is BeginToken) {
@@ -3960,10 +3776,8 @@
   }
 
   /**
-   * Inject the given token into the token stream immediately before the current token.
-   *
-   * @param token the token to be added to the token stream
-   * @return the token that was just added to the token stream
+   * Inject the given [token] into the token stream immediately before the
+   * current token.
    */
   Token _injectToken(Token token) {
     Token previous = _currentToken.previous;
@@ -4019,17 +3833,15 @@
   }
 
   /**
-   * Return `true` if the given token appears to be the beginning of a function expression.
-   *
-   * @param startToken the token that might be the start of a function expression
-   * @return `true` if the given token appears to be the beginning of a function expression
+   * Return `true` if the given [token] appears to be the beginning of a
+   * function expression.
    */
-  bool _isFunctionExpression(Token startToken) {
+  bool _isFunctionExpression(Token token) {
     // Function expressions aren't allowed in initializer lists.
     if (_inInitializer) {
       return false;
     }
-    Token afterParameters = _skipFormalParameterList(startToken);
+    Token afterParameters = _skipFormalParameterList(token);
     if (afterParameters == null) {
       return false;
     }
@@ -4042,42 +3854,35 @@
   }
 
   /**
-   * Return `true` if the given character is a valid hexadecimal digit.
-   *
-   * @param character the character being tested
-   * @return `true` if the character is a valid hexadecimal digit
+   * Return `true` if the given [character] is a valid hexadecimal digit.
    */
   bool _isHexDigit(int character) => (0x30 <= character && character <= 0x39) ||
       (0x41 <= character && character <= 0x46) ||
       (0x61 <= character && character <= 0x66);
 
   /**
-   * Return `true` if the current token is the first token in an initialized variable
-   * declaration rather than an expression. This method assumes that we have already skipped past
-   * any metadata that might be associated with the declaration.
+   * Return `true` if the current token is the first token in an initialized
+   * variable declaration rather than an expression. This method assumes that we
+   * have already skipped past any metadata that might be associated with the
+   * declaration.
    *
-   * <pre>
-   * initializedVariableDeclaration ::=
-   *     declaredIdentifier ('=' expression)? (',' initializedIdentifier)*
+   *     initializedVariableDeclaration ::=
+   *         declaredIdentifier ('=' expression)? (',' initializedIdentifier)*
    *
-   * declaredIdentifier ::=
-   *     metadata finalConstVarOrType identifier
+   *     declaredIdentifier ::=
+   *         metadata finalConstVarOrType identifier
    *
-   * finalConstVarOrType ::=
-   *     'final' type?
-   *   | 'const' type?
-   *   | 'var'
-   *   | type
+   *     finalConstVarOrType ::=
+   *         'final' type?
+   *       | 'const' type?
+   *       | 'var'
+   *       | type
    *
-   * type ::=
-   *     qualified typeArguments?
+   *     type ::=
+   *         qualified typeArguments?
    *
-   * initializedIdentifier ::=
-   *     identifier ('=' expression)?
-   * </pre>
-   *
-   * @return `true` if the current token is the first token in an initialized variable
-   *         declaration
+   *     initializedIdentifier ::=
+   *         identifier ('=' expression)?
    */
   bool _isInitializedVariableDeclaration() {
     if (_matchesKeyword(Keyword.FINAL) || _matchesKeyword(Keyword.VAR)) {
@@ -4114,16 +3919,15 @@
   }
 
   /**
-   * Given that we have just found bracketed text within a comment, look to see whether that text is
-   * (a) followed by a parenthesized link address, (b) followed by a colon, or (c) followed by
-   * optional whitespace and another square bracket.
+   * Given that we have just found bracketed text within the given [comment],
+   * look to see whether that text is (a) followed by a parenthesized link
+   * address, (b) followed by a colon, or (c) followed by optional whitespace
+   * and another square bracket. The [rightIndex] is the index of the right
+   * bracket. Return `true` if the bracketed text is followed by a link address.
    *
-   * This method uses the syntax described by the <a
-   * href="http://daringfireball.net/projects/markdown/syntax">markdown</a> project.
-   *
-   * @param comment the comment text in which the bracketed text was found
-   * @param rightIndex the index of the right bracket
-   * @return `true` if the bracketed text is followed by a link address
+   * This method uses the syntax described by the
+   * <a href="http://daringfireball.net/projects/markdown/syntax">markdown</a>
+   * project.
    */
   bool _isLinkText(String comment, int rightIndex) {
     int length = comment.length;
@@ -4146,10 +3950,8 @@
   }
 
   /**
-   * Return `true` if the given token appears to be the beginning of an operator declaration.
-   *
-   * @param startToken the token that might be the start of an operator declaration
-   * @return `true` if the given token appears to be the beginning of an operator declaration
+   * Return `true` if the given [startToken] appears to be the beginning of an
+   * operator declaration.
    */
   bool _isOperator(Token startToken) {
     // Accept any operator here, even if it is not user definable.
@@ -4170,9 +3972,8 @@
   }
 
   /**
-   * Return `true` if the current token appears to be the beginning of a switch member.
-   *
-   * @return `true` if the current token appears to be the beginning of a switch member
+   * Return `true` if the current token appears to be the beginning of a switch
+   * member.
    */
   bool _isSwitchMember() {
     Token token = _currentToken;
@@ -4222,22 +4023,18 @@
   }
 
   /**
-   * Return `true` if the current token has the given type. Note that the method
-   * [_matchesGt] should be used if the argument to this method would be
+   * Return `true` if the current token has the given [type]. Note that the
+   * method [_matchesGt] should be used if the argument to this method would be
    * [TokenType.GT].
-   *
-   * @param type the type of token that can optionally appear in the current location
-   * @return `true` if the current token has the given type
    */
   bool _matches(TokenType type) => _currentToken.type == type;
 
   /**
-   * Return `true` if the current token has a type of [TokenType.GT]. Note that this
-   * method, unlike other variants, will modify the token stream if possible to match desired type.
-   * In particular, if the next token is either a '>>' or '>>>', the token stream will be re-written
-   * and `true` will be returned.
-   *
-   * @return `true` if the current token has a type of [TokenType.GT]
+   * Return `true` if the current token has a type of [TokenType.GT]. Note that
+   * this method, unlike other variants, will modify the token stream if
+   * possible to match desired type. In particular, if the next token is either
+   * a '>>' or '>>>', the token stream will be re-written and `true` will be
+   * returned.
    */
   bool _matchesGt() {
     TokenType currentType = _currentToken.type;
@@ -4275,39 +4072,28 @@
   }
 
   /**
-   * Return `true` if the current token is a valid identifier. Valid identifiers include
-   * built-in identifiers (pseudo-keywords).
-   *
-   * @return `true` if the current token is a valid identifier
+   * Return `true` if the current token is a valid identifier. Valid identifiers
+   * include built-in identifiers (pseudo-keywords).
    */
   bool _matchesIdentifier() => _tokenMatchesIdentifier(_currentToken);
 
   /**
-   * Return `true` if the current token matches the given keyword.
-   *
-   * @param keyword the keyword that can optionally appear in the current location
-   * @return `true` if the current token matches the given keyword
+   * Return `true` if the current token matches the given [keyword].
    */
   bool _matchesKeyword(Keyword keyword) =>
       _tokenMatchesKeyword(_currentToken, keyword);
 
   /**
-   * Return `true` if the current token matches the given identifier.
-   *
-   * @param identifier the identifier that can optionally appear in the current location
-   * @return `true` if the current token matches the given identifier
+   * Return `true` if the current token matches the given [identifier].
    */
   bool _matchesString(String identifier) =>
       _currentToken.type == TokenType.IDENTIFIER &&
           _currentToken.lexeme == identifier;
 
   /**
-   * If the current token has the given type, then advance to the next token and return `true`
-   * . Otherwise, return `false` without advancing. This method should not be invoked with an
-   * argument value of [TokenType.GT].
-   *
-   * @param type the type of token that can optionally appear in the current location
-   * @return `true` if the current token has the given type
+   * If the current token has the given [type], then advance to the next token
+   * and return `true`. Otherwise, return `false` without advancing. This method
+   * should not be invoked with an argument value of [TokenType.GT].
    */
   bool _optional(TokenType type) {
     if (_matches(type)) {
@@ -4318,15 +4104,12 @@
   }
 
   /**
-   * Parse an additive expression.
+   * Parse an additive expression. Return the additive expression that was
+   * parsed.
    *
-   * <pre>
-   * additiveExpression ::=
-   *     multiplicativeExpression (additiveOperator multiplicativeExpression)*
-   *   | 'super' (additiveOperator multiplicativeExpression)+
-   * </pre>
-   *
-   * @return the additive expression that was parsed
+   *     additiveExpression ::=
+   *         multiplicativeExpression (additiveOperator multiplicativeExpression)*
+   *       | 'super' (additiveOperator multiplicativeExpression)+
    */
   Expression _parseAdditiveExpression() {
     Expression expression;
@@ -4345,14 +4128,10 @@
   }
 
   /**
-   * Parse an assert statement.
+   * Parse an assert statement. Return the assert statement.
    *
-   * <pre>
-   * assertStatement ::=
-   *     'assert' '(' conditionalExpression ')' ';'
-   * </pre>
-   *
-   * @return the assert statement
+   *     assertStatement ::=
+   *         'assert' '(' conditionalExpression ')' ';'
    */
   AssertStatement _parseAssertStatement() {
     Token keyword = _expectKeyword(Keyword.ASSERT);
@@ -4378,18 +4157,14 @@
   }
 
   /**
-   * Parse an assignable expression.
+   * Parse an assignable expression. The [primaryAllowed] is `true` if the
+   * expression is allowed to be a primary without any assignable selector.
+   * Return the assignable expression that was parsed.
    *
-   * <pre>
-   * assignableExpression ::=
-   *     primary (arguments* assignableSelector)+
-   *   | 'super' assignableSelector
-   *   | identifier
-   * </pre>
-   *
-   * @param primaryAllowed `true` if the expression is allowed to be a primary without any
-   *          assignable selector
-   * @return the assignable expression that was parsed
+   *     assignableExpression ::=
+   *         primary (arguments* assignableSelector)+
+   *       | 'super' assignableSelector
+   *       | identifier
    */
   Expression _parseAssignableExpression(bool primaryAllowed) {
     if (_matchesKeyword(Keyword.SUPER)) {
@@ -4441,18 +4216,14 @@
   }
 
   /**
-   * Parse an assignable selector.
+   * Parse an assignable selector. The [prefix] is the expression preceding the
+   * selector. The [optional] is `true` if the selector is optional. Return the
+   * assignable selector that was parsed, or the original prefix if there was no
+   * assignable selector.
    *
-   * <pre>
-   * assignableSelector ::=
-   *     '[' expression ']'
-   *   | '.' identifier
-   * </pre>
-   *
-   * @param prefix the expression preceding the selector
-   * @param optional `true` if the selector is optional
-   * @return the assignable selector that was parsed, or the original prefix if there was no
-   *         assignable selector
+   *     assignableSelector ::=
+   *         '[' expression ']'
+   *       | '.' identifier
    */
   Expression _parseAssignableSelector(Expression prefix, bool optional) {
     if (_matches(TokenType.OPEN_SQUARE_BRACKET)) {
@@ -4481,14 +4252,10 @@
   }
 
   /**
-   * Parse a await expression.
+   * Parse a await expression. Return the await expression that was parsed.
    *
-   * <pre>
-   * awaitExpression ::=
-   *     'await' unaryExpression
-   * </pre>
-   *
-   * @return the await expression that was parsed
+   *     awaitExpression ::=
+   *         'await' unaryExpression
    */
   AwaitExpression _parseAwaitExpression() {
     Token awaitToken = getAndAdvance();
@@ -4497,15 +4264,12 @@
   }
 
   /**
-   * Parse a bitwise and expression.
+   * Parse a bitwise and expression. Return the bitwise and expression that was
+   * parsed.
    *
-   * <pre>
-   * bitwiseAndExpression ::=
-   *     shiftExpression ('&' shiftExpression)*
-   *   | 'super' ('&' shiftExpression)+
-   * </pre>
-   *
-   * @return the bitwise and expression that was parsed
+   *     bitwiseAndExpression ::=
+   *         shiftExpression ('&' shiftExpression)*
+   *       | 'super' ('&' shiftExpression)+
    */
   Expression _parseBitwiseAndExpression() {
     Expression expression;
@@ -4524,15 +4288,12 @@
   }
 
   /**
-   * Parse a bitwise exclusive-or expression.
+   * Parse a bitwise exclusive-or expression. Return the bitwise exclusive-or
+   * expression that was parsed.
    *
-   * <pre>
-   * bitwiseXorExpression ::=
-   *     bitwiseAndExpression ('^' bitwiseAndExpression)*
-   *   | 'super' ('^' bitwiseAndExpression)+
-   * </pre>
-   *
-   * @return the bitwise exclusive-or expression that was parsed
+   *     bitwiseXorExpression ::=
+   *         bitwiseAndExpression ('^' bitwiseAndExpression)*
+   *       | 'super' ('^' bitwiseAndExpression)+
    */
   Expression _parseBitwiseXorExpression() {
     Expression expression;
@@ -4551,14 +4312,10 @@
   }
 
   /**
-   * Parse a break statement.
+   * Parse a break statement. Return the break statement that was parsed.
    *
-   * <pre>
-   * breakStatement ::=
-   *     'break' identifier? ';'
-   * </pre>
-   *
-   * @return the break statement that was parsed
+   *     breakStatement ::=
+   *         'break' identifier? ';'
    */
   Statement _parseBreakStatement() {
     Token breakKeyword = _expectKeyword(Keyword.BREAK);
@@ -4574,21 +4331,18 @@
   }
 
   /**
-   * Parse a cascade section.
+   * Parse a cascade section. Return the expression representing the cascaded
+   * method invocation.
    *
-   * <pre>
-   * cascadeSection ::=
-   *     '..' (cascadeSelector arguments*) (assignableSelector arguments*)* cascadeAssignment?
+   *     cascadeSection ::=
+   *         '..' (cascadeSelector arguments*) (assignableSelector arguments*)* cascadeAssignment?
    *
-   * cascadeSelector ::=
-   *     '[' expression ']'
-   *   | identifier
+   *     cascadeSelector ::=
+   *         '[' expression ']'
+   *       | identifier
    *
-   * cascadeAssignment ::=
-   *     assignmentOperator expressionWithoutCascade
-   * </pre>
-   *
-   * @return the expression representing the cascaded method invocation
+   *     cascadeAssignment ::=
+   *         assignmentOperator expressionWithoutCascade
    */
   Expression _parseCascadeSection() {
     Token period = _expect(TokenType.PERIOD_PERIOD);
@@ -4610,9 +4364,8 @@
         _inInitializer = wasInInitializer;
       }
     } else {
-      _reportErrorForToken(ParserErrorCode.MISSING_IDENTIFIER, _currentToken, [
-        _currentToken.lexeme
-      ]);
+      _reportErrorForToken(ParserErrorCode.MISSING_IDENTIFIER, _currentToken,
+          [_currentToken.lexeme]);
       functionName = _createSyntheticIdentifier();
     }
     assert((expression == null && functionName != null) ||
@@ -4668,18 +4421,14 @@
   }
 
   /**
-   * Parse a class declaration.
+   * Parse a class declaration. The [commentAndMetadata] is the metadata to be
+   * associated with the member. The [abstractKeyword] is the token for the
+   * keyword 'abstract', or `null` if the keyword was not given. Return the
+   * class declaration that was parsed.
    *
-   * <pre>
-   * classDeclaration ::=
-   *     metadata 'abstract'? 'class' name typeParameterList? (extendsClause withClause?)? implementsClause? '{' classMembers '}' |
-   *     metadata 'abstract'? 'class' mixinApplicationClass
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the member
-   * @param abstractKeyword the token for the keyword 'abstract', or `null` if the keyword was
-   *          not given
-   * @return the class declaration that was parsed
+   *     classDeclaration ::=
+   *         metadata 'abstract'? 'class' name typeParameterList? (extendsClause withClause?)? implementsClause? '{' classMembers '}' |
+   *         metadata 'abstract'? 'class' mixinApplicationClass
    */
   CompilationUnitMember _parseClassDeclaration(
       CommentAndMetadata commentAndMetadata, Token abstractKeyword) {
@@ -4791,17 +4540,13 @@
   }
 
   /**
-   * Parse a list of class members.
+   * Parse a list of class members. The [className] is the name of the class
+   * whose members are being parsed. The [closingBracket] is the closing bracket
+   * for the class, or `null` if the closing bracket is missing. Return the list
+   * of class members that were parsed.
    *
-   * <pre>
-   * classMembers ::=
-   *     (metadata memberDefinition)*
-   * </pre>
-   *
-   * @param className the name of the class whose members are being parsed
-   * @param closingBracket the closing bracket for the class, or `null` if the closing bracket
-   *          is missing
-   * @return the list of class members that were parsed
+   *     classMembers ::=
+   *         (metadata memberDefinition)*
    */
   List<ClassMember> _parseClassMembers(String className, Token closingBracket) {
     List<ClassMember> members = new List<ClassMember>();
@@ -4812,9 +4557,8 @@
             (!_matchesKeyword(Keyword.CLASS) &&
                 !_matchesKeyword(Keyword.TYPEDEF)))) {
       if (_matches(TokenType.SEMICOLON)) {
-        _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [
-          _currentToken.lexeme
-        ]);
+        _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken,
+            [_currentToken.lexeme]);
         _advance();
       } else {
         ClassMember member = parseClassMember(className);
@@ -4823,9 +4567,8 @@
         }
       }
       if (identical(_currentToken, memberStart)) {
-        _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [
-          _currentToken.lexeme
-        ]);
+        _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken,
+            [_currentToken.lexeme]);
         _advance();
       }
       memberStart = _currentToken;
@@ -4834,20 +4577,16 @@
   }
 
   /**
-   * Parse a class type alias.
+   * Parse a class type alias. The [commentAndMetadata] is the metadata to be
+   * associated with the member. The [abstractKeyword] is the token representing
+   * the 'abstract' keyword. The [classKeyword] is the token representing the
+   * 'class' keyword. Return the class type alias that was parsed.
    *
-   * <pre>
-   * classTypeAlias ::=
-   *     identifier typeParameters? '=' 'abstract'? mixinApplication
+   *     classTypeAlias ::=
+   *         identifier typeParameters? '=' 'abstract'? mixinApplication
    *
-   * mixinApplication ::=
-   *     type withClause implementsClause? ';'
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the member
-   * @param abstractKeyword the token representing the 'abstract' keyword
-   * @param classKeyword the token representing the 'class' keyword
-   * @return the class type alias that was parsed
+   *     mixinApplication ::=
+   *         type withClause implementsClause? ';'
    */
   ClassTypeAlias _parseClassTypeAlias(CommentAndMetadata commentAndMetadata,
       Token abstractKeyword, Token classKeyword) {
@@ -4892,15 +4631,12 @@
   }
 
   /**
-   * Parse a list of combinators in a directive.
+   * Parse a list of combinators in a directive. Return the combinators that
+   * were parsed.
    *
-   * <pre>
-   * combinator ::=
-   *     'show' identifier (',' identifier)*
-   *   | 'hide' identifier (',' identifier)*
-   * </pre>
-   *
-   * @return the combinators that were parsed
+   *     combinator ::=
+   *         'show' identifier (',' identifier)*
+   *       | 'hide' identifier (',' identifier)*
    */
   List<Combinator> _parseCombinators() {
     List<Combinator> combinators = new List<Combinator>();
@@ -4915,16 +4651,14 @@
   }
 
   /**
-   * Parse the documentation comment and metadata preceding a declaration. This method allows any
-   * number of documentation comments to occur before, after or between the metadata, but only
-   * returns the last (right-most) documentation comment that is found.
+   * Parse the documentation comment and metadata preceding a declaration. This
+   * method allows any number of documentation comments to occur before, after
+   * or between the metadata, but only returns the last (right-most)
+   * documentation comment that is found. Return the documentation comment and
+   * metadata that were parsed.
    *
-   * <pre>
-   * metadata ::=
-   *     annotation*
-   * </pre>
-   *
-   * @return the documentation comment and metadata that were parsed
+   *     metadata ::=
+   *         annotation*
    */
   CommentAndMetadata _parseCommentAndMetadata() {
     Comment comment = _parseDocumentationComment();
@@ -4940,17 +4674,14 @@
   }
 
   /**
-   * Parse a comment reference from the source between square brackets.
+   * Parse a comment reference from the source between square brackets. The
+   * [referenceSource] is the source occurring between the square brackets
+   * within a documentation comment. The [sourceOffset] is the offset of the
+   * first character of the reference source. Return the comment reference that
+   * was parsed, or `null` if no reference could be found.
    *
-   * <pre>
-   * commentReference ::=
-   *     'new'? prefixedIdentifier
-   * </pre>
-   *
-   * @param referenceSource the source occurring between the square brackets within a documentation
-   *          comment
-   * @param sourceOffset the offset of the first character of the reference source
-   * @return the comment reference that was parsed, or `null` if no reference could be found
+   *     commentReference ::=
+   *         'new'? prefixedIdentifier
    */
   CommentReference _parseCommentReference(
       String referenceSource, int sourceOffset) {
@@ -5011,18 +4742,16 @@
   }
 
   /**
-   * Parse all of the comment references occurring in the given array of documentation comments.
+   * Parse all of the comment references occurring in the given array of
+   * documentation comments. The [tokens] are the comment tokens representing
+   * the documentation comments to be parsed. Return the comment references that
+   * were parsed.
    *
-   * <pre>
-   * commentReference ::=
-   *     '[' 'new'? qualified ']' libraryReference?
+   *     commentReference ::=
+   *         '[' 'new'? qualified ']' libraryReference?
    *
-   * libraryReference ::=
-   *      '(' stringLiteral ')'
-   * </pre>
-   *
-   * @param tokens the comment tokens representing the documentation comments to be parsed
-   * @return the comment references that were parsed
+   *     libraryReference ::=
+   *          '(' stringLiteral ')'
    */
   List<CommentReference> _parseCommentReferences(
       List<DocumentationCommentToken> tokens) {
@@ -5082,24 +4811,21 @@
   }
 
   /**
-   * Parse a compilation unit member.
+   * Parse a compilation unit member. The [commentAndMetadata] is the metadata
+   * to be associated with the member. Return the compilation unit member that
+   * was parsed, or `null` if what was parsed could not be represented as a
+   * compilation unit member.
    *
-   * <pre>
-   * compilationUnitMember ::=
-   *     classDefinition
-   *   | functionTypeAlias
-   *   | external functionSignature
-   *   | external getterSignature
-   *   | external setterSignature
-   *   | functionSignature functionBody
-   *   | returnType? getOrSet identifier formalParameterList functionBody
-   *   | (final | const) type? staticFinalDeclarationList ';'
-   *   | variableDeclaration ';'
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the member
-   * @return the compilation unit member that was parsed, or `null` if what was parsed could
-   *         not be represented as a compilation unit member
+   *     compilationUnitMember ::=
+   *         classDefinition
+   *       | functionTypeAlias
+   *       | external functionSignature
+   *       | external getterSignature
+   *       | external setterSignature
+   *       | functionSignature functionBody
+   *       | returnType? getOrSet identifier formalParameterList functionBody
+   *       | (final | const) type? staticFinalDeclarationList ';'
+   *       | variableDeclaration ';'
    */
   CompilationUnitMember _parseCompilationUnitMember(
       CommentAndMetadata commentAndMetadata) {
@@ -5257,16 +4983,12 @@
   }
 
   /**
-   * Parse a const expression.
+   * Parse a const expression. Return the const expression that was parsed.
    *
-   * <pre>
-   * constExpression ::=
-   *     instanceCreationExpression
-   *   | listLiteral
-   *   | mapLiteral
-   * </pre>
-   *
-   * @return the const expression that was parsed
+   *     constExpression ::=
+   *         instanceCreationExpression
+   *       | listLiteral
+   *       | mapLiteral
    */
   Expression _parseConstExpression() {
     Token keyword = _expectKeyword(Keyword.CONST);
@@ -5356,14 +5078,11 @@
   }
 
   /**
-   * Parse a field initializer within a constructor.
+   * Parse a field initializer within a constructor. Return the field
+   * initializer that was parsed.
    *
-   * <pre>
-   * fieldInitializer:
-   *     ('this' '.')? identifier '=' conditionalExpression cascadeSection*
-   * </pre>
-   *
-   * @return the field initializer that was parsed
+   *     fieldInitializer:
+   *         ('this' '.')? identifier '=' conditionalExpression cascadeSection*
    */
   ConstructorFieldInitializer _parseConstructorFieldInitializer() {
     Token keyword = null;
@@ -5413,14 +5132,10 @@
   }
 
   /**
-   * Parse a continue statement.
+   * Parse a continue statement. Return the continue statement that was parsed.
    *
-   * <pre>
-   * continueStatement ::=
-   *     'continue' identifier? ';'
-   * </pre>
-   *
-   * @return the continue statement that was parsed
+   *     continueStatement ::=
+   *         'continue' identifier? ';'
    */
   Statement _parseContinueStatement() {
     Token continueKeyword = _expectKeyword(Keyword.CONTINUE);
@@ -5441,18 +5156,14 @@
   }
 
   /**
-   * Parse a directive.
+   * Parse a directive. The [commentAndMetadata] is the metadata to be
+   * associated with the directive. Return the directive that was parsed.
    *
-   * <pre>
-   * directive ::=
-   *     exportDirective
-   *   | libraryDirective
-   *   | importDirective
-   *   | partDirective
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the directive
-   * @return the directive that was parsed
+   *     directive ::=
+   *         exportDirective
+   *       | libraryDirective
+   *       | importDirective
+   *       | partDirective
    */
   Directive _parseDirective(CommentAndMetadata commentAndMetadata) {
     if (_matchesKeyword(Keyword.IMPORT)) {
@@ -5472,16 +5183,11 @@
   }
 
   /**
-   * Parse the script tag and directives in a compilation unit until the first non-directive is
-   * encountered.
+   * Parse the script tag and directives in a compilation unit until the first
+   * non-directive is encountered. Return the compilation unit that was parsed.
    *
-   *
-   * <pre>
-   * compilationUnit ::=
-   *     scriptTag? directive*
-   * </pre>
-   *
-   * @return the compilation unit that was parsed
+   *     compilationUnit ::=
+   *         scriptTag? directive*
    */
   CompilationUnit _parseDirectives() {
     Token firstToken = _currentToken;
@@ -5515,15 +5221,12 @@
   }
 
   /**
-   * Parse a documentation comment.
+   * Parse a documentation comment. Return the documentation comment that was
+   * parsed, or `null` if there was no comment.
    *
-   * <pre>
-   * documentationComment ::=
-   *     multiLineComment?
-   *   | singleLineComment*
-   * </pre>
-   *
-   * @return the documentation comment that was parsed, or `null` if there was no comment
+   *     documentationComment ::=
+   *         multiLineComment?
+   *       | singleLineComment*
    */
   Comment _parseDocumentationComment() {
     List<DocumentationCommentToken> documentationTokens =
@@ -5554,14 +5257,10 @@
   }
 
   /**
-   * Parse a do statement.
+   * Parse a do statement. Return the do statement that was parsed.
    *
-   * <pre>
-   * doStatement ::=
-   *     'do' statement 'while' '(' expression ')' ';'
-   * </pre>
-   *
-   * @return the do statement that was parsed
+   *     doStatement ::=
+   *         'do' statement 'while' '(' expression ')' ';'
    */
   Statement _parseDoStatement() {
     bool wasInLoop = _inLoop;
@@ -5582,14 +5281,10 @@
   }
 
   /**
-   * Parse an empty statement.
+   * Parse an empty statement. Return the empty statement that was parsed.
    *
-   * <pre>
-   * emptyStatement ::=
-   *     ';'
-   * </pre>
-   *
-   * @return the empty statement that was parsed
+   *     emptyStatement ::=
+   *         ';'
    */
   Statement _parseEmptyStatement() => new EmptyStatement(getAndAdvance());
 
@@ -5610,15 +5305,11 @@
   }
 
   /**
-   * Parse an enum declaration.
+   * Parse an enum declaration. The [commentAndMetadata] is the metadata to be
+   * associated with the member. Return the enum declaration that was parsed.
    *
-   * <pre>
-   * enumType ::=
-   *     metadata 'enum' id '{' id (',' id)* (',')? '}'
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the member
-   * @return the enum declaration that was parsed
+   *     enumType ::=
+   *         metadata 'enum' id '{' id (',' id)* (',')? '}'
    */
   EnumDeclaration _parseEnumDeclaration(CommentAndMetadata commentAndMetadata) {
     Token keyword = _expectKeyword(Keyword.ENUM);
@@ -5657,15 +5348,12 @@
   }
 
   /**
-   * Parse an equality expression.
+   * Parse an equality expression. Return the equality expression that was
+   * parsed.
    *
-   * <pre>
-   * equalityExpression ::=
-   *     relationalExpression (equalityOperator relationalExpression)?
-   *   | 'super' equalityOperator relationalExpression
-   * </pre>
-   *
-   * @return the equality expression that was parsed
+   *     equalityExpression ::=
+   *         relationalExpression (equalityOperator relationalExpression)?
+   *       | 'super' equalityOperator relationalExpression
    */
   Expression _parseEqualityExpression() {
     Expression expression;
@@ -5690,15 +5378,11 @@
   }
 
   /**
-   * Parse an export directive.
+   * Parse an export directive. The [commentAndMetadata] is the metadata to be
+   * associated with the directive. Return the export directive that was parsed.
    *
-   * <pre>
-   * exportDirective ::=
-   *     metadata 'export' stringLiteral combinator*';'
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the directive
-   * @return the export directive that was parsed
+   *     exportDirective ::=
+   *         metadata 'export' stringLiteral combinator*';'
    */
   ExportDirective _parseExportDirective(CommentAndMetadata commentAndMetadata) {
     Token exportKeyword = _expectKeyword(Keyword.EXPORT);
@@ -5711,14 +5395,10 @@
   }
 
   /**
-   * Parse a list of expressions.
+   * Parse a list of expressions. Return the expression that was parsed.
    *
-   * <pre>
-   * expressionList ::=
-   *     expression (',' expression)*
-   * </pre>
-   *
-   * @return the expression that was parsed
+   *     expressionList ::=
+   *         expression (',' expression)*
    */
   List<Expression> _parseExpressionList() {
     List<Expression> expressions = new List<Expression>();
@@ -5731,17 +5411,14 @@
 
   /**
    * Parse the 'final', 'const', 'var' or type preceding a variable declaration.
+   * The [optional] is `true` if the keyword and type are optional. Return the
+   * 'final', 'const', 'var' or type that was parsed.
    *
-   * <pre>
-   * finalConstVarOrType ::=
-   *   | 'final' type?
-   *   | 'const' type?
-   *   | 'var'
-   *   | type
-   * </pre>
-   *
-   * @param optional `true` if the keyword and type are optional
-   * @return the 'final', 'const', 'var' or type that was parsed
+   *     finalConstVarOrType ::=
+   *         'final' type?
+   *       | 'const' type?
+   *       | 'var'
+   *       | type
    */
   FinalConstVarOrType _parseFinalConstVarOrType(bool optional) {
     Token keyword = null;
@@ -5766,19 +5443,15 @@
 
   /**
    * Parse a formal parameter. At most one of `isOptional` and `isNamed` can be
-   * `true`.
+   * `true`. The [kind] is the kind of parameter being expected based on the
+   * presence or absence of group delimiters. Return the formal parameter that
+   * was parsed.
    *
-   * <pre>
-   * defaultFormalParameter ::=
-   *     normalFormalParameter ('=' expression)?
+   *     defaultFormalParameter ::=
+   *         normalFormalParameter ('=' expression)?
    *
-   * defaultNamedParameter ::=
-   *     normalFormalParameter (':' expression)?
-   * </pre>
-   *
-   * @param kind the kind of parameter being expected based on the presence or absence of group
-   *          delimiters
-   * @return the formal parameter that was parsed
+   *     defaultNamedParameter ::=
+   *         normalFormalParameter (':' expression)?
    */
   FormalParameter _parseFormalParameter(ParameterKind kind) {
     NormalFormalParameter parameter = parseNormalFormalParameter();
@@ -5814,23 +5487,19 @@
   }
 
   /**
-   * Parse a for statement.
+   * Parse a for statement. Return the for statement that was parsed.
    *
-   * <pre>
-   * forStatement ::=
-   *     'for' '(' forLoopParts ')' statement
+   *     forStatement ::=
+   *         'for' '(' forLoopParts ')' statement
    *
-   * forLoopParts ::=
-   *     forInitializerStatement expression? ';' expressionList?
-   *   | declaredIdentifier 'in' expression
-   *   | identifier 'in' expression
+   *     forLoopParts ::=
+   *         forInitializerStatement expression? ';' expressionList?
+   *       | declaredIdentifier 'in' expression
+   *       | identifier 'in' expression
    *
-   * forInitializerStatement ::=
-   *     localVariableDeclaration ';'
-   *   | expression? ';'
-   * </pre>
-   *
-   * @return the for statement that was parsed
+   *     forInitializerStatement ::=
+   *         localVariableDeclaration ';'
+   *       | expression? ';'
    */
   Statement _parseForStatement() {
     bool wasInLoop = _inLoop;
@@ -5875,9 +5544,8 @@
             NodeList<VariableDeclaration> variables = variableList.variables;
             if (variables.length > 1) {
               _reportErrorForCurrentToken(
-                  ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH, [
-                variables.length.toString()
-              ]);
+                  ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH,
+                  [variables.length.toString()]);
             }
             VariableDeclaration variable = variables[0];
             if (variable.initializer != null) {
@@ -5937,23 +5605,19 @@
   }
 
   /**
-   * Parse a function body.
+   * Parse a function body. The [mayBeEmpty] is `true` if the function body is
+   * allowed to be empty. The [emptyErrorCode] is the error code to report if
+   * function body expected, but not found. The [inExpression] is `true` if the
+   * function body is being parsed as part of an expression and therefore does
+   * not have a terminating semicolon. Return the function body that was parsed.
    *
-   * <pre>
-   * functionBody ::=
-   *     '=>' expression ';'
-   *   | block
+   *     functionBody ::=
+   *         '=>' expression ';'
+   *       | block
    *
-   * functionExpressionBody ::=
-   *     '=>' expression
-   *   | block
-   * </pre>
-   *
-   * @param mayBeEmpty `true` if the function body is allowed to be empty
-   * @param emptyErrorCode the error code to report if function body expected, but not found
-   * @param inExpression `true` if the function body is being parsed as part of an expression
-   *          and therefore does not have a terminating semicolon
-   * @return the function body that was parsed
+   *     functionExpressionBody ::=
+   *         '=>' expression
+   *       | block
    */
   FunctionBody _parseFunctionBody(
       bool mayBeEmpty, ParserErrorCode emptyErrorCode, bool inExpression) {
@@ -6050,20 +5714,17 @@
   }
 
   /**
-   * Parse a function declaration.
+   * Parse a function declaration. The [commentAndMetadata] is the documentation
+   * comment and metadata to be associated with the declaration. The
+   * [externalKeyword] is the 'external' keyword, or `null` if the function is
+   * not external. The [returnType] is the return type, or `null` if there is no
+   * return type. The [isStatement] is `true` if the function declaration is
+   * being parsed as a statement. Return the function declaration that was
+   * parsed.
    *
-   * <pre>
-   * functionDeclaration ::=
-   *     functionSignature functionBody
-   *   | returnType? getOrSet identifier formalParameterList functionBody
-   * </pre>
-   *
-   * @param commentAndMetadata the documentation comment and metadata to be associated with the
-   *          declaration
-   * @param externalKeyword the 'external' keyword, or `null` if the function is not external
-   * @param returnType the return type, or `null` if there is no return type
-   * @param isStatement `true` if the function declaration is being parsed as a statement
-   * @return the function declaration that was parsed
+   *     functionDeclaration ::=
+   *         functionSignature functionBody
+   *       | returnType? getOrSet identifier formalParameterList functionBody
    */
   FunctionDeclaration _parseFunctionDeclaration(
       CommentAndMetadata commentAndMetadata, Token externalKeyword,
@@ -6110,14 +5771,11 @@
   }
 
   /**
-   * Parse a function declaration statement.
+   * Parse a function declaration statement. Return the function declaration
+   * statement that was parsed.
    *
-   * <pre>
-   * functionDeclarationStatement ::=
-   *     functionSignature functionBody
-   * </pre>
-   *
-   * @return the function declaration statement that was parsed
+   *     functionDeclarationStatement ::=
+   *         functionSignature functionBody
    */
   Statement _parseFunctionDeclarationStatement() {
     Modifiers modifiers = _parseModifiers();
@@ -6127,17 +5785,13 @@
   }
 
   /**
-   * Parse a function declaration statement.
+   * Parse a function declaration statement. The [commentAndMetadata] is the
+   * documentation comment and metadata to be associated with the declaration.
+   * The [returnType] is the return type, or `null` if there is no return type.
+   * Return the function declaration statement that was parsed.
    *
-   * <pre>
-   * functionDeclarationStatement ::=
-   *     functionSignature functionBody
-   * </pre>
-   *
-   * @param commentAndMetadata the documentation comment and metadata to be associated with the
-   *          declaration
-   * @param returnType the return type, or `null` if there is no return type
-   * @return the function declaration statement that was parsed
+   *     functionDeclarationStatement ::=
+   *         functionSignature functionBody
    */
   Statement _parseFunctionDeclarationStatementAfterReturnType(
       CommentAndMetadata commentAndMetadata, TypeName returnType) {
@@ -6157,19 +5811,15 @@
   }
 
   /**
-   * Parse a function type alias.
+   * Parse a function type alias. The [commentAndMetadata] is the metadata to be
+   * associated with the member. The [keyword] is the token representing the
+   * 'typedef' keyword. Return the function type alias that was parsed.
    *
-   * <pre>
-   * functionTypeAlias ::=
-   *     functionPrefix typeParameterList? formalParameterList ';'
+   *     functionTypeAlias ::=
+   *         functionPrefix typeParameterList? formalParameterList ';'
    *
-   * functionPrefix ::=
-   *     returnType? name
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the member
-   * @param keyword the token representing the 'typedef' keyword
-   * @return the function type alias that was parsed
+   *     functionPrefix ::=
+   *         returnType? name
    */
   FunctionTypeAlias _parseFunctionTypeAlias(
       CommentAndMetadata commentAndMetadata, Token keyword) {
@@ -6213,23 +5863,18 @@
   }
 
   /**
-   * Parse a getter.
+   * Parse a getter. The [commentAndMetadata] is the documentation comment and
+   * metadata to be associated with the declaration. The externalKeyword] is the
+   * 'external' token. The staticKeyword] is the static keyword, or `null` if
+   * the getter is not static. The [returnType] the return type that has already
+   * been parsed, or `null` if there was no return type. Return the getter that
+   * was parsed.
    *
-   * <pre>
-   * getter ::=
-   *     getterSignature functionBody?
+   *     getter ::=
+   *         getterSignature functionBody?
    *
-   * getterSignature ::=
-   *     'external'? 'static'? returnType? 'get' identifier
-   * </pre>
-   *
-   * @param commentAndMetadata the documentation comment and metadata to be associated with the
-   *          declaration
-   * @param externalKeyword the 'external' token
-   * @param staticKeyword the static keyword, or `null` if the getter is not static
-   * @param the return type that has already been parsed, or `null` if there was no return
-   *          type
-   * @return the getter that was parsed
+   *     getterSignature ::=
+   *         'external'? 'static'? returnType? 'get' identifier
    */
   MethodDeclaration _parseGetter(CommentAndMetadata commentAndMetadata,
       Token externalKeyword, Token staticKeyword, TypeName returnType) {
@@ -6253,14 +5898,11 @@
   }
 
   /**
-   * Parse a list of identifiers.
+   * Parse a list of identifiers. Return the list of identifiers that were
+   * parsed.
    *
-   * <pre>
-   * identifierList ::=
-   *     identifier (',' identifier)*
-   * </pre>
-   *
-   * @return the list of identifiers that were parsed
+   *     identifierList ::=
+   *         identifier (',' identifier)*
    */
   List<SimpleIdentifier> _parseIdentifierList() {
     List<SimpleIdentifier> identifiers = new List<SimpleIdentifier>();
@@ -6273,14 +5915,10 @@
   }
 
   /**
-   * Parse an if statement.
+   * Parse an if statement. Return the if statement that was parsed.
    *
-   * <pre>
-   * ifStatement ::=
-   *     'if' '(' expression ')' statement ('else' statement)?
-   * </pre>
-   *
-   * @return the if statement that was parsed
+   *     ifStatement ::=
+   *         'if' '(' expression ')' statement ('else' statement)?
    */
   Statement _parseIfStatement() {
     Token ifKeyword = _expectKeyword(Keyword.IF);
@@ -6299,15 +5937,11 @@
   }
 
   /**
-   * Parse an import directive.
+   * Parse an import directive. The [commentAndMetadata] is the metadata to be
+   * associated with the directive. Return the import directive that was parsed.
    *
-   * <pre>
-   * importDirective ::=
-   *     metadata 'import' stringLiteral ('as' identifier)? combinator*';'
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the directive
-   * @return the import directive that was parsed
+   *     importDirective ::=
+   *         metadata 'import' stringLiteral ('as' identifier)? combinator*';'
    */
   ImportDirective _parseImportDirective(CommentAndMetadata commentAndMetadata) {
     Token importKeyword = _expectKeyword(Keyword.IMPORT);
@@ -6333,27 +5967,23 @@
   }
 
   /**
-   * Parse a list of initialized identifiers.
+   * Parse a list of initialized identifiers. The [commentAndMetadata] is the
+   * documentation comment and metadata to be associated with the declaration.
+   * The [staticKeyword] is the static keyword, or `null` if the getter is not
+   * static. The [keyword] is the token representing the 'final', 'const' or
+   * 'var' keyword, or `null` if there is no keyword. The [type] is the type
+   * that has already been parsed, or `null` if 'var' was provided. Return the
+   * getter that was parsed.
    *
-   * <pre>
-   * ?? ::=
-   *     'static'? ('var' | type) initializedIdentifierList ';'
-   *   | 'final' type? initializedIdentifierList ';'
+   *     ?? ::=
+   *         'static'? ('var' | type) initializedIdentifierList ';'
+   *       | 'final' type? initializedIdentifierList ';'
    *
-   * initializedIdentifierList ::=
-   *     initializedIdentifier (',' initializedIdentifier)*
+   *     initializedIdentifierList ::=
+   *         initializedIdentifier (',' initializedIdentifier)*
    *
-   * initializedIdentifier ::=
-   *     identifier ('=' expression)?
-   * </pre>
-   *
-   * @param commentAndMetadata the documentation comment and metadata to be associated with the
-   *          declaration
-   * @param staticKeyword the static keyword, or `null` if the getter is not static
-   * @param keyword the token representing the 'final', 'const' or 'var' keyword, or `null` if
-   *          there is no keyword
-   * @param type the type that has already been parsed, or `null` if 'var' was provided
-   * @return the getter that was parsed
+   *     initializedIdentifier ::=
+   *         identifier ('=' expression)?
    */
   FieldDeclaration _parseInitializedIdentifierList(
       CommentAndMetadata commentAndMetadata, Token staticKeyword, Token keyword,
@@ -6366,15 +5996,12 @@
   }
 
   /**
-   * Parse an instance creation expression.
+   * Parse an instance creation expression. The [keyword] is the 'new' or
+   * 'const' keyword that introduces the expression. Return the instance
+   * creation expression that was parsed.
    *
-   * <pre>
-   * instanceCreationExpression ::=
-   *     ('new' | 'const') type ('.' identifier)? argumentList
-   * </pre>
-   *
-   * @param keyword the 'new' or 'const' keyword that introduces the expression
-   * @return the instance creation expression that was parsed
+   *     instanceCreationExpression ::=
+   *         ('new' | 'const') type ('.' identifier)? argumentList
    */
   InstanceCreationExpression _parseInstanceCreationExpression(Token keyword) {
     ConstructorName constructorName = parseConstructorName();
@@ -6384,15 +6011,12 @@
   }
 
   /**
-   * Parse a library directive.
+   * Parse a library directive. The [commentAndMetadata] is the metadata to be
+   * associated with the directive. Return the library directive that was
+   * parsed.
    *
-   * <pre>
-   * libraryDirective ::=
-   *     metadata 'library' identifier ';'
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the directive
-   * @return the library directive that was parsed
+   *     libraryDirective ::=
+   *         metadata 'library' identifier ';'
    */
   LibraryDirective _parseLibraryDirective(
       CommentAndMetadata commentAndMetadata) {
@@ -6405,17 +6029,13 @@
   }
 
   /**
-   * Parse a library name.
+   * Parse a library name. The [missingNameError] is the error code to be used
+   * if the library name is missing. The [missingNameToken] is the token
+   * associated with the error produced if the library name is missing. Return
+   * the library name that was parsed.
    *
-   * <pre>
-   * libraryName ::=
-   *     libraryIdentifier
-   * </pre>
-   *
-   * @param missingNameError the error code to be used if the library name is missing
-   * @param missingNameToken the token associated with the error produced if the library name is
-   *          missing
-   * @return the library name that was parsed
+   *     libraryName ::=
+   *         libraryIdentifier
    */
   LibraryIdentifier _parseLibraryName(
       ParserErrorCode missingNameError, Token missingNameToken) {
@@ -6436,18 +6056,13 @@
   }
 
   /**
-   * Parse a list literal.
+   * Parse a list literal. The [modifier] is the 'const' modifier appearing
+   * before the literal, or `null` if there is no modifier. The [typeArguments]
+   * is the type arguments appearing before the literal, or `null` if there are
+   * no type arguments. Return the list literal that was parsed.
    *
-   * <pre>
-   * listLiteral ::=
-   *     'const'? typeArguments? '[' (expressionList ','?)? ']'
-   * </pre>
-   *
-   * @param modifier the 'const' modifier appearing before the literal, or `null` if there is
-   *          no modifier
-   * @param typeArguments the type arguments appearing before the literal, or `null` if there
-   *          are no type arguments
-   * @return the list literal that was parsed
+   *     listLiteral ::=
+   *         'const'? typeArguments? '[' (expressionList ','?)? ']'
    */
   ListLiteral _parseListLiteral(
       Token modifier, TypeArgumentList typeArguments) {
@@ -6492,17 +6107,13 @@
   }
 
   /**
-   * Parse a list or map literal.
+   * Parse a list or map literal. The [modifier] is the 'const' modifier
+   * appearing before the literal, or `null` if there is no modifier. Return the
+   * list or map literal that was parsed.
    *
-   * <pre>
-   * listOrMapLiteral ::=
-   *     listLiteral
-   *   | mapLiteral
-   * </pre>
-   *
-   * @param modifier the 'const' modifier appearing before the literal, or `null` if there is
-   *          no modifier
-   * @return the list or map literal that was parsed
+   *     listOrMapLiteral ::=
+   *         listLiteral
+   *       | mapLiteral
    */
   TypedLiteral _parseListOrMapLiteral(Token modifier) {
     TypeArgumentList typeArguments = null;
@@ -6522,14 +6133,11 @@
   }
 
   /**
-   * Parse a logical and expression.
+   * Parse a logical and expression. Return the logical and expression that was
+   * parsed.
    *
-   * <pre>
-   * logicalAndExpression ::=
-   *     equalityExpression ('&&' equalityExpression)*
-   * </pre>
-   *
-   * @return the logical and expression that was parsed
+   *     logicalAndExpression ::=
+   *         equalityExpression ('&&' equalityExpression)*
    */
   Expression _parseLogicalAndExpression() {
     Expression expression = _parseEqualityExpression();
@@ -6542,18 +6150,13 @@
   }
 
   /**
-   * Parse a map literal.
+   * Parse a map literal. The [modifier] is the 'const' modifier appearing
+   * before the literal, or `null` if there is no modifier. The [typeArguments]
+   * is the type arguments that were declared, or `null` if there are no type
+   * arguments. Return the map literal that was parsed.
    *
-   * <pre>
-   * mapLiteral ::=
-   *     'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
-   * </pre>
-   *
-   * @param modifier the 'const' modifier appearing before the literal, or `null` if there is
-   *          no modifier
-   * @param typeArguments the type arguments that were declared, or `null` if there are no
-   *          type arguments
-   * @return the map literal that was parsed
+   *     mapLiteral ::=
+   *         'const'? typeArguments? '{' (mapLiteralEntry (',' mapLiteralEntry)* ','?)? '}'
    */
   MapLiteral _parseMapLiteral(Token modifier, TypeArgumentList typeArguments) {
     Token leftBracket = _expect(TokenType.OPEN_CURLY_BRACKET);
@@ -6582,22 +6185,17 @@
   }
 
   /**
-   * Parse a method declaration.
+   * Parse a method declaration. The [commentAndMetadata] is the documentation
+   * comment and metadata to be associated with the declaration. The
+   * [externalKeyword] is the 'external' token. The [staticKeyword] is the
+   * static keyword, or `null` if the getter is not static. The [returnType] is
+   * the return type of the method. The [name] is the name of the method. The
+   * [parameters] is the parameters to the method. Return the method declaration
+   * that was parsed.
    *
-   * <pre>
-   * functionDeclaration ::=
-   *     ('external' 'static'?)? functionSignature functionBody
-   *   | 'external'? functionSignature ';'
-   * </pre>
-   *
-   * @param commentAndMetadata the documentation comment and metadata to be associated with the
-   *          declaration
-   * @param externalKeyword the 'external' token
-   * @param staticKeyword the static keyword, or `null` if the getter is not static
-   * @param returnType the return type of the method
-   * @param name the name of the method
-   * @param parameters the parameters to the method
-   * @return the method declaration that was parsed
+   *     functionDeclaration ::=
+   *         ('external' 'static'?)? functionSignature functionBody
+   *       | 'external'? functionSignature ';'
    */
   MethodDeclaration _parseMethodDeclarationAfterParameters(
       CommentAndMetadata commentAndMetadata, Token externalKeyword,
@@ -6621,20 +6219,16 @@
   }
 
   /**
-   * Parse a method declaration.
+   * Parse a method declaration. The [commentAndMetadata] is the documentation
+   * comment and metadata to be associated with the declaration. The
+   * [externalKeyword] is the 'external' token. The [staticKeyword] is the
+   * static keyword, or `null` if the getter is not static. The [returnType] is
+   * the return type of the method. Return the method declaration that was
+   * parsed.
    *
-   * <pre>
-   * functionDeclaration ::=
-   *     'external'? 'static'? functionSignature functionBody
-   *   | 'external'? functionSignature ';'
-   * </pre>
-   *
-   * @param commentAndMetadata the documentation comment and metadata to be associated with the
-   *          declaration
-   * @param externalKeyword the 'external' token
-   * @param staticKeyword the static keyword, or `null` if the getter is not static
-   * @param returnType the return type of the method
-   * @return the method declaration that was parsed
+   *     functionDeclaration ::=
+   *         'external'? 'static'? functionSignature functionBody
+   *       | 'external'? functionSignature ';'
    */
   MethodDeclaration _parseMethodDeclarationAfterReturnType(
       CommentAndMetadata commentAndMetadata, Token externalKeyword,
@@ -6658,17 +6252,15 @@
   }
 
   /**
-   * Parse the modifiers preceding a declaration. This method allows the modifiers to appear in any
-   * order but does generate errors for duplicated modifiers. Checks for other problems, such as
-   * having the modifiers appear in the wrong order or specifying both 'const' and 'final', are
-   * reported in one of the methods whose name is prefixed with `validateModifiersFor`.
+   * Parse the modifiers preceding a declaration. This method allows the
+   * modifiers to appear in any order but does generate errors for duplicated
+   * modifiers. Checks for other problems, such as having the modifiers appear
+   * in the wrong order or specifying both 'const' and 'final', are reported in
+   * one of the methods whose name is prefixed with `validateModifiersFor`.
+   * Return the modifiers that were parsed.
    *
-   * <pre>
-   * modifiers ::=
-   *     ('abstract' | 'const' | 'external' | 'factory' | 'final' | 'static' | 'var')*
-   * </pre>
-   *
-   * @return the modifiers that were parsed
+   *     modifiers ::=
+   *         ('abstract' | 'const' | 'external' | 'factory' | 'final' | 'static' | 'var')*
    */
   Modifiers _parseModifiers() {
     Modifiers modifiers = new Modifiers();
@@ -6749,15 +6341,12 @@
   }
 
   /**
-   * Parse a multiplicative expression.
+   * Parse a multiplicative expression. Return the multiplicative expression
+   * that was parsed.
    *
-   * <pre>
-   * multiplicativeExpression ::=
-   *     unaryExpression (multiplicativeOperator unaryExpression)*
-   *   | 'super' (multiplicativeOperator unaryExpression)+
-   * </pre>
-   *
-   * @return the multiplicative expression that was parsed
+   *     multiplicativeExpression ::=
+   *         unaryExpression (multiplicativeOperator unaryExpression)*
+   *       | 'super' (multiplicativeOperator unaryExpression)+
    */
   Expression _parseMultiplicativeExpression() {
     Expression expression;
@@ -6776,14 +6365,10 @@
   }
 
   /**
-   * Parse a class native clause.
+   * Parse a class native clause. Return the native clause that was parsed.
    *
-   * <pre>
-   * classNativeClause ::=
-   *     'native' name
-   * </pre>
-   *
-   * @return the class native clause that was parsed
+   *     classNativeClause ::=
+   *         'native' name
    */
   NativeClause _parseNativeClause() {
     Token keyword = getAndAdvance();
@@ -6792,40 +6377,33 @@
   }
 
   /**
-   * Parse a new expression.
+   * Parse a new expression. Return the new expression that was parsed.
    *
-   * <pre>
-   * newExpression ::=
-   *     instanceCreationExpression
-   * </pre>
-   *
-   * @return the new expression that was parsed
+   *     newExpression ::=
+   *         instanceCreationExpression
    */
   InstanceCreationExpression _parseNewExpression() =>
       _parseInstanceCreationExpression(_expectKeyword(Keyword.NEW));
 
   /**
-   * Parse a non-labeled statement.
+   * Parse a non-labeled statement. Return the non-labeled statement that was
+   * parsed.
    *
-   * <pre>
-   * nonLabeledStatement ::=
-   *     block
-   *   | assertStatement
-   *   | breakStatement
-   *   | continueStatement
-   *   | doStatement
-   *   | forStatement
-   *   | ifStatement
-   *   | returnStatement
-   *   | switchStatement
-   *   | tryStatement
-   *   | whileStatement
-   *   | variableDeclarationList ';'
-   *   | expressionStatement
-   *   | functionSignature functionBody
-   * </pre>
-   *
-   * @return the non-labeled statement that was parsed
+   *     nonLabeledStatement ::=
+   *         block
+   *       | assertStatement
+   *       | breakStatement
+   *       | continueStatement
+   *       | doStatement
+   *       | forStatement
+   *       | ifStatement
+   *       | returnStatement
+   *       | switchStatement
+   *       | tryStatement
+   *       | whileStatement
+   *       | variableDeclarationList ';'
+   *       | expressionStatement
+   *       | functionSignature functionBody
    */
   Statement _parseNonLabeledStatement() {
     // TODO(brianwilkerson) Pass the comment and metadata on where appropriate.
@@ -6981,22 +6559,17 @@
   }
 
   /**
-   * Parse an operator declaration.
+   * Parse an operator declaration. The [commentAndMetadata] is the
+   * documentation comment and metadata to be associated with the declaration.
+   * The [externalKeyword] is the 'external' token. The [returnType] is the
+   * return type that has already been parsed, or `null` if there was no return
+   * type. Return the operator declaration that was parsed.
    *
-   * <pre>
-   * operatorDeclaration ::=
-   *     operatorSignature (';' | functionBody)
+   *     operatorDeclaration ::=
+   *         operatorSignature (';' | functionBody)
    *
-   * operatorSignature ::=
-   *     'external'? returnType? 'operator' operator formalParameterList
-   * </pre>
-   *
-   * @param commentAndMetadata the documentation comment and metadata to be associated with the
-   *          declaration
-   * @param externalKeyword the 'external' token
-   * @param the return type that has already been parsed, or `null` if there was no return
-   *          type
-   * @return the operator declaration that was parsed
+   *     operatorSignature ::=
+   *         'external'? returnType? 'operator' operator formalParameterList
    */
   MethodDeclaration _parseOperator(CommentAndMetadata commentAndMetadata,
       Token externalKeyword, TypeName returnType) {
@@ -7018,9 +6591,8 @@
       if ((_tokenMatches(previous, TokenType.EQ_EQ) ||
               _tokenMatches(previous, TokenType.BANG_EQ)) &&
           _currentToken.offset == previous.offset + 2) {
-        _reportErrorForCurrentToken(ParserErrorCode.INVALID_OPERATOR, [
-          "${previous.lexeme}${_currentToken.lexeme}"
-        ]);
+        _reportErrorForCurrentToken(ParserErrorCode.INVALID_OPERATOR,
+            ["${previous.lexeme}${_currentToken.lexeme}"]);
         _advance();
       }
     }
@@ -7037,9 +6609,8 @@
   }
 
   /**
-   * Parse a return type if one is given, otherwise return `null` without advancing.
-   *
-   * @return the return type that was parsed
+   * Parse a return type if one is given, otherwise return `null` without
+   * advancing. Return the return type that was parsed.
    */
   TypeName _parseOptionalReturnType() {
     if (_matchesKeyword(Keyword.VOID)) {
@@ -7062,18 +6633,15 @@
   }
 
   /**
-   * Parse a part or part-of directive.
+   * Parse a part or part-of directive. The [commentAndMetadata] is the metadata
+   * to be associated with the directive. Return the part or part-of directive
+   * that was parsed.
    *
-   * <pre>
-   * partDirective ::=
-   *     metadata 'part' stringLiteral ';'
+   *     partDirective ::=
+   *         metadata 'part' stringLiteral ';'
    *
-   * partOfDirective ::=
-   *     metadata 'part' 'of' identifier ';'
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the directive
-   * @return the part or part-of directive that was parsed
+   *     partOfDirective ::=
+   *         metadata 'part' 'of' identifier ';'
    */
   Directive _parsePartDirective(CommentAndMetadata commentAndMetadata) {
     Token partKeyword = _expectKeyword(Keyword.PART);
@@ -7093,19 +6661,15 @@
   }
 
   /**
-   * Parse a postfix expression.
+   * Parse a postfix expression. Return the postfix expression that was parsed.
    *
-   * <pre>
-   * postfixExpression ::=
-   *     assignableExpression postfixOperator
-   *   | primary selector*
+   *     postfixExpression ::=
+   *         assignableExpression postfixOperator
+   *       | primary selector*
    *
-   * selector ::=
-   *     assignableSelector
-   *   | argumentList
-   * </pre>
-   *
-   * @return the postfix expression that was parsed
+   *     selector ::=
+   *         assignableSelector
+   *       | argumentList
    */
   Expression _parsePostfixExpression() {
     Expression operand = _parseAssignableExpression(true);
@@ -7139,31 +6703,27 @@
   }
 
   /**
-   * Parse a primary expression.
+   * Parse a primary expression. Return the primary expression that was parsed.
    *
-   * <pre>
-   * primary ::=
-   *     thisExpression
-   *   | 'super' assignableSelector
-   *   | functionExpression
-   *   | literal
-   *   | identifier
-   *   | newExpression
-   *   | constObjectExpression
-   *   | '(' expression ')'
-   *   | argumentDefinitionTest
+   *     primary ::=
+   *         thisExpression
+   *       | 'super' assignableSelector
+   *       | functionExpression
+   *       | literal
+   *       | identifier
+   *       | newExpression
+   *       | constObjectExpression
+   *       | '(' expression ')'
+   *       | argumentDefinitionTest
    *
-   * literal ::=
-   *     nullLiteral
-   *   | booleanLiteral
-   *   | numericLiteral
-   *   | stringLiteral
-   *   | symbolLiteral
-   *   | mapLiteral
-   *   | listLiteral
-   * </pre>
-   *
-   * @return the primary expression that was parsed
+   *     literal ::=
+   *         nullLiteral
+   *       | booleanLiteral
+   *       | numericLiteral
+   *       | stringLiteral
+   *       | symbolLiteral
+   *       | mapLiteral
+   *       | listLiteral
    */
   Expression _parsePrimaryExpression() {
     if (_matchesKeyword(Keyword.THIS)) {
@@ -7182,7 +6742,7 @@
       double value = 0.0;
       try {
         value = double.parse(token.lexeme);
-      } on FormatException catch (exception) {
+      } on FormatException {
         // The invalid format should have been reported by the scanner.
       }
       return new DoubleLiteral(token, value);
@@ -7191,7 +6751,7 @@
       int value = null;
       try {
         value = int.parse(token.lexeme.substring(2), radix: 16);
-      } on FormatException catch (exception) {
+      } on FormatException {
         // The invalid format should have been reported by the scanner.
       }
       return new IntegerLiteral(token, value);
@@ -7200,7 +6760,7 @@
       int value = null;
       try {
         value = int.parse(token.lexeme);
-      } on FormatException catch (exception) {
+      } on FormatException {
         // The invalid format should have been reported by the scanner.
       }
       return new IntegerLiteral(token, value);
@@ -7270,14 +6830,11 @@
   }
 
   /**
-   * Parse a redirecting constructor invocation.
+   * Parse a redirecting constructor invocation. Return the redirecting
+   * constructor invocation that was parsed.
    *
-   * <pre>
-   * redirectingConstructorInvocation ::=
-   *     'this' ('.' identifier)? arguments
-   * </pre>
-   *
-   * @return the redirecting constructor invocation that was parsed
+   *     redirectingConstructorInvocation ::=
+   *         'this' ('.' identifier)? arguments
    */
   RedirectingConstructorInvocation _parseRedirectingConstructorInvocation() {
     Token keyword = _expectKeyword(Keyword.THIS);
@@ -7293,15 +6850,12 @@
   }
 
   /**
-   * Parse a relational expression.
+   * Parse a relational expression. Return the relational expression that was
+   * parsed.
    *
-   * <pre>
-   * relationalExpression ::=
-   *     bitwiseOrExpression ('is' '!'? type | 'as' type | relationalOperator bitwiseOrExpression)?
-   *   | 'super' relationalOperator bitwiseOrExpression
-   * </pre>
-   *
-   * @return the relational expression that was parsed
+   *     relationalExpression ::=
+   *         bitwiseOrExpression ('is' '!'? type | 'as' type | relationalOperator bitwiseOrExpression)?
+   *       | 'super' relationalOperator bitwiseOrExpression
    */
   Expression _parseRelationalExpression() {
     if (_matchesKeyword(Keyword.SUPER) &&
@@ -7333,27 +6887,19 @@
   }
 
   /**
-   * Parse a rethrow expression.
+   * Parse a rethrow expression. Return the rethrow expression that was parsed.
    *
-   * <pre>
-   * rethrowExpression ::=
-   *     'rethrow'
-   * </pre>
-   *
-   * @return the rethrow expression that was parsed
+   *     rethrowExpression ::=
+   *         'rethrow'
    */
   Expression _parseRethrowExpression() =>
       new RethrowExpression(_expectKeyword(Keyword.RETHROW));
 
   /**
-   * Parse a return statement.
+   * Parse a return statement. Return the return statement that was parsed.
    *
-   * <pre>
-   * returnStatement ::=
-   *     'return' expression? ';'
-   * </pre>
-   *
-   * @return the return statement that was parsed
+   *     returnStatement ::=
+   *         'return' expression? ';'
    */
   Statement _parseReturnStatement() {
     Token returnKeyword = _expectKeyword(Keyword.RETURN);
@@ -7366,23 +6912,18 @@
   }
 
   /**
-   * Parse a setter.
+   * Parse a setter. The [commentAndMetadata] is the documentation comment and
+   * metadata to be associated with the declaration. The [externalKeyword] is
+   * the 'external' token. The [staticKeyword] is the static keyword, or `null`
+   * if the setter is not static. The [returnType] is the return type that has
+   * already been parsed, or `null` if there was no return type. Return the
+   * setter that was parsed.
    *
-   * <pre>
-   * setter ::=
-   *     setterSignature functionBody?
+   *     setter ::=
+   *         setterSignature functionBody?
    *
-   * setterSignature ::=
-   *     'external'? 'static'? returnType? 'set' identifier formalParameterList
-   * </pre>
-   *
-   * @param commentAndMetadata the documentation comment and metadata to be associated with the
-   *          declaration
-   * @param externalKeyword the 'external' token
-   * @param staticKeyword the static keyword, or `null` if the setter is not static
-   * @param the return type that has already been parsed, or `null` if there was no return
-   *          type
-   * @return the setter that was parsed
+   *     setterSignature ::=
+   *         'external'? 'static'? returnType? 'set' identifier formalParameterList
    */
   MethodDeclaration _parseSetter(CommentAndMetadata commentAndMetadata,
       Token externalKeyword, Token staticKeyword, TypeName returnType) {
@@ -7402,15 +6943,11 @@
   }
 
   /**
-   * Parse a shift expression.
+   * Parse a shift expression. Return the shift expression that was parsed.
    *
-   * <pre>
-   * shiftExpression ::=
-   *     additiveExpression (shiftOperator additiveExpression)*
-   *   | 'super' (shiftOperator additiveExpression)+
-   * </pre>
-   *
-   * @return the shift expression that was parsed
+   *     shiftExpression ::=
+   *         additiveExpression (shiftOperator additiveExpression)*
+   *       | 'super' (shiftOperator additiveExpression)+
    */
   Expression _parseShiftExpression() {
     Expression expression;
@@ -7429,14 +6966,11 @@
   }
 
   /**
-   * Parse a list of statements within a switch statement.
+   * Parse a list of statements within a switch statement. Return the statements
+   * that were parsed.
    *
-   * <pre>
-   * statements ::=
-   *     statement*
-   * </pre>
-   *
-   * @return the statements that were parsed
+   *     statements ::=
+   *         statement*
    */
   List<Statement> _parseStatementList() {
     List<Statement> statements = new List<Statement>();
@@ -7446,9 +6980,8 @@
         !_isSwitchMember()) {
       statements.add(parseStatement2());
       if (identical(_currentToken, statementStart)) {
-        _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken, [
-          _currentToken.lexeme
-        ]);
+        _reportErrorForToken(ParserErrorCode.UNEXPECTED_TOKEN, _currentToken,
+            [_currentToken.lexeme]);
         _advance();
       }
       statementStart = _currentToken;
@@ -7457,9 +6990,8 @@
   }
 
   /**
-   * Parse a string literal that contains interpolations.
-   *
-   * @return the string literal that was parsed
+   * Parse a string literal that contains interpolations. Return the string
+   * literal that was parsed.
    */
   StringInterpolation _parseStringInterpolation(Token string) {
     List<InterpolationElement> elements = new List<InterpolationElement>();
@@ -7504,14 +7036,11 @@
   }
 
   /**
-   * Parse a super constructor invocation.
+   * Parse a super constructor invocation. Return the super constructor
+   * invocation that was parsed.
    *
-   * <pre>
-   * superConstructorInvocation ::=
-   *     'super' ('.' identifier)? arguments
-   * </pre>
-   *
-   * @return the super constructor invocation that was parsed
+   *     superConstructorInvocation ::=
+   *         'super' ('.' identifier)? arguments
    */
   SuperConstructorInvocation _parseSuperConstructorInvocation() {
     Token keyword = _expectKeyword(Keyword.SUPER);
@@ -7527,20 +7056,16 @@
   }
 
   /**
-   * Parse a switch statement.
+   * Parse a switch statement. Return the switch statement that was parsed.
    *
-   * <pre>
-   * switchStatement ::=
-   *     'switch' '(' expression ')' '{' switchCase* defaultCase? '}'
+   *     switchStatement ::=
+   *         'switch' '(' expression ')' '{' switchCase* defaultCase? '}'
    *
-   * switchCase ::=
-   *     label* ('case' expression ':') statements
+   *     switchCase ::=
+   *         label* ('case' expression ':') statements
    *
-   * defaultCase ::=
-   *     label* 'default' ':' statements
-   * </pre>
-   *
-   * @return the switch statement that was parsed
+   *     defaultCase ::=
+   *         label* 'default' ':' statements
    */
   SwitchStatement _parseSwitchStatement() {
     bool wasInSwitch = _inSwitch;
@@ -7612,14 +7137,10 @@
   }
 
   /**
-   * Parse a symbol literal.
+   * Parse a symbol literal. Return the symbol literal that was parsed.
    *
-   * <pre>
-   * symbolLiteral ::=
-   *     '#' identifier ('.' identifier)*
-   * </pre>
-   *
-   * @return the symbol literal that was parsed
+   *     symbolLiteral ::=
+   *         '#' identifier ('.' identifier)*
    */
   SymbolLiteral _parseSymbolLiteral() {
     Token poundSign = getAndAdvance();
@@ -7648,14 +7169,10 @@
   }
 
   /**
-   * Parse a throw expression.
+   * Parse a throw expression. Return the throw expression that was parsed.
    *
-   * <pre>
-   * throwExpression ::=
-   *     'throw' expression
-   * </pre>
-   *
-   * @return the throw expression that was parsed
+   *     throwExpression ::=
+   *         'throw' expression
    */
   Expression _parseThrowExpression() {
     Token keyword = _expectKeyword(Keyword.THROW);
@@ -7669,14 +7186,10 @@
   }
 
   /**
-   * Parse a throw expression.
+   * Parse a throw expression. Return the throw expression that was parsed.
    *
-   * <pre>
-   * throwExpressionWithoutCascade ::=
-   *     'throw' expressionWithoutCascade
-   * </pre>
-   *
-   * @return the throw expression that was parsed
+   *     throwExpressionWithoutCascade ::=
+   *         'throw' expressionWithoutCascade
    */
   Expression _parseThrowExpressionWithoutCascade() {
     Token keyword = _expectKeyword(Keyword.THROW);
@@ -7690,24 +7203,20 @@
   }
 
   /**
-   * Parse a try statement.
+   * Parse a try statement. Return the try statement that was parsed.
    *
-   * <pre>
-   * tryStatement ::=
-   *     'try' block (onPart+ finallyPart? | finallyPart)
+   *     tryStatement ::=
+   *         'try' block (onPart+ finallyPart? | finallyPart)
    *
-   * onPart ::=
-   *     catchPart block
-   *   | 'on' type catchPart? block
+   *     onPart ::=
+   *         catchPart block
+   *       | 'on' type catchPart? block
    *
-   * catchPart ::=
-   *     'catch' '(' identifier (',' identifier)? ')'
+   *     catchPart ::=
+   *         'catch' '(' identifier (',' identifier)? ')'
    *
-   * finallyPart ::=
-   *     'finally' block
-   * </pre>
-   *
-   * @return the try statement that was parsed
+   *     finallyPart ::=
+   *         'finally' block
    */
   Statement _parseTryStatement() {
     Token tryKeyword = _expectKeyword(Keyword.TRY);
@@ -7756,31 +7265,27 @@
   }
 
   /**
-   * Parse a type alias.
+   * Parse a type alias. The [commentAndMetadata] is the metadata to be
+   * associated with the member. Return the type alias that was parsed.
    *
-   * <pre>
-   * typeAlias ::=
-   *     'typedef' typeAliasBody
+   *     typeAlias ::=
+   *         'typedef' typeAliasBody
    *
-   * typeAliasBody ::=
-   *     classTypeAlias
-   *   | functionTypeAlias
+   *     typeAliasBody ::=
+   *         classTypeAlias
+   *       | functionTypeAlias
    *
-   * classTypeAlias ::=
-   *     identifier typeParameters? '=' 'abstract'? mixinApplication
+   *     classTypeAlias ::=
+   *         identifier typeParameters? '=' 'abstract'? mixinApplication
    *
-   * mixinApplication ::=
-   *     qualified withClause implementsClause? ';'
+   *     mixinApplication ::=
+   *         qualified withClause implementsClause? ';'
    *
-   * functionTypeAlias ::=
-   *     functionPrefix typeParameterList? formalParameterList ';'
+   *     functionTypeAlias ::=
+   *         functionPrefix typeParameterList? formalParameterList ';'
    *
-   * functionPrefix ::=
-   *     returnType? name
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the member
-   * @return the type alias that was parsed
+   *     functionPrefix ::=
+   *         returnType? name
    */
   TypeAlias _parseTypeAlias(CommentAndMetadata commentAndMetadata) {
     Token keyword = _expectKeyword(Keyword.TYPEDEF);
@@ -7807,19 +7312,15 @@
   }
 
   /**
-   * Parse a unary expression.
+   * Parse a unary expression. Return the unary expression that was parsed.
    *
-   * <pre>
-   * unaryExpression ::=
-   *     prefixOperator unaryExpression
-   *   | awaitExpression
-   *   | postfixExpression
-   *   | unaryOperator 'super'
-   *   | '-' 'super'
-   *   | incrementOperator assignableExpression
-   * </pre>
-   *
-   * @return the unary expression that was parsed
+   *     unaryExpression ::=
+   *         prefixOperator unaryExpression
+   *       | awaitExpression
+   *       | postfixExpression
+   *       | unaryOperator 'super'
+   *       | '-' 'super'
+   *       | incrementOperator assignableExpression
    */
   Expression _parseUnaryExpression() {
     if (_matches(TokenType.MINUS) ||
@@ -7882,7 +7383,8 @@
   }
 
   /**
-   * Parse a string literal representing a URI.
+   * Parse a string literal representing a URI. Return the string literal that
+   * was parsed.
    */
   StringLiteral _parseUri() {
     bool iskeywordAfterUri(Token token) => token.lexeme == Keyword.AS.syntax ||
@@ -7932,14 +7434,11 @@
   }
 
   /**
-   * Parse a variable declaration.
+   * Parse a variable declaration. Return the variable declaration that was
+   * parsed.
    *
-   * <pre>
-   * variableDeclaration ::=
-   *     identifier ('=' expression)?
-   * </pre>
-   *
-   * @return the variable declaration that was parsed
+   *     variableDeclaration ::=
+   *         identifier ('=' expression)?
    */
   VariableDeclaration _parseVariableDeclaration() {
     CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata();
@@ -7955,15 +7454,12 @@
   }
 
   /**
-   * Parse a variable declaration list.
+   * Parse a variable declaration list. The [commentAndMetadata] is the metadata
+   * to be associated with the variable declaration list. Return the variable
+   * declaration list that was parsed.
    *
-   * <pre>
-   * variableDeclarationList ::=
-   *     finalConstVarOrType variableDeclaration (',' variableDeclaration)*
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the variable declaration list
-   * @return the variable declaration list that was parsed
+   *     variableDeclarationList ::=
+   *         finalConstVarOrType variableDeclaration (',' variableDeclaration)*
    */
   VariableDeclarationList _parseVariableDeclarationListAfterMetadata(
       CommentAndMetadata commentAndMetadata) {
@@ -7973,19 +7469,15 @@
   }
 
   /**
-   * Parse a variable declaration list.
+   * Parse a variable declaration list. The [commentAndMetadata] is the metadata
+   * to be associated with the variable declaration list, or `null` if there is
+   * no attempt at parsing the comment and metadata. The [keyword] is the token
+   * representing the 'final', 'const' or 'var' keyword, or `null` if there is
+   * no keyword. The [type] is the type of the variables in the list. Return the
+   * variable declaration list that was parsed.
    *
-   * <pre>
-   * variableDeclarationList ::=
-   *     finalConstVarOrType variableDeclaration (',' variableDeclaration)*
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the variable declaration list, or
-   *          `null` if there is no attempt at parsing the comment and metadata
-   * @param keyword the token representing the 'final', 'const' or 'var' keyword, or `null` if
-   *          there is no keyword
-   * @param type the type of the variables in the list
-   * @return the variable declaration list that was parsed
+   *     variableDeclarationList ::=
+   *         finalConstVarOrType variableDeclaration (',' variableDeclaration)*
    */
   VariableDeclarationList _parseVariableDeclarationListAfterType(
       CommentAndMetadata commentAndMetadata, Token keyword, TypeName type) {
@@ -8007,16 +7499,13 @@
   }
 
   /**
-   * Parse a variable declaration statement.
+   * Parse a variable declaration statement. The [commentAndMetadata] is the
+   * metadata to be associated with the variable declaration statement, or
+   * `null` if there is no attempt at parsing the comment and metadata. Return
+   * the variable declaration statement that was parsed.
    *
-   * <pre>
-   * variableDeclarationStatement ::=
-   *     variableDeclarationList ';'
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the variable declaration
-   *          statement, or `null` if there is no attempt at parsing the comment and metadata
-   * @return the variable declaration statement that was parsed
+   *     variableDeclarationStatement ::=
+   *         variableDeclarationList ';'
    */
   VariableDeclarationStatement _parseVariableDeclarationStatementAfterMetadata(
       CommentAndMetadata commentAndMetadata) {
@@ -8034,19 +7523,15 @@
   }
 
   /**
-   * Parse a variable declaration statement.
+   * Parse a variable declaration statement. The [commentAndMetadata] is the
+   * metadata to be associated with the variable declaration statement, or
+   * `null` if there is no attempt at parsing the comment and metadata. The
+   * [keyword] is the token representing the 'final', 'const' or 'var' keyword,
+   * or `null` if there is no keyword. The [type] is the type of the variables
+   * in the list. Return the variable declaration statement that was parsed.
    *
-   * <pre>
-   * variableDeclarationStatement ::=
-   *     variableDeclarationList ';'
-   * </pre>
-   *
-   * @param commentAndMetadata the metadata to be associated with the variable declaration
-   *          statement, or `null` if there is no attempt at parsing the comment and metadata
-   * @param keyword the token representing the 'final', 'const' or 'var' keyword, or `null` if
-   *          there is no keyword
-   * @param type the type of the variables in the list
-   * @return the variable declaration statement that was parsed
+   *     variableDeclarationStatement ::=
+   *         variableDeclarationList ';'
    */
   VariableDeclarationStatement _parseVariableDeclarationStatementAfterType(
       CommentAndMetadata commentAndMetadata, Token keyword, TypeName type) {
@@ -8058,14 +7543,10 @@
   }
 
   /**
-   * Parse a while statement.
+   * Parse a while statement. Return the while statement that was parsed.
    *
-   * <pre>
-   * whileStatement ::=
-   *     'while' '(' expression ')' statement
-   * </pre>
-   *
-   * @return the while statement that was parsed
+   *     whileStatement ::=
+   *         'while' '(' expression ')' statement
    */
   Statement _parseWhileStatement() {
     bool wasInLoop = _inLoop;
@@ -8084,14 +7565,10 @@
   }
 
   /**
-   * Parse a yield statement.
+   * Parse a yield statement. Return the yield statement that was parsed.
    *
-   * <pre>
-   * yieldStatement ::=
-   *     'yield' '*'? expression ';'
-   * </pre>
-   *
-   * @return the yield statement that was parsed
+   *     yieldStatement ::=
+   *         'yield' '*'? expression ';'
    */
   YieldStatement _parseYieldStatement() {
     Token yieldToken = getAndAdvance();
@@ -8105,19 +7582,15 @@
   }
 
   /**
-   * Return the token that is immediately after the current token. This is equivalent to
-   * [peekAt].
-   *
-   * @return the token that is immediately after the current token
+   * Return the token that is immediately after the current token. This is
+   * equivalent to [_peekAt](1).
    */
   Token _peek() => _currentToken.next;
 
   /**
-   * Return the token that is the given distance after the current token.
-   *
-   * @param distance the number of tokens to look ahead, where `0` is the current token,
-   *          `1` is the next token, etc.
-   * @return the token that is the given distance after the current token
+   * Return the token that is the given [distance] after the current token,
+   * where the distance is the number of tokens to look ahead. A distance of `0`
+   * is the current token, `1` is the next token, etc.
    */
   Token _peekAt(int distance) {
     Token token = _currentToken;
@@ -8128,9 +7601,7 @@
   }
 
   /**
-   * Report the given [AnalysisError].
-   *
-   * @param error the error to be reported
+   * Report the given [error].
    */
   void _reportError(AnalysisError error) {
     if (_errorListenerLock != 0) {
@@ -8140,10 +7611,8 @@
   }
 
   /**
-   * Report an error with the given error code and arguments.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param arguments the arguments to the error, used to compose the error message
+   * Report an error with the given [errorCode] and [arguments] associated with
+   * the current token.
    */
   void _reportErrorForCurrentToken(ParserErrorCode errorCode,
       [List<Object> arguments]) {
@@ -8151,11 +7620,8 @@
   }
 
   /**
-   * Report an error with the given error code and arguments.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param node the node specifying the location of the error
-   * @param arguments the arguments to the error, used to compose the error message
+   * Report an error with the given [errorCode] and [arguments] associated with
+   * the given [node].
    */
   void _reportErrorForNode(ParserErrorCode errorCode, AstNode node,
       [List<Object> arguments]) {
@@ -8164,11 +7630,8 @@
   }
 
   /**
-   * Report an error with the given error code and arguments.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param token the token specifying the location of the error
-   * @param arguments the arguments to the error, used to compose the error message
+   * Report an error with the given [errorCode] and [arguments] associated with
+   * the given [token].
    */
   void _reportErrorForToken(ErrorCode errorCode, Token token,
       [List<Object> arguments]) {
@@ -8198,21 +7661,18 @@
   }
 
   /**
-   * Parse the 'final', 'const', 'var' or type preceding a variable declaration, starting at the
-   * given token, without actually creating a type or changing the current token. Return the token
-   * following the type that was parsed, or `null` if the given token is not the first token
-   * in a valid type.
+   * Parse the 'final', 'const', 'var' or type preceding a variable declaration,
+   * starting at the given token, without actually creating a type or changing
+   * the current token. Return the token following the type that was parsed, or
+   * `null` if the given token is not the first token in a valid type. The
+   * [startToken] is the token at which parsing is to begin. Return the token
+   * following the type that was parsed.
    *
-   * <pre>
    * finalConstVarOrType ::=
    *   | 'final' type?
    *   | 'const' type?
    *   | 'var'
    *   | type
-   * </pre>
-   *
-   * @param startToken the token at which parsing is to begin
-   * @return the token following the type that was parsed
    */
   Token _skipFinalConstVarOrType(Token startToken) {
     if (_tokenMatchesKeyword(startToken, Keyword.FINAL) ||
@@ -8248,41 +7708,38 @@
   }
 
   /**
-   * Parse a list of formal parameters, starting at the given token, without actually creating a
-   * formal parameter list or changing the current token. Return the token following the formal
-   * parameter list that was parsed, or `null` if the given token is not the first token in a
-   * valid list of formal parameter.
+   * Parse a list of formal parameters, starting at the [startToken], without
+   * actually creating a formal parameter list or changing the current token.
+   * Return the token following the formal parameter list that was parsed, or
+   * `null` if the given token is not the first token in a valid list of formal
+   * parameter.
    *
-   * Note that unlike other skip methods, this method uses a heuristic. In the worst case, the
-   * parameters could be prefixed by metadata, which would require us to be able to skip arbitrary
-   * expressions. Rather than duplicate the logic of most of the parse methods we simply look for
-   * something that is likely to be a list of parameters and then skip to returning the token after
-   * the closing parenthesis.
+   * Note that unlike other skip methods, this method uses a heuristic. In the
+   * worst case, the parameters could be prefixed by metadata, which would
+   * require us to be able to skip arbitrary expressions. Rather than duplicate
+   * the logic of most of the parse methods we simply look for something that is
+   * likely to be a list of parameters and then skip to returning the token
+   * after the closing parenthesis.
    *
    * This method must be kept in sync with [parseFormalParameterList].
    *
-   * <pre>
-   * formalParameterList ::=
-   *     '(' ')'
-   *   | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
-   *   | '(' optionalFormalParameters ')'
+   *     formalParameterList ::=
+   *         '(' ')'
+   *       | '(' normalFormalParameters (',' optionalFormalParameters)? ')'
+   *       | '(' optionalFormalParameters ')'
    *
-   * normalFormalParameters ::=
-   *     normalFormalParameter (',' normalFormalParameter)*
+   *     normalFormalParameters ::=
+   *         normalFormalParameter (',' normalFormalParameter)*
    *
-   * optionalFormalParameters ::=
-   *     optionalPositionalFormalParameters
-   *   | namedFormalParameters
+   *     optionalFormalParameters ::=
+   *         optionalPositionalFormalParameters
+   *       | namedFormalParameters
    *
-   * optionalPositionalFormalParameters ::=
-   *     '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
+   *     optionalPositionalFormalParameters ::=
+   *         '[' defaultFormalParameter (',' defaultFormalParameter)* ']'
    *
-   * namedFormalParameters ::=
-   *     '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
-   * </pre>
-   *
-   * @param startToken the token at which parsing is to begin
-   * @return the token following the formal parameter list that was parsed
+   *     namedFormalParameters ::=
+   *         '{' defaultNamedParameter (',' defaultNamedParameter)* '}'
    */
   Token _skipFormalParameterList(Token startToken) {
     if (!_tokenMatches(startToken, TokenType.OPEN_PAREN)) {
@@ -8334,11 +7791,8 @@
   }
 
   /**
-   * If the given token is a begin token with an associated end token, then return the token
-   * following the end token. Otherwise, return `null`.
-   *
-   * @param startToken the token that is assumed to be a being token
-   * @return the token following the matching end token
+   * If the [startToken] is a begin token with an associated end token, then
+   * return the token following the end token. Otherwise, return `null`.
    */
   Token _skipPastMatchingToken(Token startToken) {
     if (startToken is! BeginToken) {
@@ -8352,20 +7806,15 @@
   }
 
   /**
-   * Parse a prefixed identifier, starting at the given token, without actually creating a prefixed
-   * identifier or changing the current token. Return the token following the prefixed identifier
-   * that was parsed, or `null` if the given token is not the first token in a valid prefixed
-   * identifier.
+   * Parse a prefixed identifier, starting at the [startToken], without actually
+   * creating a prefixed identifier or changing the current token. Return the
+   * token following the prefixed identifier that was parsed, or `null` if the
+   * given token is not the first token in a valid prefixed identifier.
    *
    * This method must be kept in sync with [parsePrefixedIdentifier].
    *
-   * <pre>
-   * prefixedIdentifier ::=
-   *     identifier ('.' identifier)?
-   * </pre>
-   *
-   * @param startToken the token at which parsing is to begin
-   * @return the token following the prefixed identifier that was parsed
+   *     prefixedIdentifier ::=
+   *         identifier ('.' identifier)?
    */
   Token _skipPrefixedIdentifier(Token startToken) {
     Token token = _skipSimpleIdentifier(startToken);
@@ -8378,20 +7827,16 @@
   }
 
   /**
-   * Parse a return type, starting at the given token, without actually creating a return type or
-   * changing the current token. Return the token following the return type that was parsed, or
-   * `null` if the given token is not the first token in a valid return type.
+   * Parse a return type, starting at the [startToken], without actually
+   * creating a return type or changing the current token. Return the token
+   * following the return type that was parsed, or `null` if the given token is
+   * not the first token in a valid return type.
    *
    * This method must be kept in sync with [parseReturnType].
    *
-   * <pre>
-   * returnType ::=
-   *     'void'
-   *   | type
-   * </pre>
-   *
-   * @param startToken the token at which parsing is to begin
-   * @return the token following the return type that was parsed
+   *     returnType ::=
+   *         'void'
+   *       | type
    */
   Token _skipReturnType(Token startToken) {
     if (_tokenMatchesKeyword(startToken, Keyword.VOID)) {
@@ -8402,20 +7847,15 @@
   }
 
   /**
-   * Parse a simple identifier, starting at the given token, without actually creating a simple
-   * identifier or changing the current token. Return the token following the simple identifier that
-   * was parsed, or `null` if the given token is not the first token in a valid simple
-   * identifier.
+   * Parse a simple identifier, starting at the [startToken], without actually
+   * creating a simple identifier or changing the current token. Return the
+   * token following the simple identifier that was parsed, or `null` if the
+   * given token is not the first token in a valid simple identifier.
    *
    * This method must be kept in sync with [parseSimpleIdentifier].
    *
-   * <pre>
-   * identifier ::=
-   *     IDENTIFIER
-   * </pre>
-   *
-   * @param startToken the token at which parsing is to begin
-   * @return the token following the simple identifier that was parsed
+   *     identifier ::=
+   *         IDENTIFIER
    */
   Token _skipSimpleIdentifier(Token startToken) {
     if (_tokenMatches(startToken, TokenType.IDENTIFIER) ||
@@ -8427,15 +7867,13 @@
   }
 
   /**
-   * Parse a string literal that contains interpolations, starting at the given token, without
-   * actually creating a string literal or changing the current token. Return the token following
-   * the string literal that was parsed, or `null` if the given token is not the first token
-   * in a valid string literal.
+   * Parse a string literal that contains interpolations, starting at the
+   * [startToken], without actually creating a string literal or changing the
+   * current token. Return the token following the string literal that was
+   * parsed, or `null` if the given token is not the first token in a valid
+   * string literal.
    *
    * This method must be kept in sync with [parseStringInterpolation].
-   *
-   * @param startToken the token at which parsing is to begin
-   * @return the string literal that was parsed
    */
   Token _skipStringInterpolation(Token startToken) {
     Token token = startToken;
@@ -8487,20 +7925,16 @@
   }
 
   /**
-   * Parse a string literal, starting at the given token, without actually creating a string literal
-   * or changing the current token. Return the token following the string literal that was parsed,
-   * or `null` if the given token is not the first token in a valid string literal.
+   * Parse a string literal, starting at the [startToken], without actually
+   * creating a string literal or changing the current token. Return the token
+   * following the string literal that was parsed, or `null` if the given token
+   * is not the first token in a valid string literal.
    *
    * This method must be kept in sync with [parseStringLiteral].
    *
-   * <pre>
-   * stringLiteral ::=
-   *     MULTI_LINE_STRING+
-   *   | SINGLE_LINE_STRING+
-   * </pre>
-   *
-   * @param startToken the token at which parsing is to begin
-   * @return the token following the string literal that was parsed
+   *     stringLiteral ::=
+   *         MULTI_LINE_STRING+
+   *       | SINGLE_LINE_STRING+
    */
   Token _skipStringLiteral(Token startToken) {
     Token token = startToken;
@@ -8519,22 +7953,19 @@
   }
 
   /**
-   * Parse a list of type arguments, starting at the given token, without actually creating a type argument list
-   * or changing the current token. Return the token following the type argument list that was parsed,
-   * or `null` if the given token is not the first token in a valid type argument list.
+   * Parse a list of type arguments, starting at the [startToken], without
+   * actually creating a type argument list or changing the current token.
+   * Return the token following the type argument list that was parsed, or
+   * `null` if the given token is not the first token in a valid type argument
+   * list.
    *
    * This method must be kept in sync with [parseTypeArgumentList].
    *
-   * <pre>
-   * typeArguments ::=
-   *     '<' typeList '>'
+   *     typeArguments ::=
+   *         '<' typeList '>'
    *
-   * typeList ::=
-   *     type (',' type)*
-   * </pre>
-   *
-   * @param startToken the token at which parsing is to begin
-   * @return the token following the type argument list that was parsed
+   *     typeList ::=
+   *         type (',' type)*
    */
   Token _skipTypeArgumentList(Token startToken) {
     Token token = startToken;
@@ -8543,6 +7974,12 @@
     }
     token = _skipTypeName(token.next);
     if (token == null) {
+      // If the start token '<' is followed by '>'
+      // then assume this should be type argument list but is missing a type
+      token = startToken.next;
+      if (_tokenMatches(token, TokenType.GT)) {
+        return token.next;
+      }
       return null;
     }
     while (_tokenMatches(token, TokenType.COMMA)) {
@@ -8562,19 +7999,15 @@
   }
 
   /**
-   * Parse a type name, starting at the given token, without actually creating a type name or
-   * changing the current token. Return the token following the type name that was parsed, or
-   * `null` if the given token is not the first token in a valid type name.
+   * Parse a type name, starting at the [startToken], without actually creating
+   * a type name or changing the current token. Return the token following the
+   * type name that was parsed, or `null` if the given token is not the first
+   * token in a valid type name.
    *
    * This method must be kept in sync with [parseTypeName].
    *
-   * <pre>
-   * type ::=
-   *     qualified typeArguments?
-   * </pre>
-   *
-   * @param startToken the token at which parsing is to begin
-   * @return the token following the type name that was parsed
+   *     type ::=
+   *         qualified typeArguments?
    */
   Token _skipTypeName(Token startToken) {
     Token token = _skipPrefixedIdentifier(startToken);
@@ -8588,20 +8021,16 @@
   }
 
   /**
-   * Parse a list of type parameters, starting at the given token, without actually creating a type
-   * parameter list or changing the current token. Return the token following the type parameter
-   * list that was parsed, or `null` if the given token is not the first token in a valid type
-   * parameter list.
+   * Parse a list of type parameters, starting at the [startToken], without
+   * actually creating a type parameter list or changing the current token.
+   * Return the token following the type parameter list that was parsed, or
+   * `null` if the given token is not the first token in a valid type parameter
+   * list.
    *
    * This method must be kept in sync with [parseTypeParameterList].
    *
-   * <pre>
-   * typeParameterList ::=
-   *     '<' typeParameter (',' typeParameter)* '>'
-   * </pre>
-   *
-   * @param startToken the token at which parsing is to begin
-   * @return the token following the type parameter list that was parsed
+   *     typeParameterList ::=
+   *         '<' typeParameter (',' typeParameter)* '>'
    */
   Token _skipTypeParameterList(Token startToken) {
     if (!_tokenMatches(startToken, TokenType.LT)) {
@@ -8645,19 +8074,13 @@
   }
 
   /**
-   * Return `true` if the given token has the given type.
-   *
-   * @param token the token being tested
-   * @param type the type of token that is being tested for
-   * @return `true` if the given token has the given type
+   * Return `true` if the given [token] has the given [type].
    */
   bool _tokenMatches(Token token, TokenType type) => token.type == type;
 
   /**
-   * Return `true` if the given token is a valid identifier. Valid identifiers include
-   * built-in identifiers (pseudo-keywords).
-   *
-   * @return `true` if the given token is a valid identifier
+   * Return `true` if the given [token] is a valid identifier. Valid identifiers
+   * include built-in identifiers (pseudo-keywords).
    */
   bool _tokenMatchesIdentifier(Token token) =>
       _tokenMatches(token, TokenType.IDENTIFIER) ||
@@ -8665,22 +8088,14 @@
               (token as KeywordToken).keyword.isPseudoKeyword);
 
   /**
-   * Return `true` if the given token matches the given keyword.
-   *
-   * @param token the token being tested
-   * @param keyword the keyword that is being tested for
-   * @return `true` if the given token matches the given keyword
+   * Return `true` if the given [token] matches the given [keyword].
    */
   bool _tokenMatchesKeyword(Token token, Keyword keyword) =>
       token.type == TokenType.KEYWORD &&
           (token as KeywordToken).keyword == keyword;
 
   /**
-   * Return `true` if the given token matches the given identifier.
-   *
-   * @param token the token being tested
-   * @param identifier the identifier that can optionally appear in the current location
-   * @return `true` if the current token matches the given identifier
+   * Return `true` if the given [token] matches the given [identifier].
    */
   bool _tokenMatchesString(Token token, String identifier) =>
       token.type == TokenType.IDENTIFIER && token.lexeme == identifier;
@@ -8809,13 +8224,22 @@
           // Illegal escape sequence: invalid hex digits
           _reportErrorForCurrentToken(ParserErrorCode.INVALID_UNICODE_ESCAPE);
         } else {
-          _appendScalarValue(buffer, lexeme.substring(index, currentIndex + 1),
+          _appendScalarValue(
+              buffer,
+              lexeme
+                  .substring(
+                      index,
+                      currentIndex + 1),
               (((((Character.digit(firstDigit, 16) << 4) +
                                   Character.digit(secondDigit, 16)) <<
                               4) +
                           Character.digit(thirdDigit, 16)) <<
                       4) +
-                  Character.digit(fourthDigit, 16), index, currentIndex + 3);
+                  Character
+                      .digit(fourthDigit, 16),
+              index,
+              currentIndex +
+                  3);
         }
         return currentIndex + 4;
       }
@@ -8838,9 +8262,8 @@
   }
 
   /**
-   * Validate that the given parameter list does not contain any field initializers.
-   *
-   * @param parameterList the parameter list to be validated
+   * Validate that the given [parameterList] does not contain any field
+   * initializers.
    */
   void _validateFormalParameterList(FormalParameterList parameterList) {
     for (FormalParameter parameter in parameterList.parameters) {
@@ -8853,10 +8276,8 @@
   }
 
   /**
-   * Validate that the given set of modifiers is appropriate for a class and return the 'abstract'
-   * keyword if there is one.
-   *
-   * @param modifiers the modifiers being validated
+   * Validate that the given set of [modifiers] is appropriate for a class and
+   * return the 'abstract' keyword if there is one.
    */
   Token _validateModifiersForClass(Modifiers modifiers) {
     _validateModifiersForTopLevelDeclaration(modifiers);
@@ -8877,11 +8298,8 @@
   }
 
   /**
-   * Validate that the given set of modifiers is appropriate for a constructor and return the
-   * 'const' keyword if there is one.
-   *
-   * @param modifiers the modifiers being validated
-   * @return the 'const' or 'final' keyword associated with the constructor
+   * Validate that the given set of [modifiers] is appropriate for a constructor
+   * and return the 'const' keyword if there is one.
    */
   Token _validateModifiersForConstructor(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
@@ -8919,10 +8337,8 @@
   }
 
   /**
-   * Validate that the given set of modifiers is appropriate for a class and return the 'abstract'
-   * keyword if there is one.
-   *
-   * @param modifiers the modifiers being validated
+   * Validate that the given set of [modifiers] is appropriate for a class and
+   * return the 'abstract' keyword if there is one.
    */
   void _validateModifiersForEnum(Modifiers modifiers) {
     _validateModifiersForTopLevelDeclaration(modifiers);
@@ -8946,11 +8362,8 @@
   }
 
   /**
-   * Validate that the given set of modifiers is appropriate for a field and return the 'final',
-   * 'const' or 'var' keyword if there is one.
-   *
-   * @param modifiers the modifiers being validated
-   * @return the 'final', 'const' or 'var' keyword associated with the field
+   * Validate that the given set of [modifiers] is appropriate for a field and
+   * return the 'final', 'const' or 'var' keyword if there is one.
    */
   Token _validateModifiersForField(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
@@ -8994,9 +8407,8 @@
   }
 
   /**
-   * Validate that the given set of modifiers is appropriate for a local function.
-   *
-   * @param modifiers the modifiers being validated
+   * Validate that the given set of [modifiers] is appropriate for a local
+   * function.
    */
   void _validateModifiersForFunctionDeclarationStatement(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null ||
@@ -9012,9 +8424,8 @@
   }
 
   /**
-   * Validate that the given set of modifiers is appropriate for a getter, setter, or method.
-   *
-   * @param modifiers the modifiers being validated
+   * Validate that the given set of [modifiers] is appropriate for a getter,
+   * setter, or method.
    */
   void _validateModifiersForGetterOrSetterOrMethod(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
@@ -9047,9 +8458,8 @@
   }
 
   /**
-   * Validate that the given set of modifiers is appropriate for a getter, setter, or method.
-   *
-   * @param modifiers the modifiers being validated
+   * Validate that the given set of [modifiers] is appropriate for a getter,
+   * setter, or method.
    */
   void _validateModifiersForOperator(Modifiers modifiers) {
     if (modifiers.abstractKeyword != null) {
@@ -9078,9 +8488,8 @@
   }
 
   /**
-   * Validate that the given set of modifiers is appropriate for a top-level declaration.
-   *
-   * @param modifiers the modifiers being validated
+   * Validate that the given set of [modifiers] is appropriate for a top-level
+   * declaration.
    */
   void _validateModifiersForTopLevelDeclaration(Modifiers modifiers) {
     if (modifiers.factoryKeyword != null) {
@@ -9094,9 +8503,8 @@
   }
 
   /**
-   * Validate that the given set of modifiers is appropriate for a top-level function.
-   *
-   * @param modifiers the modifiers being validated
+   * Validate that the given set of [modifiers] is appropriate for a top-level
+   * function.
    */
   void _validateModifiersForTopLevelFunction(Modifiers modifiers) {
     _validateModifiersForTopLevelDeclaration(modifiers);
@@ -9116,11 +8524,8 @@
   }
 
   /**
-   * Validate that the given set of modifiers is appropriate for a field and return the 'final',
-   * 'const' or 'var' keyword if there is one.
-   *
-   * @param modifiers the modifiers being validated
-   * @return the 'final', 'const' or 'var' keyword associated with the field
+   * Validate that the given set of [modifiers] is appropriate for a field and
+   * return the 'final', 'const' or 'var' keyword if there is one.
    */
   Token _validateModifiersForTopLevelVariable(Modifiers modifiers) {
     _validateModifiersForTopLevelDeclaration(modifiers);
@@ -9150,10 +8555,8 @@
   }
 
   /**
-   * Validate that the given set of modifiers is appropriate for a class and return the 'abstract'
-   * keyword if there is one.
-   *
-   * @param modifiers the modifiers being validated
+   * Validate that the given set of [modifiers] is appropriate for a class and
+   * return the 'abstract' keyword if there is one.
    */
   void _validateModifiersForTypedef(Modifiers modifiers) {
     _validateModifiersForTopLevelDeclaration(modifiers);
@@ -9179,14 +8582,12 @@
   }
 }
 /**
- * Instances of the class `SyntheticKeywordToken` implement a synthetic keyword token.
+ * A synthetic keyword token.
  */
 class Parser_SyntheticKeywordToken extends KeywordToken {
   /**
-   * Initialize a newly created token to represent the given keyword.
-   *
-   * @param keyword the keyword being represented by this token
-   * @param offset the offset from the beginning of the file to the first character in the token
+   * Initialize a newly created token to represent the given [keyword] at the
+   * given [offset].
    */
   Parser_SyntheticKeywordToken(Keyword keyword, int offset)
       : super(keyword, offset);
@@ -9199,11 +8600,10 @@
 }
 
 /**
- * The enumeration `ParserErrorCode` defines the error codes used for errors
- * detected by the parser. The convention for this class is for the name of the
- * error code to indicate the problem that caused the error to be generated and
- * for the error message to explain what is wrong and, when appropriate, how the
- * problem can be corrected.
+ * The error codes used for errors detected by the parser. The convention for
+ * this class is for the name of the error code to indicate the problem that
+ * caused the error to be generated and for the error message to explain what
+ * is wrong and, when appropriate, how the problem can be corrected.
  */
 class ParserErrorCode extends ErrorCode {
   static const ParserErrorCode ABSTRACT_CLASS_MEMBER = const ParserErrorCode(
@@ -9820,14 +9220,15 @@
 }
 
 /**
- * Instances of the class `ResolutionCopier` copies resolution information from one AST
- * structure to another as long as the structures of the corresponding children of a pair of nodes
- * are the same.
+ * An object that copies resolution information from one AST structure to
+ * another as long as the structures of the corresponding children of a pair of
+ * nodes are the same.
  */
 class ResolutionCopier implements AstVisitor<bool> {
   /**
-   * The AST node with which the node being visited is to be compared. This is only valid at the
-   * beginning of each visit method (until [isEqualNodes] is invoked).
+   * The AST node with which the node being visited is to be compared. This is
+   * only valid at the beginning of each visit method (until [isEqualNodes] is
+   * invoked).
    */
   AstNode _toNode;
 
@@ -11034,6 +10435,7 @@
   bool _and(bool b1, bool b2, [bool b3 = true, bool b4 = true, bool b5 = true,
       bool b6 = true, bool b7 = true, bool b8 = true, bool b9 = true,
       bool b10 = true, bool b11 = true, bool b12 = true, bool b13 = true]) {
+    // TODO(brianwilkerson) Inline this method.
     return b1 &&
         b2 &&
         b3 &&
@@ -11050,13 +10452,8 @@
   }
 
   /**
-   * Return `true` if the given lists of AST nodes have the same size and corresponding
-   * elements are equal.
-   *
-   * @param first the first node being compared
-   * @param second the second node being compared
-   * @return `true` if the given AST nodes have the same size and corresponding elements are
-   *         equal
+   * Return `true` if the [first] and [second] lists of AST nodes have the same
+   * size and corresponding elements are equal.
    */
   bool _isEqualNodeLists(NodeList first, NodeList second) {
     if (first == null) {
@@ -11078,13 +10475,9 @@
   }
 
   /**
-   * Return `true` if the given AST nodes have the same structure. As a side-effect, if the
-   * nodes do have the same structure, any resolution data from the first node will be copied to the
-   * second node.
-   *
-   * @param fromNode the node from which resolution information will be copied
-   * @param toNode the node to which resolution information will be copied
-   * @return `true` if the given AST nodes have the same structure
+   * Return `true` if the [fromNode] and [toNode] have the same structure. As a
+   * side-effect, if the nodes do have the same structure, any resolution data
+   * from the first node will be copied to the second node.
    */
   bool _isEqualNodes(AstNode fromNode, AstNode toNode) {
     if (fromNode == null) {
@@ -11115,13 +10508,8 @@
   }
 
   /**
-   * Return `true` if the given arrays of tokens have the same length and corresponding
-   * elements are equal.
-   *
-   * @param first the first node being compared
-   * @param second the second node being compared
-   * @return `true` if the given arrays of tokens have the same length and corresponding
-   *         elements are equal
+   * Return `true` if the [first] and [second] arrays of tokens have the same
+   * length and corresponding elements are equal.
    */
   bool _isEqualTokenLists(List<Token> first, List<Token> second) {
     int length = first.length;
@@ -11137,11 +10525,7 @@
   }
 
   /**
-   * Return `true` if the given tokens have the same structure.
-   *
-   * @param first the first node being compared
-   * @param second the second node being compared
-   * @return `true` if the given tokens have the same structure
+   * Return `true` if the [first] and [second] tokens have the same structure.
    */
   bool _isEqualTokens(Token first, Token second) {
     if (first == null) {
@@ -11153,10 +10537,7 @@
   }
 
   /**
-   * Copy resolution data from one node to another.
-   *
-   * @param fromNode the node from which resolution information will be copied
-   * @param toNode the node to which resolution information will be copied
+   * Copy resolution data from the [fromNode] to the [toNode].
    */
   static void copyResolutionData(AstNode fromNode, AstNode toNode) {
     ResolutionCopier copier = new ResolutionCopier();
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index b56b46a..7f95837 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -240,8 +240,8 @@
             HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node);
       } else {
         // the is not case
-        _errorReporter
-            .reportErrorForNode(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node);
+        _errorReporter.reportErrorForNode(
+            HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node);
       }
       return true;
     }
@@ -258,8 +258,8 @@
               HintCode.UNNECESSARY_TYPE_CHECK_TRUE, node);
         } else {
           // the is not case
-          _errorReporter
-              .reportErrorForNode(HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node);
+          _errorReporter.reportErrorForNode(
+              HintCode.UNNECESSARY_TYPE_CHECK_FALSE, node);
         }
         return true;
       } else if (rhsNameStr == _NULL_TYPE_NAME) {
@@ -268,8 +268,8 @@
           _errorReporter.reportErrorForNode(HintCode.TYPE_CHECK_IS_NULL, node);
         } else {
           // the is not case
-          _errorReporter
-              .reportErrorForNode(HintCode.TYPE_CHECK_IS_NOT_NULL, node);
+          _errorReporter.reportErrorForNode(
+              HintCode.TYPE_CHECK_IS_NOT_NULL, node);
         }
         return true;
       }
@@ -542,9 +542,8 @@
     }
     if (importedLibrary.hasLoadLibraryFunction) {
       _errorReporter.reportErrorForNode(
-          HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, node, [
-        importedLibrary.name
-      ]);
+          HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, node,
+          [importedLibrary.name]);
       return true;
     }
     return false;
@@ -744,15 +743,13 @@
       if (existing.nameOffset < duplicate.nameOffset) {
         return new AnalysisError.con2(duplicate.source, duplicate.nameOffset,
             duplicate.displayName.length,
-            CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME, [
-          existing.displayName
-        ]);
+            CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME,
+            [existing.displayName]);
       } else {
         return new AnalysisError.con2(existing.source, existing.nameOffset,
             existing.displayName.length,
-            CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME, [
-          existing.displayName
-        ]);
+            CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
+            [existing.displayName]);
       }
     }
     return super.getErrorForDuplicate(existing, duplicate);
@@ -1525,8 +1522,8 @@
           return null;
         } else {
           // report error on if block: false ? !1! : 2
-          _errorReporter
-              .reportErrorForNode(HintCode.DEAD_CODE, node.thenExpression);
+          _errorReporter.reportErrorForNode(
+              HintCode.DEAD_CODE, node.thenExpression);
           _safelyVisit(node.elseExpression);
           return null;
         }
@@ -1554,8 +1551,8 @@
           }
         } else {
           // report error on if block: if (false) {!} else {}
-          _errorReporter
-              .reportErrorForNode(HintCode.DEAD_CODE, node.thenStatement);
+          _errorReporter.reportErrorForNode(
+              HintCode.DEAD_CODE, node.thenStatement);
           _safelyVisit(node.elseStatement);
           return null;
         }
@@ -1741,8 +1738,7 @@
       element = propertyAccess.propertyName.staticElement;
     }
     if (element is PropertyAccessorElement) {
-      PropertyAccessorElement pae = element as PropertyAccessorElement;
-      PropertyInducingElement variable = pae.variable;
+      PropertyInducingElement variable = element.variable;
       return variable != null && variable.isConst;
     }
     return false;
@@ -3114,28 +3110,26 @@
       holder.validate();
     }
     if (element is PropertyInducingElementImpl) {
-      PropertyInducingElementImpl variable =
-          element as PropertyInducingElementImpl;
       if (_inFieldContext) {
-        (variable as FieldElementImpl).static =
+        (element as FieldElementImpl).static =
             (node.parent.parent as FieldDeclaration).isStatic;
       }
       PropertyAccessorElementImpl getter =
-          new PropertyAccessorElementImpl.forVariable(variable);
+          new PropertyAccessorElementImpl.forVariable(element);
       getter.getter = true;
       _currentHolder.addAccessor(getter);
-      variable.getter = getter;
+      element.getter = getter;
       if (!isConst && !isFinal) {
         PropertyAccessorElementImpl setter =
-            new PropertyAccessorElementImpl.forVariable(variable);
+            new PropertyAccessorElementImpl.forVariable(element);
         setter.setter = true;
         ParameterElementImpl parameter =
-            new ParameterElementImpl("_${variable.name}", variable.nameOffset);
+            new ParameterElementImpl("_${element.name}", element.nameOffset);
         parameter.synthetic = true;
         parameter.parameterKind = ParameterKind.REQUIRED;
         setter.parameters = <ParameterElement>[parameter];
         _currentHolder.addAccessor(setter);
-        variable.setter = setter;
+        element.setter = setter;
       }
     }
     return null;
@@ -3207,11 +3201,11 @@
     AstNode parent = node.parent;
     while (parent != null) {
       if (parent is ConstructorDeclaration) {
-        return (parent as ConstructorDeclaration).body;
+        return parent.body;
       } else if (parent is FunctionExpression) {
-        return (parent as FunctionExpression).body;
+        return parent.body;
       } else if (parent is MethodDeclaration) {
-        return (parent as MethodDeclaration).body;
+        return parent.body;
       }
       parent = parent.parent;
     }
@@ -3737,7 +3731,8 @@
     indexField.type = intType;
     fields.add(indexField);
     getters.add(_createGetter(indexField));
-    ConstFieldElementImpl valuesField = new ConstFieldElementImpl.con2("values", -1);
+    ConstFieldElementImpl valuesField =
+        new ConstFieldElementImpl.con2("values", -1);
     valuesField.static = true;
     valuesField.const3 = true;
     valuesField.synthetic = true;
@@ -3774,7 +3769,8 @@
     //
     // Build the value of the 'values' field.
     //
-    valuesField.evaluationResult = new EvaluationResultImpl.con1(new DartObjectImpl(valuesField.type, new ListState(constantValues)));
+    valuesField.evaluationResult = new EvaluationResultImpl.con1(
+        new DartObjectImpl(valuesField.type, new ListState(constantValues)));
     //
     // Finish building the enum.
     //
@@ -4746,10 +4742,9 @@
               _reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST,
                   scriptAttribute, [scriptSourcePath]);
             }
-          } on URISyntaxException catch (exception) {
-            _reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute, [
-              scriptSourcePath
-            ]);
+          } on URISyntaxException {
+            _reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute,
+                [scriptSourcePath]);
           }
         }
         node.scriptElement = script;
@@ -4878,110 +4873,41 @@
  * ImplicitConstructorBuilderCallback to inform it of the computations to be
  * done and their ordering dependencies.
  */
-class ImplicitConstructorBuilder extends ScopedVisitor {
+class ImplicitConstructorBuilder extends SimpleElementVisitor {
+  final AnalysisErrorListener errorListener;
+
   /**
    * Callback to receive the computations to be performed.
    */
   final ImplicitConstructorBuilderCallback _callback;
 
   /**
-   * Initialize a newly created visitor to build implicit constructors for file
-   * [source], in library [libraryElement], which has scope [libraryScope]. Use
-   * [typeProvider] to access types from the core library.
+   * Initialize a newly created visitor to build implicit constructors.
    *
    * The visit methods will pass closures to [_callback] to indicate what
    * computation needs to be performed, and its dependency order.
    */
-  ImplicitConstructorBuilder(Source source, LibraryElement libraryElement,
-      LibraryScope libraryScope, TypeProvider typeProvider, this._callback)
-      : super.con3(libraryElement, source, typeProvider, libraryScope,
-          libraryScope.errorListener);
+  ImplicitConstructorBuilder(this.errorListener, this._callback);
 
   @override
-  Object visitClassDeclaration(ClassDeclaration node) {
-    ClassElementImpl classElement = node.element;
+  void visitClassElement(ClassElementImpl classElement) {
     classElement.mixinErrorsReported = false;
-    if (node.extendsClause != null && node.withClause != null) {
-      // We don't need to build any implicitly constructors for the mixin
-      // application (since there isn't an explicit element for it), but we
-      // need to verify that they _could_ be built.
-      InterfaceType superclassType = null;
-      TypeName superclassName = node.extendsClause.superclass;
-      DartType type = superclassName.type;
-      if (type is InterfaceType) {
-        superclassType = type;
-      } else {
-        superclassType = typeProvider.objectType;
-      }
-      ClassElement superclassElement = classElement.supertype.element;
-      if (superclassElement != null) {
-        _callback(classElement, superclassElement, () {
-          bool constructorFound = false;
-          void callback(ConstructorElement explicitConstructor,
-              List<DartType> parameterTypes, List<DartType> argumentTypes) {
-            constructorFound = true;
-          }
-          if (_findForwardedConstructors(
-                  classElement, superclassName, superclassType, callback) &&
-              !constructorFound) {
-            reportErrorForNode(CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
-                node.withClause, [superclassType.element.name]);
-            classElement.mixinErrorsReported = true;
-          }
-        });
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object visitClassTypeAlias(ClassTypeAlias node) {
-    super.visitClassTypeAlias(node);
-    InterfaceType superclassType = null;
-    TypeName superclassName = node.superclass;
-    DartType type = superclassName.type;
-    if (type is InterfaceType) {
-      superclassType = type;
+    if (classElement.isTypedef) {
+      _visitClassTypeAlias(classElement);
     } else {
-      superclassType = typeProvider.objectType;
+      _visitClassDeclaration(classElement);
     }
-    ClassElementImpl classElement = node.element as ClassElementImpl;
-    if (classElement != null) {
-      ClassElement superclassElement = superclassType.element;
-      if (superclassElement != null) {
-        _callback(classElement, superclassElement, () {
-          List<ConstructorElement> implicitConstructors =
-              new List<ConstructorElement>();
-          void callback(ConstructorElement explicitConstructor,
-              List<DartType> parameterTypes, List<DartType> argumentTypes) {
-            implicitConstructors.add(_createImplicitContructor(
-                classElement.type, explicitConstructor, parameterTypes,
-                argumentTypes));
-          }
-          if (_findForwardedConstructors(
-              classElement, superclassName, superclassType, callback)) {
-            if (implicitConstructors.isEmpty) {
-              reportErrorForNode(CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
-                  node, [superclassElement.name]);
-            } else {
-              classElement.constructors = implicitConstructors;
-            }
-          }
-        });
-      }
-    }
-    return null;
   }
 
   @override
-  Object visitEnumDeclaration(EnumDeclaration node) => null;
+  void visitCompilationUnitElement(CompilationUnitElement element) {
+    element.types.forEach(visitClassElement);
+  }
 
   @override
-  Object visitFunctionDeclaration(FunctionDeclaration node) => null;
-
-  @override
-  Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) =>
-      null;
+  void visitLibraryElement(LibraryElement element) {
+    element.units.forEach(visitCompilationUnitElement);
+  }
 
   /**
    * Create an implicit constructor that is copied from the given constructor, but that is in the
@@ -5028,29 +4954,27 @@
   }
 
   /**
-   * Find all the constructors that should be forwarded from the superclass
-   * named [superclassName], having type [superclassType], to the class or
-   * mixin application [classElement], and pass information about them to
-   * [callback].
+   * Find all the constructors that should be forwarded from the given
+   * [superType], to the class or mixin application [classElement],
+   * and pass information about them to [callback].
    *
    * Return true if some constructors were considered.  (A false return value
    * can only happen if the supeclass is a built-in type, in which case it
    * can't be used as a mixin anyway).
    */
   bool _findForwardedConstructors(ClassElementImpl classElement,
-      TypeName superclassName, InterfaceType superclassType, void callback(
+      InterfaceType superType, void callback(
           ConstructorElement explicitConstructor, List<DartType> parameterTypes,
           List<DartType> argumentTypes)) {
-    ClassElement superclassElement = superclassType.element;
+    ClassElement superclassElement = superType.element;
     List<ConstructorElement> constructors = superclassElement.constructors;
     int count = constructors.length;
     if (count == 0) {
       return false;
     }
     List<DartType> parameterTypes =
-        TypeParameterTypeImpl.getTypes(superclassType.typeParameters);
-    List<DartType> argumentTypes =
-        _getArgumentTypes(superclassName.typeArguments, parameterTypes);
+        TypeParameterTypeImpl.getTypes(superType.typeParameters);
+    List<DartType> argumentTypes = _getArgumentTypes(superType, parameterTypes);
     for (int i = 0; i < count; i++) {
       ConstructorElement explicitConstructor = constructors[i];
       if (!explicitConstructor.isFactory &&
@@ -5062,27 +4986,21 @@
   }
 
   /**
-   * Return an array of argument types that corresponds to the array of parameter types and that are
-   * derived from the given list of type arguments.
-   *
-   * @param typeArguments the type arguments from which the types will be taken
-   * @param parameterTypes the parameter types that must be matched by the type arguments
-   * @return the argument types that correspond to the parameter types
+   * Return a list of argument types that corresponds to the [parameterTypes]
+   * and that are derived from the type arguments of the given [superType].
    */
   List<DartType> _getArgumentTypes(
-      TypeArgumentList typeArguments, List<DartType> parameterTypes) {
+      InterfaceType superType, List<DartType> parameterTypes) {
     DynamicTypeImpl dynamic = DynamicTypeImpl.instance;
     int parameterCount = parameterTypes.length;
     List<DartType> types = new List<DartType>(parameterCount);
-    if (typeArguments == null) {
-      for (int i = 0; i < parameterCount; i++) {
-        types[i] = dynamic;
-      }
+    if (superType == null) {
+      types = new List<DartType>.filled(parameterCount, dynamic);
     } else {
-      NodeList<TypeName> arguments = typeArguments.arguments;
-      int argumentCount = math.min(arguments.length, parameterCount);
+      List<DartType> typeArguments = superType.typeArguments;
+      int argumentCount = math.min(typeArguments.length, parameterCount);
       for (int i = 0; i < argumentCount; i++) {
-        types[i] = arguments[i].type;
+        types[i] = typeArguments[i];
       }
       for (int i = argumentCount; i < parameterCount; i++) {
         types[i] = dynamic;
@@ -5090,6 +5008,64 @@
     }
     return types;
   }
+
+  void _visitClassDeclaration(ClassElementImpl classElement) {
+    DartType superType = classElement.supertype;
+    if (superType != null && classElement.mixins.isNotEmpty) {
+      // We don't need to build any implicitly constructors for the mixin
+      // application (since there isn't an explicit element for it), but we
+      // need to verify that they _could_ be built.
+      if (superType is! InterfaceType) {
+        TypeProvider typeProvider = classElement.context.typeProvider;
+        superType = typeProvider.objectType;
+      }
+      ClassElement superElement = superType.element;
+      if (superElement != null) {
+        _callback(classElement, superElement, () {
+          bool constructorFound = false;
+          void callback(ConstructorElement explicitConstructor,
+              List<DartType> parameterTypes, List<DartType> argumentTypes) {
+            constructorFound = true;
+          }
+          if (_findForwardedConstructors(classElement, superType, callback) &&
+              !constructorFound) {
+            SourceRange withRange = classElement.withClauseRange;
+            errorListener.onError(new AnalysisError.con2(classElement.source,
+                withRange.offset, withRange.length,
+                CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
+                [superElement.name]));
+            classElement.mixinErrorsReported = true;
+          }
+        });
+      }
+    }
+  }
+
+  void _visitClassTypeAlias(ClassElementImpl classElement) {
+    InterfaceType superType = classElement.supertype;
+    if (superType is InterfaceType) {
+      ClassElement superElement = superType.element;
+      _callback(classElement, superElement, () {
+        List<ConstructorElement> implicitConstructors =
+            new List<ConstructorElement>();
+        void callback(ConstructorElement explicitConstructor,
+            List<DartType> parameterTypes, List<DartType> argumentTypes) {
+          implicitConstructors.add(_createImplicitContructor(classElement.type,
+              explicitConstructor, parameterTypes, argumentTypes));
+        }
+        if (_findForwardedConstructors(classElement, superType, callback)) {
+          if (implicitConstructors.isEmpty) {
+            errorListener.onError(new AnalysisError.con2(classElement.source,
+                classElement.nameOffset, classElement.name.length,
+                CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
+                [superElement.name]));
+          } else {
+            classElement.constructors = implicitConstructors;
+          }
+        }
+      });
+    }
+  }
 }
 
 /**
@@ -5098,11 +5074,6 @@
  */
 class ImplicitConstructorComputer {
   /**
-   * The object used to access the types from the core library.
-   */
-  final TypeProvider typeProvider;
-
-  /**
    * Directed graph of dependencies between classes that need to have their
    * implicit constructors computed.  Each edge in the graph points from a
    * derived class to its superclass.  Implicit constructors will be computed
@@ -5118,21 +5089,12 @@
       new HashMap<ClassElement, VoidFunction>();
 
   /**
-   * Create an ImplicitConstructorComputer which will use [typeProvider] to
-   * access types from the core library.
+   * Add the given [libraryElement] to the list of libraries which need to have
+   * implicit constructors built for them.
    */
-  ImplicitConstructorComputer(this.typeProvider);
-
-  /**
-   * Add the given [unit] to the list of units which need to have implicit
-   * constructors built for them.  [source] is the source file corresponding to
-   * the compilation unit, [libraryElement] is the library element containing
-   * that source, and [libraryScope] is the scope for the library element.
-   */
-  void add(CompilationUnit unit, Source source, LibraryElement libraryElement,
-      LibraryScope libraryScope) {
-    unit.accept(new ImplicitConstructorBuilder(
-        source, libraryElement, libraryScope, typeProvider, _defer));
+  void add(AnalysisErrorListener errorListener, LibraryElement libraryElement) {
+    libraryElement
+        .accept(new ImplicitConstructorBuilder(errorListener, _defer));
   }
 
   /**
@@ -6986,7 +6948,7 @@
             CompileTimeErrorCode.URI_DOES_NOT_EXIST, [uriContent]));
       }
       return source;
-    } on URISyntaxException catch (exception) {
+    } on URISyntaxException {
       _errorListener.onError(new AnalysisError.con2(librarySource,
           uriLiteral.offset, uriLiteral.length,
           CompileTimeErrorCode.INVALID_URI, [uriContent]));
@@ -7018,11 +6980,6 @@
  */
 class LibraryElementBuilder {
   /**
-   * The name of the function used as an entry point.
-   */
-  static String ENTRY_POINT_NAME = "main";
-
-  /**
    * The analysis context in which the element model will be built.
    */
   final InternalAnalysisContext _analysisContext;
@@ -7277,7 +7234,7 @@
    */
   FunctionElement _findEntryPoint(CompilationUnitElementImpl element) {
     for (FunctionElement function in element.functions) {
-      if (function.name == ENTRY_POINT_NAME) {
+      if (function.isEntryPoint) {
         return function;
       }
     }
@@ -7408,8 +7365,7 @@
     }
     if (foundElement is MultiplyDefinedElementImpl) {
       String foundEltName = foundElement.displayName;
-      List<Element> conflictingMembers =
-          (foundElement as MultiplyDefinedElementImpl).conflictingElements;
+      List<Element> conflictingMembers = foundElement.conflictingElements;
       int count = conflictingMembers.length;
       List<String> libraryNames = new List<String>(count);
       for (int i = 0; i < count; i++) {
@@ -7499,31 +7455,25 @@
   }
 
   /**
-   * Given a collection of elements that a single name could all be mapped to, remove from the list
-   * all of the names defined in the SDK. Return the element(s) that remain.
-   *
-   * @param identifier the identifier node to lookup element for, used to report correct kind of a
-   *          problem and associate problem with
-   * @param name the name associated with the element
-   * @param foundElement the element encapsulating the collection of elements
-   * @return all of the elements that are not defined in the SDK
+   * Given a collection of elements (captured by the [foundElement]) that the
+   * [identifier] (with the given [name]) resolved to, remove from the list all
+   * of the names defined in the SDK and return the element(s) that remain.
    */
   Element _removeSdkElements(Identifier identifier, String name,
       MultiplyDefinedElementImpl foundElement) {
-    List<Element> conflictingMembers = foundElement.conflictingElements;
-    int length = conflictingMembers.length;
-    int to = 0;
+    List<Element> conflictingElements = foundElement.conflictingElements;
+    List<Element> nonSdkElements = new List<Element>();
     Element sdkElement = null;
-    for (Element member in conflictingMembers) {
+    for (Element member in conflictingElements) {
       if (member.library.isInSdk) {
         sdkElement = member;
       } else {
-        conflictingMembers[to++] = member;
+        nonSdkElements.add(member);
       }
     }
-    if (sdkElement != null && to > 0) {
+    if (sdkElement != null && nonSdkElements.length > 0) {
       String sdkLibName = _getLibraryName(sdkElement);
-      String otherLibName = _getLibraryName(conflictingMembers[0]);
+      String otherLibName = _getLibraryName(nonSdkElements[0]);
       errorListener.onError(new AnalysisError.con2(getSource(identifier),
           identifier.offset, identifier.length,
           StaticWarningCode.CONFLICTING_DART_IMPORT, [
@@ -7532,21 +7482,20 @@
         otherLibName
       ]));
     }
-    if (to == length) {
+    if (nonSdkElements.length == conflictingElements.length) {
       // None of the members were removed
       return foundElement;
-    } else if (to == 1) {
+    } else if (nonSdkElements.length == 1) {
       // All but one member was removed
-      return conflictingMembers[0];
-    } else if (to == 0) {
+      return nonSdkElements[0];
+    } else if (nonSdkElements.length == 0) {
       // All members were removed
       AnalysisEngine.instance.logger
           .logInformation("Multiply defined SDK element: $foundElement");
       return foundElement;
     }
-    List<Element> remaining = new List<Element>(to);
-    JavaSystem.arraycopy(conflictingMembers, 0, remaining, 0, to);
-    return new MultiplyDefinedElementImpl(_definingLibrary.context, remaining);
+    return new MultiplyDefinedElementImpl(
+        _definingLibrary.context, nonSdkElements);
   }
 }
 
@@ -7985,7 +7934,8 @@
             // directive was invalid.
             Library exportedLibrary = _libraryMap[exportedSource];
             if (exportedLibrary != null) {
-              ExportElementImpl exportElement = new ExportElementImpl();
+              ExportElementImpl exportElement =
+                  new ExportElementImpl(directive.offset);
               StringLiteral uriLiteral = exportDirective.uri;
               exportElement.uriOffset = uriLiteral.offset;
               exportElement.uriEnd = uriLiteral.end;
@@ -8002,9 +7952,8 @@
                   SourceKind.LIBRARY) {
                 _errorListener.onError(new AnalysisError.con2(
                     library.librarySource, uriLiteral.offset, uriLiteral.length,
-                    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, [
-                  uriLiteral.toSource()
-                ]));
+                    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
+                    [uriLiteral.toSource()]));
               }
             }
           }
@@ -8024,7 +7973,7 @@
       if (libraryElement.entryPoint == null) {
         Namespace namespace = new NamespaceBuilder()
             .createExportNamespaceForLibrary(libraryElement);
-        Element element = namespace.get(LibraryElementBuilder.ENTRY_POINT_NAME);
+        Element element = namespace.get(FunctionElement.MAIN_FUNCTION_NAME);
         if (element is FunctionElement) {
           libraryElement.entryPoint = element;
         }
@@ -8072,13 +8021,9 @@
    */
   void _buildImplicitConstructors() {
     PerformanceStatistics.resolve.makeCurrentWhile(() {
-      ImplicitConstructorComputer computer =
-          new ImplicitConstructorComputer(_typeProvider);
+      ImplicitConstructorComputer computer = new ImplicitConstructorComputer();
       for (Library library in _librariesInCycles) {
-        for (Source source in library.compilationUnitSources) {
-          computer.add(library.getAST(source), source, library.libraryElement,
-              library.libraryScope);
-        }
+        computer.add(_errorListener, library.libraryElement);
       }
       computer.compute();
     });
@@ -8689,7 +8634,8 @@
             // directive was invalid.
             ResolvableLibrary exportedLibrary = _libraryMap[exportedSource];
             if (exportedLibrary != null) {
-              ExportElementImpl exportElement = new ExportElementImpl();
+              ExportElementImpl exportElement =
+                  new ExportElementImpl(directive.offset);
               StringLiteral uriLiteral = exportDirective.uri;
               if (uriLiteral != null) {
                 exportElement.uriOffset = uriLiteral.offset;
@@ -8708,9 +8654,8 @@
                   SourceKind.LIBRARY) {
                 _errorListener.onError(new AnalysisError.con2(
                     library.librarySource, uriLiteral.offset, uriLiteral.length,
-                    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, [
-                  uriLiteral.toSource()
-                ]));
+                    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
+                    [uriLiteral.toSource()]));
               }
             }
           }
@@ -8730,7 +8675,7 @@
       if (libraryElement.entryPoint == null) {
         Namespace namespace = new NamespaceBuilder()
             .createExportNamespaceForLibrary(libraryElement);
-        Element element = namespace.get(LibraryElementBuilder.ENTRY_POINT_NAME);
+        Element element = namespace.get(FunctionElement.MAIN_FUNCTION_NAME);
         if (element is FunctionElement) {
           libraryElement.entryPoint = element;
         }
@@ -8777,16 +8722,9 @@
    */
   void _buildImplicitConstructors() {
     PerformanceStatistics.resolve.makeCurrentWhile(() {
-      ImplicitConstructorComputer computer =
-          new ImplicitConstructorComputer(_typeProvider);
+      ImplicitConstructorComputer computer = new ImplicitConstructorComputer();
       for (ResolvableLibrary library in _librariesInCycle) {
-        for (ResolvableCompilationUnit unit
-            in library.resolvableCompilationUnits) {
-          Source source = unit.source;
-          CompilationUnit ast = unit.compilationUnit;
-          computer
-              .add(ast, source, library.libraryElement, library.libraryScope);
-        }
+        computer.add(_errorListener, library.libraryElement);
       }
       computer.compute();
     });
@@ -9041,9 +8979,8 @@
       }
       return new AnalysisError.con2(duplicate.source, offset,
           duplicate.displayName.length,
-          CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, [
-        existing.displayName
-      ]);
+          CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER,
+          [existing.displayName]);
     }
     return super.getErrorForDuplicate(existing, duplicate);
   }
@@ -9377,23 +9314,10 @@
    * @param definedNames the mapping table to which the names in the given namespace are to be added
    * @param namespace the namespace containing the names to be added to this namespace
    */
-  void _addAllFromMap(
-      Map<String, Element> definedNames, Map<String, Element> newNames) {
-    newNames.forEach((String name, Element element) {
-      definedNames[name] = element;
-    });
-  }
-
-  /**
-   * Add all of the names in the given namespace to the given mapping table.
-   *
-   * @param definedNames the mapping table to which the names in the given namespace are to be added
-   * @param namespace the namespace containing the names to be added to this namespace
-   */
   void _addAllFromNamespace(
       Map<String, Element> definedNames, Namespace namespace) {
     if (namespace != null) {
-      _addAllFromMap(definedNames, namespace.definedNames);
+      definedNames.addAll(namespace.definedNames);
     }
   }
 
@@ -9492,6 +9416,14 @@
    */
   HashMap<String, Element> _createExportMapping(
       LibraryElement library, HashSet<LibraryElement> visitedElements) {
+    // Check if the export namespace has been already computed.
+    {
+      Namespace exportNamespace = library.exportNamespace;
+      if (exportNamespace != null) {
+        return exportNamespace.definedNames;
+      }
+    }
+    // TODO(scheglov) Remove this after switching to the new task model.
     visitedElements.add(library);
     try {
       HashMap<String, Element> definedNames = new HashMap<String, Element>();
@@ -9506,7 +9438,7 @@
           HashMap<String, Element> exportedNames =
               _createExportMapping(exportedLibrary, visitedElements);
           exportedNames = _applyCombinators(exportedNames, element.combinators);
-          _addAllFromMap(definedNames, exportedNames);
+          definedNames.addAll(exportedNames);
         }
       }
       _addAllFromNamespace(definedNames,
@@ -10342,7 +10274,7 @@
       element = expression.propertyName.propagatedElement;
     }
     if (element is VariableElement) {
-      return element as VariableElement;
+      return element;
     }
     return null;
   }
@@ -10364,7 +10296,7 @@
       element = expression.propertyName.staticElement;
     }
     if (element is VariableElement) {
-      return element as VariableElement;
+      return element;
     }
     return null;
   }
@@ -12276,7 +12208,7 @@
           AstNode parent = node.parent;
           while (parent != null) {
             if (parent is Declaration) {
-              Element parentElement = (parent as Declaration).element;
+              Element parentElement = parent.element;
               buffer.write(parentElement == null
                   ? "<unknown> "
                   : "${parentElement.name} ");
@@ -12917,9 +12849,7 @@
    * @param overrides the overrides to be applied
    */
   void applyOverrides(Map<VariableElement, DartType> overrides) {
-    overrides.forEach((VariableElement element, DartType type) {
-      _overridenTypes[element] = type;
-    });
+    _overridenTypes.addAll(overrides);
   }
 
   /**
@@ -13242,6 +13172,11 @@
   InterfaceType get mapType;
 
   /**
+   * Return a [DartObjectImpl] representing the `null` object.
+   */
+  DartObjectImpl get nullObject;
+
+  /**
    * Return the type representing the built-in type 'Null'.
    *
    * @return the type representing the built-in type 'null'
@@ -13382,6 +13317,11 @@
   InterfaceType _mapType;
 
   /**
+   * An shared object representing the value 'null'.
+   */
+  DartObjectImpl _nullObject;
+
+  /**
    * The type representing the type 'Null'.
    */
   InterfaceType _nullType;
@@ -13432,12 +13372,24 @@
   DartType _undefinedType;
 
   /**
-   * Initialize a newly created type provider to provide the types defined in the given library.
-   *
-   * @param coreLibrary the element representing the core library (dart:core).
+   * Initialize a newly created type provider to provide the types defined in
+   * the given [coreLibrary] and [asyncLibrary].
    */
   TypeProviderImpl(LibraryElement coreLibrary, LibraryElement asyncLibrary) {
-    _initializeFrom(coreLibrary, asyncLibrary);
+    Namespace coreNamespace =
+        new NamespaceBuilder().createPublicNamespaceForLibrary(coreLibrary);
+    Namespace asyncNamespace =
+        new NamespaceBuilder().createPublicNamespaceForLibrary(asyncLibrary);
+    _initializeFrom(coreNamespace, asyncNamespace);
+  }
+
+  /**
+   * Initialize a newly created type provider to provide the types defined in
+   * the given [Namespace]s.
+   */
+  TypeProviderImpl.forNamespaces(
+      Namespace coreNamespace, Namespace asyncNamespace) {
+    _initializeFrom(coreNamespace, asyncNamespace);
   }
 
   @override
@@ -13483,6 +13435,14 @@
   InterfaceType get mapType => _mapType;
 
   @override
+  DartObjectImpl get nullObject {
+    if (_nullObject == null) {
+      _nullObject = new DartObjectImpl(nullType, NullState.NULL_STATE);
+    }
+    return _nullObject;
+  }
+
+  @override
   InterfaceType get nullType => _nullType;
 
   @override
@@ -13531,16 +13491,10 @@
   }
 
   /**
-   * Initialize the types provided by this type provider from the given library.
-   *
-   * @param library the library containing the definitions of the core types
+   * Initialize the types provided by this type provider from the given
+   * [Namespace]s.
    */
-  void _initializeFrom(
-      LibraryElement coreLibrary, LibraryElement asyncLibrary) {
-    Namespace coreNamespace =
-        new NamespaceBuilder().createPublicNamespaceForLibrary(coreLibrary);
-    Namespace asyncNamespace =
-        new NamespaceBuilder().createPublicNamespaceForLibrary(asyncLibrary);
+  void _initializeFrom(Namespace coreNamespace, Namespace asyncNamespace) {
     _boolType = _getType(coreNamespace, "bool");
     _bottomType = BottomTypeImpl.instance;
     _deprecatedType = _getType(coreNamespace, "Deprecated");
@@ -14049,9 +14003,8 @@
               // Else, if this expression is a new expression, report a
               // NEW_WITH_NON_TYPE warning.
               reportErrorForNode(StaticWarningCode.NEW_WITH_NON_TYPE,
-                  prefixedIdentifier.identifier, [
-                prefixedIdentifier.identifier.name
-              ]);
+                  prefixedIdentifier.identifier,
+                  [prefixedIdentifier.identifier.name]);
             }
             _setElement(prefix, element);
             return null;
@@ -14150,21 +14103,20 @@
     DartType type = null;
     if (element is ClassElement) {
       _setElement(typeName, element);
-      type = (element as ClassElement).type;
+      type = element.type;
     } else if (element is FunctionTypeAliasElement) {
       _setElement(typeName, element);
-      type = (element as FunctionTypeAliasElement).type;
+      type = element.type;
     } else if (element is TypeParameterElement) {
       _setElement(typeName, element);
-      type = (element as TypeParameterElement).type;
+      type = element.type;
       if (argumentList != null) {
         // Type parameters cannot have type arguments.
         // TODO(brianwilkerson) Report this error.
         //      resolver.reportError(ResolverErrorCode.?, keyType);
       }
     } else if (element is MultiplyDefinedElement) {
-      List<Element> elements =
-          (element as MultiplyDefinedElement).conflictingElements;
+      List<Element> elements = element.conflictingElements;
       type = _getTypeWhenMultiplyDefined(elements);
       if (type != null) {
         node.type = type;
@@ -14400,7 +14352,7 @@
     if (parent is ConstructorName) {
       parent = parent.parent;
       if (parent is InstanceCreationExpression) {
-        if ((parent as InstanceCreationExpression).isConst) {
+        if (parent.isConst) {
           return CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS;
         } else {
           return StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS;
@@ -14423,11 +14375,8 @@
       ConstructorName constructorName = parent as ConstructorName;
       parent = constructorName.parent;
       if (parent is ConstructorDeclaration) {
-        ConstructorDeclaration constructorDeclaration =
-            parent as ConstructorDeclaration;
-        if (identical(
-            constructorDeclaration.redirectedConstructor, constructorName)) {
-          if (constructorDeclaration.constKeyword != null) {
+        if (identical(parent.redirectedConstructor, constructorName)) {
+          if (parent.constKeyword != null) {
             return RedirectingConstructorKind.CONST;
           }
           return RedirectingConstructorKind.NORMAL;
@@ -14605,6 +14554,8 @@
           CompileTimeErrorCode.MIXIN_OF_NON_CLASS);
       if (classElement != null) {
         classElement.mixins = mixinTypes;
+        classElement.withClauseRange =
+            new SourceRange(withClause.offset, withClause.length);
       }
     }
     if (implementsClause != null) {
@@ -14849,17 +14800,6 @@
   }
 
   @override
-  Object visitMethodDeclaration(MethodDeclaration node) {
-    ExecutableElement outerFunction = _enclosingFunction;
-    try {
-      _enclosingFunction = node.element;
-      return super.visitMethodDeclaration(node);
-    } finally {
-      _enclosingFunction = outerFunction;
-    }
-  }
-
-  @override
   Object visitFunctionExpression(FunctionExpression node) {
     if (node.parent is! FunctionDeclaration) {
       ExecutableElement outerFunction = _enclosingFunction;
@@ -14878,6 +14818,17 @@
   Object visitImportDirective(ImportDirective node) => null;
 
   @override
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    ExecutableElement outerFunction = _enclosingFunction;
+    try {
+      _enclosingFunction = node.element;
+      return super.visitMethodDeclaration(node);
+    } finally {
+      _enclosingFunction = outerFunction;
+    }
+  }
+
+  @override
   Object visitSimpleIdentifier(SimpleIdentifier node) {
     // Ignore if already resolved - declaration or type.
     if (node.staticElement != null) {
@@ -15023,7 +14974,18 @@
   @override
   visitCatchClause(CatchClause node) {
     SimpleIdentifier exceptionParameter = node.exceptionParameter;
-    _useStaticElement(exceptionParameter);
+    SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
+    if (exceptionParameter != null) {
+      Element element = exceptionParameter.staticElement;
+      usedElements.addCatchException(element);
+      if (stackTraceParameter != null || node.onKeyword == null) {
+        _useElement(element);
+      }
+    }
+    if (stackTraceParameter != null) {
+      Element element = stackTraceParameter.staticElement;
+      usedElements.addCatchStackTrace(element);
+    }
     super.visitCatchClause(node);
   }
 
@@ -15152,12 +15114,6 @@
     _useElement(element);
   }
 
-  void _useStaticElement(SimpleIdentifier identifier) {
-    if (identifier != null) {
-      _useElement(identifier.staticElement);
-    }
-  }
-
   static bool _isReadIdentifier(SimpleIdentifier node) {
     // not reading at all
     if (!node.inGetterContext()) {
@@ -15324,8 +15280,15 @@
   @override
   visitLocalVariableElement(LocalVariableElement element) {
     if (!_isUsedElement(element)) {
-      _reportErrorForElement(
-          HintCode.UNUSED_LOCAL_VARIABLE, element, [element.displayName]);
+      HintCode errorCode;
+      if (_usedElements.isCatchException(element)) {
+        errorCode = HintCode.UNUSED_CATCH_CLAUSE;
+      } else if (_usedElements.isCatchStackTrace(element)) {
+        errorCode = HintCode.UNUSED_CATCH_STACK;
+      } else {
+        errorCode = HintCode.UNUSED_LOCAL_VARIABLE;
+      }
+      _reportErrorForElement(errorCode, element, [element.displayName]);
     }
   }
 
@@ -15407,6 +15370,18 @@
   final HashSet<Element> elements = new HashSet<Element>();
 
   /**
+   * [LocalVariableElement]s that represent exceptions in [CatchClause]s.
+   */
+  final HashSet<LocalVariableElement> catchExceptionElements =
+      new HashSet<LocalVariableElement>();
+
+  /**
+   * [LocalVariableElement]s that represent stack traces in [CatchClause]s.
+   */
+  final HashSet<LocalVariableElement> catchStackTraceElements =
+      new HashSet<LocalVariableElement>();
+
+  /**
    * Names of resolved or unresolved class members that are referenced in the
    * library.
    */
@@ -15417,4 +15392,24 @@
    * library.
    */
   final HashSet<String> readMembers = new HashSet<String>();
+
+  void addCatchException(LocalVariableElement element) {
+    if (element != null) {
+      catchExceptionElements.add(element);
+    }
+  }
+
+  void addCatchStackTrace(LocalVariableElement element) {
+    if (element != null) {
+      catchStackTraceElements.add(element);
+    }
+  }
+
+  bool isCatchException(LocalVariableElement element) {
+    return catchExceptionElements.contains(element);
+  }
+
+  bool isCatchStackTrace(LocalVariableElement element) {
+    return catchStackTraceElements.contains(element);
+  }
 }
diff --git a/pkg/analyzer/lib/src/generated/scanner.dart b/pkg/analyzer/lib/src/generated/scanner.dart
index 2685726..2731610 100644
--- a/pkg/analyzer/lib/src/generated/scanner.dart
+++ b/pkg/analyzer/lib/src/generated/scanner.dart
@@ -11,8 +11,8 @@
 import 'source.dart';
 
 /**
- * A `BeginToken` is the opening half of a grouping pair of tokens. This is used
- * for curly brackets ('{'), parentheses ('('), and square brackets ('[').
+ * The opening half of a grouping pair of tokens. This is used for curly
+ * brackets ('{'), parentheses ('('), and square brackets ('[').
  */
 class BeginToken extends Token {
   /**
@@ -36,7 +36,7 @@
 }
 
 /**
- * A `BeginTokenWithComment` is a begin token that is preceded by comments.
+ * A begin token that is preceded by comments.
  */
 class BeginTokenWithComment extends BeginToken {
   /**
@@ -77,8 +77,8 @@
 }
 
 /**
- * A `CharacterRangeReader` is a [CharacterReader] that reads a range of
- * characters from another character reader.
+ * A [CharacterReader] that reads a range of characters from another character
+ * reader.
  */
 class CharacterRangeReader extends CharacterReader {
   /**
@@ -129,8 +129,7 @@
 }
 
 /**
- * A `CharacterReader` is used by the scanner to read the characters to be
- * scanned.
+ * An object used by the scanner to read the characters to be scanned.
  */
 abstract class CharacterReader {
   /**
@@ -171,8 +170,7 @@
 }
 
 /**
- * A `CharSequenceReader` is a [CharacterReader] that reads characters from a
- * character sequence.
+ * A [CharacterReader] that reads characters from a character sequence.
  */
 class CharSequenceReader implements CharacterReader {
   /**
@@ -229,7 +227,7 @@
 }
 
 /**
- * A `CommentToken` is a token representing a comment.
+ * A token representing a comment.
  */
 class CommentToken extends StringToken {
   /**
@@ -271,8 +269,7 @@
 }
 
 /**
- * The enumeration `Keyword` defines the keywords in the Dart programming
- * language.
+ * The keywords in the Dart programming language.
  */
 class Keyword {
   static const Keyword ASSERT = const Keyword('ASSERT', "assert");
@@ -471,7 +468,7 @@
 }
 
 /**
- * A `KeywordState` is a state in a state machine used to scan keywords.
+ * A state in a state machine used to scan keywords.
  */
 class KeywordState {
   /**
@@ -523,16 +520,6 @@
    * the subset of strings in the given array of [strings] starting at the given
    * [offset] and having the given [length]. All of these strings have a common
    * prefix and the next character is at the given [start] index.
-   *
-   * [start] the index of the character in the strings used to transition to a
-   * new state
-   * [strings] an array containing all of the strings that will be recognized by
-   * the state machine
-   * [offset] the offset of the first string in the array that has the prefix
-   * that is assumed to have been recognized by the time we reach the state
-   * being built
-   * [length] the number of strings in the array that pass through the state
-   * being built
    */
   static KeywordState _computeKeywordStateTable(
       int start, List<String> strings, int offset, int length) {
@@ -587,7 +574,7 @@
 }
 
 /**
- * A `KeywordToken` is a keyword in the language.
+ * A token representing a keyword in the language.
  */
 class KeywordToken extends Token {
   /**
@@ -612,7 +599,7 @@
 }
 
 /**
- * A `KeywordTokenWithComment` is a keyword token that is preceded by comments.
+ * A keyword token that is preceded by comments.
  */
 class KeywordTokenWithComment extends KeywordToken {
   /**
@@ -939,17 +926,13 @@
 
   /**
    * Record that the source begins on the given [line] and [column] at the
-   * current offset as given by the reader. The line starts for lines before the
-   * given line will not be correct.
+   * current offset as given by the reader. Both the line and the column are
+   * one-based indexes. The line starts for lines before the given line will not
+   * be correct.
    *
    * This method must be invoked at most one time and must be invoked before
    * scanning begins. The values provided must be sensible. The results are
    * undefined if these conditions are violated.
-   *
-   * [line] the one-based index of the line containing the first character of
-   * the source
-   * [column] the one-based index of the column in which the first character of
-   * the source occurs
    */
   void setSourceStart(int line, int column) {
     int offset = _reader.offset;
@@ -1130,10 +1113,9 @@
   }
 
   /**
-   * Report an error at the current offset.
-   *
-   * [errorCode] the error code indicating the nature of the error
-   * [arguments] any arguments needed to complete the error message
+   * Report an error at the current offset. The [errorCode] is the error code
+   * indicating the nature of the error. The [arguments] are any arguments
+   * needed to complete the error message
    */
   void _reportError(ScannerErrorCode errorCode, [List<Object> arguments]) {
     _errorListener.onError(new AnalysisError.con2(
@@ -1778,8 +1760,7 @@
 }
 
 /**
- * The enumeration `ScannerErrorCode` defines the error codes used for errors
- * detected by the scanner.
+ * The error codes used for errors detected by the scanner.
  */
 class ScannerErrorCode extends ErrorCode {
   static const ScannerErrorCode ILLEGAL_CHARACTER =
@@ -1822,7 +1803,7 @@
 }
 
 /**
- * A `StringToken` is a token whose value is independent of it's type.
+ * A token whose value is independent of it's type.
  */
 class StringToken extends Token {
   /**
@@ -1849,7 +1830,7 @@
 }
 
 /**
- * A `StringTokenWithComment` is a string token that is preceded by comments.
+ * A string token that is preceded by comments.
  */
 class StringTokenWithComment extends StringToken {
   /**
@@ -1891,10 +1872,9 @@
 }
 
 /**
- * A `SubSequenceReader` is a [CharacterReader] that reads characters from a
- * character sequence, but adds a delta when reporting the current character
- * offset so that the character sequence can be a subsequence from a larger
- * sequence.
+ * A [CharacterReader] that reads characters from a character sequence, but adds
+ * a delta when reporting the current character offset so that the character
+ * sequence can be a subsequence from a larger sequence.
  */
 class SubSequenceReader extends CharSequenceReader {
   /**
@@ -1924,7 +1904,7 @@
 }
 
 /**
- * A `SyntheticStringToken` is a token whose value is independent of it's type.
+ * A token whose value is independent of it's type.
  */
 class SyntheticStringToken extends StringToken {
   /**
@@ -1939,9 +1919,8 @@
 }
 
 /**
- * Instances of the class `Token` represent a token that was scanned from the
- * input. Each token knows which tokens preceed and follow it, acting as a link
- * in a doubly linked list of tokens.
+ * A token that was scanned from the input. Each token knows which tokens
+ * precede and follow it, acting as a link in a doubly linked list of tokens.
  */
 class Token {
   /**
@@ -2128,8 +2107,7 @@
 }
 
 /**
- * The enumeration `TokenClass` represents classes (or groups) of tokens with a
- * similar use.
+ * The classes (or groups) of tokens with a similar use.
  */
 class TokenClass {
   /**
@@ -2246,8 +2224,7 @@
 }
 
 /**
- * The enumeration `TokenType` defines the types of tokens that can be returned
- * by the scanner.
+ * The types of tokens that can be returned by the scanner.
  */
 class TokenType {
   /**
@@ -2588,7 +2565,7 @@
 }
 
 /**
- * A `TokenWithComment` is a normal token that is preceded by comments.
+ * A normal token that is preceded by comments.
  */
 class TokenWithComment extends Token {
   /**
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 9bd5a7f..81c8a88 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -14,90 +14,74 @@
 import 'source.dart' show ContentCache, Source, UriKind;
 
 /**
- * Instances of the class `DartSdk` represent a Dart SDK installed in a specified location.
+ * A Dart SDK installed in a specified location.
  */
 abstract class DartSdk {
   /**
-   * The short name of the dart SDK async library.
+   * The short name of the dart SDK 'async' library.
    */
   static final String DART_ASYNC = "dart:async";
 
   /**
-   * The short name of the dart SDK core library.
+   * The short name of the dart SDK 'core' library.
    */
   static final String DART_CORE = "dart:core";
 
   /**
-   * The short name of the dart SDK html library.
+   * The short name of the dart SDK 'html' library.
    */
   static final String DART_HTML = "dart:html";
 
   /**
-   * The version number that is returned when the real version number could not be determined.
+   * The version number that is returned when the real version number could not
+   * be determined.
    */
   static final String DEFAULT_VERSION = "0";
 
   /**
-   * Return the [AnalysisContext] used for all of the sources in this [DartSdk].
-   *
-   * @return the [AnalysisContext] used for all of the sources in this [DartSdk]
+   * Return the analysis context used for all of the sources in this [DartSdk].
    */
   AnalysisContext get context;
 
   /**
-   * Return an array containing all of the libraries defined in this SDK.
-   *
-   * @return the libraries defined in this SDK
+   * Return a list containing all of the libraries defined in this SDK.
    */
   List<SdkLibrary> get sdkLibraries;
 
   /**
-   * Return the revision number of this SDK, or `"0"` if the revision number cannot be
-   * discovered.
-   *
-   * @return the revision number of this SDK
+   * Return the revision number of this SDK, or `"0"` if the revision number
+   * cannot be discovered.
    */
   String get sdkVersion;
 
   /**
-   * Return an array containing the library URI's for the libraries defined in this SDK.
-   *
-   * @return the library URI's for the libraries defined in this SDK
+   * Return a list containing the library URI's for the libraries defined in
+   * this SDK.
    */
   List<String> get uris;
 
   /**
-   * Return a source representing the given file: URI if the file is in this SDK, or `null` if
-   * the file is not in this SDK.
-   *
-   * @param uri the file URI for which a source is to be returned
-   * @return the source representing the given URI
-   * @throws
+   * Return a source representing the given 'file:' [uri] if the file is in this
+   * SDK, or `null` if the file is not in this SDK.
    */
   Source fromFileUri(Uri uri);
 
   /**
-   * Return the library representing the library with the given `dart:` URI, or `null`
-   * if the given URI does not denote a library in this SDK.
-   *
-   * @param dartUri the URI of the library to be returned
-   * @return the SDK library object
+   * Return the library representing the library with the given 'dart:' [uri],
+   * or `null` if the given URI does not denote a library in this SDK.
    */
-  SdkLibrary getSdkLibrary(String dartUri);
+  SdkLibrary getSdkLibrary(String uri);
 
   /**
-   * Return the source representing the library with the given `dart:` URI, or `null` if
-   * the given URI does not denote a library in this SDK.
-   *
-   * @param dartUri the URI of the library to be returned
-   * @return the source representing the specified library
+   * Return the source representing the library with the given 'dart:' [uri], or
+   * `null` if the given URI does not denote a library in this SDK.
    */
-  Source mapDartUri(String dartUri);
+  Source mapDartUri(String uri);
 }
 
 /**
- * Instances of the class `LibraryMap` map Dart library URI's to the [SdkLibraryImpl
- ].
+ * A map from Dart library URI's to the [SdkLibraryImpl] representing that
+ * library.
  */
 class LibraryMap {
   /**
@@ -107,32 +91,23 @@
       new HashMap<String, SdkLibraryImpl>();
 
   /**
-   * Return an array containing all the sdk libraries [SdkLibraryImpl] in the mapping
-   *
-   * @return the sdk libraries in the mapping
+   * Return a list containing all of the sdk libraries in this mapping.
    */
   List<SdkLibrary> get sdkLibraries => new List.from(_libraryMap.values);
 
   /**
-   * Return an array containing the library URI's for which a mapping is available.
-   *
-   * @return the library URI's for which a mapping is available
+   * Return a list containing the library URI's for which a mapping is available.
    */
   List<String> get uris => new List.from(_libraryMap.keys.toSet());
 
   /**
-   * Return the library with the given URI, or `null` if the URI does not map to a library.
-   *
-   * @param dartUri the URI of the library to be returned
-   * @return the library with the given URI
+   * Return the library with the given 'dart:' [uri], or `null` if the URI does
+   * not map to a library.
    */
-  SdkLibrary getLibrary(String dartUri) => _libraryMap[dartUri];
+  SdkLibrary getLibrary(String uri) => _libraryMap[uri];
 
   /**
-   * Return the library with the given URI, or `null` if the URI does not map to a library.
-   *
-   * @param dartUri the URI of the library to be returned
-   * @param library the library with the given URI
+   * Set the library with the given 'dart:' [uri] to the given [library].
    */
   void setLibrary(String dartUri, SdkLibraryImpl library) {
     _libraryMap[dartUri] = library;
@@ -140,43 +115,44 @@
 
   /**
    * Return the number of library URI's for which a mapping is available.
-   *
-   * @return the number of library URI's for which a mapping is available
    */
   int size() => _libraryMap.length;
 }
 
 class SdkLibrariesReader_LibraryBuilder extends RecursiveAstVisitor<Object> {
   /**
-   * The prefix added to the name of a library to form the URI used in code to reference the
-   * library.
+   * The prefix added to the name of a library to form the URI used in code to
+   * reference the library.
    */
   static String _LIBRARY_PREFIX = "dart:";
 
   /**
-   * The name of the optional parameter used to indicate whether the library is an implementation
-   * library.
+   * The name of the optional parameter used to indicate whether the library is
+   * an implementation library.
    */
   static String _IMPLEMENTATION = "implementation";
 
   /**
-   * The name of the optional parameter used to specify the path used when compiling for dart2js.
+   * The name of the optional parameter used to specify the path used when
+   * compiling for dart2js.
    */
   static String _DART2JS_PATH = "dart2jsPath";
 
   /**
-   * The name of the optional parameter used to indicate whether the library is documented.
+   * The name of the optional parameter used to indicate whether the library is
+   * documented.
    */
   static String _DOCUMENTED = "documented";
 
   /**
-   * The name of the optional parameter used to specify the category of the library.
+   * The name of the optional parameter used to specify the category of the
+   * library.
    */
   static String _CATEGORY = "category";
 
   /**
-   * The name of the optional parameter used to specify the platforms on which the library can be
-   * used.
+   * The name of the optional parameter used to specify the platforms on which
+   * the library can be used.
    */
   static String _PLATFORMS = "platforms";
 
@@ -187,29 +163,26 @@
   static String _VM_PLATFORM = "VM_PLATFORM";
 
   /**
-   * A flag indicating whether the dart2js path should be used when it is available.
+   * A flag indicating whether the dart2js path should be used when it is
+   * available.
    */
   final bool _useDart2jsPaths;
 
   /**
-   * The library map that is populated by visiting the AST structure parsed from the contents of
-   * the libraries file.
+   * The library map that is populated by visiting the AST structure parsed from
+   * the contents of the libraries file.
    */
   LibraryMap _librariesMap = new LibraryMap();
 
   /**
-   * Initialize a newly created library builder to use the dart2js path if the given value is
-   * `true`.
-   *
-   * @param useDart2jsPaths `true` if the dart2js path should be used when it is available
+   * Initialize a newly created library builder to use the dart2js path if
+   * [_useDart2jsPaths] is `true`.
    */
   SdkLibrariesReader_LibraryBuilder(this._useDart2jsPaths);
 
   /**
-   * Return the library map that was populated by visiting the AST structure parsed from the
-   * contents of the libraries file.
-   *
-   * @return the library map describing the contents of the SDK
+   * Return the library map that was populated by visiting the AST structure
+   * parsed from the contents of the libraries file.
    */
   LibraryMap get librariesMap => _librariesMap;
 
@@ -264,100 +237,84 @@
 abstract class SdkLibrary {
   /**
    * Return the name of the category containing the library.
-   *
-   * @return the name of the category containing the library
    */
   String get category;
 
   /**
    * Return `true` if this library can be compiled to JavaScript by dart2js.
-   *
-   * @return `true` if this library can be compiled to JavaScript by dart2js
    */
   bool get isDart2JsLibrary;
 
   /**
    * Return `true` if the library is documented.
-   *
-   * @return `true` if the library is documented
    */
   bool get isDocumented;
 
   /**
    * Return `true` if the library is an implementation library.
-   *
-   * @return `true` if the library is an implementation library
    */
   bool get isImplementation;
 
   /**
    * Return `true` if library is internal can be used only by other SDK libraries.
-   *
-   * @return `true` if library is internal can be used only by other SDK libraries
    */
   bool get isInternal;
 
   /**
-   * Return `true` if library can be used for both client and server.
-   *
-   * @return `true` if this library can be used for both client and server.
+   * Return `true` if this library can be used for both client and server.
    */
   bool get isShared;
 
   /**
    * Return `true` if this library can be run on the VM.
-   *
-   * @return `true` if this library can be run on the VM
    */
   bool get isVmLibrary;
 
   /**
-   * Return the path to the file defining the library. The path is relative to the `lib`
-   * directory within the SDK.
-   *
-   * @return the path to the file defining the library
+   * Return the path to the file defining the library. The path is relative to
+   * the `lib` directory within the SDK.
    */
   String get path;
 
   /**
-   * Return the short name of the library. This is the URI of the library, including `dart:`.
-   *
-   * @return the short name of the library
+   * Return the short name of the library. This is the URI of the library,
+   * including `dart:`.
    */
   String get shortName;
 }
 
 /**
- * Instances of the class `SdkLibrary` represent the information known about a single library
- * within the SDK.
+ * The information known about a single library within the SDK.
  */
 class SdkLibraryImpl implements SdkLibrary {
   /**
-   * The bit mask used to access the bit representing the flag indicating whether a library is
-   * intended to work on the dart2js platform.
+   * The bit mask used to access the bit representing the flag indicating
+   * whether a library is intended to work on the dart2js platform.
    */
   static int DART2JS_PLATFORM = 1;
 
   /**
-   * The bit mask used to access the bit representing the flag indicating whether a library is
-   * intended to work on the VM platform.
+   * The bit mask used to access the bit representing the flag indicating
+   * whether a library is intended to work on the VM platform.
    */
   static int VM_PLATFORM = 2;
 
   /**
-   * The short name of the library. This is the name used after `dart:` in a URI.
+   * The short name of the library. This is the name used after 'dart:' in a
+   * URI.
    */
   String _shortName = null;
 
   /**
-   * The path to the file defining the library. The path is relative to the `lib` directory
-   * within the SDK.
+   * The path to the file defining the library. The path is relative to the
+   * 'lib' directory within the SDK.
    */
   String path = null;
 
   /**
-   * The name of the category containing the library. Unless otherwise specified in the libraries
-   * file all libraries are assumed to be shared between server and client.
+   * The name of the category containing the library. Unless otherwise specified
+   * in the libraries file all libraries are assumed to be shared between server
+   * and client.
    */
   String category = "Shared";
 
@@ -377,27 +334,22 @@
   int _platforms = 0;
 
   /**
-   * Initialize a newly created library to represent the library with the given name.
-   *
-   * @param name the short name of the library
+   * Initialize a newly created library to represent the library with the given
+   * [name].
    */
   SdkLibraryImpl(String name) {
     this._shortName = name;
   }
 
   /**
-   * Set whether the library is documented to match the given value.
-   *
-   * @param documented `true` if the library is documented
+   * Set whether the library is documented.
    */
   void set documented(bool documented) {
     this._documented = documented;
   }
 
   /**
-   * Set whether the library is an implementation library to match the given value.
-   *
-   * @param implementation `true` if the library is an implementation library
+   * Set whether the library is an implementation library.
    */
   void set implementation(bool implementation) {
     this._implementation = implementation;
@@ -415,17 +367,9 @@
   @override
   bool get isInternal => "Internal" == category;
 
-  /**
-   * Return `true` if library can be used for both client and server
-   */
   @override
   bool get isShared => category == "Shared";
 
-  /**
-   * Return `true` if this library can be run on the VM.
-   *
-   * @return `true` if this library can be run on the VM
-   */
   @override
   bool get isVmLibrary => (_platforms & VM_PLATFORM) != 0;
 
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index 2544ebb..3a9f239 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -23,32 +23,31 @@
 import 'source_io.dart';
 
 /**
- * Instances of the class `DirectoryBasedDartSdk` represent a Dart SDK installed in a
- * specified directory. Typical Dart SDK layout is something like...
+ * A Dart SDK installed in a specified directory. Typical Dart SDK layout is
+ * something like...
  *
- * <pre>
- *    dart-sdk/
- *       bin/
- *          dart[.exe]  <-- VM
- *       lib/
- *          core/
- *             core.dart
- *             ... other core library files ...
- *          ... other libraries ...
- *       util/
- *          ... Dart utilities ...
- *    Chromium/   <-- Dartium typically exists in a sibling directory
- * </pre>
+ *     dart-sdk/
+ *        bin/
+ *           dart[.exe]  <-- VM
+ *        lib/
+ *           core/
+ *              core.dart
+ *              ... other core library files ...
+ *           ... other libraries ...
+ *        util/
+ *           ... Dart utilities ...
+ *     Chromium/   <-- Dartium typically exists in a sibling directory
  */
 class DirectoryBasedDartSdk implements DartSdk {
   /**
-   * The default SDK, or `null` if the default SDK either has not yet been created or cannot
-   * be created for some reason.
+   * The default SDK, or `null` if the default SDK either has not yet been
+   * created or cannot be created for some reason.
    */
   static DirectoryBasedDartSdk _DEFAULT_SDK;
 
   /**
-   * The name of the directory within the SDK directory that contains executables.
+   * The name of the directory within the SDK directory that contains
+   * executables.
    */
   static String _BIN_DIRECTORY_NAME = "bin";
 
@@ -68,16 +67,6 @@
   static String _DART2JS_EXECUTABLE_NAME_WIN = "dart2js.bat";
 
   /**
-   * The name of the dart formatter executable on non-windows operating systems.
-   */
-  static String _DARTFMT_EXECUTABLE_NAME = "dartfmt";
-
-  /**
-   * The name of the dart formatter executable on windows operating systems.
-   */
-  static String _DARTFMT_EXECUTABLE_NAME_WIN = "dartfmt.bat";
-
-  /**
    * The name of the file containing the Dartium executable on Linux.
    */
   static String _DARTIUM_EXECUTABLE_NAME_LINUX = "chrome";
@@ -94,30 +83,32 @@
   static String _DARTIUM_EXECUTABLE_NAME_WIN = "Chrome.exe";
 
   /**
-   * The name of the [System] property whose value is the path to the default Dart SDK
-   * directory.
+   * The name of the [System] property whose value is the path to the default
+   * Dart SDK directory.
    */
   static String _DEFAULT_DIRECTORY_PROPERTY_NAME = "com.google.dart.sdk";
 
   /**
-   * The name of the directory within the SDK directory that contains documentation for the
-   * libraries.
+   * The name of the directory within the SDK directory that contains
+   * documentation for the libraries.
    */
   static String _DOCS_DIRECTORY_NAME = "docs";
 
   /**
-   * The suffix added to the name of a library to derive the name of the file containing the
-   * documentation for that library.
+   * The suffix added to the name of a library to derive the name of the file
+   * containing the documentation for that library.
    */
   static String _DOC_FILE_SUFFIX = "_api.json";
 
   /**
-   * The name of the directory within the SDK directory that contains the libraries file.
+   * The name of the directory within the SDK directory that contains the
+   * libraries file.
    */
   static String _INTERNAL_DIR = "_internal";
 
   /**
-   * The name of the directory within the SDK directory that contains the libraries.
+   * The name of the directory within the SDK directory that contains the
+   * libraries.
    */
   static String _LIB_DIRECTORY_NAME = "lib";
 
@@ -137,25 +128,26 @@
   static String _PUB_EXECUTABLE_NAME = "pub";
 
   /**
-   * The name of the file within the SDK directory that contains the version number of the SDK.
+   * The name of the file within the SDK directory that contains the version
+   * number of the SDK.
    */
   static String _VERSION_FILE_NAME = "version";
 
   /**
-   * The name of the file containing the VM executable on the Windows operating system.
+   * The name of the file containing the VM executable on the Windows operating
+   * system.
    */
   static String _VM_EXECUTABLE_NAME_WIN = "dart.exe";
 
   /**
-   * The name of the file containing the VM executable on non-Windows operating systems.
+   * The name of the file containing the VM executable on non-Windows operating
+   * systems.
    */
   static String _VM_EXECUTABLE_NAME = "dart";
 
   /**
-   * Return the default Dart SDK, or `null` if the directory containing the default SDK cannot
-   * be determined (or does not exist).
-   *
-   * @return the default Dart SDK
+   * Return the default Dart SDK, or `null` if the directory containing the
+   * default SDK cannot be determined (or does not exist).
    */
   static DirectoryBasedDartSdk get defaultSdk {
     if (_DEFAULT_SDK == null) {
@@ -169,11 +161,9 @@
   }
 
   /**
-   * Return the default directory for the Dart SDK, or `null` if the directory cannot be
-   * determined (or does not exist). The default directory is provided by a [System] property
-   * named `com.google.dart.sdk`.
-   *
-   * @return the default directory for the Dart SDK
+   * Return the default directory for the Dart SDK, or `null` if the directory
+   * cannot be determined (or does not exist). The default directory is provided
+   * by a system property named `com.google.dart.sdk`.
    */
   static JavaFile get defaultSdkDirectory {
     String sdkProperty =
@@ -189,7 +179,7 @@
   }
 
   /**
-   * The [AnalysisContext] which is used for all of the sources in this [DartSdk].
+   * The [AnalysisContext] which is used for all of the sources in this sdk.
    */
   InternalAnalysisContext _analysisContext;
 
@@ -199,7 +189,8 @@
   JavaFile _sdkDirectory;
 
   /**
-   * The revision number of this SDK, or `"0"` if the revision number cannot be discovered.
+   * The revision number of this SDK, or `"0"` if the revision number cannot be
+   * discovered.
    */
   String _sdkVersion;
 
@@ -209,11 +200,6 @@
   JavaFile _dart2jsExecutable;
 
   /**
-   * The file containing the dart formatter executable.
-   */
-  JavaFile _dartFmtExecutable;
-
-  /**
    * The file containing the Dartium executable.
    */
   JavaFile _dartiumExecutable;
@@ -234,10 +220,9 @@
   LibraryMap _libraryMap;
 
   /**
-   * Initialize a newly created SDK to represent the Dart SDK installed in the given directory.
-   *
-   * @param sdkDirectory the directory containing the SDK
-   * @param useDart2jsPaths `true` if the dart2js path should be used when it is available
+   * Initialize a newly created SDK to represent the Dart SDK installed in the
+   * [sdkDirectory]. The flag [useDart2jsPaths] is `true` if the dart2js path
+   * should be used when it is available
    */
   DirectoryBasedDartSdk(JavaFile sdkDirectory, [bool useDart2jsPaths = false]) {
     this._sdkDirectory = sdkDirectory.getAbsoluteFile();
@@ -261,9 +246,8 @@
   }
 
   /**
-   * Return the file containing the dart2js executable, or `null` if it does not exist.
-   *
-   * @return the file containing the dart2js executable
+   * Return the file containing the dart2js executable, or `null` if it does not
+   * exist.
    */
   JavaFile get dart2JsExecutable {
     if (_dart2jsExecutable == null) {
@@ -277,25 +261,7 @@
   }
 
   /**
-   * Return the file containing the dart formatter executable, or `null` if it does not exist.
-   *
-   * @return the file containing the dart formatter executable
-   */
-  JavaFile get dartFmtExecutable {
-    if (_dartFmtExecutable == null) {
-      _dartFmtExecutable = _verifyExecutable(new JavaFile.relative(
-          new JavaFile.relative(_sdkDirectory, _BIN_DIRECTORY_NAME),
-          OSUtilities.isWindows()
-              ? _DARTFMT_EXECUTABLE_NAME_WIN
-              : _DARTFMT_EXECUTABLE_NAME));
-    }
-    return _dartFmtExecutable;
-  }
-
-  /**
    * Return the name of the file containing the Dartium executable.
-   *
-   * @return the name of the file containing the Dartium executable
    */
   String get dartiumBinaryName {
     if (OSUtilities.isWindows()) {
@@ -308,9 +274,8 @@
   }
 
   /**
-   * Return the file containing the Dartium executable, or `null` if it does not exist.
-   *
-   * @return the file containing the Dartium executable
+   * Return the file containing the Dartium executable, or `null` if it does not
+   * exist.
    */
   JavaFile get dartiumExecutable {
     if (_dartiumExecutable == null) {
@@ -321,55 +286,41 @@
   }
 
   /**
-   * Return the directory where dartium can be found (the directory that will be the working
-   * directory is Dartium is invoked without changing the default).
-   *
-   * @return the directory where dartium can be found
+   * Return the directory where dartium can be found (the directory that will be
+   * the working directory is Dartium is invoked without changing the default).
    */
   JavaFile get dartiumWorkingDirectory =>
       getDartiumWorkingDirectory(_sdkDirectory.getParentFile());
 
   /**
    * Return the directory containing the SDK.
-   *
-   * @return the directory containing the SDK
    */
   JavaFile get directory => _sdkDirectory;
 
   /**
    * Return the directory containing documentation for the SDK.
-   *
-   * @return the SDK's documentation directory
    */
   JavaFile get docDirectory =>
       new JavaFile.relative(_sdkDirectory, _DOCS_DIRECTORY_NAME);
 
   /**
    * Return `true` if this SDK includes documentation.
-   *
-   * @return `true` if this installation of the SDK has documentation
    */
   bool get hasDocumentation => docDirectory.exists();
 
   /**
    * Return `true` if the Dartium binary is available.
-   *
-   * @return `true` if the Dartium binary is available
    */
   bool get isDartiumInstalled => dartiumExecutable != null;
 
   /**
    * Return the directory within the SDK directory that contains the libraries.
-   *
-   * @return the directory that contains the libraries
    */
   JavaFile get libraryDirectory =>
       new JavaFile.relative(_sdkDirectory, _LIB_DIRECTORY_NAME);
 
   /**
    * Return the file containing the Pub executable, or `null` if it does not exist.
-   *
-   * @return the file containing the Pub executable
    */
   JavaFile get pubExecutable {
     if (_pubExecutable == null) {
@@ -384,10 +335,8 @@
   List<SdkLibrary> get sdkLibraries => _libraryMap.sdkLibraries;
 
   /**
-   * Return the revision number of this SDK, or `"0"` if the revision number cannot be
-   * discovered.
-   *
-   * @return the revision number of this SDK
+   * Return the revision number of this SDK, or `"0"` if the revision number
+   * cannot be discovered.
    */
   @override
   String get sdkVersion {
@@ -400,25 +349,18 @@
         if (revision != null) {
           _sdkVersion = revision.trim();
         }
-      } on FileSystemException catch (exception) {
+      } on FileSystemException {
         // Fall through to return the default.
       }
     }
     return _sdkVersion;
   }
 
-  /**
-   * Return an array containing the library URI's for the libraries defined in this SDK.
-   *
-   * @return the library URI's for the libraries defined in this SDK
-   */
   @override
   List<String> get uris => _libraryMap.uris;
 
   /**
    * Return the name of the file containing the VM executable.
-   *
-   * @return the name of the file containing the VM executable
    */
   String get vmBinaryName {
     if (OSUtilities.isWindows()) {
@@ -429,9 +371,8 @@
   }
 
   /**
-   * Return the file containing the VM executable, or `null` if it does not exist.
-   *
-   * @return the file containing the VM executable
+   * Return the file containing the VM executable, or `null` if it does not
+   * exist.
    */
   JavaFile get vmExecutable {
     if (_vmExecutable == null) {
@@ -482,22 +423,16 @@
   }
 
   /**
-   * Return the directory where dartium can be found (the directory that will be the working
-   * directory is Dartium is invoked without changing the default).
-   *
-   * @param installDir the installation directory
-   * @return the directory where dartium can be found
+   * Return the directory where dartium can be found (the directory that will be
+   * the working directory if Dartium is invoked without changing the default),
+   * assuming that the Editor was installed in the [installDir].
    */
   JavaFile getDartiumWorkingDirectory(JavaFile installDir) =>
       new JavaFile.relative(installDir, _DARTIUM_DIRECTORY_NAME);
 
   /**
-   * Return the auxiliary documentation file for the given library, or `null` if no such file
-   * exists.
-   *
-   * @param libraryName the name of the library associated with the documentation file to be
-   *          returned
-   * @return the auxiliary documentation file for the library
+   * Return the auxiliary documentation file for the library with the given
+   * [libraryName], or `null` if no such file exists.
    */
   JavaFile getDocFileFor(String libraryName) {
     JavaFile dir = docDirectory;
@@ -517,10 +452,9 @@
   SdkLibrary getSdkLibrary(String dartUri) => _libraryMap.getLibrary(dartUri);
 
   /**
-   * Read all of the configuration files to initialize the library maps.
-   *
-   * @param useDart2jsPaths `true` if the dart2js path should be used when it is available
-   * @return the initialized library map
+   * Read all of the configuration files to initialize the library maps. The
+   * flag [useDart2jsPaths] is `true` if the dart2js path should be used when it
+   * is available. Return the initialized library map.
    */
   LibraryMap initialLibraryMap(bool useDart2jsPaths) {
     JavaFile librariesFile = new JavaFile.relative(
@@ -561,74 +495,64 @@
         file = new JavaFile.relative(file, relativePath);
       }
       return new FileBasedSource.con2(parseUriWithException(dartUri), file);
-    } on URISyntaxException catch (exception) {
+    } on URISyntaxException {
       return null;
     }
   }
 
   /**
-   * Verify that the given executable file exists and is executable.
-   *
-   * @param file the binary file
-   * @return the file if it exists and is executable, else `null`
+   * Return the given [file] if it exists and is executable, or `null` if it
+   * does not exist or is not executable.
    */
   JavaFile _verifyExecutable(JavaFile file) =>
       file.isExecutable() ? file : null;
 }
 
 /**
- * Instances of the class `SdkLibrariesReader` read and parse the libraries file
- * (dart-sdk/lib/_internal/libraries.dart) for information about the libraries in an SDK. The
- * library information is represented as a Dart file containing a single top-level variable whose
- * value is a const map. The keys of the map are the names of libraries defined in the SDK and the
- * values in the map are info objects defining the library. For example, a subset of a typical SDK
- * might have a libraries file that looks like the following:
+ * An object used to read and parse the libraries file
+ * (dart-sdk/lib/_internal/libraries.dart) for information about the libraries
+ * in an SDK. The library information is represented as a Dart file containing a
+ * single top-level variable whose value is a const map. The keys of the map are
+ * the names of libraries defined in the SDK and the values in the map are info
+ * objects defining the library. For example, a subset of a typical SDK might
+ * have a libraries file that looks like the following:
  *
- * <pre>
- * final Map&lt;String, LibraryInfo&gt; LIBRARIES = const &lt;LibraryInfo&gt; {
- *   // Used by VM applications
- *   "builtin" : const LibraryInfo(
- *     "builtin/builtin_runtime.dart",
- *     category: "Server",
- *     platforms: VM_PLATFORM),
+ *     final Map&lt;String, LibraryInfo&gt; LIBRARIES = const &lt;LibraryInfo&gt; {
+ *       // Used by VM applications
+ *       "builtin" : const LibraryInfo(
+ *         "builtin/builtin_runtime.dart",
+ *         category: "Server",
+ *         platforms: VM_PLATFORM),
  *
- *   "compiler" : const LibraryInfo(
- *     "compiler/compiler.dart",
- *     category: "Tools",
- *     platforms: 0),
- * };
- * </pre>
+ *       "compiler" : const LibraryInfo(
+ *         "compiler/compiler.dart",
+ *         category: "Tools",
+ *         platforms: 0),
+ *     };
  */
 class SdkLibrariesReader {
   /**
-   * A flag indicating whether the dart2js path should be used when it is available.
+   * A flag indicating whether the dart2js path should be used when it is
+   * available.
    */
   final bool _useDart2jsPaths;
 
   /**
-   * Initialize a newly created library reader to use the dart2js path if the given value is
-   * `true`.
-   *
-   * @param useDart2jsPaths `true` if the dart2js path should be used when it is available
+   * Initialize a newly created library reader to use the dart2js path if
+   * [_useDart2jsPaths] is `true`.
    */
   SdkLibrariesReader(this._useDart2jsPaths);
 
   /**
-   * Return the library map read from the given source.
-   *
-   * @param file the [File] of the library file
-   * @param libraryFileContents the contents from the library file
-   * @return the library map read from the given source
+   * Return the library map read from the given [file], given that the content
+   * of the file is already known to be [libraryFileContents].
    */
   LibraryMap readFromFile(JavaFile file, String libraryFileContents) =>
       readFromSource(new FileBasedSource.con1(file), libraryFileContents);
 
   /**
-   * Return the library map read from the given source.
-   *
-   * @param source the source of the library file
-   * @param libraryFileContents the contents from the library file
-   * @return the library map read from the given source
+   * Return the library map read from the given [source], given that the content
+   * of the file is already known to be [libraryFileContents].
    */
   LibraryMap readFromSource(Source source, String libraryFileContents) {
     BooleanErrorListener errorListener = new BooleanErrorListener();
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 1297a43..af157bb 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -172,9 +172,8 @@
   /**
    * The Dart Language Specification, 16.29 (Await Expressions):
    *
-   *   Let flatten(T) = flatten(S) if T = Future<S>, and T otherwise.  The
-   *   static type of [the expression "await e"] is flatten(T) where T is the
-   *   static type of e.
+   *   The static type of [the expression "await e"] is flatten(T) where T is
+   *   the static type of e.
    */
   @override
   Object visitAwaitExpression(AwaitExpression node) {
@@ -390,25 +389,18 @@
    */
   @override
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    ExecutableElement staticMethodElement = node.staticElement;
-    // Record static return type of the static element.
-    DartType staticStaticType = _computeStaticReturnType(staticMethodElement);
-    _recordStaticType(node, staticStaticType);
-    // Record propagated return type of the static element.
-    DartType staticPropagatedType =
-        _computePropagatedReturnType(staticMethodElement);
-    _recordPropagatedTypeIfBetter(node, staticPropagatedType);
-    // Process propagated element.
-    ExecutableElement propagatedMethodElement = node.propagatedElement;
-    if (!identical(propagatedMethodElement, staticMethodElement)) {
-      // Record static return type of the propagated element.
-      DartType propagatedStaticType =
-          _computeStaticReturnType(propagatedMethodElement);
-      _recordPropagatedTypeIfBetter(node, propagatedStaticType, true);
-      // Record propagated return type of the propagated element.
-      DartType propagatedPropagatedType =
-          _computePropagatedReturnType(propagatedMethodElement);
-      _recordPropagatedTypeIfBetter(node, propagatedPropagatedType, true);
+    DartType functionStaticType = _getStaticType(node.function);
+    DartType staticType;
+    if (functionStaticType is FunctionType) {
+      staticType = functionStaticType.returnType;
+    } else {
+      staticType = _dynamicType;
+    }
+    _recordStaticType(node, staticType);
+    DartType functionPropagatedType = node.function.propagatedType;
+    if (functionPropagatedType is FunctionType) {
+      DartType propagatedType = functionPropagatedType.returnType;
+      _recordPropagatedTypeIfBetter(node, propagatedType);
     }
     return null;
   }
@@ -892,25 +884,25 @@
     }
     if (propagatedElement is ClassElement) {
       if (_isNotTypeLiteral(node)) {
-        propagatedType = (propagatedElement as ClassElement).type;
+        propagatedType = propagatedElement.type;
       } else {
         propagatedType = _typeProvider.typeType;
       }
     } else if (propagatedElement is FunctionTypeAliasElement) {
-      propagatedType = (propagatedElement as FunctionTypeAliasElement).type;
+      propagatedType = propagatedElement.type;
     } else if (propagatedElement is MethodElement) {
-      propagatedType = (propagatedElement as MethodElement).type;
+      propagatedType = propagatedElement.type;
     } else if (propagatedElement is PropertyAccessorElement) {
-      propagatedType = _getTypeOfProperty(
-          propagatedElement as PropertyAccessorElement, node.prefix.staticType);
+      propagatedType =
+          _getTypeOfProperty(propagatedElement, node.prefix.staticType);
       propagatedType =
           _getPropertyPropagatedType(propagatedElement, propagatedType);
     } else if (propagatedElement is ExecutableElement) {
-      propagatedType = (propagatedElement as ExecutableElement).type;
+      propagatedType = propagatedElement.type;
     } else if (propagatedElement is TypeParameterElement) {
-      propagatedType = (propagatedElement as TypeParameterElement).type;
+      propagatedType = propagatedElement.type;
     } else if (propagatedElement is VariableElement) {
-      propagatedType = (propagatedElement as VariableElement).type;
+      propagatedType = propagatedElement.type;
     }
     DartType overriddenType = _overrideManager.getType(propagatedElement);
     if (propagatedType == null ||
@@ -1747,15 +1739,43 @@
   }
 
   /**
-   * Implements the function "flatten" defined in the spec: "Let flatten(T) =
-   * flatten(S) if T = Future<S>, and T otherwise."
+   * Implements the function "flatten" defined in the spec:
+   *
+   *   If T = Future<S> then flatten(T) = flatten(S).
+   *
+   *   Otherwise if T <: Future then let S be a type such that T << Future<S>
+   *   and for all R, if T << Future<R> then S << R.  Then flatten(T) = S.
+   *
+   *   In any other circumstance, flatten(T) = T.
    */
   static DartType flattenFutures(TypeProvider typeProvider, DartType type) {
-    if (type is InterfaceType &&
-        type.element == typeProvider.futureType.element &&
-        type.typeArguments.length > 0) {
-      return flattenFutures(typeProvider, type.typeArguments[0]);
+    if (type is InterfaceType) {
+      // Implement the case: "If T = Future<S> then flatten(T) = flatten(S)."
+      if (type.element == typeProvider.futureType.element &&
+          type.typeArguments.length > 0) {
+        return flattenFutures(typeProvider, type.typeArguments[0]);
+      }
+
+      // Implement the case: "Otherwise if T <: Future then let S be a type
+      // such that T << Future<S> and for all R, if T << Future<R> then S << R.
+      // Then flatten(T) = S."
+      //
+      // In other words, given the set of all types R such that T << Future<R>,
+      // let S be the most specific of those types, if any such S exists.
+      //
+      // Since we only care about the most specific type, it is sufficent to
+      // look at the types appearing as a parameter to Future in the type
+      // hierarchy of T.  We don't need to consider the supertypes of those
+      // types, since they are by definition less specific.
+      List<DartType> candidateTypes =
+          _searchTypeHierarchyForFutureParameters(typeProvider, type);
+      DartType flattenResult = _findMostSpecificType(candidateTypes);
+      if (flattenResult != null) {
+        return flattenResult;
+      }
     }
+
+    // Implement the case: "In any other circumstance, flatten(T) = T."
     return type;
   }
 
@@ -1827,6 +1847,88 @@
     map["video"] = "VideoElement";
     return map;
   }
+
+  /**
+   * If there is a single type which is at least as specific as all of the
+   * types in [types], return it.  Otherwise return `null`.
+   */
+  static DartType _findMostSpecificType(List<DartType> types) {
+    // The << relation ("more specific than") is a partial ordering on types,
+    // so to find the most specific type of a set, we keep a bucket of the most
+    // specific types seen so far such that no type in the bucket is more
+    // specific than any other type in the bucket.
+    List<DartType> bucket = <DartType>[];
+
+    // Then we consider each type in turn.
+    for (DartType type in types) {
+      // If any existing type in the bucket is more specific than this type,
+      // then we can ignore this type.
+      if (bucket.any((DartType t) => t.isMoreSpecificThan(type))) {
+        continue;
+      }
+      // Otherwise, we need to add this type to the bucket and remove any types
+      // that are less specific than it.
+      bool added = false;
+      int i = 0;
+      while (i < bucket.length) {
+        if (type.isMoreSpecificThan(bucket[i])) {
+          if (added) {
+            if (i < bucket.length - 1) {
+              bucket[i] = bucket.removeLast();
+            } else {
+              bucket.removeLast();
+            }
+          } else {
+            bucket[i] = type;
+            i++;
+            added = true;
+          }
+        } else {
+          i++;
+        }
+      }
+      if (!added) {
+        bucket.add(type);
+      }
+    }
+
+    // Now that we are finished, if there is exactly one type left in the
+    // bucket, it is the most specific type.
+    if (bucket.length == 1) {
+      return bucket[0];
+    }
+
+    // Otherwise, there is no single type that is more specific than the
+    // others.
+    return null;
+  }
+
+  /**
+   * Given a seed type [type], search its class hierarchy for types of the form
+   * Future<R>, and return a list of the resulting R's.
+   */
+  static List<DartType> _searchTypeHierarchyForFutureParameters(
+      TypeProvider typeProvider, InterfaceType type) {
+    List<DartType> result = <DartType>[];
+    HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
+    void recurse(InterfaceType type) {
+      if (type.element == typeProvider.futureType.element &&
+          type.typeArguments.length > 0) {
+        result.add(type.typeArguments[0]);
+      }
+      if (visitedClasses.add(type.element)) {
+        if (type.superclass != null) {
+          recurse(type.superclass);
+        }
+        for (InterfaceType interface in type.interfaces) {
+          recurse(interface);
+        }
+        visitedClasses.remove(type.element);
+      }
+    }
+    recurse(type);
+    return result;
+  }
 }
 
 class _StaticTypeAnalyzer_computePropagatedReturnTypeOfFunction
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 150d2fa..9fab12f 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -70,6 +70,18 @@
           [List<String> parameterNames]) =>
       classElement(typeName, objectType, parameterNames);
 
+  static ClassElementImpl classTypeAlias2(String typeName,
+          [List<String> parameterNames]) =>
+      classTypeAlias(typeName, objectType, parameterNames);
+
+  static classTypeAlias(String typeName, InterfaceType superclassType,
+      [List<String> parameterNames]) {
+    ClassElementImpl element =
+        classElement(typeName, superclassType, parameterNames);
+    element.typedef = true;
+    return element;
+  }
+
   static CompilationUnitElementImpl compilationUnit(String fileName) {
     Source source = new NonExistingSource(fileName, UriKind.FILE_URI);
     CompilationUnitElementImpl unit = new CompilationUnitElementImpl(fileName);
@@ -174,7 +186,7 @@
 
   static ExportElementImpl exportFor(LibraryElement exportedLibrary,
       [List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_ARRAY]) {
-    ExportElementImpl spec = new ExportElementImpl();
+    ExportElementImpl spec = new ExportElementImpl(-1);
     spec.exportedLibrary = exportedLibrary;
     spec.combinators = combinators;
     return spec;
@@ -202,9 +214,8 @@
       setter.setter = true;
       setter.synthetic = true;
       setter.variable = field;
-      setter.parameters = <ParameterElement>[
-        requiredParameter2("_$name", type)
-      ];
+      setter.parameters =
+          <ParameterElement>[requiredParameter2("_$name", type)];
       setter.returnType = VoidTypeImpl.instance;
       setter.type = new FunctionTypeImpl.con1(setter);
       field.setter = setter;
@@ -507,9 +518,8 @@
       setter.static = true;
       setter.synthetic = true;
       setter.variable = variable;
-      setter.parameters = <ParameterElement>[
-        requiredParameter2("_$name", type)
-      ];
+      setter.parameters =
+          <ParameterElement>[requiredParameter2("_$name", type)];
       setter.returnType = VoidTypeImpl.instance;
       setter.type = new FunctionTypeImpl.con1(setter);
       variable.setter = setter;
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index 79f5448..6824459 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -7,13 +7,14 @@
 
 library engine.testing.test_type_provider;
 
+import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 
 /**
- * Instances of the class `TestTypeProvider` implement a type provider that can be used by
- * tests without creating the element model for the core library.
+ * A type provider that can be used by tests without creating the element model
+ * for the core library.
  */
 class TestTypeProvider implements TypeProvider {
   /**
@@ -92,6 +93,11 @@
   InterfaceType _mapType;
 
   /**
+   * An shared object representing the value 'null'.
+   */
+  DartObjectImpl _nullObject;
+
+  /**
    * The type representing the built-in type 'Null'.
    */
   InterfaceType _nullType;
@@ -324,6 +330,14 @@
   }
 
   @override
+  DartObjectImpl get nullObject {
+    if (_nullObject == null) {
+      _nullObject = new DartObjectImpl(nullType, NullState.NULL_STATE);
+    }
+    return _nullObject;
+  }
+
+  @override
   InterfaceType get nullType {
     if (_nullType == null) {
       _nullType = ElementFactory.classElement2("Null").type;
@@ -442,8 +456,8 @@
   }
 
   /**
-   * Initialize the numeric types. They are created as a group so that we can (a) create the right
-   * hierarchy and (b) add members to them.
+   * Initialize the numeric types. They are created as a group so that we can
+   * (a) create the right hierarchy and (b) add members to them.
    */
   void _initializeNumericTypes() {
     //
@@ -555,10 +569,9 @@
   }
 
   /**
-   * Given a class element representing a class with type parameters, propagate those type
-   * parameters to all of the accessors, methods and constructors defined for the class.
-   *
-   * @param classElement the element representing the class with type parameters
+   * Given a [classElement] representing a class with type parameters, propagate
+   * those type parameters to all of the accessors, methods and constructors
+   * defined for the class.
    */
   void _propagateTypeArguments(ClassElementImpl classElement) {
     List<DartType> typeArguments =
diff --git a/pkg/analyzer/lib/src/generated/testing/token_factory.dart b/pkg/analyzer/lib/src/generated/testing/token_factory.dart
index eeafab61..e9324be 100644
--- a/pkg/analyzer/lib/src/generated/testing/token_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/token_factory.dart
@@ -10,7 +10,7 @@
 import 'package:analyzer/src/generated/scanner.dart';
 
 /**
- * The class `TokenFactory` defines utility methods that can be used to create tokens.
+ * A set of utility methods that can be used to create tokens.
  */
 class TokenFactory {
   static Token tokenFromKeyword(Keyword keyword) =>
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
new file mode 100644
index 0000000..d858b1a
--- /dev/null
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.plugin.engine_plugin;
+
+import 'package:analyzer/plugin/plugin.dart';
+import 'package:analyzer/plugin/task.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/task/general.dart';
+import 'package:analyzer/task/model.dart';
+
+/**
+ * A plugin that defines the extension points and extensions that are inherently
+ * defined by the analysis engine.
+ */
+class EnginePlugin implements Plugin {
+  /**
+   * The simple identifier of the extension point that allows plugins to
+   * register new analysis tasks with the analysis engine.
+   */
+  static const String TASK_EXTENSION_POINT = 'task';
+
+  /**
+   * The unique identifier of this plugin.
+   */
+  static const String UNIQUE_IDENTIFIER = 'analysis_engine.core';
+
+  /**
+   * The extension point that allows plugins to register new analysis tasks with
+   * the analysis engine.
+   */
+  ExtensionPoint taskExtensionPoint;
+
+  /**
+   * Initialize a newly created plugin.
+   */
+  EnginePlugin();
+
+  /**
+   * Return a list containing all of the task descriptors that were contributed.
+   */
+  List<TaskDescriptor> taskDescriptors() {
+    return taskExtensionPoint.extensions;
+  }
+
+  @override
+  String get uniqueIdentifier => UNIQUE_IDENTIFIER;
+
+  @override
+  void registerExtensionPoints(RegisterExtensionPoint registerExtensionPoint) {
+    taskExtensionPoint =
+        registerExtensionPoint(TASK_EXTENSION_POINT, _validateTaskExtension);
+  }
+
+  @override
+  void registerExtensions(RegisterExtension registerExtension) {
+    String taskId = TASK_EXTENSION_POINT_ID;
+    //
+    // Register general tasks.
+    //
+    registerExtension(taskId, GetContentTask.DESCRIPTOR);
+    //
+    // Register Dart tasks.
+    //
+    registerExtension(taskId, BuildCompilationUnitElementTask.DESCRIPTOR);
+    registerExtension(taskId, BuildDirectiveElementsTask.DESCRIPTOR);
+    registerExtension(taskId, BuildEnumMemberElementsTask.DESCRIPTOR);
+    registerExtension(taskId, BuildExportNamespaceTask.DESCRIPTOR);
+    registerExtension(taskId, BuildExportSourceClosureTask.DESCRIPTOR);
+    registerExtension(taskId, BuildFunctionTypeAliasesTask.DESCRIPTOR);
+    registerExtension(taskId, BuildLibraryElementTask.DESCRIPTOR);
+    registerExtension(taskId, BuildPublicNamespaceTask.DESCRIPTOR);
+    registerExtension(taskId, BuildTypeProviderTask.DESCRIPTOR);
+    registerExtension(taskId, ParseDartTask.DESCRIPTOR);
+    registerExtension(taskId, ResolveLibraryTypeNamesTask.DESCRIPTOR);
+    registerExtension(taskId, ResolveUnitTypeNamesTask.DESCRIPTOR);
+    registerExtension(taskId, ScanDartTask.DESCRIPTOR);
+    //
+    // Register HTML tasks.
+    //
+  }
+
+  /**
+   * Validate the given extension by throwing an [ExtensionError] if it is not a
+   * valid domain.
+   */
+  void _validateTaskExtension(Object extension) {
+    if (extension is! TaskDescriptor) {
+      String id = taskExtensionPoint.uniqueIdentifier;
+      throw new ExtensionError('Extensions to $id must be a TaskDescriptor');
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_impl.dart b/pkg/analyzer/lib/src/plugin/plugin_impl.dart
similarity index 97%
rename from pkg/analysis_server/lib/src/plugin/plugin_impl.dart
rename to pkg/analyzer/lib/src/plugin/plugin_impl.dart
index 9b1bd98..5b9e8a2 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_impl.dart
+++ b/pkg/analyzer/lib/src/plugin/plugin_impl.dart
@@ -2,11 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analysis_server.src.plugin.plugin_impl;
+library analyzer.src.plugin.plugin_impl;
 
 import 'dart:collection';
 
-import 'package:analysis_server/plugin/plugin.dart';
+import 'package:analyzer/plugin/plugin.dart';
 
 /**
  * An object that manages the extension points for a single instance of the
diff --git a/pkg/analyzer/lib/src/services/formatter_impl.dart b/pkg/analyzer/lib/src/services/formatter_impl.dart
deleted file mode 100644
index e0512f9..0000000
--- a/pkg/analyzer/lib/src/services/formatter_impl.dart
+++ /dev/null
@@ -1,1838 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library formatter_impl;
-
-import 'dart:math';
-
-import 'package:analyzer/analyzer.dart';
-import 'package:analyzer/src/generated/parser.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/services/writer.dart';
-
-/// Formatter options.
-class FormatterOptions {
-
-  /// Create formatter options with defaults derived (where defined) from
-  /// the style guide: <http://www.dartlang.org/articles/style-guide/>.
-  const FormatterOptions({this.initialIndentationLevel: 0,
-      this.spacesPerIndent: 2, this.lineSeparator: NEW_LINE, this.pageWidth: 80,
-      this.tabsForIndent: false, this.tabSize: 2, this.codeTransforms: false});
-
-  final String lineSeparator;
-  final int initialIndentationLevel;
-  final int spacesPerIndent;
-  final int tabSize;
-  final bool tabsForIndent;
-  final int pageWidth;
-  final bool codeTransforms;
-}
-
-/// Thrown when an error occurs in formatting.
-class FormatterException implements Exception {
-
-  /// A message describing the error.
-  final String message;
-
-  /// Creates a new FormatterException with an optional error [message].
-  const FormatterException([this.message = 'FormatterException']);
-
-  FormatterException.forError(List<AnalysisError> errors, [LineInfo line])
-      : message = _createMessage(errors);
-
-  static String _createMessage(errors) {
-    //TODO(pquitslund): consider a verbosity flag to add/suppress details
-    var errorCode = errors[0].errorCode;
-    var phase = errorCode is ParserErrorCode ? 'parsing' : 'scanning';
-    return 'An error occured while $phase (${errorCode.name}).';
-  }
-
-  String toString() => '$message';
-}
-
-/// Specifies the kind of code snippet to format.
-class CodeKind {
-  final int ordinal;
-
-  const CodeKind._(this.ordinal);
-
-  /// A compilation unit snippet.
-  static const COMPILATION_UNIT = const CodeKind._(0);
-
-  /// A statement snippet.
-  static const STATEMENT = const CodeKind._(1);
-}
-
-/// Dart source code formatter.
-abstract class CodeFormatter {
-  factory CodeFormatter(
-          [FormatterOptions options = const FormatterOptions()]) =>
-      new CodeFormatterImpl(options);
-
-  /// Format the specified portion (from [offset] with [length]) of the given
-  /// [source] string, optionally providing an [indentationLevel].
-  FormattedSource format(CodeKind kind, String source, {int offset, int end,
-      int indentationLevel: 0, Selection selection: null});
-}
-
-/// Source selection state information.
-class Selection {
-
-  /// The offset of the source selection.
-  final int offset;
-
-  /// The length of the selection.
-  final int length;
-
-  Selection(this.offset, this.length);
-
-  String toString() => 'Selection (offset: $offset, length: $length)';
-}
-
-/// Formatted source.
-class FormattedSource {
-
-  /// Selection state or null if unspecified.
-  Selection selection;
-
-  /// Formatted source string.
-  final String source;
-
-  /// Create a formatted [source] result, with optional [selection] information.
-  FormattedSource(this.source, [this.selection = null]);
-}
-
-class CodeFormatterImpl implements CodeFormatter, AnalysisErrorListener {
-  final FormatterOptions options;
-  final errors = <AnalysisError>[];
-  final whitespace = new RegExp(r'[\s]+');
-
-  LineInfo lineInfo;
-
-  CodeFormatterImpl(this.options);
-
-  FormattedSource format(CodeKind kind, String source, {int offset, int end,
-      int indentationLevel: 0, Selection selection: null}) {
-    var startToken = tokenize(source);
-    checkForErrors();
-
-    var node = parse(kind, startToken);
-    checkForErrors();
-
-    var formatter = new SourceVisitor(options, lineInfo, source, selection);
-    node.accept(formatter);
-
-    var formattedSource = formatter.writer.toString();
-
-    checkTokenStreams(startToken, tokenize(formattedSource),
-        allowTransforms: options.codeTransforms);
-
-    return new FormattedSource(formattedSource, formatter.selection);
-  }
-
-  checkTokenStreams(Token t1, Token t2, {allowTransforms: false}) =>
-      new TokenStreamComparator(lineInfo, t1, t2, transforms: allowTransforms)
-          .verifyEquals();
-
-  AstNode parse(CodeKind kind, Token start) {
-    var parser = new Parser(null, this);
-
-    switch (kind) {
-      case CodeKind.COMPILATION_UNIT:
-        return parser.parseCompilationUnit(start);
-      case CodeKind.STATEMENT:
-        return parser.parseStatement(start);
-    }
-
-    throw new FormatterException('Unsupported format kind: $kind');
-  }
-
-  checkForErrors() {
-    if (errors.length > 0) {
-      throw new FormatterException.forError(errors);
-    }
-  }
-
-  onError(AnalysisError error) {
-    errors.add(error);
-  }
-
-  Token tokenize(String source) {
-    var reader = new CharSequenceReader(source);
-    var scanner = new Scanner(null, reader, this);
-    var token = scanner.tokenize();
-    lineInfo = new LineInfo(scanner.lineStarts);
-    return token;
-  }
-}
-
-// Compares two token streams.  Used for sanity checking formatted results.
-class TokenStreamComparator {
-  final LineInfo lineInfo;
-  Token token1, token2;
-  bool allowTransforms;
-
-  TokenStreamComparator(this.lineInfo, this.token1, this.token2,
-      {transforms: false})
-      : this.allowTransforms = transforms;
-
-  /// Verify that these two token streams are equal.
-  verifyEquals() {
-    while (!isEOF(token1)) {
-      checkPrecedingComments();
-      if (!checkTokens()) {
-        throwNotEqualException(token1, token2);
-      }
-      advance();
-    }
-    // TODO(pquitslund): consider a better way to notice trailing synthetics
-    if (!isEOF(token2) &&
-        !(isCLOSE_CURLY_BRACKET(token2) && isEOF(token2.next))) {
-      throw new FormatterException('Expected "EOF" but got "$token2".');
-    }
-  }
-
-  checkPrecedingComments() {
-    var comment1 = token1.precedingComments;
-    var comment2 = token2.precedingComments;
-    while (comment1 != null) {
-      if (comment2 == null) {
-        throw new FormatterException(
-            'Expected comment, "$comment1", at ${describeLocation(token1)}, '
-            'but got none.');
-      }
-      if (!equivalentComments(comment1, comment2)) {
-        throwNotEqualException(comment1, comment2);
-      }
-      comment1 = comment1.next;
-      comment2 = comment2.next;
-    }
-    if (comment2 != null) {
-      throw new FormatterException(
-          'Unexpected comment, "$comment2", at ${describeLocation(token2)}.');
-    }
-  }
-
-  bool equivalentComments(Token comment1, Token comment2) =>
-      comment1.lexeme.trim() == comment2.lexeme.trim();
-
-  throwNotEqualException(t1, t2) {
-    throw new FormatterException(
-        'Expected "$t1" but got "$t2", at ${describeLocation(t1)}.');
-  }
-
-  String describeLocation(Token token) => lineInfo == null
-      ? '<unknown>'
-      : 'Line: ${lineInfo.getLocation(token.offset).lineNumber}, '
-      'Column: ${lineInfo.getLocation(token.offset).columnNumber}';
-
-  advance() {
-    token1 = token1.next;
-    token2 = token2.next;
-  }
-
-  bool checkTokens() {
-    if (token1 == null || token2 == null) {
-      return false;
-    }
-    if (token1 == token2 || token1.lexeme == token2.lexeme) {
-      return true;
-    }
-
-    // '[' ']' => '[]'
-    if (isOPEN_SQ_BRACKET(token1) && isCLOSE_SQUARE_BRACKET(token1.next)) {
-      if (isINDEX(token2)) {
-        token1 = token1.next;
-        return true;
-      }
-    }
-    // '>' '>' => '>>'
-    if (isGT(token1) && isGT(token1.next)) {
-      if (isGT_GT(token2)) {
-        token1 = token1.next;
-        return true;
-      }
-    }
-    // Cons(){} => Cons();
-    if (isOPEN_CURLY_BRACKET(token1) && isCLOSE_CURLY_BRACKET(token1.next)) {
-      if (isSEMICOLON(token2)) {
-        token1 = token1.next;
-        advance();
-        return true;
-      }
-    }
-
-    // Transform-related special casing
-    if (allowTransforms) {
-
-      // Advance past empty statements
-      if (isSEMICOLON(token1)) {
-        // TODO whitelist
-        token1 = token1.next;
-        return checkTokens();
-      }
-
-      // Advance past synthetic { } tokens
-      if (isOPEN_CURLY_BRACKET(token2) || isCLOSE_CURLY_BRACKET(token2)) {
-        token2 = token2.next;
-        return checkTokens();
-      }
-    }
-
-    return false;
-  }
-}
-
-/// Test for token type.
-bool tokenIs(Token token, TokenType type) =>
-    token != null && token.type == type;
-
-/// Test if this token is an EOF token.
-bool isEOF(Token token) => tokenIs(token, TokenType.EOF);
-
-/// Test if this token is a GT token.
-bool isGT(Token token) => tokenIs(token, TokenType.GT);
-
-/// Test if this token is a GT_GT token.
-bool isGT_GT(Token token) => tokenIs(token, TokenType.GT_GT);
-
-/// Test if this token is an INDEX token.
-bool isINDEX(Token token) => tokenIs(token, TokenType.INDEX);
-
-/// Test if this token is a OPEN_CURLY_BRACKET token.
-bool isOPEN_CURLY_BRACKET(Token token) =>
-    tokenIs(token, TokenType.OPEN_CURLY_BRACKET);
-
-/// Test if this token is a CLOSE_CURLY_BRACKET token.
-bool isCLOSE_CURLY_BRACKET(Token token) =>
-    tokenIs(token, TokenType.CLOSE_CURLY_BRACKET);
-
-/// Test if this token is a OPEN_SQUARE_BRACKET token.
-bool isOPEN_SQ_BRACKET(Token token) =>
-    tokenIs(token, TokenType.OPEN_SQUARE_BRACKET);
-
-/// Test if this token is a CLOSE_SQUARE_BRACKET token.
-bool isCLOSE_SQUARE_BRACKET(Token token) =>
-    tokenIs(token, TokenType.CLOSE_SQUARE_BRACKET);
-
-/// Test if this token is a SEMICOLON token.
-bool isSEMICOLON(Token token) => tokenIs(token, TokenType.SEMICOLON);
-
-/// An AST visitor that drives formatting heuristics.
-class SourceVisitor implements AstVisitor {
-  static final OPEN_CURLY = syntheticToken(TokenType.OPEN_CURLY_BRACKET, '{');
-  static final CLOSE_CURLY = syntheticToken(TokenType.CLOSE_CURLY_BRACKET, '}');
-  static final SEMI_COLON = syntheticToken(TokenType.SEMICOLON, ';');
-
-  static const SYNTH_OFFSET = -13;
-
-  static StringToken syntheticToken(TokenType type, String value) =>
-      new StringToken(type, value, SYNTH_OFFSET);
-
-  static bool isSynthetic(Token token) => token.offset == SYNTH_OFFSET;
-
-  /// The writer to which the source is to be written.
-  final SourceWriter writer;
-
-  /// Cached line info for calculating blank lines.
-  LineInfo lineInfo;
-
-  /// Cached previous token for calculating preceding whitespace.
-  Token previousToken;
-
-  /// A flag to indicate that a newline should be emitted before the next token.
-  bool needsNewline = false;
-
-  /// A flag to indicate that user introduced newlines should be emitted before
-  /// the next token.
-  bool preserveNewlines = false;
-
-  /// A counter for spaces that should be emitted preceding the next token.
-  int leadingSpaces = 0;
-
-  /// A flag to specify whether line-leading spaces should be preserved (and
-  /// addded to the indent level).
-  bool allowLineLeadingSpaces;
-
-  /// A flag to specify whether zero-length spaces should be emmitted.
-  bool emitEmptySpaces = false;
-
-  /// Used for matching EOL comments
-  final twoSlashes = new RegExp(r'//[^/]');
-
-  /// A weight for potential breakpoints.
-  int currentBreakWeight = DEFAULT_SPACE_WEIGHT;
-
-  /// The last issued space weight.
-  int lastSpaceWeight = 0;
-
-  /// Original pre-format selection information (may be null).
-  final Selection preSelection;
-
-  final bool codeTransforms;
-
-  /// The source being formatted (used in interpolation handling)
-  final String source;
-
-  /// Post format selection information.
-  Selection selection;
-
-  /// Initialize a newly created visitor to write source code representing
-  /// the visited nodes to the given [writer].
-  SourceVisitor(
-      FormatterOptions options, this.lineInfo, this.source, this.preSelection)
-      : writer = new SourceWriter(
-          indentCount: options.initialIndentationLevel,
-          lineSeparator: options.lineSeparator,
-          maxLineLength: options.pageWidth,
-          useTabs: options.tabsForIndent,
-          spacesPerIndent: options.spacesPerIndent),
-        codeTransforms = options.codeTransforms;
-
-  visitAdjacentStrings(AdjacentStrings node) {
-    visitNodes(node.strings, separatedBy: space);
-  }
-
-  visitAnnotation(Annotation node) {
-    token(node.atSign);
-    visit(node.name);
-    token(node.period);
-    visit(node.constructorName);
-    visit(node.arguments);
-  }
-
-  visitArgumentList(ArgumentList node) {
-    token(node.leftParenthesis);
-    if (node.arguments.isNotEmpty) {
-      int weight = lastSpaceWeight++;
-      levelSpace(weight, 0);
-      visitCommaSeparatedNodes(node.arguments,
-          followedBy: () => levelSpace(weight));
-    }
-    token(node.rightParenthesis);
-  }
-
-  visitAsExpression(AsExpression node) {
-    visit(node.expression);
-    space();
-    token(node.asOperator);
-    space();
-    visit(node.type);
-  }
-
-  visitAssertStatement(AssertStatement node) {
-    token(node.assertKeyword);
-    token(node.leftParenthesis);
-    visit(node.condition);
-    token(node.rightParenthesis);
-    token(node.semicolon);
-  }
-
-  visitAssignmentExpression(AssignmentExpression node) {
-    visit(node.leftHandSide);
-    space();
-    token(node.operator);
-    allowContinuedLines(() {
-      levelSpace(SINGLE_SPACE_WEIGHT);
-      visit(node.rightHandSide);
-    });
-  }
-
-  @override
-  visitAwaitExpression(AwaitExpression node) {
-    token(node.awaitKeyword);
-    space();
-    visit(node.expression);
-  }
-
-  visitBinaryExpression(BinaryExpression node) {
-    Token operator = node.operator;
-    TokenType operatorType = operator.type;
-    int addOperands(List<Expression> operands, Expression e, int i) {
-      if (e is BinaryExpression && e.operator.type == operatorType) {
-        i = addOperands(operands, e.leftOperand, i);
-        i = addOperands(operands, e.rightOperand, i);
-      } else {
-        operands.insert(i++, e);
-      }
-      return i;
-    }
-    List<Expression> operands = [];
-    addOperands(operands, node.leftOperand, 0);
-    addOperands(operands, node.rightOperand, operands.length);
-    int weight = lastSpaceWeight++;
-    for (int i = 0; i < operands.length; i++) {
-      if (i != 0) {
-        space();
-        token(operator);
-        levelSpace(weight);
-      }
-      visit(operands[i]);
-    }
-  }
-
-  visitBlock(Block node) {
-    token(node.leftBracket);
-    indent();
-    if (!node.statements.isEmpty) {
-      visitNodes(node.statements, precededBy: newlines, separatedBy: newlines);
-      newlines();
-    } else {
-      preserveLeadingNewlines();
-    }
-    token(node.rightBracket, precededBy: unindent);
-  }
-
-  visitBlockFunctionBody(BlockFunctionBody node) {
-    // sync[*] or async[*]
-    token(node.keyword);
-    token(node.star);
-    if (node.keyword != null) {
-      nonBreakingSpace();
-    }
-
-    visit(node.block);
-  }
-
-  visitBooleanLiteral(BooleanLiteral node) {
-    token(node.literal);
-  }
-
-  visitBreakStatement(BreakStatement node) {
-    token(node.breakKeyword);
-    visitNode(node.label, precededBy: space);
-    token(node.semicolon);
-  }
-
-  visitCascadeExpression(CascadeExpression node) {
-    visit(node.target);
-    indent(2);
-    // Single cascades do not force a linebreak (dartbug.com/16384)
-    if (node.cascadeSections.length > 1) {
-      newlines();
-    }
-    visitNodes(node.cascadeSections, separatedBy: newlines);
-    unindent(2);
-  }
-
-  visitCatchClause(CatchClause node) {
-    token(node.onKeyword, followedBy: space);
-    visit(node.exceptionType);
-
-    if (node.catchKeyword != null) {
-      if (node.exceptionType != null) {
-        space();
-      }
-      token(node.catchKeyword);
-      space();
-      token(node.leftParenthesis);
-      visit(node.exceptionParameter);
-      token(node.comma, followedBy: space);
-      visit(node.stackTraceParameter);
-      token(node.rightParenthesis);
-      space();
-    } else {
-      space();
-    }
-    visit(node.body);
-  }
-
-  visitClassDeclaration(ClassDeclaration node) {
-    preserveLeadingNewlines();
-    visitMemberMetadata(node.metadata);
-    modifier(node.abstractKeyword);
-    token(node.classKeyword);
-    space();
-    visit(node.name);
-    allowContinuedLines(() {
-      visit(node.typeParameters);
-      visitNode(node.extendsClause, precededBy: space);
-      visitNode(node.withClause, precededBy: space);
-      visitNode(node.implementsClause, precededBy: space);
-      visitNode(node.nativeClause, precededBy: space);
-      space();
-    });
-    token(node.leftBracket);
-    indent();
-    if (!node.members.isEmpty) {
-      visitNodes(node.members, precededBy: newlines, separatedBy: newlines);
-      newlines();
-    } else {
-      preserveLeadingNewlines();
-    }
-    token(node.rightBracket, precededBy: unindent);
-  }
-
-  visitClassTypeAlias(ClassTypeAlias node) {
-    preserveLeadingNewlines();
-    visitMemberMetadata(node.metadata);
-    modifier(node.abstractKeyword);
-    token(node.typedefKeyword);
-    space();
-    visit(node.name);
-    visit(node.typeParameters);
-    space();
-    token(node.equals);
-    space();
-    visit(node.superclass);
-    visitNode(node.withClause, precededBy: space);
-    visitNode(node.implementsClause, precededBy: space);
-    token(node.semicolon);
-  }
-
-  visitComment(Comment node) => null;
-
-  visitCommentReference(CommentReference node) => null;
-
-  visitCompilationUnit(CompilationUnit node) {
-
-    // Cache EOF for leading whitespace calculation
-    var start = node.beginToken.previous;
-    if (start != null && start.type is TokenType_EOF) {
-      previousToken = start;
-    }
-
-    var scriptTag = node.scriptTag;
-    var directives = node.directives;
-    visit(scriptTag);
-
-    visitNodes(directives, separatedBy: newlines, followedBy: newlines);
-
-    visitNodes(node.declarations, separatedBy: newlines);
-
-    preserveLeadingNewlines();
-
-    // Handle trailing whitespace
-    token(node.endToken /* EOF */);
-
-    // Be a good citizen, end with a NL
-    ensureTrailingNewline();
-  }
-
-  visitConditionalExpression(ConditionalExpression node) {
-    int weight = lastSpaceWeight++;
-    visit(node.condition);
-    space();
-    token(node.question);
-    allowContinuedLines(() {
-      levelSpace(weight);
-      visit(node.thenExpression);
-      space();
-      token(node.colon);
-      levelSpace(weight);
-      visit(node.elseExpression);
-    });
-  }
-
-  visitConstructorDeclaration(ConstructorDeclaration node) {
-    visitMemberMetadata(node.metadata);
-    modifier(node.externalKeyword);
-    modifier(node.constKeyword);
-    modifier(node.factoryKeyword);
-    visit(node.returnType);
-    token(node.period);
-    visit(node.name);
-    visit(node.parameters);
-
-    // Check for redirects or initializer lists
-    if (node.separator != null) {
-      if (node.redirectedConstructor != null) {
-        visitConstructorRedirects(node);
-      } else {
-        visitConstructorInitializers(node);
-      }
-    }
-
-    var body = node.body;
-    if (codeTransforms && body is BlockFunctionBody) {
-      if (body.block.statements.isEmpty) {
-        token(SEMI_COLON);
-        newlines();
-        return;
-      }
-    }
-
-    visitPrefixedBody(space, body);
-  }
-
-  visitConstructorInitializers(ConstructorDeclaration node) {
-    if (node.initializers.length > 1) {
-      newlines();
-    } else {
-      preserveLeadingNewlines();
-      levelSpace(lastSpaceWeight++);
-    }
-    indent(2);
-    token(node.separator /* : */);
-    space();
-    for (var i = 0; i < node.initializers.length; i++) {
-      if (i > 0) {
-        // preceding comma
-        token(node.initializers[i].beginToken.previous);
-        newlines();
-        space(n: 2, allowLineLeading: true);
-      }
-      node.initializers[i].accept(this);
-    }
-    unindent(2);
-  }
-
-  visitConstructorRedirects(ConstructorDeclaration node) {
-    token(node.separator /* = */, precededBy: space, followedBy: space);
-    visitCommaSeparatedNodes(node.initializers);
-    visit(node.redirectedConstructor);
-  }
-
-  visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
-    token(node.thisKeyword);
-    token(node.period);
-    visit(node.fieldName);
-    space();
-    token(node.equals);
-    space();
-    visit(node.expression);
-  }
-
-  visitConstructorName(ConstructorName node) {
-    visit(node.type);
-    token(node.period);
-    visit(node.name);
-  }
-
-  visitContinueStatement(ContinueStatement node) {
-    token(node.continueKeyword);
-    visitNode(node.label, precededBy: space);
-    token(node.semicolon);
-  }
-
-  visitDeclaredIdentifier(DeclaredIdentifier node) {
-    modifier(node.keyword);
-    visitNode(node.type, followedBy: space);
-    visit(node.identifier);
-  }
-
-  visitDefaultFormalParameter(DefaultFormalParameter node) {
-    visit(node.parameter);
-    if (node.separator != null) {
-      // The '=' separator is preceded by a space
-      if (node.separator.type == TokenType.EQ) {
-        space();
-      }
-      token(node.separator);
-      visitNode(node.defaultValue, precededBy: space);
-    }
-  }
-
-  visitDoStatement(DoStatement node) {
-    token(node.doKeyword);
-    space();
-    visit(node.body);
-    space();
-    token(node.whileKeyword);
-    space();
-    token(node.leftParenthesis);
-    allowContinuedLines(() {
-      visit(node.condition);
-      token(node.rightParenthesis);
-    });
-    token(node.semicolon);
-  }
-
-  visitDoubleLiteral(DoubleLiteral node) {
-    token(node.literal);
-  }
-
-  visitEmptyFunctionBody(EmptyFunctionBody node) {
-    token(node.semicolon);
-  }
-
-  visitEmptyStatement(EmptyStatement node) {
-    if (!codeTransforms || node.parent is! Block) {
-      token(node.semicolon);
-    }
-  }
-
-  visitEnumConstantDeclaration(EnumConstantDeclaration node) {
-    visit(node.name);
-  }
-
-  visitEnumDeclaration(EnumDeclaration node) {
-    visitMemberMetadata(node.metadata);
-    token(node.enumKeyword);
-    space();
-    visit(node.name);
-    space();
-    token(node.leftBracket);
-    newlines();
-    indent();
-    visitCommaSeparatedNodes(node.constants);
-    newlines();
-    token(node.rightBracket, precededBy: unindent);
-  }
-
-  visitExportDirective(ExportDirective node) {
-    visitDirectiveMetadata(node.metadata);
-    token(node.keyword);
-    space();
-    visit(node.uri);
-    allowContinuedLines(() {
-      visitNodes(node.combinators, precededBy: space, separatedBy: space);
-    });
-    token(node.semicolon);
-  }
-
-  visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    int weight = lastSpaceWeight++;
-    token(node.keyword, followedBy: nonBreakingSpace);
-    token(node.functionDefinition);
-    levelSpace(weight);
-    visit(node.expression);
-    token(node.semicolon);
-  }
-
-  visitExpressionStatement(ExpressionStatement node) {
-    visit(node.expression);
-    token(node.semicolon);
-  }
-
-  visitExtendsClause(ExtendsClause node) {
-    token(node.extendsKeyword);
-    space();
-    visit(node.superclass);
-  }
-
-  visitFieldDeclaration(FieldDeclaration node) {
-    visitMemberMetadata(node.metadata);
-    modifier(node.staticKeyword);
-    visit(node.fields);
-    token(node.semicolon);
-  }
-
-  visitFieldFormalParameter(FieldFormalParameter node) {
-    token(node.keyword, followedBy: space);
-    visitNode(node.type, followedBy: space);
-    token(node.thisKeyword);
-    token(node.period);
-    visit(node.identifier);
-    visit(node.parameters);
-  }
-
-  visitForEachStatement(ForEachStatement node) {
-    token(node.awaitKeyword, followedBy: nonBreakingSpace);
-    token(node.forKeyword);
-    space();
-    token(node.leftParenthesis);
-    if (node.loopVariable != null) {
-      visit(node.loopVariable);
-    } else {
-      visit(node.identifier);
-    }
-    space();
-    token(node.inKeyword);
-    space();
-    visit(node.iterable);
-    token(node.rightParenthesis);
-    space();
-    visit(node.body);
-  }
-
-  visitFormalParameterList(FormalParameterList node) {
-    var groupEnd = null;
-    token(node.leftParenthesis);
-    var parameters = node.parameters;
-    var size = parameters.length;
-    for (var i = 0; i < size; i++) {
-      var parameter = parameters[i];
-      if (i > 0) {
-        append(',');
-        space();
-      }
-      if (groupEnd == null && parameter is DefaultFormalParameter) {
-        if (identical(parameter.kind, ParameterKind.NAMED)) {
-          groupEnd = '}';
-          append('{');
-        } else {
-          groupEnd = ']';
-          append('[');
-        }
-      }
-      parameter.accept(this);
-    }
-    if (groupEnd != null) {
-      append(groupEnd);
-    }
-    token(node.rightParenthesis);
-  }
-
-  visitForStatement(ForStatement node) {
-    token(node.forKeyword);
-    space();
-    token(node.leftParenthesis);
-    if (node.initialization != null) {
-      visit(node.initialization);
-    } else {
-      if (node.variables == null) {
-        space();
-      } else {
-        visit(node.variables);
-      }
-    }
-    token(node.leftSeparator);
-    space();
-    visit(node.condition);
-    token(node.rightSeparator);
-    if (node.updaters != null) {
-      space();
-      visitCommaSeparatedNodes(node.updaters);
-    }
-    token(node.rightParenthesis);
-    if (node.body is! EmptyStatement) {
-      space();
-    }
-    visit(node.body);
-  }
-
-  visitFunctionDeclaration(FunctionDeclaration node) {
-    preserveLeadingNewlines();
-    visitMemberMetadata(node.metadata);
-    modifier(node.externalKeyword);
-    visitNode(node.returnType, followedBy: space);
-    modifier(node.propertyKeyword);
-    visit(node.name);
-    visit(node.functionExpression);
-  }
-
-  visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
-    visit(node.functionDeclaration);
-  }
-
-  visitFunctionExpression(FunctionExpression node) {
-    visit(node.parameters);
-    if (node.body is! EmptyFunctionBody) {
-      space();
-    }
-    visit(node.body);
-  }
-
-  visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
-    visit(node.function);
-    visit(node.argumentList);
-  }
-
-  visitFunctionTypeAlias(FunctionTypeAlias node) {
-    visitMemberMetadata(node.metadata);
-    token(node.typedefKeyword);
-    space();
-    visitNode(node.returnType, followedBy: space);
-    visit(node.name);
-    visit(node.typeParameters);
-    visit(node.parameters);
-    token(node.semicolon);
-  }
-
-  visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    visitNode(node.returnType, followedBy: space);
-    visit(node.identifier);
-    visit(node.parameters);
-  }
-
-  visitHideCombinator(HideCombinator node) {
-    token(node.keyword);
-    space();
-    visitCommaSeparatedNodes(node.hiddenNames);
-  }
-
-  visitIfStatement(IfStatement node) {
-    var hasElse = node.elseStatement != null;
-    token(node.ifKeyword);
-    allowContinuedLines(() {
-      space();
-      token(node.leftParenthesis);
-      visit(node.condition);
-      token(node.rightParenthesis);
-    });
-    space();
-    if (hasElse) {
-      printAsBlock(node.thenStatement);
-      space();
-      token(node.elseKeyword);
-      space();
-      if (node.elseStatement is IfStatement) {
-        visit(node.elseStatement);
-      } else {
-        printAsBlock(node.elseStatement);
-      }
-    } else {
-      visit(node.thenStatement);
-    }
-  }
-
-  visitImplementsClause(ImplementsClause node) {
-    token(node.implementsKeyword);
-    space();
-    visitCommaSeparatedNodes(node.interfaces);
-  }
-
-  visitImportDirective(ImportDirective node) {
-    visitDirectiveMetadata(node.metadata);
-    token(node.keyword);
-    nonBreakingSpace();
-    visit(node.uri);
-    token(node.deferredKeyword, precededBy: space);
-    token(node.asKeyword, precededBy: space, followedBy: space);
-    allowContinuedLines(() {
-      visit(node.prefix);
-      visitNodes(node.combinators, precededBy: space, separatedBy: space);
-    });
-    token(node.semicolon);
-  }
-
-  visitIndexExpression(IndexExpression node) {
-    if (node.isCascaded) {
-      token(node.period);
-    } else {
-      visit(node.target);
-    }
-    token(node.leftBracket);
-    visit(node.index);
-    token(node.rightBracket);
-  }
-
-  visitInstanceCreationExpression(InstanceCreationExpression node) {
-    token(node.keyword);
-    nonBreakingSpace();
-    visit(node.constructorName);
-    visit(node.argumentList);
-  }
-
-  visitIntegerLiteral(IntegerLiteral node) {
-    token(node.literal);
-  }
-
-  visitInterpolationExpression(InterpolationExpression node) {
-    if (node.rightBracket != null) {
-      token(node.leftBracket);
-      visit(node.expression);
-      token(node.rightBracket);
-    } else {
-      token(node.leftBracket);
-      visit(node.expression);
-    }
-  }
-
-  visitInterpolationString(InterpolationString node) {
-    token(node.contents);
-  }
-
-  visitIsExpression(IsExpression node) {
-    visit(node.expression);
-    space();
-    token(node.isOperator);
-    token(node.notOperator);
-    space();
-    visit(node.type);
-  }
-
-  visitLabel(Label node) {
-    visit(node.label);
-    token(node.colon);
-  }
-
-  visitLabeledStatement(LabeledStatement node) {
-    visitNodes(node.labels, separatedBy: space, followedBy: space);
-    visit(node.statement);
-  }
-
-  visitLibraryDirective(LibraryDirective node) {
-    visitDirectiveMetadata(node.metadata);
-    token(node.keyword);
-    space();
-    visit(node.name);
-    token(node.semicolon);
-  }
-
-  visitLibraryIdentifier(LibraryIdentifier node) {
-    append(node.name);
-  }
-
-  visitListLiteral(ListLiteral node) {
-    int weight = lastSpaceWeight++;
-    modifier(node.constKeyword);
-    visit(node.typeArguments);
-    token(node.leftBracket);
-    indent();
-    levelSpace(weight, 0);
-    visitCommaSeparatedNodes(node.elements,
-        followedBy: () => levelSpace(weight));
-    optionalTrailingComma(node.rightBracket);
-    token(node.rightBracket, precededBy: unindent);
-  }
-
-  visitMapLiteral(MapLiteral node) {
-    modifier(node.constKeyword);
-    visitNode(node.typeArguments);
-    token(node.leftBracket);
-    if (!node.entries.isEmpty) {
-      newlines();
-      indent();
-      visitCommaSeparatedNodes(node.entries, followedBy: newlines);
-      optionalTrailingComma(node.rightBracket);
-      unindent();
-      newlines();
-    }
-    token(node.rightBracket);
-  }
-
-  visitMapLiteralEntry(MapLiteralEntry node) {
-    visit(node.key);
-    token(node.separator);
-    space();
-    visit(node.value);
-  }
-
-  visitMethodDeclaration(MethodDeclaration node) {
-    visitMemberMetadata(node.metadata);
-    modifier(node.externalKeyword);
-    modifier(node.modifierKeyword);
-    visitNode(node.returnType, followedBy: space);
-    modifier(node.propertyKeyword);
-    modifier(node.operatorKeyword);
-    visit(node.name);
-    if (!node.isGetter) {
-      visit(node.parameters);
-    }
-    visitPrefixedBody(nonBreakingSpace, node.body);
-  }
-
-  visitMethodInvocation(MethodInvocation node) {
-    visit(node.target);
-    token(node.period);
-    visit(node.methodName);
-    visit(node.argumentList);
-  }
-
-  visitNamedExpression(NamedExpression node) {
-    visit(node.name);
-    visitNode(node.expression, precededBy: space);
-  }
-
-  visitNativeClause(NativeClause node) {
-    token(node.nativeKeyword);
-    space();
-    visit(node.name);
-  }
-
-  visitNativeFunctionBody(NativeFunctionBody node) {
-    token(node.nativeKeyword);
-    space();
-    visit(node.stringLiteral);
-    token(node.semicolon);
-  }
-
-  visitNullLiteral(NullLiteral node) {
-    token(node.literal);
-  }
-
-  visitParenthesizedExpression(ParenthesizedExpression node) {
-    token(node.leftParenthesis);
-    visit(node.expression);
-    token(node.rightParenthesis);
-  }
-
-  visitPartDirective(PartDirective node) {
-    token(node.keyword);
-    space();
-    visit(node.uri);
-    token(node.semicolon);
-  }
-
-  visitPartOfDirective(PartOfDirective node) {
-    token(node.keyword);
-    space();
-    token(node.ofKeyword);
-    space();
-    visit(node.libraryName);
-    token(node.semicolon);
-  }
-
-  visitPostfixExpression(PostfixExpression node) {
-    visit(node.operand);
-    token(node.operator);
-  }
-
-  visitPrefixedIdentifier(PrefixedIdentifier node) {
-    visit(node.prefix);
-    token(node.period);
-    visit(node.identifier);
-  }
-
-  visitPrefixExpression(PrefixExpression node) {
-    token(node.operator);
-    visit(node.operand);
-  }
-
-  visitPropertyAccess(PropertyAccess node) {
-    if (node.isCascaded) {
-      token(node.operator);
-    } else {
-      visit(node.target);
-      token(node.operator);
-    }
-    visit(node.propertyName);
-  }
-
-  visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
-    token(node.thisKeyword);
-    token(node.period);
-    visit(node.constructorName);
-    visit(node.argumentList);
-  }
-
-  visitRethrowExpression(RethrowExpression node) {
-    token(node.rethrowKeyword);
-  }
-
-  visitReturnStatement(ReturnStatement node) {
-    var expression = node.expression;
-    if (expression == null) {
-      token(node.returnKeyword);
-      token(node.semicolon);
-    } else {
-      token(node.returnKeyword);
-      allowContinuedLines(() {
-        space();
-        expression.accept(this);
-        token(node.semicolon);
-      });
-    }
-  }
-
-  visitScriptTag(ScriptTag node) {
-    token(node.scriptTag);
-  }
-
-  visitShowCombinator(ShowCombinator node) {
-    token(node.keyword);
-    space();
-    visitCommaSeparatedNodes(node.shownNames);
-  }
-
-  visitSimpleFormalParameter(SimpleFormalParameter node) {
-    visitMemberMetadata(node.metadata);
-    modifier(node.keyword);
-    visitNode(node.type, followedBy: nonBreakingSpace);
-    visit(node.identifier);
-  }
-
-  visitSimpleIdentifier(SimpleIdentifier node) {
-    token(node.token);
-  }
-
-  visitSimpleStringLiteral(SimpleStringLiteral node) {
-    token(node.literal);
-  }
-
-  visitStringInterpolation(StringInterpolation node) {
-    // Ensure that interpolated strings don't get broken up by treating them as
-    // a single String token
-    // Process token (for comments etc. but don't print the lexeme)
-    token(node.beginToken, printToken: (tok) => null);
-    var start = node.beginToken.offset;
-    var end = node.endToken.end;
-    String string = source.substring(start, end);
-    append(string);
-    //visitNodes(node.elements);
-  }
-
-  visitSuperConstructorInvocation(SuperConstructorInvocation node) {
-    token(node.superKeyword);
-    token(node.period);
-    visit(node.constructorName);
-    visit(node.argumentList);
-  }
-
-  visitSuperExpression(SuperExpression node) {
-    token(node.superKeyword);
-  }
-
-  visitSwitchCase(SwitchCase node) {
-    visitNodes(node.labels, separatedBy: space, followedBy: space);
-    token(node.keyword);
-    space();
-    visit(node.expression);
-    token(node.colon);
-    newlines();
-    indent();
-    visitNodes(node.statements, separatedBy: newlines);
-    unindent();
-  }
-
-  visitSwitchDefault(SwitchDefault node) {
-    visitNodes(node.labels, separatedBy: space, followedBy: space);
-    token(node.keyword);
-    token(node.colon);
-    newlines();
-    indent();
-    visitNodes(node.statements, separatedBy: newlines);
-    unindent();
-  }
-
-  visitSwitchStatement(SwitchStatement node) {
-    token(node.switchKeyword);
-    space();
-    token(node.leftParenthesis);
-    visit(node.expression);
-    token(node.rightParenthesis);
-    space();
-    token(node.leftBracket);
-    indent();
-    newlines();
-    visitNodes(node.members, separatedBy: newlines, followedBy: newlines);
-    token(node.rightBracket, precededBy: unindent);
-  }
-
-  visitSymbolLiteral(SymbolLiteral node) {
-    token(node.poundSign);
-    var components = node.components;
-    for (var component in components) {
-      // The '.' separator
-      if (component.previous.lexeme == '.') {
-        token(component.previous);
-      }
-      token(component);
-    }
-  }
-
-  visitThisExpression(ThisExpression node) {
-    token(node.thisKeyword);
-  }
-
-  visitThrowExpression(ThrowExpression node) {
-    token(node.throwKeyword);
-    space();
-    visit(node.expression);
-  }
-
-  visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    visit(node.variables);
-    token(node.semicolon);
-  }
-
-  visitTryStatement(TryStatement node) {
-    token(node.tryKeyword);
-    space();
-    visit(node.body);
-    visitNodes(node.catchClauses, precededBy: space, separatedBy: space);
-    token(node.finallyKeyword, precededBy: space, followedBy: space);
-    visit(node.finallyBlock);
-  }
-
-  visitTypeArgumentList(TypeArgumentList node) {
-    token(node.leftBracket);
-    visitCommaSeparatedNodes(node.arguments);
-    token(node.rightBracket);
-  }
-
-  visitTypeName(TypeName node) {
-    visit(node.name);
-    visit(node.typeArguments);
-  }
-
-  visitTypeParameter(TypeParameter node) {
-    visitMemberMetadata(node.metadata);
-    visit(node.name);
-    token(node.extendsKeyword, precededBy: space, followedBy: space);
-    visit(node.bound);
-  }
-
-  visitTypeParameterList(TypeParameterList node) {
-    token(node.leftBracket);
-    visitCommaSeparatedNodes(node.typeParameters);
-    token(node.rightBracket);
-  }
-
-  visitVariableDeclaration(VariableDeclaration node) {
-    visit(node.name);
-    if (node.initializer != null) {
-      space();
-      token(node.equals);
-      var initializer = node.initializer;
-      if (initializer is ListLiteral || initializer is MapLiteral) {
-        space();
-        visit(initializer);
-      } else if (initializer is BinaryExpression) {
-        allowContinuedLines(() {
-          levelSpace(lastSpaceWeight);
-          visit(initializer);
-        });
-      } else {
-        allowContinuedLines(() {
-          levelSpace(SINGLE_SPACE_WEIGHT);
-          visit(initializer);
-        });
-      }
-    }
-  }
-
-  visitVariableDeclarationList(VariableDeclarationList node) {
-    visitMemberMetadata(node.metadata);
-    modifier(node.keyword);
-    visitNode(node.type, followedBy: space);
-
-    var variables = node.variables;
-    // Decls with initializers get their own lines (dartbug.com/16849)
-    if (variables.any((v) => (v.initializer != null))) {
-      var size = variables.length;
-      if (size > 0) {
-        var variable;
-        for (var i = 0; i < size; i++) {
-          variable = variables[i];
-          if (i > 0) {
-            var comma = variable.beginToken.previous;
-            token(comma);
-            newlines();
-          }
-          if (i == 1) {
-            indent(2);
-          }
-          variable.accept(this);
-        }
-        if (size > 1) {
-          unindent(2);
-        }
-      }
-    } else {
-      visitCommaSeparatedNodes(node.variables);
-    }
-  }
-
-  visitVariableDeclarationStatement(VariableDeclarationStatement node) {
-    visit(node.variables);
-    token(node.semicolon);
-  }
-
-  visitWhileStatement(WhileStatement node) {
-    token(node.whileKeyword);
-    space();
-    token(node.leftParenthesis);
-    allowContinuedLines(() {
-      visit(node.condition);
-      token(node.rightParenthesis);
-    });
-    if (node.body is! EmptyStatement) {
-      space();
-    }
-    visit(node.body);
-  }
-
-  visitWithClause(WithClause node) {
-    token(node.withKeyword);
-    space();
-    visitCommaSeparatedNodes(node.mixinTypes);
-  }
-
-  @override
-  visitYieldStatement(YieldStatement node) {
-    token(node.yieldKeyword);
-    token(node.star);
-    space();
-    visit(node.expression);
-    token(node.semicolon);
-  }
-
-  /// Safely visit the given [node].
-  visit(AstNode node) {
-    if (node != null) {
-      node.accept(this);
-    }
-  }
-
-  /// Visit member metadata
-  visitMemberMetadata(NodeList<Annotation> metadata) {
-    visitNodes(metadata, separatedBy: () {
-      space();
-      preserveLeadingNewlines();
-    }, followedBy: space);
-    if (metadata != null && metadata.length > 0) {
-      preserveLeadingNewlines();
-    }
-  }
-
-  /// Visit member metadata
-  visitDirectiveMetadata(NodeList<Annotation> metadata) {
-    visitNodes(metadata, separatedBy: newlines, followedBy: newlines);
-  }
-
-  /// Visit the given function [body], printing the [prefix] before if given
-  /// body is not empty.
-  visitPrefixedBody(prefix(), FunctionBody body) {
-    if (body is! EmptyFunctionBody) {
-      prefix();
-    }
-    visit(body);
-  }
-
-  /// Visit a list of [nodes] if not null, optionally separated and/or preceded
-  /// and followed by the given functions.
-  visitNodes(NodeList<AstNode> nodes,
-      {precededBy(): null, separatedBy(): null, followedBy(): null}) {
-    if (nodes != null) {
-      var size = nodes.length;
-      if (size > 0) {
-        if (precededBy != null) {
-          precededBy();
-        }
-        for (var i = 0; i < size; i++) {
-          if (i > 0 && separatedBy != null) {
-            separatedBy();
-          }
-          nodes[i].accept(this);
-        }
-        if (followedBy != null) {
-          followedBy();
-        }
-      }
-    }
-  }
-
-  /// Visit a comma-separated list of [nodes] if not null.
-  visitCommaSeparatedNodes(NodeList<AstNode> nodes, {followedBy(): null}) {
-    //TODO(pquitslund): handle this more neatly
-    if (followedBy == null) {
-      followedBy = space;
-    }
-    if (nodes != null) {
-      var size = nodes.length;
-      if (size > 0) {
-        var node;
-        for (var i = 0; i < size; i++) {
-          node = nodes[i];
-          if (i > 0) {
-            var comma = node.beginToken.previous;
-            token(comma);
-            followedBy();
-          }
-          node.accept(this);
-        }
-      }
-    }
-  }
-
-  /// Visit a [node], and if not null, optionally preceded or followed by the
-  /// specified functions.
-  visitNode(AstNode node, {precededBy(): null, followedBy(): null}) {
-    if (node != null) {
-      if (precededBy != null) {
-        precededBy();
-      }
-      node.accept(this);
-      if (followedBy != null) {
-        followedBy();
-      }
-    }
-  }
-
-  /// Allow [code] to be continued across lines.
-  allowContinuedLines(code()) {
-    //TODO(pquitslund): add before
-    code();
-    //TODO(pquitslund): add after
-  }
-
-  /// Emit the given [modifier] if it's non null, followed by non-breaking
-  /// whitespace.
-  modifier(Token modifier) {
-    token(modifier, followedBy: space);
-  }
-
-  /// Indicate that at least one newline should be emitted and possibly more
-  /// if the source has them.
-  newlines() {
-    needsNewline = true;
-  }
-
-  /// Optionally emit a trailing comma.
-  optionalTrailingComma(Token rightBracket) {
-    if (rightBracket.previous.lexeme == ',') {
-      token(rightBracket.previous);
-    }
-  }
-
-  /// Indicate that user introduced newlines should be emitted before the next
-  /// token.
-  preserveLeadingNewlines() {
-    preserveNewlines = true;
-  }
-
-  token(Token token,
-      {precededBy(), followedBy(), printToken(tok), int minNewlines: 0}) {
-    if (token != null) {
-      if (needsNewline) {
-        minNewlines = max(1, minNewlines);
-      }
-      var emitted = emitPrecedingCommentsAndNewlines(token, min: minNewlines);
-      if (emitted > 0) {
-        needsNewline = false;
-      }
-      if (precededBy != null) {
-        precededBy();
-      }
-      checkForSelectionUpdate(token);
-      if (printToken == null) {
-        append(token.lexeme);
-      } else {
-        printToken(token);
-      }
-      if (followedBy != null) {
-        followedBy();
-      }
-      previousToken = token;
-    }
-  }
-
-  emitSpaces() {
-    if (leadingSpaces > 0 || emitEmptySpaces) {
-      if (allowLineLeadingSpaces || !writer.currentLine.isWhitespace()) {
-        writer.spaces(leadingSpaces, breakWeight: currentBreakWeight);
-      }
-      leadingSpaces = 0;
-      allowLineLeadingSpaces = false;
-      emitEmptySpaces = false;
-      currentBreakWeight = DEFAULT_SPACE_WEIGHT;
-    }
-  }
-
-  checkForSelectionUpdate(Token token) {
-    // Cache the first token on or AFTER the selection offset
-    if (preSelection != null && selection == null) {
-      // Check for overshots
-      var overshot = token.offset - preSelection.offset;
-      if (overshot >= 0) {
-        //TODO(pquitslund): update length (may need truncating)
-        selection = new Selection(writer.toString().length +
-            leadingSpaces -
-            overshot, preSelection.length);
-      }
-    }
-  }
-
-  /// Emit a breakable 'non' (zero-length) space
-  breakableNonSpace() {
-    space(n: 0);
-    emitEmptySpaces = true;
-  }
-
-  /// Emit level spaces, even if empty (works as a break point).
-  levelSpace(int weight, [int n = 1]) {
-    space(n: n, breakWeight: weight);
-    emitEmptySpaces = true;
-  }
-
-  /// Emit a non-breakable space.
-  nonBreakingSpace() {
-    space(breakWeight: UNBREAKABLE_SPACE_WEIGHT);
-  }
-
-  /// Emit a space. If [allowLineLeading] is specified, spaces
-  /// will be preserved at the start of a line (in addition to the
-  /// indent-level), otherwise line-leading spaces will be ignored.
-  space({n: 1, allowLineLeading: false, breakWeight: DEFAULT_SPACE_WEIGHT}) {
-    //TODO(pquitslund): replace with a proper space token
-    leadingSpaces += n;
-    allowLineLeadingSpaces = allowLineLeading;
-    currentBreakWeight = breakWeight;
-  }
-
-  /// Append the given [string] to the source writer if it's non-null.
-  append(String string) {
-    if (string != null && !string.isEmpty) {
-      emitSpaces();
-      writer.write(string);
-    }
-  }
-
-  /// Indent.
-  indent([n = 1]) {
-    while (n-- > 0) {
-      writer.indent();
-    }
-  }
-
-  /// Unindent
-  unindent([n = 1]) {
-    while (n-- > 0) {
-      writer.unindent();
-    }
-  }
-
-  /// Print this statement as if it were a block (e.g., surrounded by braces).
-  printAsBlock(Statement statement) {
-    if (codeTransforms && statement is! Block) {
-      token(OPEN_CURLY);
-      indent();
-      newlines();
-      visit(statement);
-      newlines();
-      token(CLOSE_CURLY, precededBy: unindent);
-    } else {
-      visit(statement);
-    }
-  }
-
-  /// Emit any detected comments and newlines or a minimum as specified
-  /// by [min].
-  int emitPrecedingCommentsAndNewlines(Token token, {min: 0}) {
-    var comment = token.precedingComments;
-    var currentToken = comment != null ? comment : token;
-
-    //Handle EOLs before newlines
-    if (isAtEOL(comment)) {
-      emitComment(comment, previousToken);
-      comment = comment.next;
-      currentToken = comment != null ? comment : token;
-      // Ensure EOL comments force a linebreak
-      needsNewline = true;
-    }
-
-    var lines = 0;
-    if (needsNewline || preserveNewlines) {
-      lines = max(min, countNewlinesBetween(previousToken, currentToken));
-      preserveNewlines = false;
-    }
-
-    emitNewlines(lines);
-
-    previousToken =
-        currentToken.previous != null ? currentToken.previous : token.previous;
-
-    while (comment != null) {
-      emitComment(comment, previousToken);
-
-      var nextToken = comment.next != null ? comment.next : token;
-      var newlines = calculateNewlinesBetweenComments(comment, nextToken);
-      if (newlines > 0) {
-        emitNewlines(newlines);
-        lines += newlines;
-      } else {
-        var spaces = countSpacesBetween(comment, nextToken);
-        if (spaces > 0) {
-          space();
-        }
-      }
-
-      previousToken = comment;
-      comment = comment.next;
-    }
-
-    previousToken = token;
-    return lines;
-  }
-
-  void emitNewlines(lines) {
-    writer.newlines(lines);
-  }
-
-  ensureTrailingNewline() {
-    if (writer.lastToken is! NewlineToken) {
-      writer.newline();
-    }
-  }
-
-  /// Test if this EOL [comment] is at the beginning of a line.
-  bool isAtBOL(Token comment) =>
-      lineInfo.getLocation(comment.offset).columnNumber == 1;
-
-  /// Test if this [comment] is at the end of a line.
-  bool isAtEOL(Token comment) => comment != null &&
-      comment.toString().trim().startsWith(twoSlashes) &&
-      sameLine(comment, previousToken);
-
-  /// Emit this [comment], inserting leading whitespace if appropriate.
-  emitComment(Token comment, Token previousToken) {
-    if (!writer.currentLine.isWhitespace() && previousToken != null) {
-      var ws = countSpacesBetween(previousToken, comment);
-      // Preserve one space but no more
-      if (ws > 0 && leadingSpaces == 0) {
-        space();
-      }
-    }
-
-    // Don't indent commented-out lines
-    if (isAtBOL(comment)) {
-      writer.currentLine.clear();
-    }
-
-    append(comment.toString().trim());
-  }
-
-  /// Count spaces between these tokens.  Tokens on different lines return 0.
-  int countSpacesBetween(Token last, Token current) => isEOF(last) ||
-      countNewlinesBetween(last, current) > 0 ? 0 : current.offset - last.end;
-
-  /// Count the blanks between these two nodes.
-  int countBlankLinesBetween(AstNode lastNode, AstNode currentNode) =>
-      countNewlinesBetween(lastNode.endToken, currentNode.beginToken);
-
-  /// Count newlines preceeding this [node].
-  int countPrecedingNewlines(AstNode node) =>
-      countNewlinesBetween(node.beginToken.previous, node.beginToken);
-
-  /// Count newlines succeeding this [node].
-  int countSucceedingNewlines(AstNode node) => node == null
-      ? 0
-      : countNewlinesBetween(node.endToken, node.endToken.next);
-
-  /// Count the blanks between these two tokens.
-  int countNewlinesBetween(Token last, Token current) {
-    if (last == null || current == null || isSynthetic(last)) {
-      return 0;
-    }
-
-    return linesBetween(last.end - 1, current.offset);
-  }
-
-  /// Calculate the newlines that should separate these comments.
-  int calculateNewlinesBetweenComments(Token last, Token current) {
-    // Insist on a newline after doc comments or single line comments
-    // (NOTE that EOL comments have already been processed).
-    if (isOldSingleLineDocComment(last) || isSingleLineComment(last)) {
-      return max(1, countNewlinesBetween(last, current));
-    } else {
-      return countNewlinesBetween(last, current);
-    }
-  }
-
-  /// Single line multi-line comments (e.g., '/** like this */').
-  bool isOldSingleLineDocComment(Token comment) =>
-      comment.lexeme.startsWith(r'/**') && singleLine(comment);
-
-  /// Test if this [token] spans just one line.
-  bool singleLine(Token token) => linesBetween(token.offset, token.end) < 1;
-
-  /// Test if token [first] is on the same line as [second].
-  bool sameLine(Token first, Token second) =>
-      countNewlinesBetween(first, second) == 0;
-
-  /// Test if this is a multi-line [comment] (e.g., '/* ...' or '/** ...')
-  bool isMultiLineComment(Token comment) =>
-      comment.type == TokenType.MULTI_LINE_COMMENT;
-
-  /// Test if this is a single-line [comment] (e.g., '// ...')
-  bool isSingleLineComment(Token comment) =>
-      comment.type == TokenType.SINGLE_LINE_COMMENT;
-
-  /// Test if this [comment] is a block comment (e.g., '/* like this */')..
-  bool isBlock(Token comment) =>
-      isMultiLineComment(comment) && singleLine(comment);
-
-  /// Count the lines between two offsets.
-  int linesBetween(int lastOffset, int currentOffset) {
-    var lastLine = lineInfo.getLocation(lastOffset).lineNumber;
-    var currentLine = lineInfo.getLocation(currentOffset).lineNumber;
-    return currentLine - lastLine;
-  }
-
-  String toString() => writer.toString();
-}
diff --git a/pkg/analyzer/lib/src/services/writer.dart b/pkg/analyzer/lib/src/services/writer.dart
deleted file mode 100644
index 4bf182e..0000000
--- a/pkg/analyzer/lib/src/services/writer.dart
+++ /dev/null
@@ -1,498 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library source_writer;
-
-import 'dart:math' as math;
-
-class Line {
-  final List<LineToken> tokens = <LineToken>[];
-  final bool useTabs;
-  final int spacesPerIndent;
-  final int indentLevel;
-  final LinePrinter printer;
-
-  Line({this.indentLevel: 0, this.useTabs: false, this.spacesPerIndent: 2,
-      this.printer: const SimpleLinePrinter()}) {
-    if (indentLevel > 0) {
-      indent(indentLevel);
-    }
-  }
-
-  void addSpace() {
-    addSpaces(1);
-  }
-
-  void addSpaces(int n, {breakWeight: DEFAULT_SPACE_WEIGHT}) {
-    tokens.add(new SpaceToken(n, breakWeight: breakWeight));
-  }
-
-  void addToken(LineToken token) {
-    tokens.add(token);
-  }
-
-  void clear() {
-    tokens.clear();
-  }
-
-  bool isEmpty() => tokens.isEmpty;
-
-  bool isWhitespace() =>
-      tokens.every((tok) => tok is SpaceToken || tok is TabToken);
-
-  void indent(int n) {
-    tokens.insert(
-        0, useTabs ? new TabToken(n) : new SpaceToken(n * spacesPerIndent));
-  }
-
-  String toString() => printer.printLine(this);
-}
-
-/// Base class for line printers
-abstract class LinePrinter {
-  const LinePrinter();
-
-  /// Convert this [line] to a [String] representation.
-  String printLine(Line line);
-}
-
-typedef String Indenter(int n);
-
-/// A simple line breaking [LinePrinter]
-class SimpleLineBreaker extends LinePrinter {
-  static final NO_OP_INDENTER = (n) => '';
-
-  final chunks = <Chunk>[];
-  final int maxLength;
-  Indenter indenter;
-
-  SimpleLineBreaker(this.maxLength, [this.indenter]) {
-    if (indenter == null) {
-      indenter = NO_OP_INDENTER;
-    }
-  }
-
-  String printLine(Line line) {
-    var buf = new StringBuffer();
-    var chunks = breakLine(line);
-    for (var i = 0; i < chunks.length; ++i) {
-      var chunk = chunks[i];
-      if (i > 0) {
-        buf.write(indent(chunk, chunk.indent));
-      } else {
-        buf.write(chunk);
-      }
-    }
-    return buf.toString();
-  }
-
-  String indent(Chunk chunk, int level) {
-    return '\n' + indenter(level) + chunk.toString();
-  }
-
-  List<Chunk> breakLine(Line line) {
-    List<LineToken> tokens = preprocess(line.tokens);
-    List<Chunk> chunks = <Chunk>[
-      new Chunk(line.indentLevel, maxLength, tokens)
-    ];
-    // try SINGLE_SPACE_WEIGHT
-    {
-      Chunk chunk = chunks[0];
-      if (chunk.length > maxLength) {
-        for (int i = 0; i < tokens.length; i++) {
-          LineToken token = tokens[i];
-          if (token is SpaceToken && token.breakWeight == SINGLE_SPACE_WEIGHT) {
-            var beforeChunk = chunk.subChunk(chunk.indent, 0, i);
-            var restChunk = chunk.subChunk(chunk.indent + 2, i + 1);
-            // check if 'init' in 'var v = init;' fits a line
-            if (restChunk.length < maxLength) {
-              return [beforeChunk, restChunk];
-            }
-            // check if 'var v = method(' in 'var v = method(args)' does not fit
-            int weight = chunk.findMinSpaceWeight();
-            if (chunk.getLengthToSpaceWithWeight(weight) > maxLength) {
-              chunks = [beforeChunk, restChunk];
-            }
-            // done anyway
-            break;
-          }
-        }
-      }
-    }
-    // other spaces
-    while (true) {
-      List<Chunk> newChunks = <Chunk>[];
-      bool hasChanges = false;
-      for (Chunk chunk in chunks) {
-        tokens = chunk.tokens;
-        if (chunk.length > maxLength) {
-          if (chunk.hasAnySpace()) {
-            int weight = chunk.findMinSpaceWeight();
-            int newIndent = chunk.indent;
-            if (weight == DEFAULT_SPACE_WEIGHT) {
-              int start = 0;
-              int length = 0;
-              for (int i = 0; i < tokens.length; i++) {
-                LineToken token = tokens[i];
-                if (token is SpaceToken &&
-                    token.breakWeight == weight &&
-                    i < tokens.length - 1) {
-                  LineToken nextToken = tokens[i + 1];
-                  if (length + token.length + nextToken.length > maxLength) {
-                    newChunks.add(chunk.subChunk(newIndent, start, i));
-                    newIndent = chunk.indent + 2;
-                    start = i + 1;
-                    length = 0;
-                    continue;
-                  }
-                }
-                length += token.length;
-              }
-              if (start < tokens.length) {
-                newChunks.add(chunk.subChunk(newIndent, start));
-              }
-            } else {
-              int start = 0;
-              for (int i = 0; i < tokens.length; i++) {
-                LineToken token = tokens[i];
-                if (token is SpaceToken && token.breakWeight == weight) {
-                  newChunks.add(chunk.subChunk(newIndent, start, i));
-                  newIndent = chunk.indent + 2;
-                  start = i + 1;
-                }
-              }
-              if (start < tokens.length) {
-                newChunks.add(chunk.subChunk(newIndent, start));
-              }
-            }
-          } else {
-            newChunks.add(chunk);
-          }
-        } else {
-          newChunks.add(chunk);
-        }
-        if (newChunks.length > chunks.length) {
-          hasChanges = true;
-        }
-      }
-      if (!hasChanges) {
-        break;
-      }
-      chunks = newChunks;
-    }
-    return chunks;
-  }
-
-  static List<LineToken> preprocess(List<LineToken> tok) {
-    var tokens = <LineToken>[];
-    var curr;
-
-    tok.forEach((token) {
-      if (token is! SpaceToken) {
-        if (curr == null) {
-          curr = token;
-        } else {
-          curr = merge(curr, token);
-        }
-      } else {
-        if (isNonbreaking(token)) {
-          curr = merge(curr, token);
-        } else {
-          if (curr != null) {
-            tokens.add(curr);
-            curr = null;
-          }
-          tokens.add(token);
-        }
-      }
-    });
-
-    if (curr != null) {
-      tokens.add(curr);
-    }
-
-    return tokens;
-  }
-
-  static bool isNonbreaking(SpaceToken token) =>
-      token.breakWeight == UNBREAKABLE_SPACE_WEIGHT;
-
-  static LineToken merge(LineToken first, LineToken second) =>
-      new LineToken(first.value + second.value);
-}
-
-/// Test if this [string] contains only whitespace characters
-bool isWhitespace(String string) => string.codeUnits
-    .every((c) => c == 0x09 || c == 0x20 || c == 0x0A || c == 0x0D);
-
-/// Special token indicating a line start
-final LINE_START = new SpaceToken(0);
-
-const DEFAULT_SPACE_WEIGHT = UNBREAKABLE_SPACE_WEIGHT - 1;
-/// The weight of a space after '=' in variable declaration or assignment
-const SINGLE_SPACE_WEIGHT = UNBREAKABLE_SPACE_WEIGHT - 2;
-const UNBREAKABLE_SPACE_WEIGHT = 100000000;
-
-/// Simple non-breaking printer
-class SimpleLinePrinter extends LinePrinter {
-  const SimpleLinePrinter();
-
-  String printLine(Line line) {
-    var buffer = new StringBuffer();
-    line.tokens.forEach((tok) => buffer.write(tok.toString()));
-    return buffer.toString();
-  }
-}
-
-/// Describes a piece of text in a [Line].
-abstract class LineText {
-  int get length;
-}
-
-/// A working piece of text used in calculating line breaks
-class Chunk {
-  final int indent;
-  final int maxLength;
-  final List<LineToken> tokens = <LineToken>[];
-
-  Chunk(this.indent, this.maxLength, [List<LineToken> tokens]) {
-    this.tokens.addAll(tokens);
-  }
-
-  int get length {
-    return tokens.fold(0, (len, token) => len + token.length);
-  }
-
-  int getLengthToSpaceWithWeight(int weight) {
-    int length = 0;
-    for (LineToken token in tokens) {
-      if (token is SpaceToken && token.breakWeight == weight) {
-        break;
-      }
-      length += token.length;
-    }
-    return length;
-  }
-
-  bool fits(LineToken a, LineToken b) {
-    return length + a.length + a.length <= maxLength;
-  }
-
-  void add(LineToken token) {
-    tokens.add(token);
-  }
-
-  bool hasInitializerSpace() {
-    return tokens.any((token) {
-      return token is SpaceToken && token.breakWeight == SINGLE_SPACE_WEIGHT;
-    });
-  }
-
-  bool hasAnySpace() {
-    return tokens.any((token) => token is SpaceToken);
-  }
-
-  int findMinSpaceWeight() {
-    int minWeight = UNBREAKABLE_SPACE_WEIGHT;
-    for (var token in tokens) {
-      if (token is SpaceToken) {
-        minWeight = math.min(minWeight, token.breakWeight);
-      }
-    }
-    return minWeight;
-  }
-
-  Chunk subChunk(int indentLevel, int start, [int end]) {
-    List<LineToken> subTokens = tokens.sublist(start, end);
-    return new Chunk(indentLevel, maxLength, subTokens);
-  }
-
-  String toString() => tokens.join();
-}
-
-class LineToken implements LineText {
-  final String value;
-
-  LineToken(this.value);
-
-  String toString() => value;
-
-  int get length => lengthLessNewlines(value);
-
-  int lengthLessNewlines(String str) =>
-      str.endsWith('\n') ? str.length - 1 : str.length;
-}
-
-class SpaceToken extends LineToken {
-  final int breakWeight;
-
-  SpaceToken(int n, {this.breakWeight: DEFAULT_SPACE_WEIGHT})
-      : super(getSpaces(n));
-}
-
-class TabToken extends LineToken {
-  TabToken(int n) : super(getTabs(n));
-}
-
-class NewlineToken extends LineToken {
-  NewlineToken(String value) : super(value);
-}
-
-class SourceWriter {
-  final StringBuffer buffer = new StringBuffer();
-  Line currentLine;
-
-  final String lineSeparator;
-  int indentCount = 0;
-  final int spacesPerIndent;
-  final bool useTabs;
-
-  LinePrinter linePrinter;
-  LineToken _lastToken;
-
-  SourceWriter({this.indentCount: 0, this.lineSeparator: NEW_LINE,
-      this.useTabs: false, this.spacesPerIndent: 2, int maxLineLength: 80}) {
-    if (maxLineLength > 0) {
-      linePrinter = new SimpleLineBreaker(maxLineLength, (n) => getIndentString(
-          n, useTabs: useTabs, spacesPerIndent: spacesPerIndent));
-    } else {
-      linePrinter = new SimpleLinePrinter();
-    }
-    currentLine = newLine();
-  }
-
-  LineToken get lastToken => _lastToken;
-
-  _addToken(LineToken token) {
-    _lastToken = token;
-    currentLine.addToken(token);
-  }
-
-  void indent() {
-    ++indentCount;
-    // Rather than fiddle with deletions/insertions just start fresh
-    if (currentLine.isWhitespace()) {
-      currentLine = newLine();
-    }
-  }
-
-  void newline() {
-    if (currentLine.isWhitespace()) {
-      currentLine.tokens.clear();
-    }
-    _addToken(new NewlineToken(this.lineSeparator));
-    buffer.write(currentLine.toString());
-    currentLine = newLine();
-  }
-
-  void newlines(int num) {
-    while (num-- > 0) {
-      newline();
-    }
-  }
-
-  void write(String string) {
-    var lines = string.split(lineSeparator);
-    var length = lines.length;
-    for (int i = 0; i < length; i++) {
-      var line = lines[i];
-      _addToken(new LineToken(line));
-      if (i != length - 1) {
-        newline();
-        // no indentation for multi-line strings
-        currentLine.clear();
-      }
-    }
-  }
-
-  void writeln(String s) {
-    write(s);
-    newline();
-  }
-
-  void space() {
-    spaces(1);
-  }
-
-  void spaces(n, {breakWeight: DEFAULT_SPACE_WEIGHT}) {
-    currentLine.addSpaces(n, breakWeight: breakWeight);
-  }
-
-  void unindent() {
-    --indentCount;
-    // Rather than fiddle with deletions/insertions just start fresh
-    if (currentLine.isWhitespace()) {
-      currentLine = newLine();
-    }
-  }
-
-  Line newLine() => new Line(
-      indentLevel: indentCount,
-      useTabs: useTabs,
-      spacesPerIndent: spacesPerIndent,
-      printer: linePrinter);
-
-  String toString() {
-    var source = new StringBuffer(buffer.toString());
-    if (!currentLine.isWhitespace()) {
-      source.write(currentLine);
-    }
-    return source.toString();
-  }
-}
-
-const NEW_LINE = '\n';
-const SPACE = ' ';
-const SPACES = const [
-  '',
-  ' ',
-  '  ',
-  '   ',
-  '    ',
-  '     ',
-  '      ',
-  '       ',
-  '        ',
-  '         ',
-  '          ',
-  '           ',
-  '            ',
-  '             ',
-  '              ',
-  '               ',
-  '                ',
-];
-const TABS = const [
-  '',
-  '\t',
-  '\t\t',
-  '\t\t\t',
-  '\t\t\t\t',
-  '\t\t\t\t\t',
-  '\t\t\t\t\t\t',
-  '\t\t\t\t\t\t\t',
-  '\t\t\t\t\t\t\t\t',
-  '\t\t\t\t\t\t\t\t\t',
-  '\t\t\t\t\t\t\t\t\t\t',
-  '\t\t\t\t\t\t\t\t\t\t\t',
-  '\t\t\t\t\t\t\t\t\t\t\t\t',
-  '\t\t\t\t\t\t\t\t\t\t\t\t\t',
-  '\t\t\t\t\t\t\t\t\t\t\t\t\t\t',
-];
-
-String getIndentString(int indentWidth,
-        {bool useTabs: false, int spacesPerIndent: 2}) =>
-    useTabs ? getTabs(indentWidth) : getSpaces(indentWidth * spacesPerIndent);
-
-String getSpaces(int n) => n < SPACES.length ? SPACES[n] : repeat(' ', n);
-
-String getTabs(int n) => n < TABS.length ? TABS[n] : repeat('\t', n);
-
-String repeat(String ch, int times) {
-  var sb = new StringBuffer();
-  for (var i = 0; i < times; ++i) {
-    sb.write(ch);
-  }
-  return sb.toString();
-}
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 5fd3c1d..59b9efe 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -5,6 +5,7 @@
 library analyzer.src.task.dart;
 
 import 'dart:collection';
+import 'dart:math' as math;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
@@ -14,13 +15,427 @@
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/general.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
 
 /**
+ * The errors produced while resolving a library directives.
+ *
+ * The list will be empty if there were no errors, but will not be `null`.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<List<AnalysisError>> BUILD_DIRECTIVES_ERRORS =
+    new ResultDescriptor<List<AnalysisError>>(
+        'BUILD_DIRECTIVES_ERRORS', AnalysisError.NO_ERRORS,
+        contributesTo: DART_ERRORS);
+
+/**
+ * The errors produced while building function type aliases.
+ *
+ * The list will be empty if there were no errors, but will not be `null`.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<List<AnalysisError>> BUILD_FUNCTION_TYPE_ALIASES_ERRORS =
+    new ResultDescriptor<List<AnalysisError>>(
+        'BUILD_FUNCTION_TYPE_ALIASES_ERRORS', AnalysisError.NO_ERRORS,
+        contributesTo: DART_ERRORS);
+
+/**
+ * The errors produced while building a library element.
+ *
+ * The list will be empty if there were no errors, but will not be `null`.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<List<AnalysisError>> BUILD_LIBRARY_ERRORS =
+    new ResultDescriptor<List<AnalysisError>>(
+        'BUILD_LIBRARY_ERRORS', AnalysisError.NO_ERRORS,
+        contributesTo: DART_ERRORS);
+
+/**
+ * The [ClassElement]s of a [LibraryUnitTarget].
+ */
+final ListResultDescriptor<ClassElement> CLASS_ELEMENTS =
+    new ListResultDescriptor<ClassElement>('CLASS_ELEMENTS', null);
+
+/**
+ * The [ConstructorElement]s of a [ClassElement].
+ */
+final ResultDescriptor<List<ConstructorElement>> CONSTRUCTORS =
+    new ResultDescriptor<List<ConstructorElement>>('CONSTRUCTORS', null);
+
+/**
+ * The errors produced while building a [ClassElement] constructors.
+ *
+ * The list will be empty if there were no errors, but will not be `null`.
+ *
+ * The result is only available for targets representing a [ClassElement].
+ */
+final ResultDescriptor<List<AnalysisError>> CONSTRUCTORS_ERRORS =
+    new ResultDescriptor<List<AnalysisError>>(
+        'CONSTRUCTORS_ERRORS', AnalysisError.NO_ERRORS);
+
+/**
+ * The sources representing the export closure of a library.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ListResultDescriptor<Source> EXPORT_SOURCE_CLOSURE =
+    new ListResultDescriptor<Source>('EXPORT_SOURCE_CLOSURE', null);
+
+/**
+ * The partial [LibraryElement] associated with a library.
+ *
+ * The [LibraryElement] and its [CompilationUnitElement]s are attached to each
+ * other. Directives 'library', 'part' and 'part of' are resolved.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT1 =
+    new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT1', null);
+
+/**
+ * The partial [LibraryElement] associated with a library.
+ *
+ * In addition to [LIBRARY_ELEMENT1] [LibraryElement.imports] and
+ * [LibraryElement.exports] are set.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT2 =
+    new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT2', null);
+
+/**
+ * The partial [LibraryElement] associated with a library.
+ *
+ * In addition to [LIBRARY_ELEMENT2] the [LibraryElement.publicNamespace] is set.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT3 =
+    new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT3', null);
+
+/**
+ * The partial [LibraryElement] associated with a library.
+ *
+ * In addition to [LIBRARY_ELEMENT3] the [LibraryElement.entryPoint] is set,
+ * if the library does not declare one already and one of the exported
+ * libraries exports one.
+ *
+ * Also [LibraryElement.exportNamespace] is set.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT4 =
+    new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT4', null);
+
+/**
+ * The partial [LibraryElement] associated with a library.
+ *
+ * [LIBRARY_ELEMENT4] plus [RESOLVED_UNIT4] for every unit.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT5 =
+    new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT5', null);
+
+/**
+ * The partial [LibraryElement] associated with a library.
+ *
+ * Implicit constructors are built for every [ClassElement] requiring them.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<LibraryElement> LIBRARY_ELEMENT6 =
+    new ResultDescriptor<LibraryElement>('LIBRARY_ELEMENT6', null);
+
+/**
+ * The errors produced while resolving type names.
+ *
+ * The list will be empty if there were no errors, but will not be `null`.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<List<AnalysisError>> RESOLVE_TYPE_NAMES_ERRORS =
+    new ResultDescriptor<List<AnalysisError>>(
+        'RESOLVE_TYPE_NAMES_ERRORS', AnalysisError.NO_ERRORS,
+        contributesTo: DART_ERRORS);
+
+/**
+ * The partially resolved [CompilationUnit] associated with a unit.
+ *
+ * All declarations bound to the element defined by the declaration.
+ *
+ * The result is only available for targets representing a unit.
+ */
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT1 =
+    new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT1', null);
+
+/**
+ * The partially resolved [CompilationUnit] associated with a unit.
+ *
+ * All the enum member elements are built.
+ *
+ * The result is only available for targets representing a unit.
+ */
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT2 =
+    new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT2', null);
+
+/**
+ * The partially resolved [CompilationUnit] associated with a unit.
+ *
+ * All the function type aliases are resolved.
+ *
+ * The result is only available for targets representing a unit.
+ */
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT3 =
+    new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT3', null);
+
+/**
+ * The partially resolved [CompilationUnit] associated with a unit.
+ *
+ * [RESOLVED_UNIT3] with resolved type names.
+ *
+ * The result is only available for targets representing a unit.
+ */
+final ResultDescriptor<CompilationUnit> RESOLVED_UNIT4 =
+    new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT4', null);
+
+/**
+ * The [TypeProvider] of the context.
+ */
+final ResultDescriptor<TypeProvider> TYPE_PROVIDER =
+    new ResultDescriptor<TypeProvider>('TYPE_PROVIDER', null);
+
+/**
+ * A task that builds implicit constructors for a [ClassElement], or keeps
+ * the existing explicit constructors if the class has them.
+ */
+class BuildClassConstructorsTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [CONSTRUCTORS] input for the superclass.
+   */
+  static const String SUPER_CONSTRUCTORS = 'SUPER_CONSTRUCTORS';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'BuildConstructorsForClassTask', createTask, buildInputs,
+      <ResultDescriptor>[CONSTRUCTORS, CONSTRUCTORS_ERRORS]);
+
+  BuildClassConstructorsTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    List<AnalysisError> errors = <AnalysisError>[];
+    //
+    // Prepare inputs.
+    //
+    ClassElementImpl classElement = this.target;
+    List<ConstructorElement> superConstructors = inputs[SUPER_CONSTRUCTORS];
+    DartType superType = classElement.supertype;
+    ClassElement superElement = superType.element;
+    //
+    // Shortcut for ClassElement(s) without implicit constructors.
+    //
+    if (superConstructors == null) {
+      outputs[CONSTRUCTORS] = classElement.constructors;
+      outputs[CONSTRUCTORS_ERRORS] = AnalysisError.NO_ERRORS;
+      return;
+    }
+    //
+    // ClassTypeAlias
+    //
+    if (classElement.isTypedef) {
+      List<ConstructorElement> implicitConstructors =
+          new List<ConstructorElement>();
+      void callback(ConstructorElement explicitConstructor,
+          List<DartType> parameterTypes, List<DartType> argumentTypes) {
+        implicitConstructors.add(_createImplicitContructor(classElement.type,
+            explicitConstructor, parameterTypes, argumentTypes));
+      }
+      if (_findForwardedConstructors(classElement, superType, callback)) {
+        if (implicitConstructors.isEmpty) {
+          errors.add(new AnalysisError.con2(classElement.source,
+              classElement.nameOffset, classElement.name.length,
+              CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
+              [superElement.name]));
+        } else {
+          classElement.constructors = implicitConstructors;
+        }
+      }
+      outputs[CONSTRUCTORS] = classElement.constructors;
+      outputs[CONSTRUCTORS_ERRORS] = errors;
+    }
+    //
+    // ClassDeclaration
+    //
+    if (!classElement.isTypedef) {
+      bool constructorFound = false;
+      void callback(ConstructorElement explicitConstructor,
+          List<DartType> parameterTypes, List<DartType> argumentTypes) {
+        constructorFound = true;
+      }
+      if (_findForwardedConstructors(classElement, superType, callback) &&
+          !constructorFound) {
+        SourceRange withRange = classElement.withClauseRange;
+        errors.add(new AnalysisError.con2(classElement.source, withRange.offset,
+            withRange.length, CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
+            [superElement.name]));
+        classElement.mixinErrorsReported = true;
+      }
+      outputs[CONSTRUCTORS] = classElement.constructors;
+      outputs[CONSTRUCTORS_ERRORS] = errors;
+    }
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [classElement].
+   */
+  static Map<String, TaskInput> buildInputs(ClassElement classElement) {
+    // TODO(scheglov) Here we implicitly depend on LIBRARY_ELEMENT5, i.e. that
+    // "supertype" for the "classElement" is set.
+    // We need to make it an explicit dependency.
+    DartType superType = classElement.supertype;
+    if (superType is InterfaceType) {
+      if (classElement.isTypedef || classElement.mixins.isNotEmpty) {
+        ClassElement superElement = superType.element;
+        return <String, TaskInput>{
+          SUPER_CONSTRUCTORS: CONSTRUCTORS.of(superElement)
+        };
+      }
+    }
+    // No implicit constructors, no inputs required.
+    return <String, TaskInput>{};
+  }
+
+  /**
+   * Create a [BuildClassConstructorsTask] based on the given
+   * [target] in the given [context].
+   */
+  static BuildClassConstructorsTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new BuildClassConstructorsTask(context, target);
+  }
+
+  /**
+   * Create an implicit constructor that is copied from the given
+   * [explicitConstructor], but that is in the given class.
+   *
+   * [classType] - the class in which the implicit constructor is defined.
+   * [explicitConstructor] - the constructor on which the implicit constructor
+   *    is modeled.
+   * [parameterTypes] - the types to be replaced when creating parameters.
+   * [argumentTypes] - the types with which the parameters are to be replaced.
+   */
+  static ConstructorElement _createImplicitContructor(InterfaceType classType,
+      ConstructorElement explicitConstructor, List<DartType> parameterTypes,
+      List<DartType> argumentTypes) {
+    ConstructorElementImpl implicitConstructor =
+        new ConstructorElementImpl(explicitConstructor.name, -1);
+    implicitConstructor.synthetic = true;
+    implicitConstructor.redirectedConstructor = explicitConstructor;
+    implicitConstructor.const2 = explicitConstructor.isConst;
+    implicitConstructor.returnType = classType;
+    List<ParameterElement> explicitParameters = explicitConstructor.parameters;
+    int count = explicitParameters.length;
+    if (count > 0) {
+      List<ParameterElement> implicitParameters =
+          new List<ParameterElement>(count);
+      for (int i = 0; i < count; i++) {
+        ParameterElement explicitParameter = explicitParameters[i];
+        ParameterElementImpl implicitParameter =
+            new ParameterElementImpl(explicitParameter.name, -1);
+        implicitParameter.const3 = explicitParameter.isConst;
+        implicitParameter.final2 = explicitParameter.isFinal;
+        implicitParameter.parameterKind = explicitParameter.parameterKind;
+        implicitParameter.synthetic = true;
+        implicitParameter.type =
+            explicitParameter.type.substitute2(argumentTypes, parameterTypes);
+        implicitParameters[i] = implicitParameter;
+      }
+      implicitConstructor.parameters = implicitParameters;
+    }
+    FunctionTypeImpl type = new FunctionTypeImpl.con1(implicitConstructor);
+    type.typeArguments = classType.typeArguments;
+    implicitConstructor.type = type;
+    return implicitConstructor;
+  }
+
+  /**
+   * Find all the constructors that should be forwarded from the given
+   * [superType], to the class or mixin application [classElement],
+   * and pass information about them to [callback].
+   *
+   * Return true if some constructors were considered.  (A false return value
+   * can only happen if the supeclass is a built-in type, in which case it
+   * can't be used as a mixin anyway).
+   */
+  static bool _findForwardedConstructors(ClassElementImpl classElement,
+      InterfaceType superType, void callback(
+          ConstructorElement explicitConstructor, List<DartType> parameterTypes,
+          List<DartType> argumentTypes)) {
+    ClassElement superclassElement = superType.element;
+    List<ConstructorElement> constructors = superclassElement.constructors;
+    int count = constructors.length;
+    if (count == 0) {
+      return false;
+    }
+    List<DartType> parameterTypes =
+        TypeParameterTypeImpl.getTypes(superType.typeParameters);
+    List<DartType> argumentTypes = _getArgumentTypes(superType, parameterTypes);
+    for (int i = 0; i < count; i++) {
+      ConstructorElement explicitConstructor = constructors[i];
+      if (!explicitConstructor.isFactory &&
+          classElement.isSuperConstructorAccessible(explicitConstructor)) {
+        callback(explicitConstructor, parameterTypes, argumentTypes);
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Return a list of argument types that corresponds to the [parameterTypes]
+   * and that are derived from the type arguments of the given [superType].
+   */
+  static List<DartType> _getArgumentTypes(
+      InterfaceType superType, List<DartType> parameterTypes) {
+    DynamicTypeImpl dynamic = DynamicTypeImpl.instance;
+    int parameterCount = parameterTypes.length;
+    List<DartType> types = new List<DartType>(parameterCount);
+    if (superType == null) {
+      types = new List<DartType>.filled(parameterCount, dynamic);
+    } else {
+      List<DartType> typeArguments = superType.typeArguments;
+      int argumentCount = math.min(typeArguments.length, parameterCount);
+      for (int i = 0; i < argumentCount; i++) {
+        types[i] = typeArguments[i];
+      }
+      for (int i = argumentCount; i < parameterCount; i++) {
+        types[i] = dynamic;
+      }
+    }
+    return types;
+  }
+}
+
+/**
  * A task that builds a compilation unit element for a single compilation unit.
  */
 class BuildCompilationUnitElementTask extends SourceBasedAnalysisTask {
@@ -28,19 +443,23 @@
    * The name of the input whose value is the line information for the
    * compilation unit.
    */
-  static const String LINE_INFO_INPUT_NAME = "lineInfo";
+  static const String LINE_INFO_INPUT_NAME = 'LINE_INFO_INPUT_NAME';
 
   /**
    * The name of the input whose value is the AST for the compilation unit.
    */
-  static const String PARSED_UNIT_INPUT_NAME = "parsedUnit";
+  static const String PARSED_UNIT_INPUT_NAME = 'PARSED_UNIT_INPUT_NAME';
 
   /**
    * The task descriptor describing this kind of task.
    */
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'BUILD_COMPILATION_UNIT_ELEMENT', createTask, buildInputs,
-      <ResultDescriptor>[COMPILATION_UNIT_ELEMENT, BUILT_UNIT]);
+      'BuildCompilationUnitElementTask', createTask, buildInputs,
+      <ResultDescriptor>[
+    CLASS_ELEMENTS,
+    COMPILATION_UNIT_ELEMENT,
+    RESOLVED_UNIT1
+  ]);
 
   /**
    * Initialize a newly created task to build a compilation unit element for
@@ -55,23 +474,33 @@
 
   @override
   void internalPerform() {
+    //
+    // Prepare inputs.
+    //
     Source source = getRequiredSource();
     CompilationUnit unit = getRequiredInput(PARSED_UNIT_INPUT_NAME);
-
+    //
+    // Process inputs.
+    //
+    unit = AstCloner.clone(unit);
     CompilationUnitBuilder builder = new CompilationUnitBuilder();
     CompilationUnitElement element = builder.buildCompilationUnit(source, unit);
-
+    //
+    // Record outputs.
+    //
+    outputs[CLASS_ELEMENTS] = element.types;
     outputs[COMPILATION_UNIT_ELEMENT] = element;
-    outputs[BUILT_UNIT] = unit;
+    outputs[RESOLVED_UNIT1] = unit;
   }
 
   /**
    * Return a map from the names of the inputs of this kind of task to the task
-   * input descriptors describing those inputs for a task with the given [target].
+   * input descriptors describing those inputs for a task with the given
+   * [target].
    */
-  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+  static Map<String, TaskInput> buildInputs(LibraryUnitTarget target) {
     return <String, TaskInput>{
-      PARSED_UNIT_INPUT_NAME: PARSED_UNIT.inputFor(target)
+      PARSED_UNIT_INPUT_NAME: PARSED_UNIT.of(target.unit)
     };
   }
 
@@ -86,6 +515,1102 @@
 }
 
 /**
+ * A task that builds imports and export directive elements for a library.
+ */
+class BuildDirectiveElementsTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the input for [RESOLVED_UNIT1] of a library unit.
+   */
+  static const String UNIT_INPUT_NAME = 'UNIT_INPUT_NAME';
+
+  /**
+   * The input with a list of [LIBRARY_ELEMENT3]s of imported libraries.
+   */
+  static const String IMPORTS_LIBRARY_ELEMENT_INPUT_NAME =
+      'IMPORTS_LIBRARY_ELEMENT1_INPUT_NAME';
+
+  /**
+   * The input with a list of [LIBRARY_ELEMENT3]s of exported libraries.
+   */
+  static const String EXPORTS_LIBRARY_ELEMENT_INPUT_NAME =
+      'EXPORTS_LIBRARY_ELEMENT_INPUT_NAME';
+
+  /**
+   * The input with a list of [SOURCE_KIND]s of imported libraries.
+   */
+  static const String IMPORTS_SOURCE_KIND_INPUT_NAME =
+      'IMPORTS_SOURCE_KIND_INPUT_NAME';
+
+  /**
+   * The input with a list of [SOURCE_KIND]s of exported libraries.
+   */
+  static const String EXPORTS_SOURCE_KIND_INPUT_NAME =
+      'EXPORTS_SOURCE_KIND_INPUT_NAME';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'BuildDirectiveElementsTask', createTask, buildInputs, <ResultDescriptor>[
+    LIBRARY_ELEMENT2,
+    BUILD_DIRECTIVES_ERRORS
+  ]);
+
+  BuildDirectiveElementsTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    List<AnalysisError> errors = <AnalysisError>[];
+    //
+    // Prepare inputs.
+    //
+    CompilationUnit libraryUnit = getRequiredInput(UNIT_INPUT_NAME);
+    Map<Source, LibraryElement> importLibraryMap =
+        getRequiredInput(IMPORTS_LIBRARY_ELEMENT_INPUT_NAME);
+    Map<Source, LibraryElement> exportLibraryMap =
+        getRequiredInput(EXPORTS_LIBRARY_ELEMENT_INPUT_NAME);
+    Map<Source, SourceKind> importSourceKindMap =
+        getRequiredInput(IMPORTS_SOURCE_KIND_INPUT_NAME);
+    Map<Source, SourceKind> exportSourceKindMap =
+        getRequiredInput(EXPORTS_SOURCE_KIND_INPUT_NAME);
+    //
+    // Process inputs.
+    //
+    LibraryElementImpl libraryElement = libraryUnit.element.library;
+    Source librarySource = libraryElement.source;
+    //
+    // Resolve directives.
+    //
+    HashMap<String, PrefixElementImpl> nameToPrefixMap =
+        new HashMap<String, PrefixElementImpl>();
+    List<ImportElement> imports = <ImportElement>[];
+    List<ExportElement> exports = <ExportElement>[];
+    bool explicitlyImportsCore = false;
+    for (Directive directive in libraryUnit.directives) {
+      if (directive is ImportDirective) {
+        ImportDirective importDirective = directive;
+        String uriContent = importDirective.uriContent;
+        if (DartUriResolver.isDartExtUri(uriContent)) {
+          libraryElement.hasExtUri = true;
+        }
+        Source importedSource = importDirective.source;
+        if (importedSource != null && context.exists(importedSource)) {
+          // The imported source will be null if the URI in the import
+          // directive was invalid.
+          LibraryElement importedLibrary = importLibraryMap[importedSource];
+          if (importedLibrary != null) {
+            ImportElementImpl importElement =
+                new ImportElementImpl(directive.offset);
+            StringLiteral uriLiteral = importDirective.uri;
+            if (uriLiteral != null) {
+              importElement.uriOffset = uriLiteral.offset;
+              importElement.uriEnd = uriLiteral.end;
+            }
+            importElement.uri = uriContent;
+            importElement.deferred = importDirective.deferredKeyword != null;
+            importElement.combinators = _buildCombinators(importDirective);
+            importElement.importedLibrary = importedLibrary;
+            SimpleIdentifier prefixNode = directive.prefix;
+            if (prefixNode != null) {
+              importElement.prefixOffset = prefixNode.offset;
+              String prefixName = prefixNode.name;
+              PrefixElementImpl prefix = nameToPrefixMap[prefixName];
+              if (prefix == null) {
+                prefix = new PrefixElementImpl.forNode(prefixNode);
+                nameToPrefixMap[prefixName] = prefix;
+              }
+              importElement.prefix = prefix;
+              prefixNode.staticElement = prefix;
+            }
+            directive.element = importElement;
+            imports.add(importElement);
+            if (importSourceKindMap[importedSource] != SourceKind.LIBRARY) {
+              ErrorCode errorCode = (importElement.isDeferred
+                  ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
+                  : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
+              errors.add(new AnalysisError.con2(importedSource,
+                  uriLiteral.offset, uriLiteral.length, errorCode,
+                  [uriLiteral.toSource()]));
+            }
+          }
+        }
+      } else if (directive is ExportDirective) {
+        ExportDirective exportDirective = directive;
+        Source exportedSource = exportDirective.source;
+        if (exportedSource != null && context.exists(exportedSource)) {
+          // The exported source will be null if the URI in the export
+          // directive was invalid.
+          LibraryElement exportedLibrary = exportLibraryMap[exportedSource];
+          if (exportedLibrary != null) {
+            ExportElementImpl exportElement =
+                new ExportElementImpl(directive.offset);
+            StringLiteral uriLiteral = exportDirective.uri;
+            if (uriLiteral != null) {
+              exportElement.uriOffset = uriLiteral.offset;
+              exportElement.uriEnd = uriLiteral.end;
+            }
+            exportElement.uri = exportDirective.uriContent;
+            exportElement.combinators = _buildCombinators(exportDirective);
+            exportElement.exportedLibrary = exportedLibrary;
+            directive.element = exportElement;
+            exports.add(exportElement);
+            if (exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) {
+              errors.add(new AnalysisError.con2(exportedSource,
+                  uriLiteral.offset, uriLiteral.length,
+                  CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
+                  [uriLiteral.toSource()]));
+            }
+          }
+        }
+      }
+    }
+    //
+    // Ensure "dart:core" import.
+    //
+    Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
+    if (!explicitlyImportsCore && coreLibrarySource != librarySource) {
+      ImportElementImpl importElement = new ImportElementImpl(-1);
+      importElement.importedLibrary = importLibraryMap[coreLibrarySource];
+      importElement.synthetic = true;
+      imports.add(importElement);
+    }
+    //
+    // Populate the library element.
+    //
+    libraryElement.imports = imports;
+    libraryElement.exports = exports;
+    //
+    // Record outputs.
+    //
+    outputs[LIBRARY_ELEMENT2] = libraryElement;
+    outputs[BUILD_DIRECTIVES_ERRORS] = errors;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given library [libSource].
+   */
+  static Map<String, TaskInput> buildInputs(Source libSource) {
+    return <String, TaskInput>{
+      'defining_LIBRARY_ELEMENT1': LIBRARY_ELEMENT1.of(libSource),
+      UNIT_INPUT_NAME:
+          RESOLVED_UNIT1.of(new LibraryUnitTarget(libSource, libSource)),
+      IMPORTS_LIBRARY_ELEMENT_INPUT_NAME:
+          IMPORTED_LIBRARIES.of(libSource).toMapOf(LIBRARY_ELEMENT1),
+      EXPORTS_LIBRARY_ELEMENT_INPUT_NAME:
+          EXPORTED_LIBRARIES.of(libSource).toMapOf(LIBRARY_ELEMENT1),
+      IMPORTS_SOURCE_KIND_INPUT_NAME:
+          IMPORTED_LIBRARIES.of(libSource).toMapOf(SOURCE_KIND),
+      EXPORTS_SOURCE_KIND_INPUT_NAME:
+          EXPORTED_LIBRARIES.of(libSource).toMapOf(SOURCE_KIND)
+    };
+  }
+
+  /**
+   * Create a [BuildDirectiveElementsTask] based on the given [target] in
+   * the given [context].
+   */
+  static BuildDirectiveElementsTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new BuildDirectiveElementsTask(context, target);
+  }
+
+  /**
+   * Build the element model representing the combinators declared by
+   * the given [directive].
+   */
+  static List<NamespaceCombinator> _buildCombinators(
+      NamespaceDirective directive) {
+    List<NamespaceCombinator> combinators = <NamespaceCombinator>[];
+    for (Combinator combinator in directive.combinators) {
+      if (combinator is ShowCombinator) {
+        ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
+        show.offset = combinator.offset;
+        show.end = combinator.end;
+        show.shownNames = _getIdentifiers(combinator.shownNames);
+        combinators.add(show);
+      } else if (combinator is HideCombinator) {
+        HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
+        hide.hiddenNames = _getIdentifiers(combinator.hiddenNames);
+        combinators.add(hide);
+      }
+    }
+    return combinators;
+  }
+
+  /**
+   * Return the lexical identifiers associated with the given [identifiers].
+   */
+  static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) {
+    return identifiers.map((identifier) => identifier.name).toList();
+  }
+}
+
+/**
+ * A task that builds the elements representing the members of enum
+ * declarations.
+ */
+class BuildEnumMemberElementsTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [TYPE_PROVIDER] input.
+   */
+  static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
+
+  /**
+   * The name of the [RESOLVED_UNIT1] input.
+   */
+  static const String UNIT_INPUT = 'UNIT_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'BuildEnumMemberElementsTask', createTask, buildInputs,
+      <ResultDescriptor>[RESOLVED_UNIT2]);
+
+  BuildEnumMemberElementsTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    //
+    // Prepare inputs.
+    //
+    TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
+    CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+    //
+    // Record outputs.
+    //
+    EnumMemberBuilder builder = new EnumMemberBuilder(typeProvider);
+    unit.accept(builder);
+    outputs[RESOLVED_UNIT2] = unit;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [target].
+   */
+  static Map<String, TaskInput> buildInputs(LibraryUnitTarget target) {
+    return <String, TaskInput>{
+      TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
+      UNIT_INPUT: RESOLVED_UNIT1.of(target)
+    };
+  }
+
+  /**
+   * Create a [BuildEnumMemberElementsTask] based on the given [target] in
+   * the given [context].
+   */
+  static BuildEnumMemberElementsTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new BuildEnumMemberElementsTask(context, target);
+  }
+}
+
+/**
+ * A task that builds [EXPORT_NAMESPACE] and [LIBRARY_ELEMENT4] for a library.
+ */
+class BuildExportNamespaceTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the input for [LIBRARY_ELEMENT3] of a library.
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'BuildExportNamespaceTask', createTask, buildInputs,
+      <ResultDescriptor>[LIBRARY_ELEMENT4]);
+
+  BuildExportNamespaceTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    LibraryElementImpl library = getRequiredInput(LIBRARY_INPUT);
+    //
+    // Compute export namespace.
+    //
+    ExportNamespaceBuilder builder = new ExportNamespaceBuilder();
+    Namespace namespace = builder.build(library);
+    library.exportNamespace = namespace;
+    //
+    // Update entry point.
+    //
+    if (library.entryPoint == null) {
+      Iterable<Element> exportedElements = namespace.definedNames.values;
+      library.entryPoint = exportedElements.firstWhere(
+          (element) => element is FunctionElement && element.isEntryPoint,
+          orElse: () => null);
+    }
+    //
+    // Record outputs.
+    //
+    outputs[LIBRARY_ELEMENT4] = library;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given library [libSource].
+   */
+  static Map<String, TaskInput> buildInputs(Source libSource) {
+    return <String, TaskInput>{
+      LIBRARY_INPUT: LIBRARY_ELEMENT3.of(libSource),
+      'exportsLibraryPublicNamespace':
+          EXPORT_SOURCE_CLOSURE.of(libSource).toMapOf(LIBRARY_ELEMENT3)
+    };
+  }
+
+  /**
+   * Create a [BuildExportNamespaceTask] based on the given [target] in
+   * the given [context].
+   */
+  static BuildExportNamespaceTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new BuildExportNamespaceTask(context, target);
+  }
+}
+
+/**
+ * A task that builds [EXPORT_SOURCE_CLOSURE] of a library.
+ */
+class BuildExportSourceClosureTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the input for [LIBRARY_ELEMENT3] of a library.
+   */
+  static const String LIBRARY2_ELEMENT_INPUT = 'LIBRARY2_ELEMENT_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'BuildExportSourceClosureTask', createTask, buildInputs,
+      <ResultDescriptor>[EXPORT_SOURCE_CLOSURE]);
+
+  BuildExportSourceClosureTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    LibraryElement library = getRequiredInput(LIBRARY2_ELEMENT_INPUT);
+    //
+    // Compute export closure.
+    //
+    Set<LibraryElement> libraries = new Set<LibraryElement>();
+    _buildExportClosure(libraries, library);
+    List<Source> sources = libraries.map((lib) => lib.source).toList();
+    //
+    // Record outputs.
+    //
+    outputs[EXPORT_SOURCE_CLOSURE] = sources;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given library [libSource].
+   */
+  static Map<String, TaskInput> buildInputs(Source libSource) {
+    return <String, TaskInput>{
+      LIBRARY2_ELEMENT_INPUT: LIBRARY_ELEMENT2.of(libSource)
+    };
+  }
+
+  /**
+   * Create a [BuildExportSourceClosureTask] based on the given [target] in
+   * the given [context].
+   */
+  static BuildExportSourceClosureTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new BuildExportSourceClosureTask(context, target);
+  }
+
+  /**
+   * Create a set representing the export closure of the given [library].
+   */
+  static void _buildExportClosure(
+      Set<LibraryElement> libraries, LibraryElement library) {
+    if (library != null && libraries.add(library)) {
+      for (ExportElement exportElement in library.exports) {
+        _buildExportClosure(libraries, exportElement.exportedLibrary);
+      }
+    }
+  }
+}
+
+/**
+ * A task that builds [RESOLVED_UNIT3] for a unit.
+ */
+class BuildFunctionTypeAliasesTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [TYPE_PROVIDER] input.
+   */
+  static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
+
+  /**
+   * The name of the [LIBRARY_ELEMENT4] input.
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The name of the [RESOLVED_UNIT2] input.
+   */
+  static const String UNIT_INPUT = 'UNIT_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'BuildFunctionTypeAliasesTask', createTask, buildInputs,
+      <ResultDescriptor>[BUILD_FUNCTION_TYPE_ALIASES_ERRORS, RESOLVED_UNIT3]);
+
+  BuildFunctionTypeAliasesTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    RecordingErrorListener errorListener = new RecordingErrorListener();
+    //
+    // Prepare inputs.
+    //
+    Source source = getRequiredSource();
+    TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
+    CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+    LibraryElement libraryElement = getRequiredInput(LIBRARY_INPUT);
+    //
+    // Resolve FunctionTypeAlias declarations.
+    //
+    TypeResolverVisitor visitor = new TypeResolverVisitor.con2(
+        libraryElement, source, typeProvider, errorListener);
+    for (CompilationUnitMember member in unit.declarations) {
+      if (member is FunctionTypeAlias) {
+        member.accept(visitor);
+      }
+    }
+    //
+    // Record outputs.
+    //
+    outputs[BUILD_FUNCTION_TYPE_ALIASES_ERRORS] = errorListener.errors;
+    outputs[RESOLVED_UNIT3] = unit;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [target].
+   */
+  static Map<String, TaskInput> buildInputs(LibraryUnitTarget target) {
+    return <String, TaskInput>{
+      TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
+      'importsExportNamespace':
+          IMPORTED_LIBRARIES.of(target.library).toMapOf(LIBRARY_ELEMENT4),
+      LIBRARY_INPUT: LIBRARY_ELEMENT4.of(target.library),
+      UNIT_INPUT: RESOLVED_UNIT2.of(target)
+    };
+  }
+
+  /**
+   * Create a [BuildFunctionTypeAliasesTask] based on the given [target] in
+   * the given [context].
+   */
+  static BuildFunctionTypeAliasesTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new BuildFunctionTypeAliasesTask(context, target);
+  }
+}
+
+/**
+ * An artifitial task that does nothing except to force building constructors
+ * for for the defining and part units of a library.
+ */
+class BuildLibraryConstructorsTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [LIBRARY_ELEMENT5] input.
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'BuildLibraryConstructorsTask', createTask, buildInputs,
+      <ResultDescriptor>[LIBRARY_ELEMENT6]);
+
+  BuildLibraryConstructorsTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+    outputs[LIBRARY_ELEMENT6] = library;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [target].
+   */
+  static Map<String, TaskInput> buildInputs(Source libSource) {
+    return <String, TaskInput>{
+      LIBRARY_INPUT: LIBRARY_ELEMENT5.of(libSource),
+      'resolvedConstructors':
+          CLASS_ELEMENTS.of(libSource).toListOf(CONSTRUCTORS),
+    };
+  }
+
+  /**
+   * Create a [BuildLibraryConstructorsTask] based on the given [target] in
+   * the given [context].
+   */
+  static BuildLibraryConstructorsTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new BuildLibraryConstructorsTask(context, target);
+  }
+}
+
+/**
+ * A task that builds a library element for a Dart library.
+ */
+class BuildLibraryElementTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the input whose value is the defining [RESOLVED_UNIT1].
+   */
+  static const String DEFINING_UNIT_INPUT = 'DEFINING_UNIT_INPUT';
+
+  /**
+   * The name of the input whose value is a list of built [RESOLVED_UNIT1]s
+   * of the parts sourced by a library.
+   */
+  static const String PARTS_UNIT_INPUT = 'PARTS_UNIT_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'BuildLibraryElementTask', createTask, buildInputs, <ResultDescriptor>[
+    BUILD_LIBRARY_ERRORS,
+    CLASS_ELEMENTS,
+    LIBRARY_ELEMENT1,
+    IS_LAUNCHABLE,
+    HAS_HTML_IMPORT
+  ]);
+
+  /**
+   * The constant used as an unknown common library name in parts.
+   */
+  static const String _UNKNOWN_LIBRARY_NAME = 'unknown-library-name';
+
+  /**
+   * Initialize a newly created task to build a library element for the given
+   * [target] in the given [context].
+   */
+  BuildLibraryElementTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    List<AnalysisError> errors = <AnalysisError>[];
+    //
+    // Prepare inputs.
+    //
+    Source librarySource = getRequiredSource();
+    CompilationUnit definingCompilationUnit =
+        getRequiredInput(DEFINING_UNIT_INPUT);
+    List<CompilationUnit> partUnits = getRequiredInput(PARTS_UNIT_INPUT);
+    //
+    // Process inputs.
+    //
+    CompilationUnitElementImpl definingCompilationUnitElement =
+        definingCompilationUnit.element;
+    Map<Source, CompilationUnit> partUnitMap =
+        new HashMap<Source, CompilationUnit>();
+    for (CompilationUnit partUnit in partUnits) {
+      Source partSource = partUnit.element.source;
+      partUnitMap[partSource] = partUnit;
+    }
+    Source htmlSource = context.sourceFactory.forUri(DartSdk.DART_HTML);
+    //
+    // Update "part" directives.
+    //
+    LibraryIdentifier libraryNameNode = null;
+    String partsLibraryName = _UNKNOWN_LIBRARY_NAME;
+    bool hasHtmlImport = false;
+    bool hasPartDirective = false;
+    FunctionElement entryPoint =
+        _findEntryPoint(definingCompilationUnitElement);
+    List<Directive> directivesToResolve = <Directive>[];
+    List<CompilationUnitElementImpl> sourcedCompilationUnits =
+        <CompilationUnitElementImpl>[];
+    for (Directive directive in definingCompilationUnit.directives) {
+      if (directive is ImportDirective) {
+        hasHtmlImport = hasHtmlImport || directive.source == htmlSource;
+      } else if (directive is LibraryDirective) {
+        if (libraryNameNode == null) {
+          libraryNameNode = directive.name;
+          directivesToResolve.add(directive);
+        }
+      } else if (directive is PartDirective) {
+        PartDirective partDirective = directive;
+        StringLiteral partUri = partDirective.uri;
+        Source partSource = partDirective.source;
+        if (context.exists(partSource)) {
+          hasPartDirective = true;
+          CompilationUnit partUnit = partUnitMap[partSource];
+          CompilationUnitElementImpl partElement = partUnit.element;
+          partElement.uriOffset = partUri.offset;
+          partElement.uriEnd = partUri.end;
+          partElement.uri = partDirective.uriContent;
+          //
+          // Validate that the part contains a part-of directive with the same
+          // name as the library.
+          //
+          String partLibraryName =
+              _getPartLibraryName(partSource, partUnit, directivesToResolve);
+          if (partLibraryName == null) {
+            errors.add(new AnalysisError.con2(librarySource, partUri.offset,
+                partUri.length, CompileTimeErrorCode.PART_OF_NON_PART,
+                [partUri.toSource()]));
+          } else if (libraryNameNode == null) {
+            if (partsLibraryName == _UNKNOWN_LIBRARY_NAME) {
+              partsLibraryName = partLibraryName;
+            } else if (partsLibraryName != partLibraryName) {
+              partsLibraryName = null;
+            }
+          } else if (libraryNameNode.name != partLibraryName) {
+            errors.add(new AnalysisError.con2(librarySource, partUri.offset,
+                partUri.length, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [
+              libraryNameNode.name,
+              partLibraryName
+            ]));
+          }
+          if (entryPoint == null) {
+            entryPoint = _findEntryPoint(partElement);
+          }
+          directive.element = partElement;
+          sourcedCompilationUnits.add(partElement);
+        }
+      }
+    }
+    if (hasPartDirective && libraryNameNode == null) {
+      AnalysisError error;
+      if (partsLibraryName != _UNKNOWN_LIBRARY_NAME &&
+          partsLibraryName != null) {
+        error = new AnalysisErrorWithProperties.con1(librarySource,
+            ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART)
+          ..setProperty(ErrorProperty.PARTS_LIBRARY_NAME, partsLibraryName);
+      } else {
+        error = new AnalysisError.con1(librarySource,
+            ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART);
+      }
+      errors.add(error);
+    }
+    //
+    // Create and populate the library element.
+    //
+    LibraryElementImpl libraryElement =
+        new LibraryElementImpl.forNode(context, libraryNameNode);
+    libraryElement.definingCompilationUnit = definingCompilationUnitElement;
+    libraryElement.entryPoint = entryPoint;
+    libraryElement.parts = sourcedCompilationUnits;
+    for (Directive directive in directivesToResolve) {
+      directive.element = libraryElement;
+    }
+    if (sourcedCompilationUnits.isNotEmpty) {
+      _patchTopLevelAccessors(libraryElement);
+    }
+    //
+    // Prepare all class elements.
+    //
+    List<ClassElement> classElements = libraryElement.units
+        .map((CompilationUnitElement unitElement) => unitElement.types)
+        .expand((List<ClassElement> unitClassElements) => unitClassElements)
+        .toList();
+    //
+    // Record outputs.
+    //
+    outputs[BUILD_LIBRARY_ERRORS] = errors;
+    outputs[CLASS_ELEMENTS] = classElements;
+    outputs[LIBRARY_ELEMENT1] = libraryElement;
+    outputs[IS_LAUNCHABLE] = entryPoint != null;
+    outputs[HAS_HTML_IMPORT] = hasHtmlImport;
+  }
+
+  /**
+   * Add all of the non-synthetic [getters] and [setters] defined in the given
+   * [unit] that have no corresponding accessor to one of the given collections.
+   */
+  void _collectAccessors(Map<String, PropertyAccessorElement> getters,
+      List<PropertyAccessorElement> setters, CompilationUnitElement unit) {
+    for (PropertyAccessorElement accessor in unit.accessors) {
+      if (accessor.isGetter) {
+        if (!accessor.isSynthetic && accessor.correspondingSetter == null) {
+          getters[accessor.displayName] = accessor;
+        }
+      } else {
+        if (!accessor.isSynthetic && accessor.correspondingGetter == null) {
+          setters.add(accessor);
+        }
+      }
+    }
+  }
+
+  /**
+   * Return the top-level [FunctionElement] entry point, or `null` if the given
+   * [element] does not define an entry point.
+   */
+  FunctionElement _findEntryPoint(CompilationUnitElementImpl element) {
+    for (FunctionElement function in element.functions) {
+      if (function.isEntryPoint) {
+        return function;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Return the name of the library that the given part is declared to be a
+   * part of, or `null` if the part does not contain a part-of directive.
+   */
+  String _getPartLibraryName(Source partSource, CompilationUnit partUnit,
+      List<Directive> directivesToResolve) {
+    for (Directive directive in partUnit.directives) {
+      if (directive is PartOfDirective) {
+        directivesToResolve.add(directive);
+        LibraryIdentifier libraryName = directive.libraryName;
+        if (libraryName != null) {
+          return libraryName.name;
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Look through all of the compilation units defined for the given [library],
+   * looking for getters and setters that are defined in different compilation
+   * units but that have the same names. If any are found, make sure that they
+   * have the same variable element.
+   */
+  void _patchTopLevelAccessors(LibraryElementImpl library) {
+    HashMap<String, PropertyAccessorElement> getters =
+        new HashMap<String, PropertyAccessorElement>();
+    List<PropertyAccessorElement> setters = <PropertyAccessorElement>[];
+    _collectAccessors(getters, setters, library.definingCompilationUnit);
+    for (CompilationUnitElement unit in library.parts) {
+      _collectAccessors(getters, setters, unit);
+    }
+    for (PropertyAccessorElementImpl setter in setters) {
+      PropertyAccessorElement getter = getters[setter.displayName];
+      if (getter != null) {
+        TopLevelVariableElementImpl variable = getter.variable;
+        TopLevelVariableElementImpl setterVariable = setter.variable;
+        CompilationUnitElementImpl setterUnit = setterVariable.enclosingElement;
+        setterUnit.replaceTopLevelVariable(setterVariable, variable);
+        variable.setter = setter;
+        setter.variable = variable;
+      }
+    }
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the given
+   * [libSource].
+   */
+  static Map<String, TaskInput> buildInputs(Source libSource) {
+    return <String, TaskInput>{
+      DEFINING_UNIT_INPUT:
+          RESOLVED_UNIT1.of(new LibraryUnitTarget(libSource, libSource)),
+      PARTS_UNIT_INPUT: INCLUDED_PARTS.of(libSource).toList((Source unit) {
+        LibraryUnitTarget lut = new LibraryUnitTarget(libSource, unit);
+        return RESOLVED_UNIT1.of(lut);
+      })
+    };
+  }
+
+  /**
+   * Create a [BuildLibraryElementTask] based on the given [target] in the
+   * given [context].
+   */
+  static BuildLibraryElementTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new BuildLibraryElementTask(context, target);
+  }
+}
+
+/**
+ * A task that builds [PUBLIC_NAMESPACE] for a library.
+ */
+class BuildPublicNamespaceTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the input for [LIBRARY_ELEMENT2] of a library.
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'BuildPublicNamespaceTask', createTask, buildInputs,
+      <ResultDescriptor>[LIBRARY_ELEMENT3]);
+
+  BuildPublicNamespaceTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    LibraryElementImpl library = getRequiredInput(LIBRARY_INPUT);
+    library.publicNamespace = new PublicNamespaceBuilder().build(library);
+    outputs[LIBRARY_ELEMENT3] = library;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given library [libSource].
+   */
+  static Map<String, TaskInput> buildInputs(Source libSource) {
+    return <String, TaskInput>{LIBRARY_INPUT: LIBRARY_ELEMENT2.of(libSource)};
+  }
+
+  /**
+   * Create a [BuildPublicNamespaceTask] based on the given [target] in
+   * the given [context].
+   */
+  static BuildPublicNamespaceTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new BuildPublicNamespaceTask(context, target);
+  }
+}
+
+/**
+ * A task that builds [TYPE_PROVIDER] for a context.
+ */
+class BuildTypeProviderTask extends SourceBasedAnalysisTask {
+  /**
+   * The [PUBLIC_NAMESPACE] input of the `dart:core` library.
+   */
+  static const String CORE_INPUT = 'CORE_INPUT';
+
+  /**
+   * The [PUBLIC_NAMESPACE] input of the `dart:async` library.
+   */
+  static const String ASYNC_INPUT = 'ASYNC_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'BuildTypeProviderTask', createTask, buildInputs,
+      <ResultDescriptor>[TYPE_PROVIDER]);
+
+  BuildTypeProviderTask(
+      InternalAnalysisContext context, AnalysisContextTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    LibraryElement coreLibrary = getRequiredInput(CORE_INPUT);
+    LibraryElement asyncLibrary = getRequiredInput(ASYNC_INPUT);
+    Namespace coreNamespace = coreLibrary.publicNamespace;
+    Namespace asyncNamespace = asyncLibrary.publicNamespace;
+    //
+    // Record outputs.
+    //
+    TypeProvider typeProvider =
+        new TypeProviderImpl.forNamespaces(coreNamespace, asyncNamespace);
+    (context as ExtendedAnalysisContext).typeProvider = typeProvider;
+    outputs[TYPE_PROVIDER] = typeProvider;
+  }
+
+  static Map<String, TaskInput> buildInputs(AnalysisContextTarget target) {
+    SourceFactory sourceFactory = target.context.sourceFactory;
+    Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
+    Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
+    return <String, TaskInput>{
+      CORE_INPUT: LIBRARY_ELEMENT3.of(coreSource),
+      ASYNC_INPUT: LIBRARY_ELEMENT3.of(asyncSource)
+    };
+  }
+
+  /**
+   * Create a [BuildTypeProviderTask] based on the given [context].
+   */
+  static BuildTypeProviderTask createTask(
+      AnalysisContext context, AnalysisContextTarget target) {
+    return new BuildTypeProviderTask(context, target);
+  }
+}
+
+/**
+ * The helper for building the export [Namespace] of a [LibraryElement].
+ */
+class ExportNamespaceBuilder {
+  /**
+   * Build the export [Namespace] of the given [LibraryElement].
+   */
+  Namespace build(LibraryElement library) {
+    return new Namespace(
+        _createExportMapping(library, new HashSet<LibraryElement>()));
+  }
+
+  /**
+   * Create a mapping table representing the export namespace of the given
+   * [library].
+   *
+   * The given [visitedElements] a set of libraries that do not need to be
+   * visited when processing the export directives of the given library because
+   * all of the names defined by them will be added by another library.
+   */
+  HashMap<String, Element> _createExportMapping(
+      LibraryElement library, HashSet<LibraryElement> visitedElements) {
+    visitedElements.add(library);
+    try {
+      HashMap<String, Element> definedNames = new HashMap<String, Element>();
+      // Add names of the export directives.
+      for (ExportElement element in library.exports) {
+        LibraryElement exportedLibrary = element.exportedLibrary;
+        if (exportedLibrary != null &&
+            !visitedElements.contains(exportedLibrary)) {
+          //
+          // The exported library will be null if the URI does not reference a
+          // valid library.
+          //
+          HashMap<String, Element> exportedNames =
+              _createExportMapping(exportedLibrary, visitedElements);
+          exportedNames = _applyCombinators(exportedNames, element.combinators);
+          definedNames.addAll(exportedNames);
+        }
+      }
+      // Add names of the public namespace.
+      {
+        Namespace publicNamespace = library.publicNamespace;
+        if (publicNamespace != null) {
+          definedNames.addAll(publicNamespace.definedNames);
+        }
+      }
+      return definedNames;
+    } finally {
+      visitedElements.remove(library);
+    }
+  }
+
+  /**
+   * Apply the given [combinators] to all of the names in [definedNames].
+   */
+  static HashMap<String, Element> _applyCombinators(
+      HashMap<String, Element> definedNames,
+      List<NamespaceCombinator> combinators) {
+    for (NamespaceCombinator combinator in combinators) {
+      if (combinator is HideElementCombinator) {
+        _hide(definedNames, combinator.hiddenNames);
+      } else if (combinator is ShowElementCombinator) {
+        definedNames = _show(definedNames, combinator.shownNames);
+      }
+    }
+    return definedNames;
+  }
+
+  /**
+   * Hide all of the [hiddenNames] by removing them from the given
+   * [definedNames].
+   */
+  static void _hide(
+      HashMap<String, Element> definedNames, List<String> hiddenNames) {
+    for (String name in hiddenNames) {
+      definedNames.remove(name);
+      definedNames.remove('$name=');
+    }
+  }
+
+  /**
+   * Show only the given [shownNames] by removing all other names from the given
+   * [definedNames].
+   */
+  static HashMap<String, Element> _show(
+      HashMap<String, Element> definedNames, List<String> shownNames) {
+    HashMap<String, Element> newNames = new HashMap<String, Element>();
+    for (String name in shownNames) {
+      Element element = definedNames[name];
+      if (element != null) {
+        newNames[name] = element;
+      }
+      String setterName = '$name=';
+      element = definedNames[setterName];
+      if (element != null) {
+        newNames[setterName] = element;
+      }
+    }
+    return newNames;
+  }
+}
+
+/**
+ * A pair of a library [Source] and a unit [Source] in this library.
+ */
+class LibraryUnitTarget implements AnalysisTarget {
+  final Source library;
+  final Source unit;
+
+  LibraryUnitTarget(this.library, this.unit);
+
+  @override
+  int get hashCode {
+    return JenkinsSmiHash.combine(library.hashCode, unit.hashCode);
+  }
+
+  @override
+  Source get source => unit;
+
+  @override
+  bool operator ==(other) {
+    return other is LibraryUnitTarget &&
+        other.library == library &&
+        other.unit == unit;
+  }
+}
+
+/**
  * A task that parses the content of a Dart file, producing an AST structure.
  */
 class ParseDartTask extends SourceBasedAnalysisTask {
@@ -93,24 +1618,25 @@
    * The name of the input whose value is the line information produced for the
    * file.
    */
-  static const String LINE_INFO_INPUT_NAME = "lineInfo";
+  static const String LINE_INFO_INPUT_NAME = 'LINE_INFO_INPUT_NAME';
 
   /**
    * The name of the input whose value is the token stream produced for the file.
    */
-  static const String TOKEN_STREAM_INPUT_NAME = "tokenStream";
+  static const String TOKEN_STREAM_INPUT_NAME = 'TOKEN_STREAM_INPUT_NAME';
 
   /**
    * The task descriptor describing this kind of task.
    */
-  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor('PARSE_DART',
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor('ParseDartTask',
       createTask, buildInputs, <ResultDescriptor>[
     EXPORTED_LIBRARIES,
     IMPORTED_LIBRARIES,
     INCLUDED_PARTS,
     PARSE_ERRORS,
     PARSED_UNIT,
-    SOURCE_KIND
+    SOURCE_KIND,
+    UNITS
   ]);
 
   /**
@@ -160,33 +1686,45 @@
               }
             } else {
               throw new AnalysisException(
-                  "$runtimeType failed to handle a ${directive.runtimeType}");
+                  '$runtimeType failed to handle a ${directive.runtimeType}');
             }
           }
         }
       }
     }
+    //
+    // Always include "dart:core" source.
+    //
+    Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
+    importedSources.add(coreLibrarySource);
+    //
+    // Compute kind.
+    //
     SourceKind sourceKind = SourceKind.LIBRARY;
     if (!hasNonPartOfDirective && hasPartOfDirective) {
       sourceKind = SourceKind.PART;
     }
-
+    //
+    // Record outputs.
+    //
     outputs[EXPORTED_LIBRARIES] = exportedSources.toList();
     outputs[IMPORTED_LIBRARIES] = importedSources.toList();
     outputs[INCLUDED_PARTS] = includedSources.toList();
     outputs[PARSE_ERRORS] = errorListener.getErrorsForSource(source);
     outputs[PARSED_UNIT] = unit;
     outputs[SOURCE_KIND] = sourceKind;
+    outputs[UNITS] = <Source>[source]..addAll(includedSources);
   }
 
   /**
    * Return a map from the names of the inputs of this kind of task to the task
-   * input descriptors describing those inputs for a task with the given [target].
+   * input descriptors describing those inputs for a task with the given
+   * [source].
    */
-  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+  static Map<String, TaskInput> buildInputs(Source source) {
     return <String, TaskInput>{
-      LINE_INFO_INPUT_NAME: LINE_INFO.inputFor(target),
-      TOKEN_STREAM_INPUT_NAME: TOKEN_STREAM.inputFor(target)
+      LINE_INFO_INPUT_NAME: LINE_INFO.of(source),
+      TOKEN_STREAM_INPUT_NAME: TOKEN_STREAM.of(source)
     };
   }
 
@@ -242,18 +1780,176 @@
 }
 
 /**
+ * The helper for building the public [Namespace] of a [LibraryElement].
+ */
+class PublicNamespaceBuilder {
+  final HashMap<String, Element> definedNames = new HashMap<String, Element>();
+
+  /**
+   * Build a public [Namespace] of the given [library].
+   */
+  Namespace build(LibraryElement library) {
+    definedNames.clear();
+    _addPublicNames(library.definingCompilationUnit);
+    library.parts.forEach(_addPublicNames);
+    return new Namespace(definedNames);
+  }
+
+  /**
+   * Add the given [element] if it has a publicly visible name.
+   */
+  void _addIfPublic(Element element) {
+    String name = element.name;
+    if (name != null && !Scope.isPrivateName(name)) {
+      definedNames[name] = element;
+    }
+  }
+
+  /**
+   * Add all of the public top-level names that are defined in the given
+   * [compilationUnit].
+   */
+  void _addPublicNames(CompilationUnitElement compilationUnit) {
+    compilationUnit.accessors.forEach(_addIfPublic);
+    compilationUnit.enums.forEach(_addIfPublic);
+    compilationUnit.functions.forEach(_addIfPublic);
+    compilationUnit.functionTypeAliases.forEach(_addIfPublic);
+    compilationUnit.types.forEach(_addIfPublic);
+  }
+}
+
+/**
+ * An artifitial task that does nothing except to force type names resolution
+ * for the defining and part units of a library.
+ */
+class ResolveLibraryTypeNamesTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [LIBRARY_ELEMENT4] input.
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'ResolveLibraryTypeNamesTask', createTask, buildInputs,
+      <ResultDescriptor>[LIBRARY_ELEMENT5]);
+
+  ResolveLibraryTypeNamesTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+    outputs[LIBRARY_ELEMENT5] = library;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [target].
+   */
+  static Map<String, TaskInput> buildInputs(Source libSource) {
+    return <String, TaskInput>{
+      LIBRARY_INPUT: LIBRARY_ELEMENT4.of(libSource),
+      'resolvedUnits': UNITS.of(libSource).toMap((Source source) =>
+          RESOLVED_UNIT4.of(new LibraryUnitTarget(libSource, source)))
+    };
+  }
+
+  /**
+   * Create a [ResolveLibraryTypeNamesTask] based on the given [target] in
+   * the given [context].
+   */
+  static ResolveLibraryTypeNamesTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new ResolveLibraryTypeNamesTask(context, target);
+  }
+}
+
+/**
+ * A task that builds [RESOLVED_UNIT4] for a unit.
+ */
+class ResolveUnitTypeNamesTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [RESOLVED_UNIT3] input.
+   */
+  static const String UNIT_INPUT = 'UNIT_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'ResolveUnitTypeNamesTask', createTask, buildInputs, <ResultDescriptor>[
+    RESOLVE_TYPE_NAMES_ERRORS,
+    RESOLVED_UNIT4
+  ]);
+
+  ResolveUnitTypeNamesTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    RecordingErrorListener errorListener = new RecordingErrorListener();
+    //
+    // Prepare inputs.
+    //
+    CompilationUnit unit = getRequiredInput(UNIT_INPUT);
+    CompilationUnitElement unitElement = unit.element;
+    //
+    // Resolve TypeName nodes.
+    //
+    TypeResolverVisitor visitor = new TypeResolverVisitor.con2(
+        unitElement.library, unitElement.source, context.typeProvider,
+        errorListener);
+    unit.accept(visitor);
+    //
+    // Record outputs.
+    //
+    outputs[RESOLVE_TYPE_NAMES_ERRORS] = errorListener.errors;
+    outputs[RESOLVED_UNIT4] = unit;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [target].
+   */
+  static Map<String, TaskInput> buildInputs(LibraryUnitTarget target) {
+    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT3.of(target)};
+  }
+
+  /**
+   * Create a [ResolveUnitTypeNamesTask] based on the given [target] in
+   * the given [context].
+   */
+  static ResolveUnitTypeNamesTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new ResolveUnitTypeNamesTask(context, target);
+  }
+}
+
+/**
  * A task that scans the content of a file, producing a set of Dart tokens.
  */
 class ScanDartTask extends SourceBasedAnalysisTask {
   /**
    * The name of the input whose value is the content of the file.
    */
-  static const String CONTENT_INPUT_NAME = "content";
+  static const String CONTENT_INPUT_NAME = 'CONTENT_INPUT_NAME';
 
   /**
    * The task descriptor describing this kind of task.
    */
-  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor('SCAN_DART',
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor('ScanDartTask',
       createTask, buildInputs, <ResultDescriptor>[
     LINE_INFO,
     SCAN_ERRORS,
@@ -286,10 +1982,11 @@
 
   /**
    * Return a map from the names of the inputs of this kind of task to the task
-   * input descriptors describing those inputs for a task with the given [target].
+   * input descriptors describing those inputs for a task with the given
+   * [source].
    */
-  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
-    return <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.inputFor(target)};
+  static Map<String, TaskInput> buildInputs(Source source) {
+    return <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)};
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index e5dbb9d4..88df107 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
 import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/task/inputs.dart';
 import 'package:analyzer/src/task/manager.dart';
 import 'package:analyzer/task/model.dart';
@@ -66,15 +67,17 @@
 
   /**
    * Perform work until the given [result] has been computed for the given
-   * [target].
+   * [target]. Return the last [AnalysisTask] that was performed.
    */
-  void computeResult(AnalysisTarget target, ResultDescriptor result) {
+  AnalysisTask computeResult(AnalysisTarget target, ResultDescriptor result) {
+    AnalysisTask task;
     WorkOrder workOrder = createWorkOrderForResult(target, result);
     if (workOrder != null) {
       while (workOrder.moveNext()) {
-        performWorkItem(workOrder.current);
+        task = performWorkItem(workOrder.current);
       }
     }
+    return task;
   }
 
   /**
@@ -185,17 +188,15 @@
 
   /**
    * Perform the given work item.
+   * Return the performed [AnalysisTask].
    */
-  void performWorkItem(WorkItem item) {
+  AnalysisTask performWorkItem(WorkItem item) {
     if (item.exception != null) {
       // Mark all of the results that the task would have computed as being in
       // ERROR with the exception recorded on the work item.
       CacheEntry targetEntry = context.getCacheEntry(item.target);
-      targetEntry.exception = item.exception;
-      for (ResultDescriptor result in item.descriptor.results) {
-        targetEntry.setState(result, CacheState.ERROR);
-      }
-      return;
+      targetEntry.setErrorState(item.exception, item.descriptor.results);
+      return null;
     }
     // Otherwise, perform the task.
     AnalysisTask task = item.buildTask();
@@ -210,12 +211,10 @@
         entry.setValue(result, outputs[result]);
       }
     } else {
-      entry.exception = task.caughtException;
-      for (ResultDescriptor result in task.descriptor.results) {
-        entry.setState(result, CacheState.ERROR);
-      }
+      entry.setErrorState(task.caughtException, item.descriptor.results);
     }
     _onTaskCompletedController.add(task);
+    return task;
   }
 
   /**
@@ -235,6 +234,7 @@
 abstract class ExtendedAnalysisContext implements InternalAnalysisContext {
   List<AnalysisTarget> get explicitTargets;
   List<AnalysisTarget> get priorityTargets;
+  void set typeProvider(TypeProvider typeProvider);
   CacheEntry getCacheEntry(AnalysisTarget target);
 }
 
@@ -283,8 +283,12 @@
    * described by the given descriptor.
    */
   WorkItem(this.context, this.target, this.descriptor) {
+    AnalysisTarget actualTarget = identical(
+            target, AnalysisContextTarget.request)
+        ? new AnalysisContextTarget(context)
+        : target;
     Map<String, TaskInput> inputDescriptors =
-        descriptor.createTaskInputs(target);
+        descriptor.createTaskInputs(actualTarget);
     builder = new TopLevelTaskInputBuilder(inputDescriptors);
     if (!builder.moveNext()) {
       builder = null;
diff --git a/pkg/analyzer/lib/src/task/general.dart b/pkg/analyzer/lib/src/task/general.dart
index 0905771..8e52537 100644
--- a/pkg/analyzer/lib/src/task/general.dart
+++ b/pkg/analyzer/lib/src/task/general.dart
@@ -24,7 +24,7 @@
    * Initialize a newly created task to access the content of the source
    * associated with the given [target] in the given [context].
    */
-  GetContentTask(InternalAnalysisContext context, AnalysisTarget target)
+  GetContentTask(AnalysisContext context, AnalysisTarget target)
       : super(context, target);
 
   @override
@@ -71,8 +71,7 @@
   @override
   String get description {
     Source source = target.source;
-    String sourceName =
-        target.source == null ? '<unknown source>' : source.fullName;
+    String sourceName = source == null ? '<unknown source>' : source.fullName;
     return '${descriptor.name} for source $sourceName';
   }
 }
diff --git a/pkg/analyzer/lib/src/task/inputs.dart b/pkg/analyzer/lib/src/task/inputs.dart
index bddcfc4..a7b67df 100644
--- a/pkg/analyzer/lib/src/task/inputs.dart
+++ b/pkg/analyzer/lib/src/task/inputs.dart
@@ -9,11 +9,48 @@
 import 'package:analyzer/task/model.dart';
 
 /**
- * A function that converts an arbitrary object into a [TaskInput]. This is
- * used, for example, by a [ListBasedTaskInput] to create task inputs for each
- * value in a list of values.
+ * A function that converts an object of the type [B] into a [TaskInput].
+ * This is used, for example, by a [ListToListTaskInput] to create task inputs
+ * for each value in a list of values.
  */
-typedef TaskInput<E> GenerateTaskInputs<E>(Object object);
+typedef TaskInput<E> GenerateTaskInputs<B, E>(B object);
+
+/**
+ * An input to an [AnalysisTask] that is computed by accessing a single result
+ * defined on a single target.
+ */
+class ListTaskInputImpl<E> extends SimpleTaskInput<List<E>>
+    with ListTaskInputMixin<E> implements ListTaskInput<E> {
+  /**
+   * Initialize a newly created task input that computes the input by accessing
+   * the given [result] associated with the given [target].
+   */
+  ListTaskInputImpl(AnalysisTarget target, ResultDescriptor<List<E>> result)
+      : super(target, result);
+}
+
+/**
+ * A mixin-ready implementation of [ListTaskInput].
+ */
+abstract class ListTaskInputMixin<E> implements ListTaskInput<E> {
+  ListTaskInput /*<V>*/ toList(UnaryFunction<E, dynamic /*<V>*/ > mapper) {
+    return new ListToListTaskInput<E, dynamic /*V*/ >(this, mapper);
+  }
+
+  ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult) {
+    return (this as ListTaskInputImpl<AnalysisTarget>).toList(valueResult.of);
+  }
+
+  TaskInput<Map<E, dynamic /*V*/ >> toMap(
+      UnaryFunction<E, dynamic /*<V>*/ > mapper) {
+    return new ListToMapTaskInput<E, dynamic /*V*/ >(this, mapper);
+  }
+
+  TaskInput<Map<AnalysisTarget, dynamic /*V*/ >> toMapOf(
+      ResultDescriptor /*<V>*/ valueResult) {
+    return (this as ListTaskInputImpl<AnalysisTarget>).toMap(valueResult.of);
+  }
+}
 
 /**
  * An input to an [AnalysisTask] that is computed by the following steps. First
@@ -22,134 +59,100 @@
  * input. Finally, each of the task inputs are used to access analysis results,
  * and the list of the analysis results is used as the input to the task.
  */
-class ListBasedTaskInput<B, E> implements TaskInput<List<E>> {
-  /**
-   * The accessor used to access the list of elements being mapped.
-   */
-  final TaskInput<B> baseAccessor;
-
-  /**
-   * The function used to convert an element in the list returned by the
-   * [baseAccessor] to a task input.
-   */
-  GenerateTaskInputs<E> generateTaskInputs;
-
+class ListToListTaskInput<B, E>
+    extends _ListToCollectionTaskInput<B, E, List<E>>
+    with ListTaskInputMixin<E> {
   /**
    * Initialize a result accessor to use the given [baseAccessor] to access a
-   * list of values that can be passed to the given [generateTaskInputs] to generate
-   * a list of task inputs that can be used to access the elements of the input
-   * being accessed.
+   * list of values that can be passed to the given [generateTaskInputs] to
+   * generate a list of task inputs that can be used to access the elements of
+   * the input being accessed.
    */
-  ListBasedTaskInput(this.baseAccessor, this.generateTaskInputs);
+  ListToListTaskInput(TaskInput<List<B>> baseAccessor,
+      GenerateTaskInputs<B, E> generateTaskInputs)
+      : super(baseAccessor, generateTaskInputs);
 
   @override
   TaskInputBuilder<List<E>> createBuilder() =>
-      new ListBasedTaskInputBuilder<B, E>(this);
+      new ListToListTaskInputBuilder<B, E>(this);
 }
 
 /**
- * A [TaskInputBuilder] used to build an input based on a [ListBasedTaskInput].
+ * A [TaskInputBuilder] used to build an input based on a [ListToListTaskInput].
  */
-class ListBasedTaskInputBuilder<B, E> implements TaskInputBuilder<List<E>> {
-  /**
-   * The input being built.
-   */
-  final ListBasedTaskInput<B, E> input;
-
-  /**
-   * The builder used to build the current result.
-   */
-  TaskInputBuilder currentBuilder;
-
-  /**
-   * The list of values computed by the [input]'s base accessor.
-   */
-  List _baseList = null;
-
-  /**
-   * The index in the [_baseList] of the value for which a value is currently
-   * being built.
-   */
-  int _baseListIndex = -1;
-
+class ListToListTaskInputBuilder<B, E>
+    extends _ListToCollectionTaskInputBuilder<B, E, List<E>> {
   /**
    * The list of values being built.
    */
-  List<E> _resultValue = null;
+  List<E> _resultValue;
 
   /**
    * Initialize a newly created task input builder that computes the result
    * specified by the given [input].
    */
-  ListBasedTaskInputBuilder(this.input);
+  ListToListTaskInputBuilder(ListToListTaskInput<B, E> input) : super(input);
 
   @override
-  ResultDescriptor get currentResult {
-    if (currentBuilder == null) {
-      return null;
-    }
-    return currentBuilder.currentResult;
+  void _addResultElement(B baseElement, E resultElement) {
+    _resultValue.add(resultElement);
   }
 
   @override
-  AnalysisTarget get currentTarget {
-    if (currentBuilder == null) {
-      return null;
-    }
-    return currentBuilder.currentTarget;
+  void _initResultValue() {
+    _resultValue = <E>[];
+  }
+}
+
+/**
+ * An input to an [AnalysisTask] that is computed by the following steps. First
+ * another (base) task input is used to compute a [List]-valued result. An input
+ * generator function is then used to map each element of that list to a task
+ * input. Finally, each of the task inputs are used to access analysis results,
+ * and the map of the base elements to the analysis results is used as the
+ * input to the task.
+ */
+class ListToMapTaskInput<B, E>
+    extends _ListToCollectionTaskInput<B, E, Map<B, E>> {
+  /**
+   * Initialize a result accessor to use the given [baseAccessor] to access a
+   * list of values that can be passed to the given [generateTaskInputs] to
+   * generate a list of task inputs that can be used to access the elements of
+   * the input being accessed.
+   */
+  ListToMapTaskInput(TaskInput<List<B>> baseAccessor,
+      GenerateTaskInputs<B, E> generateTaskInputs)
+      : super(baseAccessor, generateTaskInputs);
+
+  @override
+  TaskInputBuilder<Map<B, E>> createBuilder() =>
+      new ListToMapTaskInputBuilder<B, E>(this);
+}
+
+/**
+ * A [TaskInputBuilder] used to build an input based on a [ListToMapTaskInput].
+ */
+class ListToMapTaskInputBuilder<B, E>
+    extends _ListToCollectionTaskInputBuilder<B, E, Map<B, E>> {
+  /**
+   * The map being built.
+   */
+  Map<B, E> _resultValue;
+
+  /**
+   * Initialize a newly created task input builder that computes the result
+   * specified by the given [input].
+   */
+  ListToMapTaskInputBuilder(ListToMapTaskInput<B, E> input) : super(input);
+
+  @override
+  void _addResultElement(B baseElement, E resultElement) {
+    _resultValue[baseElement] = resultElement;
   }
 
   @override
-  void set currentValue(Object value) {
-    if (currentBuilder == null) {
-      throw new StateError(
-          'Cannot set the result value when there is no current result');
-    }
-    currentBuilder.currentValue = value;
-  }
-
-  @override
-  List<E> get inputValue {
-    if (currentBuilder != null || _resultValue == null) {
-      throw new StateError('Result value has not been created');
-    }
-    return _resultValue;
-  }
-
-  @override
-  bool moveNext() {
-    if (currentBuilder == null) {
-      if (_resultValue == null) {
-        // This is the first time moveNext has been invoked, so start by
-        // computing the list of values from which the results will be derived.
-        currentBuilder = input.baseAccessor.createBuilder();
-        return currentBuilder.moveNext();
-      } else {
-        // We have already computed all of the results, so just return false.
-        return false;
-      }
-    }
-    if (currentBuilder.moveNext()) {
-      return true;
-    }
-    if (_resultValue == null) {
-      // We have finished computing the list of values from which the results
-      // will be derived.
-      _baseList = currentBuilder.inputValue;
-      _baseListIndex = 0;
-      _resultValue = <E>[];
-    } else {
-      // We have finished computing one of the elements in the result list.
-      _resultValue.add(currentBuilder.inputValue);
-      _baseListIndex++;
-    }
-    if (_baseListIndex >= _baseList.length) {
-      currentBuilder = null;
-      return false;
-    }
-    currentBuilder =
-        input.generateTaskInputs(_baseList[_baseListIndex]).createBuilder();
-    return currentBuilder.moveNext();
+  void _initResultValue() {
+    _resultValue = new HashMap<B, E>();
   }
 }
 
@@ -377,3 +380,146 @@
     return currentBuilder.moveNext();
   }
 }
+
+/**
+ * An input to an [AnalysisTask] that is computed by the following steps. First
+ * another (base) task input is used to compute a [List]-valued result. An input
+ * generator function is then used to map each element of that list to a task
+ * input. Finally, each of the task inputs are used to access analysis results,
+ * and a collection of the analysis results is used as the input to the task.
+ */
+abstract class _ListToCollectionTaskInput<B, E, C> implements TaskInput<C> {
+  /**
+   * The accessor used to access the list of elements being mapped.
+   */
+  final TaskInput<List<B>> baseAccessor;
+
+  /**
+   * The function used to convert an element in the list returned by the
+   * [baseAccessor] to a task input.
+   */
+  final GenerateTaskInputs<B, E> generateTaskInputs;
+
+  /**
+   * Initialize a result accessor to use the given [baseAccessor] to access a
+   * list of values that can be passed to the given [generateTaskInputs] to
+   * generate a list of task inputs that can be used to access the elements of
+   * the input being accessed.
+   */
+  _ListToCollectionTaskInput(this.baseAccessor, this.generateTaskInputs);
+}
+
+/**
+ * A [TaskInputBuilder] used to build an [_ListToCollectionTaskInput].
+ */
+abstract class _ListToCollectionTaskInputBuilder<B, E, C>
+    implements TaskInputBuilder<C> {
+  /**
+   * The input being built.
+   */
+  final _ListToCollectionTaskInput<B, E, C> input;
+
+  /**
+   * The builder used to build the current result.
+   */
+  TaskInputBuilder currentBuilder;
+
+  /**
+   * The list of values computed by the [input]'s base accessor.
+   */
+  List<B> _baseList = null;
+
+  /**
+   * The index in the [_baseList] of the value for which a value is currently
+   * being built.
+   */
+  int _baseListIndex = -1;
+
+  /**
+   * The element of the [_baseList] for which a value is currently being built.
+   */
+  B _baseListElement;
+
+  /**
+   * Initialize a newly created task input builder that computes the result
+   * specified by the given [input].
+   */
+  _ListToCollectionTaskInputBuilder(this.input);
+
+  @override
+  ResultDescriptor get currentResult {
+    if (currentBuilder == null) {
+      return null;
+    }
+    return currentBuilder.currentResult;
+  }
+
+  @override
+  AnalysisTarget get currentTarget {
+    if (currentBuilder == null) {
+      return null;
+    }
+    return currentBuilder.currentTarget;
+  }
+
+  @override
+  void set currentValue(Object value) {
+    if (currentBuilder == null) {
+      throw new StateError(
+          'Cannot set the result value when there is no current result');
+    }
+    currentBuilder.currentValue = value;
+  }
+
+  @override
+  C get inputValue {
+    if (currentBuilder != null || _resultValue == null) {
+      throw new StateError('Result value has not been created');
+    }
+    return _resultValue;
+  }
+
+  /**
+   * The list of values being built.
+   */
+  C get _resultValue;
+
+  @override
+  bool moveNext() {
+    if (currentBuilder == null) {
+      if (_resultValue == null) {
+        // This is the first time moveNext has been invoked, so start by
+        // computing the list of values from which the results will be derived.
+        currentBuilder = input.baseAccessor.createBuilder();
+        return currentBuilder.moveNext();
+      } else {
+        // We have already computed all of the results, so just return false.
+        return false;
+      }
+    }
+    if (currentBuilder.moveNext()) {
+      return true;
+    }
+    if (_resultValue == null) {
+      // We have finished computing the list of values from which the results
+      // will be derived.
+      _baseList = currentBuilder.inputValue;
+      _baseListIndex = 0;
+      _initResultValue();
+    } else {
+      // We have finished computing one of the elements in the result list.
+      _addResultElement(_baseListElement, currentBuilder.inputValue);
+      _baseListIndex++;
+    }
+    if (_baseListIndex >= _baseList.length) {
+      currentBuilder = null;
+      return false;
+    }
+    _baseListElement = _baseList[_baseListIndex];
+    currentBuilder = input.generateTaskInputs(_baseListElement).createBuilder();
+    return currentBuilder.moveNext();
+  }
+
+  void _addResultElement(B baseElement, E resultElement);
+  void _initResultValue();
+}
diff --git a/pkg/analyzer/lib/src/task/model.dart b/pkg/analyzer/lib/src/task/model.dart
index 05a922b..66ffb9e 100644
--- a/pkg/analyzer/lib/src/task/model.dart
+++ b/pkg/analyzer/lib/src/task/model.dart
@@ -9,19 +9,19 @@
 import 'package:analyzer/task/model.dart';
 
 /**
- * A concrete implementation of a [ContributionPoint].
+ * A concrete implementation of a [CompositeResultDescriptor].
  */
-class ContributionPointImpl<V> extends ResultDescriptorImpl<V>
-    implements ContributionPoint<V> {
+class CompositeResultDescriptorImpl<V> extends ResultDescriptorImpl<V>
+    implements CompositeResultDescriptor<V> {
   /**
    * The results that contribute to this result.
    */
   final List<ResultDescriptor<V>> contributors = <ResultDescriptor<V>>[];
 
   /**
-   * Initialize a newly created contribution point to have the given [name].
+   * Initialize a newly created composite result to have the given [name].
    */
-  ContributionPointImpl(String name) : super(name, null);
+  CompositeResultDescriptorImpl(String name) : super(name, null);
 
   /**
    * Record that the given analysis [result] contibutes to this result.
@@ -32,6 +32,25 @@
 }
 
 /**
+ * A concrete implementation of a [ListResultDescriptor].
+ */
+class ListResultDescriptorImpl<E> extends ResultDescriptorImpl<List<E>>
+    implements ListResultDescriptor<E> {
+  /**
+   * Initialize a newly created analysis result to have the given [name] and
+   * [defaultValue]. If a composite result is specified, then this result will
+   * contribute to it.
+   */
+  ListResultDescriptorImpl(String name, List<E> defaultValue,
+      {CompositeResultDescriptor contributesTo})
+      : super(name, defaultValue, contributesTo: contributesTo);
+
+  @override
+  ListTaskInput<E> of(AnalysisTarget target) =>
+      new ListTaskInputImpl<E>(target, this);
+}
+
+/**
  * A concrete implementation of a [ResultDescriptor].
  */
 class ResultDescriptorImpl<V> implements ResultDescriptor<V> {
@@ -47,18 +66,18 @@
 
   /**
    * Initialize a newly created analysis result to have the given [name] and
-   * [defaultValue]. If a contribution point is specified, then this result will
+   * [defaultValue]. If a composite result is specified, then this result will
    * contribute to it.
    */
   ResultDescriptorImpl(this.name, this.defaultValue,
-      {ContributionPoint contributesTo}) {
-    if (contributesTo is ContributionPointImpl) {
+      {CompositeResultDescriptor contributesTo}) {
+    if (contributesTo is CompositeResultDescriptorImpl) {
       contributesTo.recordContributor(this);
     }
   }
 
   @override
-  TaskInput<V> inputFor(AnalysisTarget target) =>
+  TaskInput<V> of(AnalysisTarget target) =>
       new SimpleTaskInput<V>(target, this);
 
   @override
diff --git a/pkg/analyzer/lib/task/dart.dart b/pkg/analyzer/lib/task/dart.dart
index 2bfbdc8..2918d20 100644
--- a/pkg/analyzer/lib/task/dart.dart
+++ b/pkg/analyzer/lib/task/dart.dart
@@ -9,19 +9,9 @@
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
 
 /**
- * The compilation unit associated with a [Source] after it has had all
- * declarations bound to the element defined by the declaration.
- *
- * The result is only available for targets representing a Dart compilation unit.
- */
-final ResultDescriptor<CompilationUnit> BUILT_UNIT =
-    new ResultDescriptor<CompilationUnit>('BUILT_UNIT', null);
-
-/**
  * The element model associated with a single compilation unit.
  *
  * The result is only available for targets representing a Dart compilation unit.
@@ -31,6 +21,17 @@
         'COMPILATION_UNIT_ELEMENT', null);
 
 /**
+ * The analysis errors associated with a target.
+ *
+ * The value combines errors represented by multiple other results.
+ */
+// TODO(brianwilkerson) If we want to associate errors with targets smaller than
+// a file, we will need other contribution points to collect them. In which case
+// we might want to rename this and/or document that it applies to files.
+final CompositeResultDescriptor<List<AnalysisError>> DART_ERRORS =
+    new CompositeResultDescriptor<List<AnalysisError>>('DART_ERRORS');
+
+/**
  * The sources of the libraries that are exported from a library.
  *
  * The list will be empty if there are no exported libraries, but will not be
@@ -38,21 +39,28 @@
  *
  * The result is only available for targets representing a Dart library.
  */
-final ResultDescriptor<List<Source>> EXPORTED_LIBRARIES =
-    new ResultDescriptor<List<Source>>(
-        'EXPORTED_LIBRARIES', Source.EMPTY_ARRAY);
+final ListResultDescriptor<Source> EXPORTED_LIBRARIES =
+    new ListResultDescriptor<Source>('EXPORTED_LIBRARIES', Source.EMPTY_ARRAY);
+
+/**
+ * A flag specifying whether a library imports 'dart:html'.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<bool> HAS_HTML_IMPORT =
+    new ResultDescriptor<bool>('HAS_HTML_IMPORT', false);
 
 /**
  * The sources of the libraries that are imported into a library.
  *
- * The list will be empty if there are no imported libraries, but will not be
- * `null`.
+ * Not `null`.
+ * The default value is empty.
+ * When computed, this list will always contain at least `dart:core` source.
  *
  * The result is only available for targets representing a Dart library.
  */
-final ResultDescriptor<List<Source>> IMPORTED_LIBRARIES =
-    new ResultDescriptor<List<Source>>(
-        'IMPORTED_LIBRARIES', Source.EMPTY_ARRAY);
+final ListResultDescriptor<Source> IMPORTED_LIBRARIES =
+    new ListResultDescriptor<Source>('IMPORTED_LIBRARIES', Source.EMPTY_ARRAY);
 
 /**
  * The sources of the parts that are included in a library.
@@ -62,8 +70,16 @@
  *
  * The result is only available for targets representing a Dart library.
  */
-final ResultDescriptor<List<Source>> INCLUDED_PARTS =
-    new ResultDescriptor<List<Source>>('INCLUDED_PARTS', Source.EMPTY_ARRAY);
+final ListResultDescriptor<Source> INCLUDED_PARTS =
+    new ListResultDescriptor<Source>('INCLUDED_PARTS', Source.EMPTY_ARRAY);
+
+/**
+ * A flag specifying whether a library is launchable.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ResultDescriptor<bool> IS_LAUNCHABLE =
+    new ResultDescriptor<bool>('IS_LAUNCHABLE', false);
 
 /**
  * The errors produced while parsing a compilation unit.
@@ -74,8 +90,7 @@
  */
 final ResultDescriptor<List<AnalysisError>> PARSE_ERRORS =
     new ResultDescriptor<List<AnalysisError>>(
-        'PARSE_ERRORS', AnalysisError.NO_ERRORS,
-        contributesTo: ANALYSIS_ERRORS);
+        'PARSE_ERRORS', AnalysisError.NO_ERRORS, contributesTo: DART_ERRORS);
 
 /**
  * The compilation unit AST produced while parsing a compilation unit.
@@ -96,7 +111,7 @@
  */
 final ResultDescriptor<List<AnalysisError>> SCAN_ERRORS =
     new ResultDescriptor<List<AnalysisError>>(
-        'SCAN_ERRORS', AnalysisError.NO_ERRORS, contributesTo: ANALYSIS_ERRORS);
+        'SCAN_ERRORS', AnalysisError.NO_ERRORS, contributesTo: DART_ERRORS);
 
 /**
  * The token stream produced while scanning a compilation unit.
@@ -108,3 +123,14 @@
  */
 final ResultDescriptor<Token> TOKEN_STREAM =
     new ResultDescriptor<Token>('TOKEN_STREAM', null);
+
+/**
+ * The sources of the Dart files that a library consists of.
+ *
+ * The list will include the source of the defining unit and [INCLUDED_PARTS].
+ * So, it is never empty or `null`.
+ *
+ * The result is only available for targets representing a Dart library.
+ */
+final ListResultDescriptor<Source> UNITS =
+    new ListResultDescriptor<Source>('UNITS', Source.EMPTY_ARRAY);
diff --git a/pkg/analyzer/lib/task/general.dart b/pkg/analyzer/lib/task/general.dart
index 3a92c30..7cf1b97 100644
--- a/pkg/analyzer/lib/task/general.dart
+++ b/pkg/analyzer/lib/task/general.dart
@@ -4,25 +4,10 @@
 
 library analyzer.task.general;
 
-import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/task/model.dart';
 
 /**
- * The analysis errors associated with a target.
- *
- * The value combines errors represented by multiple other results.
- */
-// TODO(brianwilkerson) If we want to associate errors with targets smaller than
-// a file, we will need other contribution points to collect them. In which case
-// we might want to rename this and/or document that it applies to files. For
-// that matter, we might also want to have one that applies to Dart files and a
-// different one that applies to HTML files, because the list of errors being
-// combined is likely to be different.
-final ContributionPoint<List<AnalysisError>> ANALYSIS_ERRORS =
-    new ContributionPoint<List<AnalysisError>>('ANALYSIS_ERRORS');
-
-/**
  * The contents of a single file.
  */
 final ResultDescriptor<String> CONTENT =
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/task/model.dart
index 48e616d..4da15af 100644
--- a/pkg/analyzer/lib/task/model.dart
+++ b/pkg/analyzer/lib/task/model.dart
@@ -27,6 +27,27 @@
 typedef Map<String, TaskInput> CreateTaskInputs(AnalysisTarget target);
 
 /**
+ * A function that converts an object of the type [B] into a [TaskInput].
+ * This is used, for example, by a [ListTaskInput] to create task inputs
+ * for each value in a list of values.
+ */
+typedef TaskInput<E> UnaryFunction<B, E>(B object);
+
+/**
+ * An [AnalysisTarget] wrapper for an [AnalysisContext].
+ */
+class AnalysisContextTarget implements AnalysisTarget {
+  static final AnalysisContextTarget request = new AnalysisContextTarget(null);
+
+  final AnalysisContext context;
+
+  AnalysisContextTarget(this.context);
+
+  @override
+  Source get source => null;
+}
+
+/**
  * An object with which an analysis result can be associated.
  *
  * Clients are allowed to subtype this class when creating new kinds of targets.
@@ -197,7 +218,7 @@
       } finally {
         stopwatch.stop();
       }
-    } on AnalysisException catch (exception) {
+    } on AnalysisException {
       rethrow;
     } catch (exception, stackTrace) {
       throw new AnalysisException(
@@ -213,15 +234,16 @@
  *
  * Clients are not expected to subtype this class.
  */
-abstract class ContributionPoint<V> extends ResultDescriptor<V> {
+abstract class CompositeResultDescriptor<V> extends ResultDescriptor<V> {
   /**
-   * Initialize a newly created contribution point to have the given [name].
+   * Initialize a newly created composite result to have the given [name].
    */
-  factory ContributionPoint(String name) = ContributionPointImpl;
+  factory CompositeResultDescriptor(
+      String name) = CompositeResultDescriptorImpl;
 
   /**
    * Return a list containing the descriptors of the results that are unioned
-   * together to comprise the value of this result.
+   * together to compose the value of this result.
    *
    * Clients must not modify the returned list.
    */
@@ -229,6 +251,60 @@
 }
 
 /**
+ * A description of a [List]-based analysis result that can be computed by an
+ * [AnalysisTask].
+ *
+ * Clients are not expected to subtype this class.
+ */
+abstract class ListResultDescriptor<E> implements ResultDescriptor<List<E>> {
+  /**
+   * Initialize a newly created analysis result to have the given [name]. If a
+   * composite result is specified, then this result will contribute to it.
+   */
+  factory ListResultDescriptor(String name, List<E> defaultValue,
+      {CompositeResultDescriptor<List<E>> contributesTo}) = ListResultDescriptorImpl<E>;
+
+  @override
+  ListTaskInput<E> of(AnalysisTarget target);
+}
+
+/**
+ * A description of an input to an [AnalysisTask] that can be used to compute
+ * that input.
+ *
+ * Clients are not expected to subtype this class.
+ */
+abstract class ListTaskInput<E> extends TaskInput<List<E>> {
+  /**
+   * Return a task input that can be used to compute a list whose elements are
+   * the result of passing the elements of this input to the [mapper] function.
+   */
+  ListTaskInput /*<V>*/ toList(UnaryFunction<E, dynamic /*<V>*/ > mapper);
+
+  /**
+   * Return a task input that can be used to compute a list whose elements are
+   * [valueResult]'s associated with those elements.
+   */
+  ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult);
+
+  /**
+   * Return a task input that can be used to compute a map whose keys are the
+   * elements of this input and whose values are the result of passing the
+   * corresponding key to the [mapper] function.
+   */
+  TaskInput<Map<E, dynamic /*V*/ >> toMap(
+      UnaryFunction<E, dynamic /*<V>*/ > mapper);
+
+  /**
+   * Return a task input that can be used to compute a map whose keys are the
+   * elements of this input and whose values are the [valueResult]'s associated
+   * with those elements.
+   */
+  TaskInput<Map<AnalysisTarget, dynamic /*V*/ >> toMapOf(
+      ResultDescriptor /*<V>*/ valueResult);
+}
+
+/**
  * A description of an analysis result that can be computed by an [AnalysisTask].
  *
  * Clients are not expected to subtype this class.
@@ -236,10 +312,10 @@
 abstract class ResultDescriptor<V> {
   /**
    * Initialize a newly created analysis result to have the given [name]. If a
-   * contribution point is specified, then this result will contribute to it.
+   * composite result is specified, then this result will contribute to it.
    */
   factory ResultDescriptor(String name, V defaultValue,
-      {ContributionPoint<V> contributesTo}) = ResultDescriptorImpl;
+      {CompositeResultDescriptor<V> contributesTo}) = ResultDescriptorImpl;
 
   /**
    * Return the default value for results described by this descriptor.
@@ -247,10 +323,15 @@
   V get defaultValue;
 
   /**
+   * Return the name of this descriptor.
+   */
+  String get name;
+
+  /**
    * Return a task input that can be used to compute this result for the given
    * [target].
    */
-  TaskInput<V> inputFor(AnalysisTarget target);
+  TaskInput<V> of(AnalysisTarget target);
 }
 
 /**
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index d4b49c4..8ac7743 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.24.0
+version: 0.25.0-dev.2
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/file_system/memory_file_system_test.dart b/pkg/analyzer/test/file_system/memory_file_system_test.dart
index b17d39e..83d3694 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -14,541 +14,548 @@
 import 'package:unittest/unittest.dart';
 import 'package:watcher/watcher.dart';
 
+import '../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(FileSystemExceptionTest);
+  runReflectiveTests(FileTest);
+  runReflectiveTests(FolderTest);
+  runReflectiveTests(MemoryFileSourceExistingTest);
+  runReflectiveTests(MemoryFileSourceNotExistingTest);
+  runReflectiveTests(MemoryResourceProviderTest);
+}
+
 var _isFile = new isInstanceOf<File>();
 var _isFileSystemException = new isInstanceOf<FileSystemException>();
 var _isFolder = new isInstanceOf<Folder>();
 
-main() {
-  groupSep = ' | ';
+@reflectiveTest
+class FileSystemExceptionTest {
+  void test_constructor() {
+    var exception = new FileSystemException('/my/path', 'my message');
+    expect(exception.path, '/my/path');
+    expect(exception.message, 'my message');
+    expect(exception.toString(),
+        'FileSystemException(path=/my/path; message=my message)');
+  }
+}
 
-  group('MemoryResourceProvider', () {
-    MemoryResourceProvider provider;
+@reflectiveTest
+class FileTest {
+  MemoryResourceProvider provider = new MemoryResourceProvider();
 
-    setUp(() {
-      provider = new MemoryResourceProvider();
+  void test_equals_beforeAndAfterCreate() {
+    String path = '/file.txt';
+    File file1 = provider.getResource(path);
+    provider.newFile(path, 'contents');
+    File file2 = provider.getResource(path);
+    expect(file1 == file2, isTrue);
+  }
+
+  void test_equals_false() {
+    File fileA = provider.getResource('/fileA.txt');
+    File fileB = provider.getResource('/fileB.txt');
+    expect(fileA == new Object(), isFalse);
+    expect(fileA == fileB, isFalse);
+  }
+
+  void test_equals_true() {
+    File file = provider.getResource('/file.txt');
+    expect(file == file, isTrue);
+  }
+
+  void test_exists_false() {
+    File file = provider.getResource('/file.txt');
+    expect(file, isNotNull);
+    expect(file.exists, isFalse);
+  }
+
+  void test_exists_true() {
+    provider.newFile('/foo/file.txt', 'qwerty');
+    File file = provider.getResource('/foo/file.txt');
+    expect(file, isNotNull);
+    expect(file.exists, isTrue);
+  }
+
+  void test_fullName() {
+    File file = provider.getResource('/foo/bar/file.txt');
+    expect(file.path, '/foo/bar/file.txt');
+  }
+
+  void test_hashCode() {
+    String path = '/foo/bar/file.txt';
+    File file1 = provider.getResource(path);
+    provider.newFile(path, 'contents');
+    File file2 = provider.getResource(path);
+    expect(file1.hashCode, equals(file2.hashCode));
+  }
+
+  void test_isOrContains() {
+    String path = '/foo/bar/file.txt';
+    File file = provider.getResource(path);
+    expect(file.isOrContains(path), isTrue);
+    expect(file.isOrContains('/foo/bar'), isFalse);
+  }
+
+  void test_modificationStamp_doesNotExist() {
+    String path = '/foo/bar/file.txt';
+    File file = provider.newFile(path, 'qwerty');
+    provider.deleteFile(path);
+    expect(() {
+      file.modificationStamp;
+    }, throwsA(_isFileSystemException));
+  }
+
+  void test_modificationStamp_exists() {
+    String path = '/foo/bar/file.txt';
+    File file = provider.newFile(path, 'qwerty');
+    expect(file.modificationStamp, isNonNegative);
+  }
+
+  void test_parent() {
+    provider.newFile('/foo/bar/file.txt', 'content');
+    File file = provider.getResource('/foo/bar/file.txt');
+    Resource parent = file.parent;
+    expect(parent, new isInstanceOf<Folder>());
+    expect(parent.path, equals('/foo/bar'));
+  }
+
+  void test_readAsStringSync_doesNotExist() {
+    File file = provider.getResource('/test.txt');
+    expect(() {
+      file.readAsStringSync();
+    }, throwsA(_isFileSystemException));
+  }
+
+  void test_readAsStringSync_exists() {
+    File file = provider.newFile('/file.txt', 'abc');
+    expect(file.readAsStringSync(), 'abc');
+  }
+
+  void test_shortName() {
+    File file = provider.getResource('/foo/bar/file.txt');
+    expect(file.shortName, 'file.txt');
+  }
+
+  void test_toString() {
+    File file = provider.getResource('/foo/bar/file.txt');
+    expect(file.toString(), '/foo/bar/file.txt');
+  }
+}
+
+@reflectiveTest
+class FolderTest {
+  static const String path = '/foo/bar';
+
+  MemoryResourceProvider provider = new MemoryResourceProvider();
+  Folder folder;
+
+  void setUp() {
+    folder = provider.newFolder(path);
+  }
+
+  void test_canonicalizePath() {
+    expect(folder.canonicalizePath('baz'), equals('/foo/bar/baz'));
+    expect(folder.canonicalizePath('/baz'), equals('/baz'));
+    expect(folder.canonicalizePath('../baz'), equals('/foo/baz'));
+    expect(folder.canonicalizePath('/a/b/../c'), equals('/a/c'));
+    expect(folder.canonicalizePath('./baz'), equals('/foo/bar/baz'));
+    expect(folder.canonicalizePath('/a/b/./c'), equals('/a/b/c'));
+  }
+
+  void test_contains() {
+    expect(folder.contains('/foo/bar/aaa.txt'), isTrue);
+    expect(folder.contains('/foo/bar/aaa/bbb.txt'), isTrue);
+    expect(folder.contains('/baz.txt'), isFalse);
+    expect(folder.contains('/foo/bar'), isFalse);
+  }
+
+  void test_equal_false() {
+    String path2 = '/foo/baz';
+    Folder folder2 = provider.newFolder(path2);
+    expect(folder == folder2, isFalse);
+  }
+
+  void test_equal_true() {
+    Folder folder2 = provider.getResource(path);
+    expect(folder == folder2, isTrue);
+  }
+
+  void test_getChild_doesNotExist() {
+    File file = folder.getChild('file.txt');
+    expect(file, isNotNull);
+    expect(file.exists, isFalse);
+  }
+
+  void test_getChild_file() {
+    provider.newFile('/foo/bar/file.txt', 'content');
+    File child = folder.getChild('file.txt');
+    expect(child, isNotNull);
+    expect(child.exists, isTrue);
+  }
+
+  void test_getChild_folder() {
+    provider.newFolder('/foo/bar/baz');
+    Folder child = folder.getChild('baz');
+    expect(child, isNotNull);
+    expect(child.exists, isTrue);
+  }
+
+  void test_getChildAssumingFolder_doesNotExist() {
+    Folder child = folder.getChildAssumingFolder('foldername');
+    expect(child, isNotNull);
+    expect(child.exists, isFalse);
+  }
+
+  void test_getChildAssumingFolder_file() {
+    provider.newFile('/foo/bar/foldername', 'content');
+    Folder child = folder.getChildAssumingFolder('foldername');
+    expect(child, isNotNull);
+    expect(child.exists, isFalse);
+  }
+
+  void test_getChildAssumingFolder_folder() {
+    provider.newFolder('/foo/bar/foldername');
+    Folder child = folder.getChildAssumingFolder('foldername');
+    expect(child, isNotNull);
+    expect(child.exists, isTrue);
+  }
+
+  void test_getChildren_doesNotExist() {
+    folder = folder.getChildAssumingFolder('no-such-folder');
+    expect(() {
+      folder.getChildren();
+    }, throwsA(_isFileSystemException));
+  }
+
+  void test_getChildren_exists() {
+    provider.newFile('/foo/bar/a.txt', 'aaa');
+    provider.newFolder('/foo/bar/bFolder');
+    provider.newFile('/foo/bar/c.txt', 'ccc');
+    // prepare 3 children
+    List<Resource> children = folder.getChildren();
+    expect(children, hasLength(3));
+    children.sort((a, b) => a.shortName.compareTo(b.shortName));
+    // check that each child exists
+    children.forEach((child) {
+      expect(child.exists, true);
     });
+    // check names
+    expect(children[0].shortName, 'a.txt');
+    expect(children[1].shortName, 'bFolder');
+    expect(children[2].shortName, 'c.txt');
+    // check types
+    expect(children[0], _isFile);
+    expect(children[1], _isFolder);
+    expect(children[2], _isFile);
+  }
 
-    test('FileSystemException', () {
-      var exception = new FileSystemException('/my/path', 'my message');
-      expect(exception.path, '/my/path');
-      expect(exception.message, 'my message');
-      expect(exception.toString(),
-          'FileSystemException(path=/my/path; message=my message)');
-    });
+  void test_hashCode() {
+    Folder folder2 = provider.getResource(path);
+    expect(folder.hashCode, folder2.hashCode);
+  }
 
-    group('Watch', () {
-      Future delayed(computation()) {
-        return new Future.delayed(Duration.ZERO, computation);
-      }
+  void test_isOrContains() {
+    expect(folder.isOrContains('/foo/bar'), isTrue);
+    expect(folder.isOrContains('/foo/bar/aaa.txt'), isTrue);
+    expect(folder.isOrContains('/foo/bar/aaa/bbb.txt'), isTrue);
+    expect(folder.isOrContains('/baz.txt'), isFalse);
+  }
 
-      watchingFolder(String path, test(List<WatchEvent> changesReceived)) {
-        Folder folder = provider.getResource(path);
-        var changesReceived = <WatchEvent>[];
-        folder.changes.listen(changesReceived.add);
-        return test(changesReceived);
-      }
+  void test_parent() {
+    Resource parent1 = folder.parent;
+    expect(parent1, new isInstanceOf<Folder>());
+    expect(parent1.path, equals('/foo'));
+    Resource parent2 = parent1.parent;
+    expect(parent2, new isInstanceOf<Folder>());
+    expect(parent2.path, equals('/'));
+    expect(parent2.parent, isNull);
+  }
+}
 
-      test('create file', () {
-        String rootPath = '/my/path';
-        provider.newFolder(rootPath);
-        watchingFolder(rootPath, (changesReceived) {
-          expect(changesReceived, hasLength(0));
-          String path = posix.join(rootPath, 'foo');
-          provider.newFile(path, 'contents');
-          return delayed(() {
-            expect(changesReceived, hasLength(1));
-            expect(changesReceived[0].type, equals(ChangeType.ADD));
-            expect(changesReceived[0].path, equals(path));
-          });
-        });
-      });
+@reflectiveTest
+class MemoryFileSourceExistingTest {
+  MemoryResourceProvider provider = new MemoryResourceProvider();
+  Source source;
 
-      test('modify file', () {
-        String rootPath = '/my/path';
-        provider.newFolder(rootPath);
-        String path = posix.join(rootPath, 'foo');
-        provider.newFile(path, 'contents 1');
-        return watchingFolder(rootPath, (changesReceived) {
-          expect(changesReceived, hasLength(0));
-          provider.modifyFile(path, 'contents 2');
-          return delayed(() {
-            expect(changesReceived, hasLength(1));
-            expect(changesReceived[0].type, equals(ChangeType.MODIFY));
-            expect(changesReceived[0].path, equals(path));
-          });
-        });
-      });
+  setUp() {
+    File file = provider.newFile('/foo/test.dart', 'library test;');
+    source = file.createSource();
+  }
 
-      test('modify file in subdir', () {
-        String rootPath = '/my/path';
-        provider.newFolder(rootPath);
-        String subdirPath = posix.join(rootPath, 'foo');
-        provider.newFolder(subdirPath);
-        String path = posix.join(rootPath, 'bar');
-        provider.newFile(path, 'contents 1');
-        return watchingFolder(rootPath, (changesReceived) {
-          expect(changesReceived, hasLength(0));
-          provider.modifyFile(path, 'contents 2');
-          return delayed(() {
-            expect(changesReceived, hasLength(1));
-            expect(changesReceived[0].type, equals(ChangeType.MODIFY));
-            expect(changesReceived[0].path, equals(path));
-          });
-        });
-      });
+  void test_contents() {
+    TimestampedData<String> contents = source.contents;
+    expect(contents.data, 'library test;');
+  }
 
-      test('delete file', () {
-        String rootPath = '/my/path';
-        provider.newFolder(rootPath);
-        String path = posix.join(rootPath, 'foo');
-        provider.newFile(path, 'contents 1');
-        return watchingFolder(rootPath, (changesReceived) {
-          expect(changesReceived, hasLength(0));
-          provider.deleteFile(path);
-          return delayed(() {
-            expect(changesReceived, hasLength(1));
-            expect(changesReceived[0].type, equals(ChangeType.REMOVE));
-            expect(changesReceived[0].path, equals(path));
-          });
-        });
+  void test_encoding() {
+    expect(source.encoding, 'file:///foo/test.dart');
+  }
+
+  void test_equals_false_differentFile() {
+    File fileA = provider.newFile('/foo/a.dart', '');
+    File fileB = provider.newFile('/foo/b.dart', '');
+    Source sourceA = fileA.createSource();
+    Source sourceB = fileB.createSource();
+    expect(sourceA == sourceB, isFalse);
+  }
+
+  void test_equals_false_notMemorySource() {
+    File file = provider.newFile('/foo/test.dart', '');
+    Source source = file.createSource();
+    expect(source == new Object(), isFalse);
+  }
+
+  void test_equals_true_sameFile() {
+    File file = provider.newFile('/foo/test.dart', '');
+    Source sourceA = file.createSource();
+    Source sourceB = file.createSource();
+    expect(sourceA == sourceB, isTrue);
+  }
+
+  void test_equals_true_self() {
+    File file = provider.newFile('/foo/test.dart', '');
+    Source source = file.createSource();
+    expect(source == source, isTrue);
+  }
+
+  void test_exists() {
+    expect(source.exists(), isTrue);
+  }
+
+  void test_fullName() {
+    expect(source.fullName, '/foo/test.dart');
+  }
+
+  void test_hashCode() {
+    source.hashCode;
+  }
+
+  void test_resolveRelative() {
+    Uri relative = source.resolveRelativeUri(new Uri.file('bar/baz.dart'));
+    expect(relative.path, '/foo/bar/baz.dart');
+  }
+
+  void test_shortName() {
+    expect(source.shortName, 'test.dart');
+  }
+}
+
+@reflectiveTest
+class MemoryFileSourceNotExistingTest {
+  MemoryResourceProvider provider = new MemoryResourceProvider();
+  Source source;
+
+  setUp() {
+    File file = provider.getResource('/foo/test.dart');
+    source = file.createSource();
+  }
+
+  void test_contents() {
+    expect(() {
+      source.contents;
+    }, throwsA(_isFileSystemException));
+  }
+
+  void test_encoding() {
+    expect(source.encoding, 'file:///foo/test.dart');
+  }
+
+  void test_exists() {
+    expect(source.exists(), isFalse);
+  }
+
+  void test_fullName() {
+    expect(source.fullName, '/foo/test.dart');
+  }
+
+  void test_modificationStamp() {
+    expect(source.modificationStamp, -1);
+  }
+
+  void test_resolveRelative() {
+    Uri relative = source.resolveRelativeUri(new Uri.file('bar/baz.dart'));
+    expect(relative.path, '/foo/bar/baz.dart');
+  }
+
+  void test_shortName() {
+    expect(source.shortName, 'test.dart');
+  }
+}
+
+@reflectiveTest
+class MemoryResourceProviderTest {
+  MemoryResourceProvider provider = new MemoryResourceProvider();
+
+  void test_deleteFile_folder() {
+    String path = '/my/file';
+    provider.newFolder(path);
+    expect(() {
+      provider.deleteFile(path);
+    }, throwsA(new isInstanceOf<ArgumentError>()));
+    expect(provider.getResource(path), new isInstanceOf<Folder>());
+  }
+
+  void test_deleteFile_notExistent() {
+    String path = '/my/file';
+    expect(() {
+      provider.deleteFile(path);
+    }, throwsA(new isInstanceOf<ArgumentError>()));
+    Resource file = provider.getResource(path);
+    expect(file, isNotNull);
+    expect(file.exists, isFalse);
+  }
+
+  void test_deleteFile_success() {
+    String path = '/my/file';
+    provider.newFile(path, 'contents');
+    Resource file = provider.getResource(path);
+    expect(file, new isInstanceOf<File>());
+    expect(file.exists, isTrue);
+    provider.deleteFile(path);
+    expect(file.exists, isFalse);
+  }
+
+  void test_getStateLocation_uniqueness() {
+    String idOne = 'one';
+    Folder folderOne = provider.getStateLocation(idOne);
+    expect(folderOne, isNotNull);
+    String idTwo = 'two';
+    Folder folderTwo = provider.getStateLocation(idTwo);
+    expect(folderTwo, isNotNull);
+    expect(folderTwo, isNot(equals(folderOne)));
+    expect(provider.getStateLocation(idOne), equals(folderOne));
+  }
+
+  void test_modifyFile_isFolder() {
+    String path = '/my/file';
+    provider.newFolder(path);
+    expect(() {
+      provider.modifyFile(path, 'contents');
+    }, throwsA(new isInstanceOf<ArgumentError>()));
+    expect(provider.getResource(path), new isInstanceOf<Folder>());
+  }
+
+  void test_modifyFile_notExistent() {
+    String path = '/my/file';
+    expect(() {
+      provider.modifyFile(path, 'contents');
+    }, throwsA(new isInstanceOf<ArgumentError>()));
+    Resource file = provider.getResource(path);
+    expect(file, isNotNull);
+    expect(file.exists, isFalse);
+  }
+
+  void test_modifyFile_success() {
+    String path = '/my/file';
+    provider.newFile(path, 'contents 1');
+    Resource file = provider.getResource(path);
+    expect(file, new isInstanceOf<File>());
+    Source source = (file as File).createSource();
+    expect(source.contents.data, equals('contents 1'));
+    provider.modifyFile(path, 'contents 2');
+    expect(source.contents.data, equals('contents 2'));
+  }
+
+  void test_newFolder_aleadyExists_asFile() {
+    provider.newFile('/my/file', 'qwerty');
+    expect(() {
+      provider.newFolder('/my/file');
+    }, throwsA(new isInstanceOf<ArgumentError>()));
+  }
+
+  void test_newFolder_aleadyExists_asFolder() {
+    Folder folder = provider.newFolder('/my/folder');
+    Folder newFolder = provider.newFolder('/my/folder');
+    expect(newFolder, folder);
+  }
+
+  void test_newFolder_emptyPath() {
+    expect(() {
+      provider.newFolder('');
+    }, throwsA(new isInstanceOf<ArgumentError>()));
+  }
+
+  void test_newFolder_notAbsolute() {
+    expect(() {
+      provider.newFolder('not/absolute');
+    }, throwsA(new isInstanceOf<ArgumentError>()));
+  }
+
+  test_watch_createFile() {
+    String rootPath = '/my/path';
+    provider.newFolder(rootPath);
+    return _watchingFolder(rootPath, (changesReceived) {
+      expect(changesReceived, hasLength(0));
+      String path = posix.join(rootPath, 'foo');
+      provider.newFile(path, 'contents');
+      return _delayed(() {
+        expect(changesReceived, hasLength(1));
+        expect(changesReceived[0].type, equals(ChangeType.ADD));
+        expect(changesReceived[0].path, equals(path));
       });
     });
+  }
 
-    group('getStateLocation', () {
-      test('uniqueness', () {
-        String idOne = 'one';
-        Folder folderOne = provider.getStateLocation(idOne);
-        expect(folderOne, isNotNull);
-        String idTwo = 'two';
-        Folder folderTwo = provider.getStateLocation(idTwo);
-        expect(folderTwo, isNotNull);
-        expect(folderTwo, isNot(equals(folderOne)));
-        expect(provider.getStateLocation(idOne), equals(folderOne));
+  test_watch_deleteFile() {
+    String rootPath = '/my/path';
+    provider.newFolder(rootPath);
+    String path = posix.join(rootPath, 'foo');
+    provider.newFile(path, 'contents 1');
+    return _watchingFolder(rootPath, (changesReceived) {
+      expect(changesReceived, hasLength(0));
+      provider.deleteFile(path);
+      return _delayed(() {
+        expect(changesReceived, hasLength(1));
+        expect(changesReceived[0].type, equals(ChangeType.REMOVE));
+        expect(changesReceived[0].path, equals(path));
       });
     });
+  }
 
-    group('newFolder', () {
-      test('empty path', () {
-        expect(() {
-          provider.newFolder('');
-        }, throwsA(new isInstanceOf<ArgumentError>()));
-      });
-
-      test('not absolute', () {
-        expect(() {
-          provider.newFolder('not/absolute');
-        }, throwsA(new isInstanceOf<ArgumentError>()));
-      });
-
-      group('already exists', () {
-        test('as folder', () {
-          Folder folder = provider.newFolder('/my/folder');
-          Folder newFolder = provider.newFolder('/my/folder');
-          expect(newFolder, folder);
-        });
-
-        test('as file', () {
-          provider.newFile('/my/file', 'qwerty');
-          expect(() {
-            provider.newFolder('/my/file');
-          }, throwsA(new isInstanceOf<ArgumentError>()));
-        });
+  test_watch_modifyFile() {
+    String rootPath = '/my/path';
+    provider.newFolder(rootPath);
+    String path = posix.join(rootPath, 'foo');
+    provider.newFile(path, 'contents 1');
+    return _watchingFolder(rootPath, (changesReceived) {
+      expect(changesReceived, hasLength(0));
+      provider.modifyFile(path, 'contents 2');
+      return _delayed(() {
+        expect(changesReceived, hasLength(1));
+        expect(changesReceived[0].type, equals(ChangeType.MODIFY));
+        expect(changesReceived[0].path, equals(path));
       });
     });
+  }
 
-    group('modifyFile', () {
-      test('nonexistent', () {
-        String path = '/my/file';
-        expect(() {
-          provider.modifyFile(path, 'contents');
-        }, throwsA(new isInstanceOf<ArgumentError>()));
-        Resource file = provider.getResource(path);
-        expect(file, isNotNull);
-        expect(file.exists, isFalse);
-      });
-
-      test('is folder', () {
-        String path = '/my/file';
-        provider.newFolder(path);
-        expect(() {
-          provider.modifyFile(path, 'contents');
-        }, throwsA(new isInstanceOf<ArgumentError>()));
-        expect(provider.getResource(path), new isInstanceOf<Folder>());
-      });
-
-      test('successful', () {
-        String path = '/my/file';
-        provider.newFile(path, 'contents 1');
-        Resource file = provider.getResource(path);
-        expect(file, new isInstanceOf<File>());
-        Source source = (file as File).createSource();
-        expect(source.contents.data, equals('contents 1'));
-        provider.modifyFile(path, 'contents 2');
-        expect(source.contents.data, equals('contents 2'));
+  test_watch_modifyFile_inSubDir() {
+    String rootPath = '/my/path';
+    provider.newFolder(rootPath);
+    String subdirPath = posix.join(rootPath, 'foo');
+    provider.newFolder(subdirPath);
+    String path = posix.join(rootPath, 'bar');
+    provider.newFile(path, 'contents 1');
+    return _watchingFolder(rootPath, (changesReceived) {
+      expect(changesReceived, hasLength(0));
+      provider.modifyFile(path, 'contents 2');
+      return _delayed(() {
+        expect(changesReceived, hasLength(1));
+        expect(changesReceived[0].type, equals(ChangeType.MODIFY));
+        expect(changesReceived[0].path, equals(path));
       });
     });
+  }
 
-    group('deleteFile', () {
-      test('nonexistent', () {
-        String path = '/my/file';
-        expect(() {
-          provider.deleteFile(path);
-        }, throwsA(new isInstanceOf<ArgumentError>()));
-        Resource file = provider.getResource(path);
-        expect(file, isNotNull);
-        expect(file.exists, isFalse);
-      });
+  Future _delayed(computation()) {
+    return new Future.delayed(Duration.ZERO, computation);
+  }
 
-      test('is folder', () {
-        String path = '/my/file';
-        provider.newFolder(path);
-        expect(() {
-          provider.deleteFile(path);
-        }, throwsA(new isInstanceOf<ArgumentError>()));
-        expect(provider.getResource(path), new isInstanceOf<Folder>());
-      });
-
-      test('successful', () {
-        String path = '/my/file';
-        provider.newFile(path, 'contents');
-        Resource file = provider.getResource(path);
-        expect(file, new isInstanceOf<File>());
-        expect(file.exists, isTrue);
-        provider.deleteFile(path);
-        expect(file.exists, isFalse);
-      });
-    });
-
-    group('File', () {
-      group('==', () {
-        test('false', () {
-          File fileA = provider.getResource('/fileA.txt');
-          File fileB = provider.getResource('/fileB.txt');
-          expect(fileA == new Object(), isFalse);
-          expect(fileA == fileB, isFalse);
-        });
-
-        test('true', () {
-          File file = provider.getResource('/file.txt');
-          expect(file == file, isTrue);
-        });
-
-        test('before and after creation', () {
-          String path = '/file.txt';
-          File file1 = provider.getResource(path);
-          provider.newFile(path, 'contents');
-          File file2 = provider.getResource(path);
-          expect(file1 == file2, isTrue);
-        });
-      });
-
-      group('exists', () {
-        test('false', () {
-          File file = provider.getResource('/file.txt');
-          expect(file, isNotNull);
-          expect(file.exists, isFalse);
-        });
-
-        test('true', () {
-          provider.newFile('/foo/file.txt', 'qwerty');
-          File file = provider.getResource('/foo/file.txt');
-          expect(file, isNotNull);
-          expect(file.exists, isTrue);
-        });
-      });
-
-      test('fullName', () {
-        File file = provider.getResource('/foo/bar/file.txt');
-        expect(file.path, '/foo/bar/file.txt');
-      });
-
-      test('hashCode', () {
-        String path = '/foo/bar/file.txt';
-        File file1 = provider.getResource(path);
-        provider.newFile(path, 'contents');
-        File file2 = provider.getResource(path);
-        expect(file1.hashCode, equals(file2.hashCode));
-      });
-
-      test('isOrContains', () {
-        String path = '/foo/bar/file.txt';
-        File file = provider.getResource(path);
-        expect(file.isOrContains(path), isTrue);
-        expect(file.isOrContains('/foo/bar'), isFalse);
-      });
-
-      group('modificationStamp', () {
-        test('exists', () {
-          String path = '/foo/bar/file.txt';
-          File file = provider.newFile(path, 'qwerty');
-          expect(file.modificationStamp, isNonNegative);
-        });
-
-        test('does not exist', () {
-          String path = '/foo/bar/file.txt';
-          File file = provider.newFile(path, 'qwerty');
-          provider.deleteFile(path);
-          expect(() {
-            file.modificationStamp;
-          }, throwsA(_isFileSystemException));
-        });
-      });
-
-      test('shortName', () {
-        File file = provider.getResource('/foo/bar/file.txt');
-        expect(file.shortName, 'file.txt');
-      });
-
-      test('toString', () {
-        File file = provider.getResource('/foo/bar/file.txt');
-        expect(file.toString(), '/foo/bar/file.txt');
-      });
-
-      test('parent', () {
-        provider.newFile('/foo/bar/file.txt', 'content');
-        File file = provider.getResource('/foo/bar/file.txt');
-        Resource parent = file.parent;
-        expect(parent, new isInstanceOf<Folder>());
-        expect(parent.path, equals('/foo/bar'));
-      });
-    });
-
-    group('Folder', () {
-      Folder folder;
-      const String path = '/foo/bar';
-
-      setUp(() {
-        folder = provider.newFolder(path);
-      });
-
-      test('hashCode', () {
-        Folder folder2 = provider.getResource(path);
-        expect(folder.hashCode, equals(folder2.hashCode));
-      });
-
-      test('equality: same path', () {
-        Folder folder2 = provider.getResource(path);
-        expect(folder == folder2, isTrue);
-      });
-
-      test('equality: different paths', () {
-        String path2 = '/foo/baz';
-        Folder folder2 = provider.newFolder(path2);
-        expect(folder == folder2, isFalse);
-      });
-
-      test('contains', () {
-        expect(folder.contains('/foo/bar/aaa.txt'), isTrue);
-        expect(folder.contains('/foo/bar/aaa/bbb.txt'), isTrue);
-        expect(folder.contains('/baz.txt'), isFalse);
-        expect(folder.contains('/foo/bar'), isFalse);
-      });
-
-      test('isOrContains', () {
-        expect(folder.isOrContains('/foo/bar'), isTrue);
-        expect(folder.isOrContains('/foo/bar/aaa.txt'), isTrue);
-        expect(folder.isOrContains('/foo/bar/aaa/bbb.txt'), isTrue);
-        expect(folder.isOrContains('/baz.txt'), isFalse);
-      });
-
-      group('getChild', () {
-        test('does not exist', () {
-          File file = folder.getChild('file.txt');
-          expect(file, isNotNull);
-          expect(file.exists, isFalse);
-        });
-
-        test('file', () {
-          provider.newFile('/foo/bar/file.txt', 'content');
-          File child = folder.getChild('file.txt');
-          expect(child, isNotNull);
-          expect(child.exists, isTrue);
-        });
-
-        test('folder', () {
-          provider.newFolder('/foo/bar/baz');
-          Folder child = folder.getChild('baz');
-          expect(child, isNotNull);
-          expect(child.exists, isTrue);
-        });
-      });
-
-      group('getChildAssumingFolder', () {
-        test('does not exist', () {
-          Folder child = folder.getChildAssumingFolder('foldername');
-          expect(child, isNotNull);
-          expect(child.exists, isFalse);
-        });
-
-        test('file', () {
-          provider.newFile('/foo/bar/foldername', 'content');
-          Folder child = folder.getChildAssumingFolder('foldername');
-          expect(child, isNotNull);
-          expect(child.exists, isFalse);
-        });
-
-        test('folder', () {
-          provider.newFolder('/foo/bar/foldername');
-          Folder child = folder.getChildAssumingFolder('foldername');
-          expect(child, isNotNull);
-          expect(child.exists, isTrue);
-        });
-      });
-
-      test('getChildren', () {
-        provider.newFile('/foo/bar/a.txt', 'aaa');
-        provider.newFolder('/foo/bar/bFolder');
-        provider.newFile('/foo/bar/c.txt', 'ccc');
-        // prepare 3 children
-        List<Resource> children = folder.getChildren();
-        expect(children, hasLength(3));
-        children.sort((a, b) => a.shortName.compareTo(b.shortName));
-        // check that each child exists
-        children.forEach((child) {
-          expect(child.exists, true);
-        });
-        // check names
-        expect(children[0].shortName, 'a.txt');
-        expect(children[1].shortName, 'bFolder');
-        expect(children[2].shortName, 'c.txt');
-        // check types
-        expect(children[0], _isFile);
-        expect(children[1], _isFolder);
-        expect(children[2], _isFile);
-      });
-
-      test('parent', () {
-        Resource parent1 = folder.parent;
-        expect(parent1, new isInstanceOf<Folder>());
-        expect(parent1.path, equals('/foo'));
-        Resource parent2 = parent1.parent;
-        expect(parent2, new isInstanceOf<Folder>());
-        expect(parent2.path, equals('/'));
-        expect(parent2.parent, isNull);
-      });
-
-      test('canonicalizePath', () {
-        expect(folder.canonicalizePath('baz'), equals('/foo/bar/baz'));
-        expect(folder.canonicalizePath('/baz'), equals('/baz'));
-        expect(folder.canonicalizePath('../baz'), equals('/foo/baz'));
-        expect(folder.canonicalizePath('/a/b/../c'), equals('/a/c'));
-        expect(folder.canonicalizePath('./baz'), equals('/foo/bar/baz'));
-        expect(folder.canonicalizePath('/a/b/./c'), equals('/a/b/c'));
-      });
-    });
-
-    group('_MemoryFileSource', () {
-      Source source;
-
-      group('existent', () {
-        setUp(() {
-          File file = provider.newFile('/foo/test.dart', 'library test;');
-          source = file.createSource();
-        });
-
-        group('==', () {
-          group('true', () {
-            test('self', () {
-              File file = provider.newFile('/foo/test.dart', '');
-              Source source = file.createSource();
-              expect(source == source, isTrue);
-            });
-
-            test('same file', () {
-              File file = provider.newFile('/foo/test.dart', '');
-              Source sourceA = file.createSource();
-              Source sourceB = file.createSource();
-              expect(sourceA == sourceB, isTrue);
-            });
-          });
-
-          group('false', () {
-            test('not a memory Source', () {
-              File file = provider.newFile('/foo/test.dart', '');
-              Source source = file.createSource();
-              expect(source == new Object(), isFalse);
-            });
-
-            test('different file', () {
-              File fileA = provider.newFile('/foo/a.dart', '');
-              File fileB = provider.newFile('/foo/b.dart', '');
-              Source sourceA = fileA.createSource();
-              Source sourceB = fileB.createSource();
-              expect(sourceA == sourceB, isFalse);
-            });
-          });
-        });
-
-        test('contents', () {
-          TimestampedData<String> contents = source.contents;
-          expect(contents.data, 'library test;');
-        });
-
-        test('encoding', () {
-          expect(source.encoding, 'file:///foo/test.dart');
-        });
-
-        test('exists', () {
-          expect(source.exists(), isTrue);
-        });
-
-        test('fullName', () {
-          expect(source.fullName, '/foo/test.dart');
-        });
-
-        test('hashCode', () {
-          source.hashCode;
-        });
-
-        test('shortName', () {
-          expect(source.shortName, 'test.dart');
-        });
-
-        test('resolveRelative', () {
-          Uri relative =
-              source.resolveRelativeUri(new Uri.file('bar/baz.dart'));
-          expect(relative.path, '/foo/bar/baz.dart');
-        });
-      });
-
-      group('non-existent', () {
-        setUp(() {
-          File file = provider.getResource('/foo/test.dart');
-          source = file.createSource();
-        });
-
-        test('contents', () {
-          expect(() {
-            source.contents;
-          }, throwsA(_isFileSystemException));
-        });
-
-        test('encoding', () {
-          expect(source.encoding, 'file:///foo/test.dart');
-        });
-
-        test('exists', () {
-          expect(source.exists(), isFalse);
-        });
-
-        test('fullName', () {
-          expect(source.fullName, '/foo/test.dart');
-        });
-
-        test('modificationStamp', () {
-          expect(source.modificationStamp, -1);
-        });
-
-        test('shortName', () {
-          expect(source.shortName, 'test.dart');
-        });
-
-        test('resolveRelative', () {
-          Uri relative =
-              source.resolveRelativeUri(new Uri.file('bar/baz.dart'));
-          expect(relative.path, '/foo/bar/baz.dart');
-        });
-      });
-    });
-  });
+  _watchingFolder(String path, test(List<WatchEvent> changesReceived)) {
+    Folder folder = provider.getResource(path);
+    var changesReceived = <WatchEvent>[];
+    folder.changes.listen(changesReceived.add);
+    return test(changesReceived);
+  }
 }
diff --git a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
index 69eaa11..33ef876 100644
--- a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
+++ b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
@@ -14,360 +14,382 @@
 import 'package:unittest/unittest.dart';
 import 'package:watcher/watcher.dart';
 
-var _isFile = new isInstanceOf<File>();
-var _isFolder = new isInstanceOf<Folder>();
-var _isFileSystemException = new isInstanceOf<FileSystemException>();
+import '../reflective_tests.dart';
 
 main() {
   groupSep = ' | ';
+  runReflectiveTests(PhysicalResourceProviderTest);
+  runReflectiveTests(FileTest);
+  runReflectiveTests(FolderTest);
+}
 
-  group('PhysicalResourceProvider', () {
-    io.Directory tempDirectory;
-    String tempPath;
+var _isFile = new isInstanceOf<File>();
+var _isFileSystemException = new isInstanceOf<FileSystemException>();
+var _isFolder = new isInstanceOf<Folder>();
 
-    setUp(() {
-      tempDirectory = io.Directory.systemTemp.createTempSync('test_resource');
-      tempPath = tempDirectory.absolute.path;
+@reflectiveTest
+class FileTest extends _BaseTest {
+  String path;
+  File file;
+
+  setUp() {
+    super.setUp();
+    path = join(tempPath, 'file.txt');
+    file = PhysicalResourceProvider.INSTANCE.getResource(path);
+  }
+
+  void test_createSource() {
+    new io.File(path).writeAsStringSync('contents');
+    Source source = file.createSource();
+    expect(source.uriKind, UriKind.FILE_URI);
+    expect(source.exists(), isTrue);
+    expect(source.contents.data, 'contents');
+  }
+
+  void test_equals_differentPaths() {
+    String path2 = join(tempPath, 'file2.txt');
+    File file2 = PhysicalResourceProvider.INSTANCE.getResource(path2);
+    expect(file == file2, isFalse);
+  }
+
+  void test_equals_samePath() {
+    new io.File(path).writeAsStringSync('contents');
+    File file2 = PhysicalResourceProvider.INSTANCE.getResource(path);
+    expect(file == file2, isTrue);
+  }
+
+  void test_exists_false() {
+    expect(file.exists, isFalse);
+  }
+
+  void test_exists_true() {
+    new io.File(path).writeAsStringSync('contents');
+    expect(file.exists, isTrue);
+  }
+
+  void test_fullName() {
+    expect(file.path, path);
+  }
+
+  void test_hashCode() {
+    new io.File(path).writeAsStringSync('contents');
+    File file2 = PhysicalResourceProvider.INSTANCE.getResource(path);
+    expect(file.hashCode, equals(file2.hashCode));
+  }
+
+  void test_isOrContains() {
+    File file = PhysicalResourceProvider.INSTANCE.getResource(path);
+    expect(file.isOrContains(path), isTrue);
+    expect(file.isOrContains('foo'), isFalse);
+  }
+
+  void test_modificationStamp_doesNotExist() {
+    File file = PhysicalResourceProvider.INSTANCE.getResource(path);
+    expect(() {
+      file.modificationStamp;
+    }, throwsA(_isFileSystemException));
+  }
+
+  void test_modificationStamp_exists() {
+    new io.File(path).writeAsStringSync('contents');
+    File file = PhysicalResourceProvider.INSTANCE.getResource(path);
+    expect(file.modificationStamp, isNonNegative);
+  }
+
+  void test_parent() {
+    Resource parent = file.parent;
+    expect(parent, new isInstanceOf<Folder>());
+    expect(parent.path, equals(tempPath));
+  }
+
+  void test_readAsStringSync_doesNotExist() {
+    File file = PhysicalResourceProvider.INSTANCE.getResource(path);
+    expect(() {
+      file.readAsStringSync();
+    }, throwsA(_isFileSystemException));
+  }
+
+  void test_readAsStringSync_exists() {
+    new io.File(path).writeAsStringSync('abc');
+    File file = PhysicalResourceProvider.INSTANCE.getResource(path);
+    expect(file.readAsStringSync(), 'abc');
+  }
+
+  void test_shortName() {
+    expect(file.shortName, 'file.txt');
+  }
+
+  void test_toString() {
+    expect(file.toString(), path);
+  }
+}
+
+@reflectiveTest
+class FolderTest extends _BaseTest {
+  String path;
+  Folder folder;
+
+  setUp() {
+    super.setUp();
+    path = join(tempPath, 'folder');
+    new io.Directory(path).createSync();
+    folder = PhysicalResourceProvider.INSTANCE.getResource(path);
+  }
+
+  void test_canonicalizePath() {
+    String path2 = join(tempPath, 'folder2');
+    String path3 = join(tempPath, 'folder3');
+    expect(folder.canonicalizePath('baz'), equals(join(path, 'baz')));
+    expect(folder.canonicalizePath(path2), equals(path2));
+    expect(folder.canonicalizePath(join('..', 'folder2')), equals(path2));
+    expect(
+        folder.canonicalizePath(join(path2, '..', 'folder3')), equals(path3));
+    expect(
+        folder.canonicalizePath(join('.', 'baz')), equals(join(path, 'baz')));
+    expect(folder.canonicalizePath(join(path2, '.', 'baz')),
+        equals(join(path2, 'baz')));
+  }
+
+  void test_contains() {
+    expect(folder.contains(join(path, 'aaa.txt')), isTrue);
+    expect(folder.contains(join(path, 'aaa', 'bbb.txt')), isTrue);
+    expect(folder.contains(join(tempPath, 'baz.txt')), isFalse);
+    expect(folder.contains(path), isFalse);
+  }
+
+  void test_equals_differentPaths() {
+    String path2 = join(tempPath, 'folder2');
+    new io.Directory(path2).createSync();
+    Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path2);
+    expect(folder == folder2, isFalse);
+  }
+
+  void test_equals_samePath() {
+    Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path);
+    expect(folder == folder2, isTrue);
+  }
+
+  void test_getChild_doesNotExist() {
+    var child = folder.getChild('no-such-resource');
+    expect(child, isNotNull);
+    expect(child.exists, isFalse);
+  }
+
+  void test_getChild_file() {
+    new io.File(join(path, 'myFile')).createSync();
+    var child = folder.getChild('myFile');
+    expect(child, _isFile);
+    expect(child.exists, isTrue);
+  }
+
+  void test_getChild_folder() {
+    new io.Directory(join(path, 'myFolder')).createSync();
+    var child = folder.getChild('myFolder');
+    expect(child, _isFolder);
+    expect(child.exists, isTrue);
+  }
+
+  void test_getChildAssumingFolder_doesNotExist() {
+    Folder child = folder.getChildAssumingFolder('no-such-resource');
+    expect(child, isNotNull);
+    expect(child.exists, isFalse);
+  }
+
+  void test_getChildAssumingFolder_file() {
+    new io.File(join(path, 'myFile')).createSync();
+    Folder child = folder.getChildAssumingFolder('myFile');
+    expect(child, isNotNull);
+    expect(child.exists, isFalse);
+  }
+
+  void test_getChildAssumingFolder_folder() {
+    new io.Directory(join(path, 'myFolder')).createSync();
+    Folder child = folder.getChildAssumingFolder('myFolder');
+    expect(child, isNotNull);
+    expect(child.exists, isTrue);
+  }
+
+  void test_getChildren_doesNotExist() {
+    folder = folder.getChildAssumingFolder('no-such-folder');
+    expect(() {
+      folder.getChildren();
+    }, throwsA(_isFileSystemException));
+  }
+
+  void test_getChildren_exists() {
+    // create 2 files and 1 folder
+    new io.File(join(path, 'a.txt')).createSync();
+    new io.Directory(join(path, 'bFolder')).createSync();
+    new io.File(join(path, 'c.txt')).createSync();
+    // prepare 3 children
+    List<Resource> children = folder.getChildren();
+    expect(children, hasLength(3));
+    children.sort((a, b) => a.shortName.compareTo(b.shortName));
+    // check that each child exists
+    children.forEach((child) {
+      expect(child.exists, true);
     });
+    // check names
+    expect(children[0].shortName, 'a.txt');
+    expect(children[1].shortName, 'bFolder');
+    expect(children[2].shortName, 'c.txt');
+    // check types
+    expect(children[0], _isFile);
+    expect(children[1], _isFolder);
+    expect(children[2], _isFile);
+  }
 
-    tearDown(() {
-      tempDirectory.deleteSync(recursive: true);
-    });
+  void test_hashCode() {
+    Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path);
+    expect(folder.hashCode, equals(folder2.hashCode));
+  }
 
-    group('Watch', () {
-      Future delayed(computation()) {
-        // Give the tests 1 second to detect the changes. While it may only
-        // take up to a few hundred ms, a whole second gives a good margin
-        // for when running tests.
-        return new Future.delayed(new Duration(seconds: 1), computation);
+  void test_isOrContains() {
+    expect(folder.isOrContains(path), isTrue);
+    expect(folder.isOrContains(join(path, 'aaa.txt')), isTrue);
+    expect(folder.isOrContains(join(path, 'aaa', 'bbb.txt')), isTrue);
+    expect(folder.isOrContains(join(tempPath, 'baz.txt')), isFalse);
+  }
+
+  void test_parent() {
+    Resource parent = folder.parent;
+    expect(parent, new isInstanceOf<Folder>());
+    expect(parent.path, equals(tempPath));
+
+    // Since the OS is in control of where tempPath is, we don't know how
+    // far it should be from the root.  So just verify that each call to
+    // parent results in a a folder with a shorter path, and that we
+    // reach the root eventually.
+    while (true) {
+      Resource grandParent = parent.parent;
+      if (grandParent == null) {
+        break;
       }
+      expect(grandParent, new isInstanceOf<Folder>());
+      expect(grandParent.path.length, lessThan(parent.path.length));
+      parent = grandParent;
+    }
+  }
+}
 
-      watchingFolder(String path, test(List<WatchEvent> changesReceived)) {
-        // Delay before we start watching the folder.  This is necessary
-        // because on MacOS, file modifications that occur just before we
-        // start watching are sometimes misclassified as happening just after
-        // we start watching.
-        return delayed(() {
-          Folder folder = PhysicalResourceProvider.INSTANCE.getResource(path);
-          var changesReceived = <WatchEvent>[];
-          var subscription = folder.changes.listen(changesReceived.add);
-          // Delay running the rest of the test to allow folder.changes to
-          // take a snapshot of the current directory state.  Otherwise it
-          // won't be able to reliably distinguish new files from modified
-          // ones.
-          return delayed(() => test(changesReceived)).whenComplete(() {
-            subscription.cancel();
-          });
-        });
-      }
+@reflectiveTest
+class PhysicalResourceProviderTest extends _BaseTest {
+  void test_getStateLocation_uniqueness() {
+    PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE;
+    String idOne = 'one';
+    Folder folderOne = provider.getStateLocation(idOne);
+    expect(folderOne, isNotNull);
+    String idTwo = 'two';
+    Folder folderTwo = provider.getStateLocation(idTwo);
+    expect(folderTwo, isNotNull);
+    expect(folderTwo, isNot(equals(folderOne)));
+    expect(provider.getStateLocation(idOne), equals(folderOne));
+  }
 
-      test('create file', () => watchingFolder(tempPath, (changesReceived) {
-        expect(changesReceived, hasLength(0));
-        var path = join(tempPath, 'foo');
-        new io.File(path).writeAsStringSync('contents');
-        return delayed(() {
-          // There should be an "add" event indicating that the file was added.
-          // Depending on how long it took to write the contents, it may be
-          // followed by "modify" events.
-          expect(changesReceived, isNotEmpty);
-          expect(changesReceived[0].type, equals(ChangeType.ADD));
-          expect(changesReceived[0].path, equals(path));
-          for (int i = 1; i < changesReceived.length; i++) {
-            expect(changesReceived[i].type, equals(ChangeType.MODIFY));
-            expect(changesReceived[i].path, equals(path));
-          }
-        });
-      }));
-
-      test('modify file', () {
-        var path = join(tempPath, 'foo');
-        var file = new io.File(path);
-        file.writeAsStringSync('contents 1');
-        return watchingFolder(tempPath, (changesReceived) {
-          expect(changesReceived, hasLength(0));
-          file.writeAsStringSync('contents 2');
-          return delayed(() {
-            expect(changesReceived, hasLength(1));
-            expect(changesReceived[0].type, equals(ChangeType.MODIFY));
-            expect(changesReceived[0].path, equals(path));
-          });
-        });
-      });
-
-      test('modify file in subdir', () {
-        var subdirPath = join(tempPath, 'foo');
-        new io.Directory(subdirPath).createSync();
-        var path = join(tempPath, 'bar');
-        var file = new io.File(path);
-        file.writeAsStringSync('contents 1');
-        return watchingFolder(tempPath, (changesReceived) {
-          expect(changesReceived, hasLength(0));
-          file.writeAsStringSync('contents 2');
-          return delayed(() {
-            expect(changesReceived, hasLength(1));
-            expect(changesReceived[0].type, equals(ChangeType.MODIFY));
-            expect(changesReceived[0].path, equals(path));
-          });
-        });
-      });
-
-      test('delete file', () {
-        var path = join(tempPath, 'foo');
-        var file = new io.File(path);
-        file.writeAsStringSync('contents 1');
-        return watchingFolder(tempPath, (changesReceived) {
-          expect(changesReceived, hasLength(0));
-          file.deleteSync();
-          return delayed(() {
-            expect(changesReceived, hasLength(1));
-            expect(changesReceived[0].type, equals(ChangeType.REMOVE));
-            expect(changesReceived[0].path, equals(path));
-          });
-        });
-      });
-    });
-
-    group('getStateLocation', () {
-      test('uniqueness', () {
-        PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE;
-        String idOne = 'one';
-        Folder folderOne = provider.getStateLocation(idOne);
-        expect(folderOne, isNotNull);
-        String idTwo = 'two';
-        Folder folderTwo = provider.getStateLocation(idTwo);
-        expect(folderTwo, isNotNull);
-        expect(folderTwo, isNot(equals(folderOne)));
-        expect(provider.getStateLocation(idOne), equals(folderOne));
-      });
-    });
-
-    group('File', () {
-      String path;
-      File file;
-
-      setUp(() {
-        path = join(tempPath, 'file.txt');
-        file = PhysicalResourceProvider.INSTANCE.getResource(path);
-      });
-
-      test('createSource', () {
-        new io.File(path).writeAsStringSync('contents');
-        Source source = file.createSource();
-        expect(source.uriKind, UriKind.FILE_URI);
-        expect(source.exists(), isTrue);
-        expect(source.contents.data, 'contents');
-      });
-
-      group('exists', () {
-        test('false', () {
-          expect(file.exists, isFalse);
-        });
-
-        test('true', () {
-          new io.File(path).writeAsStringSync('contents');
-          expect(file.exists, isTrue);
-        });
-      });
-
-      test('fullName', () {
-        expect(file.path, path);
-      });
-
-      test('hashCode', () {
-        new io.File(path).writeAsStringSync('contents');
-        File file2 = PhysicalResourceProvider.INSTANCE.getResource(path);
-        expect(file.hashCode, equals(file2.hashCode));
-      });
-
-      test('equality: same path', () {
-        new io.File(path).writeAsStringSync('contents');
-        File file2 = PhysicalResourceProvider.INSTANCE.getResource(path);
-        expect(file == file2, isTrue);
-      });
-
-      test('equality: different paths', () {
-        String path2 = join(tempPath, 'file2.txt');
-        File file2 = PhysicalResourceProvider.INSTANCE.getResource(path2);
-        expect(file == file2, isFalse);
-      });
-
-      test('isOrContains', () {
-        File file = PhysicalResourceProvider.INSTANCE.getResource(path);
-        expect(file.isOrContains(path), isTrue);
-        expect(file.isOrContains('foo'), isFalse);
-      });
-
-      group('modificationStamp', () {
-        test('exists', () {
-          new io.File(path).writeAsStringSync('contents');
-          File file = PhysicalResourceProvider.INSTANCE.getResource(path);
-          expect(file.modificationStamp, isNonNegative);
-        });
-
-        test('does not exist', () {
-          File file = PhysicalResourceProvider.INSTANCE.getResource(path);
-          expect(() {
-            file.modificationStamp;
-          }, throwsA(_isFileSystemException));
-        });
-      });
-
-      test('shortName', () {
-        expect(file.shortName, 'file.txt');
-      });
-
-      test('toString', () {
-        expect(file.toString(), path);
-      });
-
-      test('parent', () {
-        Resource parent = file.parent;
-        expect(parent, new isInstanceOf<Folder>());
-        expect(parent.path, equals(tempPath));
-      });
-    });
-
-    group('Folder', () {
-      String path;
-      Folder folder;
-
-      setUp(() {
-        path = join(tempPath, 'folder');
-        new io.Directory(path).createSync();
-        folder = PhysicalResourceProvider.INSTANCE.getResource(path);
-      });
-
-      test('hashCode', () {
-        Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path);
-        expect(folder.hashCode, equals(folder2.hashCode));
-      });
-
-      test('equality: same path', () {
-        Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path);
-        expect(folder == folder2, isTrue);
-      });
-
-      test('equality: different paths', () {
-        String path2 = join(tempPath, 'folder2');
-        new io.Directory(path2).createSync();
-        Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path2);
-        expect(folder == folder2, isFalse);
-      });
-
-      test('contains', () {
-        expect(folder.contains(join(path, 'aaa.txt')), isTrue);
-        expect(folder.contains(join(path, 'aaa', 'bbb.txt')), isTrue);
-        expect(folder.contains(join(tempPath, 'baz.txt')), isFalse);
-        expect(folder.contains(path), isFalse);
-      });
-
-      test('isOrContains', () {
-        expect(folder.isOrContains(path), isTrue);
-        expect(folder.isOrContains(join(path, 'aaa.txt')), isTrue);
-        expect(folder.isOrContains(join(path, 'aaa', 'bbb.txt')), isTrue);
-        expect(folder.isOrContains(join(tempPath, 'baz.txt')), isFalse);
-      });
-
-      group('getChild', () {
-        test('does not exist', () {
-          var child = folder.getChild('no-such-resource');
-          expect(child, isNotNull);
-          expect(child.exists, isFalse);
-        });
-
-        test('file', () {
-          new io.File(join(path, 'myFile')).createSync();
-          var child = folder.getChild('myFile');
-          expect(child, _isFile);
-          expect(child.exists, isTrue);
-        });
-
-        test('folder', () {
-          new io.Directory(join(path, 'myFolder')).createSync();
-          var child = folder.getChild('myFolder');
-          expect(child, _isFolder);
-          expect(child.exists, isTrue);
-        });
-      });
-
-      group('getChildAssumingFolder', () {
-        test('does not exist', () {
-          Folder child = folder.getChildAssumingFolder('no-such-resource');
-          expect(child, isNotNull);
-          expect(child.exists, isFalse);
-        });
-
-        test('file', () {
-          new io.File(join(path, 'myFile')).createSync();
-          Folder child = folder.getChildAssumingFolder('myFile');
-          expect(child, isNotNull);
-          expect(child.exists, isFalse);
-        });
-
-        test('folder', () {
-          new io.Directory(join(path, 'myFolder')).createSync();
-          Folder child = folder.getChildAssumingFolder('myFolder');
-          expect(child, isNotNull);
-          expect(child.exists, isTrue);
-        });
-      });
-
-      test('getChildren', () {
-        // create 2 files and 1 folder
-        new io.File(join(path, 'a.txt')).createSync();
-        new io.Directory(join(path, 'bFolder')).createSync();
-        new io.File(join(path, 'c.txt')).createSync();
-        // prepare 3 children
-        List<Resource> children = folder.getChildren();
-        expect(children, hasLength(3));
-        children.sort((a, b) => a.shortName.compareTo(b.shortName));
-        // check that each child exists
-        children.forEach((child) {
-          expect(child.exists, true);
-        });
-        // check names
-        expect(children[0].shortName, 'a.txt');
-        expect(children[1].shortName, 'bFolder');
-        expect(children[2].shortName, 'c.txt');
-        // check types
-        expect(children[0], _isFile);
-        expect(children[1], _isFolder);
-        expect(children[2], _isFile);
-      });
-
-      test('parent', () {
-        Resource parent = folder.parent;
-        expect(parent, new isInstanceOf<Folder>());
-        expect(parent.path, equals(tempPath));
-
-        // Since the OS is in control of where tempPath is, we don't know how
-        // far it should be from the root.  So just verify that each call to
-        // parent results in a a folder with a shorter path, and that we
-        // reach the root eventually.
-        while (true) {
-          Resource grandParent = parent.parent;
-          if (grandParent == null) {
-            break;
-          }
-          expect(grandParent, new isInstanceOf<Folder>());
-          expect(grandParent.path.length, lessThan(parent.path.length));
-          parent = grandParent;
+  test_watch_createFile() {
+    return _watchingFolder(tempPath, (changesReceived) {
+      expect(changesReceived, hasLength(0));
+      var path = join(tempPath, 'foo');
+      new io.File(path).writeAsStringSync('contents');
+      return _delayed(() {
+        // There should be an "add" event indicating that the file was added.
+        // Depending on how long it took to write the contents, it may be
+        // followed by "modify" events.
+        expect(changesReceived, isNotEmpty);
+        expect(changesReceived[0].type, equals(ChangeType.ADD));
+        expect(changesReceived[0].path, equals(path));
+        for (int i = 1; i < changesReceived.length; i++) {
+          expect(changesReceived[i].type, equals(ChangeType.MODIFY));
+          expect(changesReceived[i].path, equals(path));
         }
       });
+    });
+  }
 
-      test('canonicalizePath', () {
-        String path2 = join(tempPath, 'folder2');
-        String path3 = join(tempPath, 'folder3');
-        expect(folder.canonicalizePath('baz'), equals(join(path, 'baz')));
-        expect(folder.canonicalizePath(path2), equals(path2));
-        expect(folder.canonicalizePath(join('..', 'folder2')), equals(path2));
-        expect(folder.canonicalizePath(join(path2, '..', 'folder3')),
-            equals(path3));
-        expect(folder.canonicalizePath(join('.', 'baz')),
-            equals(join(path, 'baz')));
-        expect(folder.canonicalizePath(join(path2, '.', 'baz')),
-            equals(join(path2, 'baz')));
+  test_watch_deleteFile() {
+    var path = join(tempPath, 'foo');
+    var file = new io.File(path);
+    file.writeAsStringSync('contents 1');
+    return _watchingFolder(tempPath, (changesReceived) {
+      expect(changesReceived, hasLength(0));
+      file.deleteSync();
+      return _delayed(() {
+        expect(changesReceived, hasLength(1));
+        expect(changesReceived[0].type, equals(ChangeType.REMOVE));
+        expect(changesReceived[0].path, equals(path));
       });
     });
-  });
+  }
+
+  test_watch_modifyFile() {
+    var path = join(tempPath, 'foo');
+    var file = new io.File(path);
+    file.writeAsStringSync('contents 1');
+    return _watchingFolder(tempPath, (changesReceived) {
+      expect(changesReceived, hasLength(0));
+      file.writeAsStringSync('contents 2');
+      return _delayed(() {
+        expect(changesReceived, hasLength(1));
+        expect(changesReceived[0].type, equals(ChangeType.MODIFY));
+        expect(changesReceived[0].path, equals(path));
+      });
+    });
+  }
+
+  test_watch_modifyFile_inSubDir() {
+    var subdirPath = join(tempPath, 'foo');
+    new io.Directory(subdirPath).createSync();
+    var path = join(tempPath, 'bar');
+    var file = new io.File(path);
+    file.writeAsStringSync('contents 1');
+    return _watchingFolder(tempPath, (changesReceived) {
+      expect(changesReceived, hasLength(0));
+      file.writeAsStringSync('contents 2');
+      return _delayed(() {
+        expect(changesReceived, hasLength(1));
+        expect(changesReceived[0].type, equals(ChangeType.MODIFY));
+        expect(changesReceived[0].path, equals(path));
+      });
+    });
+  }
+
+  Future _delayed(computation()) {
+    // Give the tests 1 second to detect the changes. While it may only
+    // take up to a few hundred ms, a whole second gives a good margin
+    // for when running tests.
+    return new Future.delayed(new Duration(seconds: 1), computation);
+  }
+
+  _watchingFolder(String path, test(List<WatchEvent> changesReceived)) {
+    // Delay before we start watching the folder.  This is necessary
+    // because on MacOS, file modifications that occur just before we
+    // start watching are sometimes misclassified as happening just after
+    // we start watching.
+    return _delayed(() {
+      Folder folder = PhysicalResourceProvider.INSTANCE.getResource(path);
+      var changesReceived = <WatchEvent>[];
+      var subscription = folder.changes.listen(changesReceived.add);
+      // Delay running the rest of the test to allow folder.changes to
+      // take a snapshot of the current directory state.  Otherwise it
+      // won't be able to reliably distinguish new files from modified
+      // ones.
+      return _delayed(() => test(changesReceived)).whenComplete(() {
+        subscription.cancel();
+      });
+    });
+  }
+}
+
+class _BaseTest {
+  io.Directory tempDirectory;
+  String tempPath;
+
+  setUp() {
+    tempDirectory = io.Directory.systemTemp.createTempSync('test_resource');
+    tempPath = tempDirectory.absolute.path;
+  }
+
+  tearDown() {
+    tempDirectory.deleteSync(recursive: true);
+  }
 }
diff --git a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
index 95b0ffa..b888c56 100644
--- a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
+++ b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
@@ -9,39 +9,49 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:unittest/unittest.dart';
 
+import '../reflective_tests.dart';
+
 main() {
   groupSep = ' | ';
-  group('ResourceUriResolver', () {
-    MemoryResourceProvider provider;
-    ResourceUriResolver resolver;
+  runReflectiveTests(ResourceUriResolverTest);
+}
 
-    setUp(() {
-      provider = new MemoryResourceProvider();
-      resolver = new ResourceUriResolver(provider);
-      provider.newFile('/test.dart', '');
-      provider.newFolder('/folder');
-    });
+@reflectiveTest
+class ResourceUriResolverTest {
+  MemoryResourceProvider provider;
+  ResourceUriResolver resolver;
 
-    group('resolveAbsolute', () {
-      test('file', () {
-        var uri = new Uri(scheme: 'file', path: '/test.dart');
-        Source source = resolver.resolveAbsolute(uri);
-        expect(source, isNotNull);
-        expect(source.exists(), isTrue);
-        expect(source.fullName, '/test.dart');
-      });
+  void setUp() {
+    provider = new MemoryResourceProvider();
+    resolver = new ResourceUriResolver(provider);
+    provider.newFile('/test.dart', '');
+    provider.newFolder('/folder');
+  }
 
-      test('folder', () {
-        var uri = new Uri(scheme: 'file', path: '/folder');
-        Source source = resolver.resolveAbsolute(uri);
-        expect(source, isNull);
-      });
+  void test_resolveAbsolute_file() {
+    var uri = new Uri(scheme: 'file', path: '/test.dart');
+    Source source = resolver.resolveAbsolute(uri);
+    expect(source, isNotNull);
+    expect(source.exists(), isTrue);
+    expect(source.fullName, '/test.dart');
+  }
 
-      test('not a file URI', () {
-        var uri = new Uri(scheme: 'https', path: '127.0.0.1/test.dart');
-        Source source = resolver.resolveAbsolute(uri);
-        expect(source, isNull);
-      });
-    });
-  });
+  void test_resolveAbsolute_folder() {
+    var uri = new Uri(scheme: 'file', path: '/folder');
+    Source source = resolver.resolveAbsolute(uri);
+    expect(source, isNull);
+  }
+
+  void test_resolveAbsolute_notFile() {
+    var uri = new Uri(scheme: 'https', path: '127.0.0.1/test.dart');
+    Source source = resolver.resolveAbsolute(uri);
+    expect(source, isNull);
+  }
+
+  void test_restoreAbsolute() {
+    var uri = new Uri(scheme: 'file', path: '/test.dart');
+    Source source = resolver.resolveAbsolute(uri);
+    expect(source, isNotNull);
+    expect(resolver.restoreAbsolute(source), uri);
+  }
 }
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 2c317aa..23959e4 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -589,7 +589,7 @@
   }
 
   void test_divide_int_int() {
-    _assertValue3(1, "3 / 2");
+    _assertValue2(1.5, "3 / 2");
   }
   void test_divide_int_int_byZero() {
     EvaluationResult result = _getExpressionValue("3 / 0");
@@ -842,8 +842,8 @@
     NodeList<VariableDeclaration> variables =
         (declaration as TopLevelVariableDeclaration).variables.variables;
     expect(variables, hasLength(1));
-    ConstantEvaluator evaluator = new ConstantEvaluator(
-        source, (analysisContext as AnalysisContextImpl).typeProvider);
+    ConstantEvaluator evaluator =
+        new ConstantEvaluator(source, analysisContext.typeProvider);
     return evaluator.evaluate(variables[0].initializer);
   }
 }
@@ -2576,7 +2576,7 @@
   }
 
   void test_divide_knownInt_knownInt() {
-    _assertDivide(_intValue(3), _intValue(6), _intValue(2));
+    _assertDivide(_doubleValue(3.0), _intValue(6), _intValue(2));
   }
 
   void test_divide_knownInt_knownString() {
@@ -2588,7 +2588,7 @@
   }
 
   void test_divide_knownInt_unknownInt() {
-    _assertDivide(_intValue(null), _intValue(6), _intValue(null));
+    _assertDivide(_doubleValue(null), _intValue(6), _intValue(null));
   }
 
   void test_divide_knownString_knownInt() {
@@ -2608,7 +2608,7 @@
   }
 
   void test_divide_unknownInt_knownInt() {
-    _assertDivide(_intValue(null), _intValue(null), _intValue(2));
+    _assertDivide(_doubleValue(null), _intValue(null), _intValue(2));
   }
 
   void test_equalEqual_bool_false() {
@@ -3322,7 +3322,7 @@
     try {
       _assertLogicalAnd(_boolValue(false), _boolValue(false), _nullValue());
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalAnd_false_string() {
@@ -3330,7 +3330,7 @@
       _assertLogicalAnd(
           _boolValue(false), _boolValue(false), _stringValue("false"));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalAnd_false_true() {
@@ -3341,14 +3341,14 @@
     try {
       _assertLogicalAnd(_boolValue(false), _nullValue(), _boolValue(false));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalAnd_null_true() {
     try {
       _assertLogicalAnd(_boolValue(false), _nullValue(), _boolValue(true));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalAnd_string_false() {
@@ -3356,7 +3356,7 @@
       _assertLogicalAnd(
           _boolValue(false), _stringValue("true"), _boolValue(false));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalAnd_string_true() {
@@ -3364,7 +3364,7 @@
       _assertLogicalAnd(
           _boolValue(false), _stringValue("false"), _boolValue(true));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalAnd_true_false() {
@@ -3380,7 +3380,7 @@
       _assertLogicalAnd(
           _boolValue(false), _boolValue(true), _stringValue("true"));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalAnd_true_true() {
@@ -3399,7 +3399,7 @@
     try {
       _assertLogicalNot(_boolValue(true), _stringValue(null));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalNot_true() {
@@ -3423,7 +3423,7 @@
       _assertLogicalOr(
           _boolValue(false), _boolValue(false), _stringValue("false"));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalOr_false_true() {
@@ -3434,14 +3434,14 @@
     try {
       _assertLogicalOr(_boolValue(false), _nullValue(), _boolValue(false));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalOr_null_true() {
     try {
       _assertLogicalOr(_boolValue(true), _nullValue(), _boolValue(true));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalOr_string_false() {
@@ -3449,7 +3449,7 @@
       _assertLogicalOr(
           _boolValue(false), _stringValue("true"), _boolValue(false));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalOr_string_true() {
@@ -3457,7 +3457,7 @@
       _assertLogicalOr(
           _boolValue(true), _stringValue("false"), _boolValue(true));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalOr_true_false() {
@@ -3468,7 +3468,7 @@
     try {
       _assertLogicalOr(_boolValue(true), _boolValue(true), _nullValue());
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalOr_true_string() {
@@ -3476,7 +3476,7 @@
       _assertLogicalOr(
           _boolValue(true), _boolValue(true), _stringValue("true"));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_logicalOr_true_true() {
@@ -3762,7 +3762,7 @@
     try {
       _assertStringLength(_intValue(null), _intValue(0));
       fail("Expected EvaluationException");
-    } on EvaluationException catch (exception) {}
+    } on EvaluationException {}
   }
 
   void test_stringLength_knownString() {
@@ -3840,7 +3840,7 @@
       try {
         leftOperand.add(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = leftOperand.add(_typeProvider, rightOperand);
       expect(result, isNotNull);
@@ -3863,7 +3863,7 @@
       try {
         leftOperand.bitAnd(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = leftOperand.bitAnd(_typeProvider, rightOperand);
       expect(result, isNotNull);
@@ -3884,7 +3884,7 @@
       try {
         operand.bitNot(_typeProvider);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = operand.bitNot(_typeProvider);
       expect(result, isNotNull);
@@ -3907,7 +3907,7 @@
       try {
         leftOperand.bitOr(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = leftOperand.bitOr(_typeProvider, rightOperand);
       expect(result, isNotNull);
@@ -3930,7 +3930,7 @@
       try {
         leftOperand.bitXor(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = leftOperand.bitXor(_typeProvider, rightOperand);
       expect(result, isNotNull);
@@ -3953,7 +3953,7 @@
       try {
         leftOperand.concatenate(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result =
           leftOperand.concatenate(_typeProvider, rightOperand);
@@ -3977,7 +3977,7 @@
       try {
         leftOperand.divide(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = leftOperand.divide(_typeProvider, rightOperand);
       expect(result, isNotNull);
@@ -4000,7 +4000,7 @@
       try {
         leftOperand.equalEqual(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result =
           leftOperand.equalEqual(_typeProvider, rightOperand);
@@ -4024,7 +4024,7 @@
       try {
         leftOperand.greaterThan(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result =
           leftOperand.greaterThan(_typeProvider, rightOperand);
@@ -4048,7 +4048,7 @@
       try {
         leftOperand.greaterThanOrEqual(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result =
           leftOperand.greaterThanOrEqual(_typeProvider, rightOperand);
@@ -4092,7 +4092,7 @@
       try {
         leftOperand.integerDivide(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result =
           leftOperand.integerDivide(_typeProvider, rightOperand);
@@ -4116,7 +4116,7 @@
       try {
         leftOperand.lessThan(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = leftOperand.lessThan(_typeProvider, rightOperand);
       expect(result, isNotNull);
@@ -4139,7 +4139,7 @@
       try {
         leftOperand.lessThanOrEqual(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result =
           leftOperand.lessThanOrEqual(_typeProvider, rightOperand);
@@ -4163,7 +4163,7 @@
       try {
         leftOperand.logicalAnd(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result =
           leftOperand.logicalAnd(_typeProvider, rightOperand);
@@ -4185,7 +4185,7 @@
       try {
         operand.logicalNot(_typeProvider);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = operand.logicalNot(_typeProvider);
       expect(result, isNotNull);
@@ -4208,7 +4208,7 @@
       try {
         leftOperand.logicalOr(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result =
           leftOperand.logicalOr(_typeProvider, rightOperand);
@@ -4232,7 +4232,7 @@
       try {
         leftOperand.minus(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = leftOperand.minus(_typeProvider, rightOperand);
       expect(result, isNotNull);
@@ -4253,7 +4253,7 @@
       try {
         operand.negated(_typeProvider);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = operand.negated(_typeProvider);
       expect(result, isNotNull);
@@ -4276,7 +4276,7 @@
       try {
         leftOperand.notEqual(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = leftOperand.notEqual(_typeProvider, rightOperand);
       expect(result, isNotNull);
@@ -4297,7 +4297,7 @@
       try {
         operand.performToString(_typeProvider);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = operand.performToString(_typeProvider);
       expect(result, isNotNull);
@@ -4320,7 +4320,7 @@
       try {
         leftOperand.remainder(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result =
           leftOperand.remainder(_typeProvider, rightOperand);
@@ -4344,7 +4344,7 @@
       try {
         leftOperand.shiftLeft(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result =
           leftOperand.shiftLeft(_typeProvider, rightOperand);
@@ -4368,7 +4368,7 @@
       try {
         leftOperand.shiftRight(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result =
           leftOperand.shiftRight(_typeProvider, rightOperand);
@@ -4390,7 +4390,7 @@
       try {
         operand.stringLength(_typeProvider);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = operand.stringLength(_typeProvider);
       expect(result, isNotNull);
@@ -4413,7 +4413,7 @@
       try {
         leftOperand.times(_typeProvider, rightOperand);
         fail("Expected an EvaluationException");
-      } on EvaluationException catch (exception) {}
+      } on EvaluationException {}
     } else {
       DartObjectImpl result = leftOperand.times(_typeProvider, rightOperand);
       expect(result, isNotNull);
@@ -4684,14 +4684,6 @@
     expect(executable.isExecutable(), isTrue);
   }
 
-  void test_getDartFmtExecutable() {
-    DirectoryBasedDartSdk sdk = _createDartSdk();
-    JavaFile executable = sdk.dartFmtExecutable;
-    expect(executable, isNotNull);
-    expect(executable.exists(), isTrue);
-    expect(executable.isExecutable(), isTrue);
-  }
-
   void test_getDirectory() {
     DirectoryBasedDartSdk sdk = _createDartSdk();
     JavaFile directory = sdk.directory;
@@ -8043,14 +8035,14 @@
     try {
       factory.fromEncoding("<:&%>");
       fail("Expected IllegalArgumentException");
-    } on IllegalArgumentException catch (exception) {}
+    } on IllegalArgumentException {}
   }
   void test_fromEncoding_noResolver() {
     SourceFactory factory = new SourceFactory([]);
     try {
       factory.fromEncoding("foo:/does/not/exist.dart");
       fail("Expected IllegalArgumentException");
-    } on IllegalArgumentException catch (exception) {}
+    } on IllegalArgumentException {}
   }
   void test_fromEncoding_valid() {
     String encoding = "file:///does/not/exist.dart";
diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart
index 347c87e..51ad0ca 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -522,7 +522,7 @@
   }
 
   Object _getConstantValue(String source) =>
-      ParserTestCase.parseExpression(source).accept(new ConstantEvaluator());
+      parseExpression(source).accept(new ConstantEvaluator());
 }
 
 @reflectiveTest
@@ -728,7 +728,7 @@
     try {
       list.insert(-1, AstFactory.booleanLiteral(true));
       fail("Expected IndexOutOfBoundsException");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
@@ -738,7 +738,7 @@
     try {
       list.insert(1, AstFactory.booleanLiteral(true));
       fail("Expected IndexOutOfBoundsException");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
@@ -787,7 +787,7 @@
     try {
       list[-1];
       fail("Expected IndexOutOfBoundsException");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
@@ -797,7 +797,7 @@
     try {
       list[1];
       fail("Expected IndexOutOfBoundsException");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
@@ -869,7 +869,7 @@
     try {
       list.removeAt(-1);
       fail("Expected IndexOutOfBoundsException");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
@@ -879,7 +879,7 @@
     try {
       list.removeAt(1);
       fail("Expected IndexOutOfBoundsException");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
@@ -909,7 +909,7 @@
     try {
       javaListSet(list, -1, node);
       fail("Expected IndexOutOfBoundsException");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
@@ -920,7 +920,7 @@
     try {
       javaListSet(list, 1, node);
       fail("Expected IndexOutOfBoundsException");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
diff --git a/pkg/analyzer/test/generated/element_test.dart b/pkg/analyzer/test/generated/element_test.dart
index f94b44a..70509b3 100644
--- a/pkg/analyzer/test/generated/element_test.dart
+++ b/pkg/analyzer/test/generated/element_test.dart
@@ -25,6 +25,7 @@
 main() {
   groupSep = ' | ';
   runReflectiveTests(ElementKindTest);
+  runReflectiveTests(FieldElementImplTest);
   runReflectiveTests(FunctionTypeImplTest);
   runReflectiveTests(InterfaceTypeImplTest);
   runReflectiveTests(TypeParameterTypeImplTest);
@@ -113,33 +114,6 @@
     expect(classA.getMethod("${methodName}x"), isNull);
   }
 
-  void test_getNode() {
-    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
-    AnalysisContext context = contextHelper.context;
-    Source source = contextHelper.addSource("/test.dart", r'''
-class A {}
-class B {}''');
-    // prepare CompilationUnitElement
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
-    // A
-    {
-      ClassElement elementA = unitElement.getType("A");
-      ClassDeclaration nodeA = elementA.node;
-      expect(nodeA, isNotNull);
-      expect(nodeA.name.name, "A");
-      expect(nodeA.element, same(elementA));
-    }
-    // B
-    {
-      ClassElement elementB = unitElement.getType("B");
-      ClassDeclaration nodeB = elementB.node;
-      expect(nodeB, isNotNull);
-      expect(nodeB.name.name, "B");
-      expect(nodeB.element, same(elementB));
-    }
-  }
-
   void test_hasNonFinalField_false_const() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     classA.fields = <FieldElement>[
@@ -883,6 +857,61 @@
         <ClassElement>[classA, classB];
     expect(classA.lookUpSetter("s", library), isNull);
   }
+
+  void test_node_ClassDeclaration() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource("/test.dart", r'''
+class A {}
+class B {}
+enum C {C1, C2, C3}''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // A
+    {
+      ClassElement elementA = unitElement.getType("A");
+      ClassDeclaration nodeA = elementA.node;
+      expect(nodeA, isNotNull);
+      expect(nodeA.name.name, "A");
+      expect(nodeA.element, same(elementA));
+    }
+    // B
+    {
+      ClassElement elementB = unitElement.getType("B");
+      ClassDeclaration nodeB = elementB.node;
+      expect(nodeB, isNotNull);
+      expect(nodeB.name.name, "B");
+      expect(nodeB.element, same(elementB));
+    }
+    // C
+    {
+      ClassElement elementC = unitElement.getEnum("C");
+      EnumDeclaration nodeC = elementC.node;
+      expect(nodeC, isNotNull);
+      expect(nodeC.name.name, "C");
+      expect(nodeC.element, same(elementC));
+    }
+  }
+
+  void test_node_ClassTypeAlias() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource("/test.dart", r'''
+abstract class A<K, V> = Object with MapMixin<K, V>;
+''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // A
+    {
+      ClassElement elementA = unitElement.getType("A");
+      ClassTypeAlias nodeA = elementA.node;
+      expect(nodeA, isNotNull);
+      expect(nodeA.name.name, "A");
+      expect(nodeA.element, same(elementA));
+    }
+  }
 }
 
 @reflectiveTest
@@ -1102,6 +1131,38 @@
 }
 
 @reflectiveTest
+class FieldElementImplTest extends EngineTestCase {
+  void test_node() {
+    AnalysisContextHelper contextHelper = new AnalysisContextHelper();
+    AnalysisContext context = contextHelper.context;
+    Source source = contextHelper.addSource("/test.dart", r'''
+class A {
+  int a;
+}
+enum B {B1, B2, B3}''');
+    // prepare CompilationUnitElement
+    LibraryElement libraryElement = context.computeLibraryElement(source);
+    CompilationUnitElement unitElement = libraryElement.definingCompilationUnit;
+    // A
+    {
+      FieldElement elementA = unitElement.getType("A").getField('a');
+      VariableDeclaration nodeA = elementA.node;
+      expect(nodeA, isNotNull);
+      expect(nodeA.name.name, "a");
+      expect(nodeA.element, same(elementA));
+    }
+    // B
+    {
+      FieldElement elementB = unitElement.getEnum("B").getField('B2');
+      EnumConstantDeclaration nodeB = elementB.node;
+      expect(nodeB, isNotNull);
+      expect(nodeB.name.name, "B2");
+      expect(nodeB.element, same(elementB));
+    }
+  }
+}
+
+@reflectiveTest
 class FunctionTypeImplTest extends EngineTestCase {
   void test_creation() {
     expect(new FunctionTypeImpl.con1(
@@ -1218,12 +1279,12 @@
 
   void test_isSubtypeOf_namedParameters_isNotAssignable() {
     // ! ({name: A}) -> void <: ({name: B}) -> void
-    FunctionType t = ElementFactory.functionElement4("t", null, null, <String>[
-      "name"
-    ], <ClassElement>[ElementFactory.classElement2("A")]).type;
-    FunctionType s = ElementFactory.functionElement4("s", null, null, <String>[
-      "name"
-    ], <ClassElement>[ElementFactory.classElement2("B")]).type;
+    FunctionType t = ElementFactory.functionElement4("t", null, null,
+        <String>["name"],
+        <ClassElement>[ElementFactory.classElement2("A")]).type;
+    FunctionType s = ElementFactory.functionElement4("s", null, null,
+        <String>["name"],
+        <ClassElement>[ElementFactory.classElement2("B")]).type;
     expect(t.isSubtypeOf(s), isFalse);
   }
 
@@ -3426,12 +3487,10 @@
     AnalysisContext context = createAnalysisContext();
     LibraryElementImpl library = ElementFactory.library(context, "app");
     LibraryElementImpl libraryA = ElementFactory.library(context, "A");
-    libraryA.imports = <ImportElementImpl>[
-      ElementFactory.importFor(library, null)
-    ];
-    library.imports = <ImportElementImpl>[
-      ElementFactory.importFor(libraryA, null)
-    ];
+    libraryA.imports =
+        <ImportElementImpl>[ElementFactory.importFor(library, null)];
+    library.imports =
+        <ImportElementImpl>[ElementFactory.importFor(libraryA, null)];
     List<LibraryElement> libraries = library.visibleLibraries;
     expect(libraries, unorderedEquals(<LibraryElement>[library, libraryA]));
   }
@@ -3449,9 +3508,8 @@
     AnalysisContext context = createAnalysisContext();
     LibraryElementImpl library = ElementFactory.library(context, "app");
     LibraryElementImpl libraryA = ElementFactory.library(context, "A");
-    library.imports = <ImportElementImpl>[
-      ElementFactory.importFor(libraryA, null)
-    ];
+    library.imports =
+        <ImportElementImpl>[ElementFactory.importFor(libraryA, null)];
     List<LibraryElement> libraries = library.visibleLibraries;
     expect(libraries, unorderedEquals(<LibraryElement>[library, libraryA]));
   }
@@ -3462,9 +3520,8 @@
     LibraryElementImpl libraryA = ElementFactory.library(context, "A");
     LibraryElementImpl libraryAA = ElementFactory.library(context, "AA");
     libraryA.exports = <ExportElementImpl>[ElementFactory.exportFor(libraryAA)];
-    library.imports = <ImportElementImpl>[
-      ElementFactory.importFor(libraryA, null)
-    ];
+    library.imports =
+        <ImportElementImpl>[ElementFactory.importFor(libraryA, null)];
     List<LibraryElement> libraries = library.visibleLibraries;
     expect(libraries,
         unorderedEquals(<LibraryElement>[library, libraryA, libraryAA]));
@@ -3476,9 +3533,8 @@
     LibraryElementImpl libraryA = ElementFactory.library(context, "A");
     LibraryElementImpl libraryAA = ElementFactory.library(context, "AA");
     LibraryElementImpl libraryB = ElementFactory.library(context, "B");
-    libraryA.imports = <ImportElementImpl>[
-      ElementFactory.importFor(libraryAA, null)
-    ];
+    libraryA.imports =
+        <ImportElementImpl>[ElementFactory.importFor(libraryAA, null)];
     library.imports = <ImportElementImpl>[
       ElementFactory.importFor(libraryA, null),
       ElementFactory.importFor(libraryB, null)
@@ -3730,7 +3786,7 @@
   void test_emptyUnionsNotAllowed() {
     try {
       UnionTypeImpl.union([]);
-    } on IllegalArgumentException catch (e) {
+    } on IllegalArgumentException {
       return;
     }
     fail("Expected illegal argument exception.");
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 2b2c5f3..52b8c40 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -205,8 +205,9 @@
     _analyzeAll_assertFinished();
     expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
         reason: "htmlUnit resolved 1");
-    expect(_context.getResolvedCompilationUnit2(libBSource, libBSource),
-        isNotNull, reason: "libB resolved 1");
+    expect(
+        _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
+        reason: "libB resolved 1");
     expect(!_hasAnalysisErrorWithErrorSeverity(_context.getErrors(htmlSource)),
         isTrue, reason: "htmlSource doesn't have errors");
     // remove libB.dart content and analyze
@@ -655,7 +656,7 @@
     try {
       _context.computeResolvableCompilationUnit(source);
       fail("Expected AnalysisException");
-    } on AnalysisException catch (exception) {
+    } on AnalysisException {
       // Expected
     }
   }
@@ -665,7 +666,7 @@
     try {
       _context.computeResolvableCompilationUnit(source);
       fail("Expected AnalysisException");
-    } on AnalysisException catch (exception) {
+    } on AnalysisException {
       // Expected
     }
   }
@@ -690,8 +691,9 @@
     DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
     dartEntry.flushAstStructures();
     bool completed = false;
-    _context.computeResolvedCompilationUnitAsync(source, source).then(
-        (CompilationUnit unit) {
+    _context
+        .computeResolvedCompilationUnitAsync(source, source)
+        .then((CompilationUnit unit) {
       expect(unit, isNotNull);
       completed = true;
     });
@@ -1362,7 +1364,7 @@
     try {
       _context.parseCompilationUnit(source);
       fail("Expected AnalysisException");
-    } on AnalysisException catch (exception) {
+    } on AnalysisException {
       // Expected
     }
   }
@@ -1385,7 +1387,7 @@
     try {
       _context.parseCompilationUnit(source);
       fail("Expected AnalysisException because file does not exist");
-    } on AnalysisException catch (exception) {
+    } on AnalysisException {
       // Expected result
     }
   }
@@ -1684,8 +1686,9 @@
     _analyzeAll_assertFinished();
     expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
         reason: "htmlUnit resolved 1");
-    expect(_context.getResolvedCompilationUnit2(libBSource, libBSource),
-        isNotNull, reason: "libB resolved 2");
+    expect(
+        _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
+        reason: "libB resolved 2");
     // TODO (danrubel) commented out to fix red bots
 //    AnalysisErrorInfo errors = _context.getErrors(htmlSource);
 //    expect(
@@ -2218,6 +2221,7 @@
       options.analyzeFunctionBodies = booleanValue;
       options.cacheSize = i;
       options.dart2jsHint = booleanValue;
+      options.enableStrictCallChecks = booleanValue;
       options.generateImplicitErrors = booleanValue;
       options.generateSdkErrors = booleanValue;
       options.hint = booleanValue;
@@ -2227,6 +2231,7 @@
       expect(copy.analyzeFunctionBodies, options.analyzeFunctionBodies);
       expect(copy.cacheSize, options.cacheSize);
       expect(copy.dart2jsHint, options.dart2jsHint);
+      expect(copy.enableStrictCallChecks, options.enableStrictCallChecks);
       expect(copy.generateImplicitErrors, options.generateImplicitErrors);
       expect(copy.generateSdkErrors, options.generateSdkErrors);
       expect(copy.hint, options.hint);
@@ -2349,9 +2354,8 @@
       new AnalysisError.con1(
           source, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED)
     ]);
-    entry.setValueInLibrary(DartEntry.HINTS, source, <AnalysisError>[
-      new AnalysisError.con1(source, HintCode.DEAD_CODE)
-    ]);
+    entry.setValueInLibrary(DartEntry.HINTS, source,
+        <AnalysisError>[new AnalysisError.con1(source, HintCode.DEAD_CODE)]);
     expect(entry.allErrors, hasLength(6));
   }
 
@@ -2485,8 +2489,8 @@
     DartEntry entry = new DartEntry();
     try {
       entry.getState(DartEntry.RESOLUTION_ERRORS);
-      fail("Expected IllegalArgumentException for RESOLUTION_ERRORS");
-    } on ArgumentError catch (exception) {
+      fail("Expected ArgumentError for RESOLUTION_ERRORS");
+    } on ArgumentError {
       // Expected
     }
   }
@@ -2495,8 +2499,8 @@
     DartEntry entry = new DartEntry();
     try {
       entry.getState(DartEntry.VERIFICATION_ERRORS);
-      fail("Expected IllegalArgumentException for VERIFICATION_ERRORS");
-    } on ArgumentError catch (exception) {
+      fail("Expected ArgumentError for VERIFICATION_ERRORS");
+    } on ArgumentError {
       // Expected
     }
   }
@@ -2505,8 +2509,8 @@
     DartEntry entry = new DartEntry();
     try {
       entry.getStateInLibrary(DartEntry.ELEMENT, new TestSource());
-      fail("Expected IllegalArgumentException for ELEMENT");
-    } on ArgumentError catch (exception) {
+      fail("Expected ArgumentError for ELEMENT");
+    } on ArgumentError {
       // Expected
     }
   }
@@ -2529,16 +2533,16 @@
     DartEntry entry = new DartEntry();
     try {
       entry.getValue(DartEntry.RESOLUTION_ERRORS);
-      fail("Expected IllegalArgumentException for RESOLUTION_ERRORS");
-    } on ArgumentError catch (exception) {}
+      fail("Expected ArgumentError for RESOLUTION_ERRORS");
+    } on ArgumentError {}
   }
 
   void test_getValue_invalid_verificationErrors() {
     DartEntry entry = new DartEntry();
     try {
       entry.getValue(DartEntry.VERIFICATION_ERRORS);
-      fail("Expected IllegalArgumentException for VERIFICATION_ERRORS");
-    } on ArgumentError catch (exception) {
+      fail("Expected ArgumentError for VERIFICATION_ERRORS");
+    } on ArgumentError {
       // Expected
     }
   }
@@ -2547,8 +2551,8 @@
     DartEntry entry = new DartEntry();
     try {
       entry.getValueInLibrary(DartEntry.ELEMENT, new TestSource());
-      fail("Expected IllegalArgumentException for ELEMENT");
-    } on ArgumentError catch (exception) {
+      fail("Expected ArgumentError for ELEMENT");
+    } on ArgumentError {
       // Expected
     }
   }
@@ -2566,8 +2570,8 @@
         DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
     try {
       entry.getValueInLibrary(DartEntry.ELEMENT, source3);
-      fail("Expected IllegalArgumentException for ELEMENT");
-    } on ArgumentError catch (exception) {
+      fail("Expected ArgumentError for ELEMENT");
+    } on ArgumentError {
       // Expected
     }
   }
@@ -3299,8 +3303,8 @@
     DartEntry entry = new DartEntry();
     try {
       entry.setStateInLibrary(DartEntry.ELEMENT, null, CacheState.FLUSHED);
-      fail("Expected IllegalArgumentException for ELEMENT");
-    } on ArgumentError catch (exception) {
+      fail("Expected ArgumentError for ELEMENT");
+    } on ArgumentError {
       // Expected
     }
   }
@@ -3309,8 +3313,8 @@
     DartEntry entry = new DartEntry();
     try {
       entry.setState(DartEntry.RESOLUTION_ERRORS, CacheState.FLUSHED);
-      fail("Expected IllegalArgumentException for RESOLUTION_ERRORS");
-    } on ArgumentError catch (exception) {
+      fail("Expected ArgumentError for RESOLUTION_ERRORS");
+    } on ArgumentError {
       // Expected
     }
   }
@@ -3320,15 +3324,15 @@
     try {
       entry.setState(SourceEntry.LINE_INFO, CacheState.VALID);
       fail("Expected ArgumentError for a state of VALID");
-    } on ArgumentError catch (exception) {}
+    } on ArgumentError {}
   }
 
   void test_setState_invalid_verificationErrors() {
     DartEntry entry = new DartEntry();
     try {
       entry.setState(DartEntry.VERIFICATION_ERRORS, CacheState.FLUSHED);
-      fail("Expected IllegalArgumentException for VERIFICATION_ERRORS");
-    } on ArgumentError catch (exception) {
+      fail("Expected ArgumentError for VERIFICATION_ERRORS");
+    } on ArgumentError {
       // Expected
     }
   }
@@ -3391,9 +3395,8 @@
   }
 
   void test_setValue_hints() {
-    _setValueInLibrary(DartEntry.HINTS, <AnalysisError>[
-      new AnalysisError.con1(null, HintCode.DEAD_CODE)
-    ]);
+    _setValueInLibrary(DartEntry.HINTS,
+        <AnalysisError>[new AnalysisError.con1(null, HintCode.DEAD_CODE)]);
   }
 
   void test_setValue_importedLibraries() {
@@ -3951,9 +3954,8 @@
     entry.setValue(HtmlEntry.RESOLUTION_ERRORS, <AnalysisError>[
       new AnalysisError.con1(source, HtmlWarningCode.INVALID_URI, ["-"])
     ]);
-    entry.setValue(HtmlEntry.HINTS, <AnalysisError>[
-      new AnalysisError.con1(source, HintCode.DEAD_CODE)
-    ]);
+    entry.setValue(HtmlEntry.HINTS,
+        <AnalysisError>[new AnalysisError.con1(source, HintCode.DEAD_CODE)]);
     expect(entry.allErrors, hasLength(3));
   }
 
@@ -4018,17 +4020,16 @@
   }
 
   void test_setValue_hints() {
-    _setValue(HtmlEntry.HINTS, <AnalysisError>[
-      new AnalysisError.con1(null, HintCode.DEAD_CODE)
-    ]);
+    _setValue(HtmlEntry.HINTS,
+        <AnalysisError>[new AnalysisError.con1(null, HintCode.DEAD_CODE)]);
   }
 
   void test_setValue_illegal() {
     HtmlEntry entry = new HtmlEntry();
     try {
       entry.setValue(DartEntry.ELEMENT, null);
-      fail("Expected IllegalArgumentException for DartEntry.ELEMENT");
-    } on ArgumentError catch (exception) {}
+      fail("Expected ArgumentError for DartEntry.ELEMENT");
+    } on ArgumentError {}
   }
 
   void test_setValue_lineInfo() {
@@ -4875,7 +4876,7 @@
   Uri resolveRelativeUri(Uri containedUri) {
     try {
       return parseUriWithException("file:/does/not/exist.dart");
-    } on URISyntaxException catch (exception) {
+    } on URISyntaxException {
       return null;
     }
   }
@@ -5495,6 +5496,10 @@
     return null;
   }
   @override
+  void set typeProvider(TypeProvider typeProvider) {
+    fail("Unexpected invocation of set typeProvider");
+  }
+  @override
   TypeResolverVisitorFactory get typeResolverVisitorFactory {
     fail("Unexpected invocation of getTypeResolverVisitorFactory");
     return null;
@@ -5734,6 +5739,7 @@
     fail("Unexpected invocation of resolveHtmlUnit");
     return null;
   }
+
   @override
   void setChangedContents(Source source, String contents, int offset,
       int oldLength, int newLength) {
@@ -6495,7 +6501,7 @@
     try {
       iterator.next();
       fail("Expected NoSuchElementException");
-    } on NoSuchElementException catch (exception) {}
+    } on NoSuchElementException {}
   }
   void test_iterator_nonEmpty() {
     TestSource source = new TestSource();
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 3c57a97..8b664f9 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -910,6 +910,30 @@
 ''');
   }
 
+  void test_false_getter_body_add() {
+    _assertDoesNotMatchOK(r'''
+class A {
+  int get foo;
+}
+''', r'''
+class A {
+  int get foo => 0;
+}
+''');
+  }
+
+  void test_false_getter_body_remove() {
+    _assertDoesNotMatchOK(r'''
+class A {
+  int get foo => 0;
+}
+''', r'''
+class A {
+  int get foo;
+}
+''');
+  }
+
   void test_false_implementsClause_add() {
     _assertDoesNotMatch(r'''
 class A {}
@@ -1088,6 +1112,30 @@
 ''');
   }
 
+  void test_false_method_body_add() {
+    _assertDoesNotMatchOK(r'''
+class A {
+  void foo();
+}
+''', r'''
+class A {
+  void foo() {}
+}
+''');
+  }
+
+  void test_false_method_body_remove() {
+    _assertDoesNotMatchOK(r'''
+class A {
+  void foo() {}
+}
+''', r'''
+class A {
+  void foo();
+}
+''');
+  }
+
   void test_false_method_generator_add() {
     _assertDoesNotMatchOK(r'''
 class A {
@@ -1622,6 +1670,30 @@
 ''');
   }
 
+  void test_true_constructor_body_add() {
+    _assertMatches(r'''
+class A {
+  A(int p);
+}
+''', r'''
+class A {
+  A(int p) {}
+}
+''');
+  }
+
+  void test_true_constructor_body_remove() {
+    _assertMatches(r'''
+class A {
+  A(int p) {}
+}
+''', r'''
+class A {
+  A(int p);
+}
+''');
+  }
+
   void test_true_constructor_named_same() {
     _assertMatches(r'''
 class A {
@@ -3807,7 +3879,7 @@
     try {
       _scopeFor(AstFactory.identifier3("x"));
       fail("Expected AnalysisException");
-    } on AnalysisException catch (exception) {
+    } on AnalysisException {
       // Expected
     }
   }
@@ -3816,7 +3888,7 @@
     try {
       _scopeFor(null);
       fail("Expected AnalysisException");
-    } on AnalysisException catch (exception) {
+    } on AnalysisException {
       // Expected
     }
   }
@@ -3825,7 +3897,7 @@
     try {
       _scopeFor(AstFactory.compilationUnit());
       fail("Expected AnalysisException");
-    } on AnalysisException catch (exception) {
+    } on AnalysisException {
       // Expected
     }
   }
@@ -3838,9 +3910,8 @@
     unit.declarations.add(classNode);
     ClassElement classElement = ElementFactory.classElement2(className);
     classNode.name.staticElement = classElement;
-    (unit.element as CompilationUnitElementImpl).types = <ClassElement>[
-      classElement
-    ];
+    (unit.element as CompilationUnitElementImpl).types =
+        <ClassElement>[classElement];
     return classNode;
   }
 
@@ -3852,9 +3923,8 @@
     unit.declarations.add(classNode);
     ClassElement classElement = ElementFactory.classElement2(className);
     classNode.name.staticElement = classElement;
-    (unit.element as CompilationUnitElementImpl).types = <ClassElement>[
-      classElement
-    ];
+    (unit.element as CompilationUnitElementImpl).types =
+        <ClassElement>[classElement];
     return classNode;
   }
 
@@ -3876,9 +3946,8 @@
     ConstructorElement constructorElement =
         ElementFactory.constructorElement2(classNode.element, null);
     constructorNode.element = constructorElement;
-    (classNode.element as ClassElementImpl).constructors = <ConstructorElement>[
-      constructorElement
-    ];
+    (classNode.element as ClassElementImpl).constructors =
+        <ConstructorElement>[constructorElement];
     return constructorNode;
   }
 
@@ -3891,9 +3960,8 @@
     FunctionElement functionElement =
         ElementFactory.functionElement(functionName);
     functionNode.name.staticElement = functionElement;
-    (unit.element as CompilationUnitElementImpl).functions = <FunctionElement>[
-      functionElement
-    ];
+    (unit.element as CompilationUnitElementImpl).functions =
+        <FunctionElement>[functionElement];
     return functionNode;
   }
 
@@ -3922,9 +3990,8 @@
     MethodElement methodElement =
         ElementFactory.methodElement(methodName, null);
     methodNode.name.staticElement = methodElement;
-    (classNode.element as ClassElementImpl).methods = <MethodElement>[
-      methodElement
-    ];
+    (classNode.element as ClassElementImpl).methods =
+        <MethodElement>[methodElement];
     return methodNode;
   }
 
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 5fc22dc..1120177 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -971,9 +971,8 @@
   const B(): super();
 }''');
     resolve(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT
-    ]);
+    assertErrors(source,
+        [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT]);
     verify([source]);
   }
 
@@ -1668,6 +1667,18 @@
     verify([source]);
   }
 
+  void test_functionWithoutCall_staticCallMethod() {
+    Source source = addSource(r'''
+class A { }
+class B extends A {
+  static call() { }
+}
+''');
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_functionWithoutCall_withNoSuchMethod() {
     // 16078
     Source source = addSource(r'''
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 78c7934..648ea6b 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -125,13 +125,13 @@
 @reflectiveTest
 class ComplexParserTest extends ParserTestCase {
   void test_additiveExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x + y - z");
+    BinaryExpression expression = parseExpression("x + y - z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_additiveExpression_noSpaces() {
-    BinaryExpression expression = ParserTestCase.parseExpression("i+1");
+    BinaryExpression expression = parseExpression("i+1");
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftOperand);
     EngineTestCase.assertInstanceOf((obj) => obj is IntegerLiteral,
@@ -139,34 +139,31 @@
   }
 
   void test_additiveExpression_precedence_multiplicative_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x * y + z");
+    BinaryExpression expression = parseExpression("x * y + z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_additiveExpression_precedence_multiplicative_left_withSuper() {
-    BinaryExpression expression =
-        ParserTestCase.parseExpression("super * y - z");
+    BinaryExpression expression = parseExpression("super * y - z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_additiveExpression_precedence_multiplicative_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x + y * z");
+    BinaryExpression expression = parseExpression("x + y * z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.rightOperand);
   }
 
   void test_additiveExpression_super() {
-    BinaryExpression expression =
-        ParserTestCase.parseExpression("super + y - z");
+    BinaryExpression expression = parseExpression("super + y - z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_assignableExpression_arguments_normal_chain() {
-    PropertyAccess propertyAccess1 =
-        ParserTestCase.parseExpression("a(b)(c).d(e).f");
+    PropertyAccess propertyAccess1 = parseExpression("a(b)(c).d(e).f");
     expect(propertyAccess1.propertyName.name, "f");
     //
     // a(b)(c).d(e)
@@ -200,8 +197,7 @@
   }
 
   void test_assignmentExpression_compound() {
-    AssignmentExpression expression =
-        ParserTestCase.parseExpression("x = y = 0");
+    AssignmentExpression expression = parseExpression("x = y = 0");
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftHandSide);
     EngineTestCase.assertInstanceOf((obj) => obj is AssignmentExpression,
@@ -209,8 +205,7 @@
   }
 
   void test_assignmentExpression_indexExpression() {
-    AssignmentExpression expression =
-        ParserTestCase.parseExpression("x[1] = 0");
+    AssignmentExpression expression = parseExpression("x[1] = 0");
     EngineTestCase.assertInstanceOf((obj) => obj is IndexExpression,
         IndexExpression, expression.leftHandSide);
     EngineTestCase.assertInstanceOf((obj) => obj is IntegerLiteral,
@@ -218,7 +213,7 @@
   }
 
   void test_assignmentExpression_prefixedIdentifier() {
-    AssignmentExpression expression = ParserTestCase.parseExpression("x.y = 0");
+    AssignmentExpression expression = parseExpression("x.y = 0");
     EngineTestCase.assertInstanceOf((obj) => obj is PrefixedIdentifier,
         PrefixedIdentifier, expression.leftHandSide);
     EngineTestCase.assertInstanceOf((obj) => obj is IntegerLiteral,
@@ -226,8 +221,7 @@
   }
 
   void test_assignmentExpression_propertyAccess() {
-    AssignmentExpression expression =
-        ParserTestCase.parseExpression("super.y = 0");
+    AssignmentExpression expression = parseExpression("super.y = 0");
     EngineTestCase.assertInstanceOf((obj) => obj is PropertyAccess,
         PropertyAccess, expression.leftHandSide);
     EngineTestCase.assertInstanceOf((obj) => obj is IntegerLiteral,
@@ -235,83 +229,80 @@
   }
 
   void test_bitwiseAndExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x & y & z");
+    BinaryExpression expression = parseExpression("x & y & z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_bitwiseAndExpression_precedence_equality_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x == y && z");
+    BinaryExpression expression = parseExpression("x == y && z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_bitwiseAndExpression_precedence_equality_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x && y == z");
+    BinaryExpression expression = parseExpression("x && y == z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.rightOperand);
   }
 
   void test_bitwiseAndExpression_super() {
-    BinaryExpression expression =
-        ParserTestCase.parseExpression("super & y & z");
+    BinaryExpression expression = parseExpression("super & y & z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_bitwiseOrExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x | y | z");
+    BinaryExpression expression = parseExpression("x | y | z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_bitwiseOrExpression_precedence_xor_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x ^ y | z");
+    BinaryExpression expression = parseExpression("x ^ y | z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_bitwiseOrExpression_precedence_xor_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x | y ^ z");
+    BinaryExpression expression = parseExpression("x | y ^ z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.rightOperand);
   }
 
   void test_bitwiseOrExpression_super() {
-    BinaryExpression expression =
-        ParserTestCase.parseExpression("super | y | z");
+    BinaryExpression expression = parseExpression("super | y | z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_bitwiseXorExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x ^ y ^ z");
+    BinaryExpression expression = parseExpression("x ^ y ^ z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_bitwiseXorExpression_precedence_and_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x & y ^ z");
+    BinaryExpression expression = parseExpression("x & y ^ z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_bitwiseXorExpression_precedence_and_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x ^ y & z");
+    BinaryExpression expression = parseExpression("x ^ y & z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.rightOperand);
   }
 
   void test_bitwiseXorExpression_super() {
-    BinaryExpression expression =
-        ParserTestCase.parseExpression("super ^ y ^ z");
+    BinaryExpression expression = parseExpression("super ^ y ^ z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_cascade_withAssignment() {
     CascadeExpression cascade =
-        ParserTestCase.parseExpression("new Map()..[3] = 4 ..[0] = 11;");
+        parseExpression("new Map()..[3] = 4 ..[0] = 11;");
     Expression target = cascade.target;
     for (Expression section in cascade.cascadeSections) {
       EngineTestCase.assertInstanceOf(
@@ -326,8 +317,7 @@
   }
 
   void test_conditionalExpression_precedence_logicalOrExpression() {
-    ConditionalExpression expression =
-        ParserTestCase.parseExpression("a | b ? y : z");
+    ConditionalExpression expression = parseExpression("a | b ? y : z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.condition);
   }
@@ -344,65 +334,63 @@
   }
 
   void test_equalityExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
+    BinaryExpression expression = parseExpression(
         "x == y != z", [ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_equalityExpression_precedence_relational_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x is y == z");
+    BinaryExpression expression = parseExpression("x is y == z");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is IsExpression, IsExpression, expression.leftOperand);
   }
 
   void test_equalityExpression_precedence_relational_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x == y is z");
+    BinaryExpression expression = parseExpression("x == y is z");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is IsExpression, IsExpression, expression.rightOperand);
   }
 
   void test_equalityExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "super == y != z", [
-      ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND
-    ]);
+    BinaryExpression expression = parseExpression("super == y != z",
+        [ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_logicalAndExpression() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x && y && z");
+    BinaryExpression expression = parseExpression("x && y && z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_logicalAndExpression_precedence_bitwiseOr_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x | y < z");
+    BinaryExpression expression = parseExpression("x | y < z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_logicalAndExpression_precedence_bitwiseOr_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x < y | z");
+    BinaryExpression expression = parseExpression("x < y | z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.rightOperand);
   }
 
   void test_logicalOrExpression() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x || y || z");
+    BinaryExpression expression = parseExpression("x || y || z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_logicalOrExpression_precedence_logicalAnd_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x && y || z");
+    BinaryExpression expression = parseExpression("x && y || z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_logicalOrExpression_precedence_logicalAnd_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x || y && z");
+    BinaryExpression expression = parseExpression("x || y && z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.rightOperand);
   }
@@ -416,57 +404,55 @@
   }
 
   void test_multiplicativeExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x * y / z");
+    BinaryExpression expression = parseExpression("x * y / z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_multiplicativeExpression_precedence_unary_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("-x * y");
+    BinaryExpression expression = parseExpression("-x * y");
     EngineTestCase.assertInstanceOf((obj) => obj is PrefixExpression,
         PrefixExpression, expression.leftOperand);
   }
 
   void test_multiplicativeExpression_precedence_unary_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x * -y");
+    BinaryExpression expression = parseExpression("x * -y");
     EngineTestCase.assertInstanceOf((obj) => obj is PrefixExpression,
         PrefixExpression, expression.rightOperand);
   }
 
   void test_multiplicativeExpression_super() {
-    BinaryExpression expression =
-        ParserTestCase.parseExpression("super * y / z");
+    BinaryExpression expression = parseExpression("super * y / z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_relationalExpression_precedence_shift_right() {
-    IsExpression expression = ParserTestCase.parseExpression("x << y is z");
+    IsExpression expression = parseExpression("x << y is z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.expression);
   }
 
   void test_shiftExpression_normal() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x >> 4 << 3");
+    BinaryExpression expression = parseExpression("x >> 4 << 3");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_shiftExpression_precedence_additive_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x + y << z");
+    BinaryExpression expression = parseExpression("x + y << z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
 
   void test_shiftExpression_precedence_additive_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("x << y + z");
+    BinaryExpression expression = parseExpression("x << y + z");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.rightOperand);
   }
 
   void test_shiftExpression_super() {
-    BinaryExpression expression =
-        ParserTestCase.parseExpression("super >> 4 << 3");
+    BinaryExpression expression = parseExpression("super >> 4 << 3");
     EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
         BinaryExpression, expression.leftOperand);
   }
@@ -489,27 +475,28 @@
     // literals that are being created are not always zero length (because they
     // could have type parameters), which violates the contract of
     // isSynthetic().
-    TypedLiteral literal = ParserTestCase.parse3("parseListOrMapLiteral",
-        <Object>[null], "1", [ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
+    TypedLiteral literal = parse3("parseListOrMapLiteral", <Object>[null], "1",
+        [ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
     expect(literal.isSynthetic, isTrue);
   }
 
   void fail_illegalAssignmentToNonAssignable_superAssigned() {
     // TODO(brianwilkerson) When this test starts to pass, remove the test
     // test_illegalAssignmentToNonAssignable_superAssigned.
-    ParserTestCase.parseExpression(
+    parseExpression(
         "super = x;", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
   }
 
   void fail_invalidCommentReference__new_nonIdentifier() {
     // This test fails because the method parseCommentReference returns null.
-    ParserTestCase.parse3("parseCommentReference", <Object>["new 42", 0], "", [
-      ParserErrorCode.INVALID_COMMENT_REFERENCE
-    ]);
+    parse3("parseCommentReference", <Object>[
+      "new 42",
+      0
+    ], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
 
   void fail_invalidCommentReference__new_tooMuch() {
-    ParserTestCase.parse3("parseCommentReference", <Object>[
+    parse3("parseCommentReference", <Object>[
       "new a.b.c.d",
       0
     ], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
@@ -517,24 +504,25 @@
 
   void fail_invalidCommentReference__nonNew_nonIdentifier() {
     // This test fails because the method parseCommentReference returns null.
-    ParserTestCase.parse3("parseCommentReference", <Object>["42", 0], "", [
-      ParserErrorCode.INVALID_COMMENT_REFERENCE
-    ]);
+    parse3("parseCommentReference", <Object>[
+      "42",
+      0
+    ], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
 
   void fail_invalidCommentReference__nonNew_tooMuch() {
-    ParserTestCase.parse3("parseCommentReference", <Object>["a.b.c.d", 0], "", [
-      ParserErrorCode.INVALID_COMMENT_REFERENCE
-    ]);
+    parse3("parseCommentReference", <Object>[
+      "a.b.c.d",
+      0
+    ], "", [ParserErrorCode.INVALID_COMMENT_REFERENCE]);
   }
 
   void fail_missingClosingParenthesis() {
     // It is possible that it is not possible to generate this error (that it's
     // being reported in code that cannot actually be reached), but that hasn't
     // been proven yet.
-    ParserTestCase.parse4("parseFormalParameterList", "(int a, int b ;", [
-      ParserErrorCode.MISSING_CLOSING_PARENTHESIS
-    ]);
+    parse4("parseFormalParameterList", "(int a, int b ;",
+        [ParserErrorCode.MISSING_CLOSING_PARENTHESIS]);
   }
 
   void fail_missingFunctionParameters_local_nonVoid_block() {
@@ -554,8 +542,8 @@
   }
 
   void fail_namedFunctionExpression() {
-    Expression expression = ParserTestCase.parse4("parsePrimaryExpression",
-        "f() {}", [ParserErrorCode.NAMED_FUNCTION_EXPRESSION]);
+    Expression expression = parse4("parsePrimaryExpression", "f() {}",
+        [ParserErrorCode.NAMED_FUNCTION_EXPRESSION]);
     EngineTestCase.assertInstanceOf(
         (obj) => obj is FunctionExpression, FunctionExpression, expression);
   }
@@ -563,7 +551,7 @@
   void fail_unexpectedToken_invalidPostfixExpression() {
     // Note: this might not be the right error to produce, but some error should
     // be produced
-    ParserTestCase.parseExpression("f()++", [ParserErrorCode.UNEXPECTED_TOKEN]);
+    parseExpression("f()++", [ParserErrorCode.UNEXPECTED_TOKEN]);
   }
 
   void fail_varAndType_local() {
@@ -575,39 +563,33 @@
   void fail_varAndType_parameter() {
     // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but
     // this would be a better error message.
-    ParserTestCase.parse4("parseFormalParameterList", "(var int x)", [
-      ParserErrorCode.VAR_AND_TYPE
-    ]);
+    parse4("parseFormalParameterList", "(var int x)",
+        [ParserErrorCode.VAR_AND_TYPE]);
   }
 
   void test_abstractClassMember_constructor() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "abstract C.c();", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    parse3("parseClassMember", <Object>["C"], "abstract C.c();",
+        [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
 
   void test_abstractClassMember_field() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "abstract C f;", [
-      ParserErrorCode.ABSTRACT_CLASS_MEMBER
-    ]);
+    parse3("parseClassMember", <Object>["C"], "abstract C f;",
+        [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
 
   void test_abstractClassMember_getter() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "abstract get m;", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    parse3("parseClassMember", <Object>["C"], "abstract get m;",
+        [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
 
   void test_abstractClassMember_method() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "abstract m();", [
-      ParserErrorCode.ABSTRACT_CLASS_MEMBER
-    ]);
+    parse3("parseClassMember", <Object>["C"], "abstract m();",
+        [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
 
   void test_abstractClassMember_setter() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "abstract set m(v);", [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
+    parse3("parseClassMember", <Object>["C"], "abstract set m(v);",
+        [ParserErrorCode.ABSTRACT_CLASS_MEMBER]);
   }
 
   void test_abstractEnum() {
@@ -641,62 +623,54 @@
   }
 
   void test_annotationOnEnumConstant_first() {
-    ParserTestCase.parseCompilationUnit("enum E { @override C }", [
-      ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT
-    ]);
+    ParserTestCase.parseCompilationUnit("enum E { @override C }",
+        [ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT]);
   }
 
   void test_annotationOnEnumConstant_middle() {
-    ParserTestCase.parseCompilationUnit("enum E { C, @override D, E }", [
-      ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT
-    ]);
+    ParserTestCase.parseCompilationUnit("enum E { C, @override D, E }",
+        [ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT]);
   }
 
   void test_assertDoesNotTakeAssignment() {
-    ParserTestCase.parse4("parseAssertStatement", "assert(b = true);", [
-      ParserErrorCode.ASSERT_DOES_NOT_TAKE_ASSIGNMENT
-    ]);
+    parse4("parseAssertStatement", "assert(b = true);",
+        [ParserErrorCode.ASSERT_DOES_NOT_TAKE_ASSIGNMENT]);
   }
 
   void test_assertDoesNotTakeCascades() {
-    ParserTestCase.parse4("parseAssertStatement", "assert(new A()..m());", [
-      ParserErrorCode.ASSERT_DOES_NOT_TAKE_CASCADE
-    ]);
+    parse4("parseAssertStatement", "assert(new A()..m());",
+        [ParserErrorCode.ASSERT_DOES_NOT_TAKE_CASCADE]);
   }
 
   void test_assertDoesNotTakeRethrow() {
-    ParserTestCase.parse4("parseAssertStatement", "assert(rethrow);", [
-      ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW
-    ]);
+    parse4("parseAssertStatement", "assert(rethrow);",
+        [ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW]);
   }
 
   void test_assertDoesNotTakeThrow() {
-    ParserTestCase.parse4("parseAssertStatement", "assert(throw x);", [
-      ParserErrorCode.ASSERT_DOES_NOT_TAKE_THROW
-    ]);
+    parse4("parseAssertStatement", "assert(throw x);",
+        [ParserErrorCode.ASSERT_DOES_NOT_TAKE_THROW]);
   }
 
   void test_breakOutsideOfLoop_breakInDoStatement() {
-    ParserTestCase.parse4("parseDoStatement", "do {break;} while (x);");
+    parse4("parseDoStatement", "do {break;} while (x);");
   }
 
   void test_breakOutsideOfLoop_breakInForStatement() {
-    ParserTestCase.parse4("parseForStatement", "for (; x;) {break;}");
+    parse4("parseForStatement", "for (; x;) {break;}");
   }
 
   void test_breakOutsideOfLoop_breakInIfStatement() {
-    ParserTestCase.parse4("parseIfStatement", "if (x) {break;}", [
-      ParserErrorCode.BREAK_OUTSIDE_OF_LOOP
-    ]);
+    parse4("parseIfStatement", "if (x) {break;}",
+        [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
   }
 
   void test_breakOutsideOfLoop_breakInSwitchStatement() {
-    ParserTestCase.parse4(
-        "parseSwitchStatement", "switch (x) {case 1: break;}");
+    parse4("parseSwitchStatement", "switch (x) {case 1: break;}");
   }
 
   void test_breakOutsideOfLoop_breakInWhileStatement() {
-    ParserTestCase.parse4("parseWhileStatement", "while (x) {break;}");
+    parse4("parseWhileStatement", "while (x) {break;}");
   }
 
   void test_breakOutsideOfLoop_functionExpression_inALoop() {
@@ -721,9 +695,8 @@
   void test_classTypeAlias_abstractAfterEq() {
     // This syntax has been removed from the language in favor of
     // "abstract class A = B with C;" (issue 18098).
-    ParserTestCase.parse3("parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "class A = abstract B with C;", [
+    parse3("parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "class A = abstract B with C;", [
       ParserErrorCode.EXPECTED_TOKEN,
       ParserErrorCode.EXPECTED_TOKEN
     ]);
@@ -735,15 +708,13 @@
   }
 
   void test_constAndFinal() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "const final int x;", [ParserErrorCode.CONST_AND_FINAL]);
+    parse3("parseClassMember", <Object>["C"], "const final int x;",
+        [ParserErrorCode.CONST_AND_FINAL]);
   }
 
   void test_constAndVar() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "const var x;", [
-      ParserErrorCode.CONST_AND_VAR
-    ]);
+    parse3("parseClassMember", <Object>["C"], "const var x;",
+        [ParserErrorCode.CONST_AND_VAR]);
   }
 
   void test_constClass() {
@@ -752,9 +723,8 @@
   }
 
   void test_constConstructorWithBody() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "const C() {}", [
-      ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY
-    ]);
+    parse3("parseClassMember", <Object>["C"], "const C() {}",
+        [ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY]);
   }
 
   void test_constEnum() {
@@ -763,27 +733,23 @@
   }
 
   void test_constFactory() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "const factory C() {}", [ParserErrorCode.CONST_FACTORY]);
+    parse3("parseClassMember", <Object>["C"], "const factory C() {}",
+        [ParserErrorCode.CONST_FACTORY]);
   }
 
   void test_constMethod() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "const int m() {}", [ParserErrorCode.CONST_METHOD]);
+    parse3("parseClassMember", <Object>["C"], "const int m() {}",
+        [ParserErrorCode.CONST_METHOD]);
   }
 
   void test_constructorWithReturnType() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "C C() {}", [
-      ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE
-    ]);
+    parse3("parseClassMember", <Object>["C"], "C C() {}",
+        [ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]);
   }
 
   void test_constructorWithReturnType_var() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "var C() {}", [
-      ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE
-    ]);
+    parse3("parseClassMember", <Object>["C"], "var C() {}",
+        [ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE]);
   }
 
   void test_constTypedef() {
@@ -792,32 +758,29 @@
   }
 
   void test_continueOutsideOfLoop_continueInDoStatement() {
-    ParserTestCase.parse4("parseDoStatement", "do {continue;} while (x);");
+    parse4("parseDoStatement", "do {continue;} while (x);");
   }
 
   void test_continueOutsideOfLoop_continueInForStatement() {
-    ParserTestCase.parse4("parseForStatement", "for (; x;) {continue;}");
+    parse4("parseForStatement", "for (; x;) {continue;}");
   }
 
   void test_continueOutsideOfLoop_continueInIfStatement() {
-    ParserTestCase.parse4("parseIfStatement", "if (x) {continue;}", [
-      ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP
-    ]);
+    parse4("parseIfStatement", "if (x) {continue;}",
+        [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
   }
 
   void test_continueOutsideOfLoop_continueInSwitchStatement() {
-    ParserTestCase.parse4(
-        "parseSwitchStatement", "switch (x) {case 1: continue a;}");
+    parse4("parseSwitchStatement", "switch (x) {case 1: continue a;}");
   }
 
   void test_continueOutsideOfLoop_continueInWhileStatement() {
-    ParserTestCase.parse4("parseWhileStatement", "while (x) {continue;}");
+    parse4("parseWhileStatement", "while (x) {continue;}");
   }
 
   void test_continueOutsideOfLoop_functionExpression_inALoop() {
-    ParserTestCase.parseStatement("for(; x;) {() {continue;};}", [
-      ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP
-    ]);
+    ParserTestCase.parseStatement("for(; x;) {() {continue;};}",
+        [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
   }
 
   void test_continueOutsideOfLoop_functionExpression_withALoop() {
@@ -825,19 +788,16 @@
   }
 
   void test_continueWithoutLabelInCase_error() {
-    ParserTestCase.parse4("parseSwitchStatement",
-        "switch (x) {case 1: continue;}", [
-      ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE
-    ]);
+    parse4("parseSwitchStatement", "switch (x) {case 1: continue;}",
+        [ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE]);
   }
 
   void test_continueWithoutLabelInCase_noError() {
-    ParserTestCase.parse4(
-        "parseSwitchStatement", "switch (x) {case 1: continue a;}");
+    parse4("parseSwitchStatement", "switch (x) {case 1: continue a;}");
   }
 
   void test_continueWithoutLabelInCase_noError_switchInLoop() {
-    ParserTestCase.parse4(
+    parse4(
         "parseWhileStatement", "while (a) { switch (b) {default: continue;}}");
   }
 
@@ -847,74 +807,63 @@
   }
 
   void test_deprecatedClassTypeAlias_withGeneric() {
-    ParserTestCase.parseCompilationUnit("typedef C<T> = S<T> with M;", [
-      ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS
-    ]);
+    ParserTestCase.parseCompilationUnit("typedef C<T> = S<T> with M;",
+        [ParserErrorCode.DEPRECATED_CLASS_TYPE_ALIAS]);
   }
 
   void test_directiveAfterDeclaration_classBeforeDirective() {
     CompilationUnit unit = ParserTestCase.parseCompilationUnit(
-        "class Foo{} library l;", [
-      ParserErrorCode.DIRECTIVE_AFTER_DECLARATION
-    ]);
+        "class Foo{} library l;",
+        [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
     expect(unit, isNotNull);
   }
 
   void test_directiveAfterDeclaration_classBetweenDirectives() {
     CompilationUnit unit = ParserTestCase.parseCompilationUnit(
-        "library l;\nclass Foo{}\npart 'a.dart';", [
-      ParserErrorCode.DIRECTIVE_AFTER_DECLARATION
-    ]);
+        "library l;\nclass Foo{}\npart 'a.dart';",
+        [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION]);
     expect(unit, isNotNull);
   }
 
   void test_duplicatedModifier_const() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "const const m;", [
-      ParserErrorCode.DUPLICATED_MODIFIER
-    ]);
+    parse3("parseClassMember", <Object>["C"], "const const m;",
+        [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
 
   void test_duplicatedModifier_external() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "external external f();", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    parse3("parseClassMember", <Object>["C"], "external external f();",
+        [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
 
   void test_duplicatedModifier_factory() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "factory factory C() {}", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    parse3("parseClassMember", <Object>["C"], "factory factory C() {}",
+        [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
 
   void test_duplicatedModifier_final() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "final final m;", [
-      ParserErrorCode.DUPLICATED_MODIFIER
-    ]);
+    parse3("parseClassMember", <Object>["C"], "final final m;",
+        [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
 
   void test_duplicatedModifier_static() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "static static var m;", [ParserErrorCode.DUPLICATED_MODIFIER]);
+    parse3("parseClassMember", <Object>["C"], "static static var m;",
+        [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
 
   void test_duplicatedModifier_var() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "var var m;", [
-      ParserErrorCode.DUPLICATED_MODIFIER
-    ]);
+    parse3("parseClassMember", <Object>["C"], "var var m;",
+        [ParserErrorCode.DUPLICATED_MODIFIER]);
   }
 
   void test_duplicateLabelInSwitchStatement() {
-    ParserTestCase.parse4("parseSwitchStatement",
-        "switch (e) {l1: case 0: break; l1: case 1: break;}", [
-      ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT
-    ]);
+    parse4("parseSwitchStatement",
+        "switch (e) {l1: case 0: break; l1: case 1: break;}",
+        [ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT]);
   }
 
   void test_emptyEnumBody() {
-    ParserTestCase.parse3("parseEnumDeclaration", <Object>[
-      emptyCommentAndMetadata()
-    ], "enum E {}", [ParserErrorCode.EMPTY_ENUM_BODY]);
+    parse3("parseEnumDeclaration", <Object>[emptyCommentAndMetadata()],
+        "enum E {}", [ParserErrorCode.EMPTY_ENUM_BODY]);
   }
 
   void test_enumInClass() {
@@ -928,72 +877,64 @@
   }
 
   void test_equalityCannotBeEqualityOperand_eq_eq() {
-    ParserTestCase.parseExpression(
+    parseExpression(
         "1 == 2 == 3", [ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
   }
 
   void test_equalityCannotBeEqualityOperand_eq_neq() {
-    ParserTestCase.parseExpression(
+    parseExpression(
         "1 == 2 != 3", [ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
   }
 
   void test_equalityCannotBeEqualityOperand_neq_eq() {
-    ParserTestCase.parseExpression(
+    parseExpression(
         "1 != 2 == 3", [ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
   }
 
   void test_expectedCaseOrDefault() {
-    ParserTestCase.parse4("parseSwitchStatement", "switch (e) {break;}", [
-      ParserErrorCode.EXPECTED_CASE_OR_DEFAULT
-    ]);
+    parse4("parseSwitchStatement", "switch (e) {break;}",
+        [ParserErrorCode.EXPECTED_CASE_OR_DEFAULT]);
   }
 
   void test_expectedClassMember_inClass_afterType() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "heart 2 heart", [
-      ParserErrorCode.EXPECTED_CLASS_MEMBER
-    ]);
+    parse3("parseClassMember", <Object>["C"], "heart 2 heart",
+        [ParserErrorCode.EXPECTED_CLASS_MEMBER]);
   }
 
   void test_expectedClassMember_inClass_beforeType() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "4 score", [
-      ParserErrorCode.EXPECTED_CLASS_MEMBER
-    ]);
+    parse3("parseClassMember", <Object>["C"], "4 score",
+        [ParserErrorCode.EXPECTED_CLASS_MEMBER]);
   }
 
   void test_expectedExecutable_inClass_afterVoid() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "void 2 void", [
-      ParserErrorCode.EXPECTED_EXECUTABLE
-    ]);
+    parse3("parseClassMember", <Object>["C"], "void 2 void",
+        [ParserErrorCode.EXPECTED_EXECUTABLE]);
   }
 
   void test_expectedExecutable_topLevel_afterType() {
-    ParserTestCase.parse3("parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "heart 2 heart", [ParserErrorCode.EXPECTED_EXECUTABLE]);
+    parse3("parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "heart 2 heart", [ParserErrorCode.EXPECTED_EXECUTABLE]);
   }
 
   void test_expectedExecutable_topLevel_afterVoid() {
-    ParserTestCase.parse3("parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "void 2 void", [ParserErrorCode.EXPECTED_EXECUTABLE]);
+    parse3("parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "void 2 void", [ParserErrorCode.EXPECTED_EXECUTABLE]);
   }
 
   void test_expectedExecutable_topLevel_beforeType() {
-    ParserTestCase.parse3("parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "4 score", [ParserErrorCode.EXPECTED_EXECUTABLE]);
+    parse3("parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "4 score", [ParserErrorCode.EXPECTED_EXECUTABLE]);
   }
 
   void test_expectedExecutable_topLevel_eof() {
-    ParserTestCase.parse2("parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "x", [
+    parse2("parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "x", [
       new AnalysisError.con2(null, 0, 1, ParserErrorCode.EXPECTED_EXECUTABLE)
     ]);
   }
 
   void test_expectedInterpolationIdentifier() {
-    ParserTestCase.parse4(
+    parse4(
         "parseStringLiteral", "'\$x\$'", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
 
@@ -1001,20 +942,19 @@
     // The scanner inserts an empty string token between the two $'s; we need to
     // make sure that the MISSING_IDENTIFIER error that is generated has a
     // nonzero width so that it will show up in the editor UI.
-    ParserTestCase.parse2("parseStringLiteral", <Object>[], "'\$\$foo'", [
+    parse2("parseStringLiteral", <Object>[], "'\$\$foo'", [
       new AnalysisError.con2(null, 2, 1, ParserErrorCode.MISSING_IDENTIFIER)
     ]);
   }
 
   void test_expectedStringLiteral() {
-    StringLiteral expression = ParserTestCase.parse4(
+    StringLiteral expression = parse4(
         "parseStringLiteral", "1", [ParserErrorCode.EXPECTED_STRING_LITERAL]);
     expect(expression.isSynthetic, isTrue);
   }
 
   void test_expectedToken_commaMissingInArgumentList() {
-    ParserTestCase.parse4(
-        "parseArgumentList", "(x, y z)", [ParserErrorCode.EXPECTED_TOKEN]);
+    parse4("parseArgumentList", "(x, y z)", [ParserErrorCode.EXPECTED_TOKEN]);
   }
 
   void test_expectedToken_parseStatement_afterVoid() {
@@ -1026,7 +966,7 @@
 
   void test_expectedToken_semicolonAfterClass() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.CLASS);
-    ParserTestCase.parse3("parseClassTypeAlias", <Object>[
+    parse3("parseClassTypeAlias", <Object>[
       emptyCommentAndMetadata(),
       null,
       token
@@ -1061,32 +1001,27 @@
   }
 
   void test_expectedTypeName_is() {
-    ParserTestCase.parseExpression(
-        "x is", [ParserErrorCode.EXPECTED_TYPE_NAME]);
+    parseExpression("x is", [ParserErrorCode.EXPECTED_TYPE_NAME]);
   }
 
   void test_exportDirectiveAfterPartDirective() {
-    ParserTestCase.parseCompilationUnit("part 'a.dart'; export 'b.dart';", [
-      ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE
-    ]);
+    ParserTestCase.parseCompilationUnit("part 'a.dart'; export 'b.dart';",
+        [ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
   }
 
   void test_externalAfterConst() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "const external C();", [ParserErrorCode.EXTERNAL_AFTER_CONST]);
+    parse3("parseClassMember", <Object>["C"], "const external C();",
+        [ParserErrorCode.EXTERNAL_AFTER_CONST]);
   }
 
   void test_externalAfterFactory() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "factory external C();", [ParserErrorCode.EXTERNAL_AFTER_FACTORY]);
+    parse3("parseClassMember", <Object>["C"], "factory external C();",
+        [ParserErrorCode.EXTERNAL_AFTER_FACTORY]);
   }
 
   void test_externalAfterStatic() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "static external int m();", [ParserErrorCode.EXTERNAL_AFTER_STATIC]);
+    parse3("parseClassMember", <Object>["C"], "static external int m();",
+        [ParserErrorCode.EXTERNAL_AFTER_STATIC]);
   }
 
   void test_externalClass() {
@@ -1095,17 +1030,13 @@
   }
 
   void test_externalConstructorWithBody_factory() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "external factory C() {}", [
-      ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY
-    ]);
+    parse3("parseClassMember", <Object>["C"], "external factory C() {}",
+        [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
   }
 
   void test_externalConstructorWithBody_named() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "external C.c() {}", [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
+    parse3("parseClassMember", <Object>["C"], "external C.c() {}",
+        [ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY]);
   }
 
   void test_externalEnum() {
@@ -1114,61 +1045,49 @@
   }
 
   void test_externalField_const() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "external const A f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    parse3("parseClassMember", <Object>["C"], "external const A f;",
+        [ParserErrorCode.EXTERNAL_FIELD]);
   }
 
   void test_externalField_final() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "external final A f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    parse3("parseClassMember", <Object>["C"], "external final A f;",
+        [ParserErrorCode.EXTERNAL_FIELD]);
   }
 
   void test_externalField_static() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "external static A f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    parse3("parseClassMember", <Object>["C"], "external static A f;",
+        [ParserErrorCode.EXTERNAL_FIELD]);
   }
 
   void test_externalField_typed() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "external A f;", [
-      ParserErrorCode.EXTERNAL_FIELD
-    ]);
+    parse3("parseClassMember", <Object>["C"], "external A f;",
+        [ParserErrorCode.EXTERNAL_FIELD]);
   }
 
   void test_externalField_untyped() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "external var f;", [ParserErrorCode.EXTERNAL_FIELD]);
+    parse3("parseClassMember", <Object>["C"], "external var f;",
+        [ParserErrorCode.EXTERNAL_FIELD]);
   }
 
   void test_externalGetterWithBody() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "external int get x {}", [ParserErrorCode.EXTERNAL_GETTER_WITH_BODY]);
+    parse3("parseClassMember", <Object>["C"], "external int get x {}",
+        [ParserErrorCode.EXTERNAL_GETTER_WITH_BODY]);
   }
 
   void test_externalMethodWithBody() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "external m() {}", [ParserErrorCode.EXTERNAL_METHOD_WITH_BODY]);
+    parse3("parseClassMember", <Object>["C"], "external m() {}",
+        [ParserErrorCode.EXTERNAL_METHOD_WITH_BODY]);
   }
 
   void test_externalOperatorWithBody() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "external operator +(int value) {}", [
-      ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY
-    ]);
+    parse3("parseClassMember", <Object>["C"],
+        "external operator +(int value) {}",
+        [ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY]);
   }
 
   void test_externalSetterWithBody() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "external set x(int value) {}", [
-      ParserErrorCode.EXTERNAL_SETTER_WITH_BODY
-    ]);
+    parse3("parseClassMember", <Object>["C"], "external set x(int value) {}",
+        [ParserErrorCode.EXTERNAL_SETTER_WITH_BODY]);
   }
 
   void test_externalTypedef() {
@@ -1182,32 +1101,28 @@
   }
 
   void test_factoryTopLevelDeclaration_typedef() {
-    ParserTestCase.parseCompilationUnit("factory typedef F();", [
-      ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION
-    ]);
+    ParserTestCase.parseCompilationUnit("factory typedef F();",
+        [ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION]);
   }
 
   void test_factoryWithInitializers() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "factory C() : x = 3 {}", [ParserErrorCode.FACTORY_WITH_INITIALIZERS]);
+    parse3("parseClassMember", <Object>["C"], "factory C() : x = 3 {}",
+        [ParserErrorCode.FACTORY_WITH_INITIALIZERS]);
   }
 
   void test_factoryWithoutBody() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "factory C();", [
-      ParserErrorCode.FACTORY_WITHOUT_BODY
-    ]);
+    parse3("parseClassMember", <Object>["C"], "factory C();",
+        [ParserErrorCode.FACTORY_WITHOUT_BODY]);
   }
 
   void test_fieldInitializerOutsideConstructor() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "void m(this.x);",
+    parse3("parseClassMember", <Object>["C"], "void m(this.x);",
         [ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]);
   }
 
   void test_finalAndVar() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "final var x;", [
-      ParserErrorCode.FINAL_AND_VAR
-    ]);
+    parse3("parseClassMember", <Object>["C"], "final var x;",
+        [ParserErrorCode.FINAL_AND_VAR]);
   }
 
   void test_finalClass() {
@@ -1216,9 +1131,8 @@
   }
 
   void test_finalConstructor() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "final C() {}", [
-      ParserErrorCode.FINAL_CONSTRUCTOR
-    ]);
+    parse3("parseClassMember", <Object>["C"], "final C() {}",
+        [ParserErrorCode.FINAL_CONSTRUCTOR]);
   }
 
   void test_finalEnum() {
@@ -1227,9 +1141,8 @@
   }
 
   void test_finalMethod() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "final int m() {}", [ParserErrorCode.FINAL_METHOD]);
+    parse3("parseClassMember", <Object>["C"], "final int m() {}",
+        [ParserErrorCode.FINAL_METHOD]);
   }
 
   void test_finalTypedef() {
@@ -1273,28 +1186,27 @@
   }
 
   void test_getterWithParameters() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "int get x() {}", [
-      ParserErrorCode.GETTER_WITH_PARAMETERS
-    ]);
+    parse3("parseClassMember", <Object>["C"], "int get x() {}",
+        [ParserErrorCode.GETTER_WITH_PARAMETERS]);
   }
 
   void test_illegalAssignmentToNonAssignable_postfix_minusMinus_literal() {
-    ParserTestCase.parseExpression(
+    parseExpression(
         "0--", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
   }
 
   void test_illegalAssignmentToNonAssignable_postfix_plusPlus_literal() {
-    ParserTestCase.parseExpression(
+    parseExpression(
         "0++", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
   }
 
   void test_illegalAssignmentToNonAssignable_postfix_plusPlus_parethesized() {
-    ParserTestCase.parseExpression(
+    parseExpression(
         "(x)++", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
   }
 
   void test_illegalAssignmentToNonAssignable_primarySelectorPostfix() {
-    ParserTestCase.parseExpression(
+    parseExpression(
         "x(y)(z)++", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
   }
 
@@ -1304,78 +1216,69 @@
     // remove this test (there should only be one error generated, but we're
     // keeping this test until that time so that we can catch other forms of
     // regressions).
-    ParserTestCase.parseExpression("super = x;", [
+    parseExpression("super = x;", [
       ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR,
       ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE
     ]);
   }
 
   void test_implementsBeforeExtends() {
-    ParserTestCase.parseCompilationUnit("class A implements B extends C {}", [
-      ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS
-    ]);
+    ParserTestCase.parseCompilationUnit("class A implements B extends C {}",
+        [ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS]);
   }
 
   void test_implementsBeforeWith() {
     ParserTestCase.parseCompilationUnit(
-        "class A extends B implements C with D {}", [
-      ParserErrorCode.IMPLEMENTS_BEFORE_WITH
-    ]);
+        "class A extends B implements C with D {}",
+        [ParserErrorCode.IMPLEMENTS_BEFORE_WITH]);
   }
 
   void test_importDirectiveAfterPartDirective() {
-    ParserTestCase.parseCompilationUnit("part 'a.dart'; import 'b.dart';", [
-      ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE
-    ]);
+    ParserTestCase.parseCompilationUnit("part 'a.dart'; import 'b.dart';",
+        [ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE]);
   }
 
   void test_initializedVariableInForEach() {
-    ParserTestCase.parse4("parseForStatement", "for (int a = 0 in foo) {}", [
-      ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH
-    ]);
+    parse4("parseForStatement", "for (int a = 0 in foo) {}",
+        [ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH]);
   }
 
   void test_invalidAwaitInFor() {
-    ParserTestCase.parse4("parseForStatement", "await for (; ;) {}", [
-      ParserErrorCode.INVALID_AWAIT_IN_FOR
-    ]);
+    parse4("parseForStatement", "await for (; ;) {}",
+        [ParserErrorCode.INVALID_AWAIT_IN_FOR]);
   }
 
   void test_invalidCodePoint() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\uD900'", [
-      ParserErrorCode.INVALID_CODE_POINT
-    ]);
+    parse4("parseStringLiteral", "'\\uD900'",
+        [ParserErrorCode.INVALID_CODE_POINT]);
   }
 
   void test_invalidHexEscape_invalidDigit() {
-    ParserTestCase.parse4(
+    parse4(
         "parseStringLiteral", "'\\x0 a'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
   }
 
   void test_invalidHexEscape_tooFewDigits() {
-    ParserTestCase.parse4(
+    parse4(
         "parseStringLiteral", "'\\x0'", [ParserErrorCode.INVALID_HEX_ESCAPE]);
   }
 
   void test_invalidInterpolationIdentifier_startWithDigit() {
-    ParserTestCase.parse4(
-        "parseStringLiteral", "'\$1'", [ParserErrorCode.MISSING_IDENTIFIER]);
+    parse4("parseStringLiteral", "'\$1'", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
 
   void test_invalidOperator() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "void operator ===(x) {}", [ParserErrorCode.INVALID_OPERATOR]);
+    parse3("parseClassMember", <Object>["C"], "void operator ===(x) {}",
+        [ParserErrorCode.INVALID_OPERATOR]);
   }
 
   void test_invalidOperatorForSuper() {
-    ParserTestCase.parse4("parseUnaryExpression", "++super", [
-      ParserErrorCode.INVALID_OPERATOR_FOR_SUPER
-    ]);
+    parse4("parseUnaryExpression", "++super",
+        [ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]);
   }
 
   void test_invalidStarAfterAsync() {
-    ParserTestCase.parse3("parseFunctionBody", <Object>[
+    parse3("parseFunctionBody", <Object>[
       false,
       null,
       false
@@ -1383,7 +1286,7 @@
   }
 
   void test_invalidSync() {
-    ParserTestCase.parse3("parseFunctionBody", <Object>[
+    parse3("parseFunctionBody", <Object>[
       false,
       null,
       false
@@ -1391,72 +1294,62 @@
   }
 
   void test_invalidUnicodeEscape_incomplete_noDigits() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u{'", [
-      ParserErrorCode.INVALID_UNICODE_ESCAPE
-    ]);
+    parse4("parseStringLiteral", "'\\u{'",
+        [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
 
   void test_invalidUnicodeEscape_incomplete_someDigits() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u{0A'", [
-      ParserErrorCode.INVALID_UNICODE_ESCAPE
-    ]);
+    parse4("parseStringLiteral", "'\\u{0A'",
+        [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
 
   void test_invalidUnicodeEscape_invalidDigit() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u0 a'", [
-      ParserErrorCode.INVALID_UNICODE_ESCAPE
-    ]);
+    parse4("parseStringLiteral", "'\\u0 a'",
+        [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
 
   void test_invalidUnicodeEscape_tooFewDigits_fixed() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u04'", [
-      ParserErrorCode.INVALID_UNICODE_ESCAPE
-    ]);
+    parse4("parseStringLiteral", "'\\u04'",
+        [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
 
   void test_invalidUnicodeEscape_tooFewDigits_variable() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u{}'", [
-      ParserErrorCode.INVALID_UNICODE_ESCAPE
-    ]);
+    parse4("parseStringLiteral", "'\\u{}'",
+        [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
 
   void test_invalidUnicodeEscape_tooManyDigits_variable() {
-    ParserTestCase.parse4("parseStringLiteral", "'\\u{12345678}'", [
+    parse4("parseStringLiteral", "'\\u{12345678}'", [
       ParserErrorCode.INVALID_UNICODE_ESCAPE,
       ParserErrorCode.INVALID_CODE_POINT
     ]);
   }
 
   void test_libraryDirectiveNotFirst() {
-    ParserTestCase.parseCompilationUnit("import 'x.dart'; library l;", [
-      ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST
-    ]);
+    ParserTestCase.parseCompilationUnit("import 'x.dart'; library l;",
+        [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST]);
   }
 
   void test_libraryDirectiveNotFirst_afterPart() {
     CompilationUnit unit = ParserTestCase.parseCompilationUnit(
-        "part 'a.dart';\nlibrary l;", [
-      ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST
-    ]);
+        "part 'a.dart';\nlibrary l;",
+        [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST]);
     expect(unit, isNotNull);
   }
 
   void test_localFunctionDeclarationModifier_abstract() {
-    ParserTestCase.parseStatement("abstract f() {}", [
-      ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER
-    ]);
+    ParserTestCase.parseStatement("abstract f() {}",
+        [ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER]);
   }
 
   void test_localFunctionDeclarationModifier_external() {
-    ParserTestCase.parseStatement("external f() {}", [
-      ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER
-    ]);
+    ParserTestCase.parseStatement("external f() {}",
+        [ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER]);
   }
 
   void test_localFunctionDeclarationModifier_factory() {
-    ParserTestCase.parseStatement("factory f() {}", [
-      ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER
-    ]);
+    ParserTestCase.parseStatement("factory f() {}",
+        [ParserErrorCode.LOCAL_FUNCTION_DECLARATION_MODIFIER]);
   }
 
   void test_localFunctionDeclarationModifier_static() {
@@ -1465,36 +1358,34 @@
   }
 
   void test_missingAssignableSelector_identifiersAssigned() {
-    ParserTestCase.parseExpression("x.y = y;");
+    parseExpression("x.y = y;");
   }
 
   void test_missingAssignableSelector_prefix_minusMinus_literal() {
-    ParserTestCase.parseExpression(
-        "--0", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
+    parseExpression("--0", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
   }
 
   void test_missingAssignableSelector_prefix_plusPlus_literal() {
-    ParserTestCase.parseExpression(
-        "++0", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
+    parseExpression("++0", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
   }
 
   void test_missingAssignableSelector_selector() {
-    ParserTestCase.parseExpression("x(y)(z).a++");
+    parseExpression("x(y)(z).a++");
   }
 
   void test_missingAssignableSelector_superPrimaryExpression() {
-    SuperExpression expression = ParserTestCase.parse4("parsePrimaryExpression",
-        "super", [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
+    SuperExpression expression = parse4("parsePrimaryExpression", "super",
+        [ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR]);
     expect(expression.superKeyword, isNotNull);
   }
 
   void test_missingAssignableSelector_superPropertyAccessAssigned() {
-    ParserTestCase.parseExpression("super.x = x;");
+    parseExpression("super.x = x;");
   }
 
   void test_missingCatchOrFinally() {
-    TryStatement statement = ParserTestCase.parse4("parseTryStatement",
-        "try {}", [ParserErrorCode.MISSING_CATCH_OR_FINALLY]);
+    TryStatement statement = parse4("parseTryStatement", "try {}",
+        [ParserErrorCode.MISSING_CATCH_OR_FINALLY]);
     expect(statement, isNotNull);
   }
 
@@ -1504,37 +1395,32 @@
   }
 
   void test_missingConstFinalVarOrType_static() {
-    ParserTestCase.parseCompilationUnit("class A { static f; }", [
-      ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE
-    ]);
+    ParserTestCase.parseCompilationUnit("class A { static f; }",
+        [ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE]);
   }
 
   void test_missingConstFinalVarOrType_topLevel() {
-    ParserTestCase.parse3("parseFinalConstVarOrType", <Object>[false], "a;", [
-      ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE
-    ]);
+    parse3("parseFinalConstVarOrType", <Object>[false], "a;",
+        [ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE]);
   }
 
   void test_missingEnumBody() {
-    ParserTestCase.parse3("parseEnumDeclaration", <Object>[
-      emptyCommentAndMetadata()
-    ], "enum E;", [ParserErrorCode.MISSING_ENUM_BODY]);
+    parse3("parseEnumDeclaration", <Object>[emptyCommentAndMetadata()],
+        "enum E;", [ParserErrorCode.MISSING_ENUM_BODY]);
   }
 
   void test_missingExpressionInThrow_withCascade() {
-    ParserTestCase.parse4("parseThrowExpression", "throw;", [
-      ParserErrorCode.MISSING_EXPRESSION_IN_THROW
-    ]);
+    parse4("parseThrowExpression", "throw;",
+        [ParserErrorCode.MISSING_EXPRESSION_IN_THROW]);
   }
 
   void test_missingExpressionInThrow_withoutCascade() {
-    ParserTestCase.parse4("parseThrowExpressionWithoutCascade", "throw;", [
-      ParserErrorCode.MISSING_EXPRESSION_IN_THROW
-    ]);
+    parse4("parseThrowExpressionWithoutCascade", "throw;",
+        [ParserErrorCode.MISSING_EXPRESSION_IN_THROW]);
   }
 
   void test_missingFunctionBody_emptyNotAllowed() {
-    ParserTestCase.parse3("parseFunctionBody", <Object>[
+    parse3("parseFunctionBody", <Object>[
       false,
       ParserErrorCode.MISSING_FUNCTION_BODY,
       false
@@ -1542,7 +1428,7 @@
   }
 
   void test_missingFunctionBody_invalid() {
-    ParserTestCase.parse3("parseFunctionBody", <Object>[
+    parse3("parseFunctionBody", <Object>[
       false,
       ParserErrorCode.MISSING_FUNCTION_BODY,
       false
@@ -1580,48 +1466,43 @@
   }
 
   void test_missingIdentifier_afterOperator() {
-    ParserTestCase.parse4("parseMultiplicativeExpression", "1 *", [
-      ParserErrorCode.MISSING_IDENTIFIER
-    ]);
+    parse4("parseMultiplicativeExpression", "1 *",
+        [ParserErrorCode.MISSING_IDENTIFIER]);
   }
 
   void test_missingIdentifier_beforeClosingCurly() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "int}", [
+    parse3("parseClassMember", <Object>["C"], "int}", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.EXPECTED_TOKEN
     ]);
   }
 
   void test_missingIdentifier_functionDeclaration_returnTypeWithoutName() {
-    ParserTestCase.parse4("parseFunctionDeclarationStatement", "A<T> () {}", [
-      ParserErrorCode.MISSING_IDENTIFIER
-    ]);
+    parse4("parseFunctionDeclarationStatement", "A<T> () {}",
+        [ParserErrorCode.MISSING_IDENTIFIER]);
   }
 
   void test_missingIdentifier_inEnum() {
-    ParserTestCase.parse3("parseEnumDeclaration", <Object>[
-      emptyCommentAndMetadata()
-    ], "enum E {, TWO}", [ParserErrorCode.MISSING_IDENTIFIER]);
+    parse3("parseEnumDeclaration", <Object>[emptyCommentAndMetadata()],
+        "enum E {, TWO}", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
 
   void test_missingIdentifier_inSymbol_afterPeriod() {
-    ParserTestCase.parse4(
-        "parseSymbolLiteral", "#a.", [ParserErrorCode.MISSING_IDENTIFIER]);
+    parse4("parseSymbolLiteral", "#a.", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
 
   void test_missingIdentifier_inSymbol_first() {
-    ParserTestCase.parse4(
-        "parseSymbolLiteral", "#", [ParserErrorCode.MISSING_IDENTIFIER]);
+    parse4("parseSymbolLiteral", "#", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
 
   void test_missingIdentifier_number() {
-    SimpleIdentifier expression = ParserTestCase.parse4(
+    SimpleIdentifier expression = parse4(
         "parseSimpleIdentifier", "1", [ParserErrorCode.MISSING_IDENTIFIER]);
     expect(expression.isSynthetic, isTrue);
   }
 
   void test_missingKeywordOperator() {
-    ParserTestCase.parse3("parseOperator", <Object>[
+    parse3("parseOperator", <Object>[
       emptyCommentAndMetadata(),
       null,
       null
@@ -1629,33 +1510,28 @@
   }
 
   void test_missingKeywordOperator_parseClassMember() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "+() {}", [
-      ParserErrorCode.MISSING_KEYWORD_OPERATOR
-    ]);
+    parse3("parseClassMember", <Object>["C"], "+() {}",
+        [ParserErrorCode.MISSING_KEYWORD_OPERATOR]);
   }
 
   void test_missingKeywordOperator_parseClassMember_afterTypeName() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "int +() {}", [
-      ParserErrorCode.MISSING_KEYWORD_OPERATOR
-    ]);
+    parse3("parseClassMember", <Object>["C"], "int +() {}",
+        [ParserErrorCode.MISSING_KEYWORD_OPERATOR]);
   }
 
   void test_missingKeywordOperator_parseClassMember_afterVoid() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "void +() {}", [
-      ParserErrorCode.MISSING_KEYWORD_OPERATOR
-    ]);
+    parse3("parseClassMember", <Object>["C"], "void +() {}",
+        [ParserErrorCode.MISSING_KEYWORD_OPERATOR]);
   }
 
   void test_missingMethodParameters_void_block() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "void m {} }", [
-      ParserErrorCode.MISSING_METHOD_PARAMETERS
-    ]);
+    parse3("parseClassMember", <Object>["C"], "void m {} }",
+        [ParserErrorCode.MISSING_METHOD_PARAMETERS]);
   }
 
   void test_missingMethodParameters_void_expression() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "void m => null; }", [ParserErrorCode.MISSING_METHOD_PARAMETERS]);
+    parse3("parseClassMember", <Object>["C"], "void m => null; }",
+        [ParserErrorCode.MISSING_METHOD_PARAMETERS]);
   }
 
   void test_missingNameInLibraryDirective() {
@@ -1671,13 +1547,12 @@
   }
 
   void test_missingPrefixInDeferredImport() {
-    ParserTestCase.parseCompilationUnit("import 'foo.dart' deferred;", [
-      ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT
-    ]);
+    ParserTestCase.parseCompilationUnit("import 'foo.dart' deferred;",
+        [ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT]);
   }
 
   void test_missingStartAfterSync() {
-    ParserTestCase.parse3("parseFunctionBody", <Object>[
+    parse3("parseFunctionBody", <Object>[
       false,
       null,
       false
@@ -1693,15 +1568,13 @@
   }
 
   void test_missingTerminatorForParameterGroup_named() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, {b: 0)", [
-      ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP
-    ]);
+    parse4("parseFormalParameterList", "(a, {b: 0)",
+        [ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP]);
   }
 
   void test_missingTerminatorForParameterGroup_optional() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, [b = 0)", [
-      ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP
-    ]);
+    parse4("parseFormalParameterList", "(a, [b = 0)",
+        [ParserErrorCode.MISSING_TERMINATOR_FOR_PARAMETER_GROUP]);
   }
 
   void test_missingTypedefParameters_nonVoid() {
@@ -1720,21 +1593,18 @@
   }
 
   void test_missingVariableInForEach() {
-    ParserTestCase.parse4("parseForStatement", "for (a < b in foo) {}", [
-      ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH
-    ]);
+    parse4("parseForStatement", "for (a < b in foo) {}",
+        [ParserErrorCode.MISSING_VARIABLE_IN_FOR_EACH]);
   }
 
   void test_mixedParameterGroups_namedPositional() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, {b}, [c])", [
-      ParserErrorCode.MIXED_PARAMETER_GROUPS
-    ]);
+    parse4("parseFormalParameterList", "(a, {b}, [c])",
+        [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
   }
 
   void test_mixedParameterGroups_positionalNamed() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, [b], {c})", [
-      ParserErrorCode.MIXED_PARAMETER_GROUPS
-    ]);
+    parse4("parseFormalParameterList", "(a, [b], {c})",
+        [ParserErrorCode.MIXED_PARAMETER_GROUPS]);
   }
 
   void test_mixin_application_lacks_with_clause() {
@@ -1743,9 +1613,8 @@
   }
 
   void test_multipleExtendsClauses() {
-    ParserTestCase.parseCompilationUnit("class A extends B extends C {}", [
-      ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES
-    ]);
+    ParserTestCase.parseCompilationUnit("class A extends B extends C {}",
+        [ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES]);
   }
 
   void test_multipleImplementsClauses() {
@@ -1759,9 +1628,8 @@
   }
 
   void test_multipleNamedParameterGroups() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, {b}, {c})", [
-      ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS
-    ]);
+    parse4("parseFormalParameterList", "(a, {b}, {c})",
+        [ParserErrorCode.MULTIPLE_NAMED_PARAMETER_GROUPS]);
   }
 
   void test_multiplePartOfDirectives() {
@@ -1770,39 +1638,33 @@
   }
 
   void test_multiplePositionalParameterGroups() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, [b], [c])", [
-      ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS
-    ]);
+    parse4("parseFormalParameterList", "(a, [b], [c])",
+        [ParserErrorCode.MULTIPLE_POSITIONAL_PARAMETER_GROUPS]);
   }
 
   void test_multipleVariablesInForEach() {
-    ParserTestCase.parse4("parseForStatement", "for (int a, b in foo) {}", [
-      ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH
-    ]);
+    parse4("parseForStatement", "for (int a, b in foo) {}",
+        [ParserErrorCode.MULTIPLE_VARIABLES_IN_FOR_EACH]);
   }
 
   void test_multipleWithClauses() {
-    ParserTestCase.parseCompilationUnit("class A extends B with C with D {}", [
-      ParserErrorCode.MULTIPLE_WITH_CLAUSES
-    ]);
+    ParserTestCase.parseCompilationUnit("class A extends B with C with D {}",
+        [ParserErrorCode.MULTIPLE_WITH_CLAUSES]);
   }
 
   void test_namedParameterOutsideGroup() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, b : 0)", [
-      ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP
-    ]);
+    parse4("parseFormalParameterList", "(a, b : 0)",
+        [ParserErrorCode.NAMED_PARAMETER_OUTSIDE_GROUP]);
   }
 
   void test_nonConstructorFactory_field() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "factory int x;", [
-      ParserErrorCode.NON_CONSTRUCTOR_FACTORY
-    ]);
+    parse3("parseClassMember", <Object>["C"], "factory int x;",
+        [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]);
   }
 
   void test_nonConstructorFactory_method() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "factory int m() {}", [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]);
+    parse3("parseClassMember", <Object>["C"], "factory int m() {}",
+        [ParserErrorCode.NON_CONSTRUCTOR_FACTORY]);
   }
 
   void test_nonIdentifierLibraryName_library() {
@@ -1818,23 +1680,18 @@
   }
 
   void test_nonPartOfDirectiveInPart_after() {
-    ParserTestCase.parseCompilationUnit("part of l; part 'f.dart';", [
-      ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART
-    ]);
+    ParserTestCase.parseCompilationUnit("part of l; part 'f.dart';",
+        [ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART]);
   }
 
   void test_nonPartOfDirectiveInPart_before() {
-    ParserTestCase.parseCompilationUnit("part 'f.dart'; part of m;", [
-      ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART
-    ]);
+    ParserTestCase.parseCompilationUnit("part 'f.dart'; part of m;",
+        [ParserErrorCode.NON_PART_OF_DIRECTIVE_IN_PART]);
   }
 
   void test_nonUserDefinableOperator() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "operator +=(int x) => x + 1;", [
-      ParserErrorCode.NON_USER_DEFINABLE_OPERATOR
-    ]);
+    parse3("parseClassMember", <Object>["C"], "operator +=(int x) => x + 1;",
+        [ParserErrorCode.NON_USER_DEFINABLE_OPERATOR]);
   }
 
   void test_optionalAfterNormalParameters_named() {
@@ -1848,7 +1705,7 @@
   }
 
   void test_parseCascadeSection_missingIdentifier() {
-    MethodInvocation methodInvocation = ParserTestCase.parse4(
+    MethodInvocation methodInvocation = parse4(
         "parseCascadeSection", "..()", [ParserErrorCode.MISSING_IDENTIFIER]);
     expect(methodInvocation.target, isNull);
     expect(methodInvocation.methodName.name, "");
@@ -1856,21 +1713,18 @@
   }
 
   void test_positionalAfterNamedArgument() {
-    ParserTestCase.parse4("parseArgumentList", "(x: 1, 2)", [
-      ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT
-    ]);
+    parse4("parseArgumentList", "(x: 1, 2)",
+        [ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT]);
   }
 
   void test_positionalParameterOutsideGroup() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, b = 0)", [
-      ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP
-    ]);
+    parse4("parseFormalParameterList", "(a, b = 0)",
+        [ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP]);
   }
 
   void test_redirectionInNonFactoryConstructor() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "C() = D;", [
-      ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR
-    ]);
+    parse3("parseClassMember", <Object>["C"], "C() = D;",
+        [ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR]);
   }
 
   void test_setterInFunction_block() {
@@ -1884,53 +1738,45 @@
   }
 
   void test_staticAfterConst() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "final static int f;", [ParserErrorCode.STATIC_AFTER_FINAL]);
+    parse3("parseClassMember", <Object>["C"], "final static int f;",
+        [ParserErrorCode.STATIC_AFTER_FINAL]);
   }
 
   void test_staticAfterFinal() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "const static int f;", [ParserErrorCode.STATIC_AFTER_CONST]);
+    parse3("parseClassMember", <Object>["C"], "const static int f;",
+        [ParserErrorCode.STATIC_AFTER_CONST]);
   }
 
   void test_staticAfterVar() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "var static f;", [
-      ParserErrorCode.STATIC_AFTER_VAR
-    ]);
+    parse3("parseClassMember", <Object>["C"], "var static f;",
+        [ParserErrorCode.STATIC_AFTER_VAR]);
   }
 
   void test_staticConstructor() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "static C.m() {}", [ParserErrorCode.STATIC_CONSTRUCTOR]);
+    parse3("parseClassMember", <Object>["C"], "static C.m() {}",
+        [ParserErrorCode.STATIC_CONSTRUCTOR]);
   }
 
   void test_staticGetterWithoutBody() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "static get m;", [
-      ParserErrorCode.STATIC_GETTER_WITHOUT_BODY
-    ]);
+    parse3("parseClassMember", <Object>["C"], "static get m;",
+        [ParserErrorCode.STATIC_GETTER_WITHOUT_BODY]);
   }
 
   void test_staticOperator_noReturnType() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "static operator +(int x) => x + 1;", [ParserErrorCode.STATIC_OPERATOR]);
+    parse3("parseClassMember", <Object>["C"],
+        "static operator +(int x) => x + 1;",
+        [ParserErrorCode.STATIC_OPERATOR]);
   }
 
   void test_staticOperator_returnType() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "static int operator +(int x) => x + 1;", [
-      ParserErrorCode.STATIC_OPERATOR
-    ]);
+    parse3("parseClassMember", <Object>["C"],
+        "static int operator +(int x) => x + 1;",
+        [ParserErrorCode.STATIC_OPERATOR]);
   }
 
   void test_staticSetterWithoutBody() {
-    ParserTestCase.parse3("parseClassMember", <Object>[
-      "C"
-    ], "static set m(x);", [ParserErrorCode.STATIC_SETTER_WITHOUT_BODY]);
+    parse3("parseClassMember", <Object>["C"], "static set m(x);",
+        [ParserErrorCode.STATIC_SETTER_WITHOUT_BODY]);
   }
 
   void test_staticTopLevelDeclaration_class() {
@@ -1954,14 +1800,13 @@
   }
 
   void test_switchHasCaseAfterDefaultCase() {
-    ParserTestCase.parse4("parseSwitchStatement",
-        "switch (a) {default: return 0; case 1: return 1;}", [
-      ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE
-    ]);
+    parse4("parseSwitchStatement",
+        "switch (a) {default: return 0; case 1: return 1;}",
+        [ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE]);
   }
 
   void test_switchHasCaseAfterDefaultCase_repeated() {
-    ParserTestCase.parse4("parseSwitchStatement",
+    parse4("parseSwitchStatement",
         "switch (a) {default: return 0; case 1: return 1; case 2: return 2;}", [
       ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE,
       ParserErrorCode.SWITCH_HAS_CASE_AFTER_DEFAULT_CASE
@@ -1969,14 +1814,13 @@
   }
 
   void test_switchHasMultipleDefaultCases() {
-    ParserTestCase.parse4("parseSwitchStatement",
-        "switch (a) {default: return 0; default: return 1;}", [
-      ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES
-    ]);
+    parse4("parseSwitchStatement",
+        "switch (a) {default: return 0; default: return 1;}",
+        [ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES]);
   }
 
   void test_switchHasMultipleDefaultCases_repeated() {
-    ParserTestCase.parse4("parseSwitchStatement",
+    parse4("parseSwitchStatement",
         "switch (a) {default: return 0; default: return 1; default: return 2;}",
         [
       ParserErrorCode.SWITCH_HAS_MULTIPLE_DEFAULT_CASES,
@@ -1985,27 +1829,21 @@
   }
 
   void test_topLevelOperator_withoutType() {
-    ParserTestCase.parse3("parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "operator +(bool x, bool y) => x | y;", [
-      ParserErrorCode.TOP_LEVEL_OPERATOR
-    ]);
+    parse3("parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "operator +(bool x, bool y) => x | y;",
+        [ParserErrorCode.TOP_LEVEL_OPERATOR]);
   }
 
   void test_topLevelOperator_withType() {
-    ParserTestCase.parse3("parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "bool operator +(bool x, bool y) => x | y;", [
-      ParserErrorCode.TOP_LEVEL_OPERATOR
-    ]);
+    parse3("parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "bool operator +(bool x, bool y) => x | y;",
+        [ParserErrorCode.TOP_LEVEL_OPERATOR]);
   }
 
   void test_topLevelOperator_withVoid() {
-    ParserTestCase.parse3("parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "void operator +(bool x, bool y) => x | y;", [
-      ParserErrorCode.TOP_LEVEL_OPERATOR
-    ]);
+    parse3("parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "void operator +(bool x, bool y) => x | y;",
+        [ParserErrorCode.TOP_LEVEL_OPERATOR]);
   }
 
   void test_typedefInClass_withoutReturnType() {
@@ -2014,21 +1852,18 @@
   }
 
   void test_typedefInClass_withReturnType() {
-    ParserTestCase.parseCompilationUnit("class C { typedef int F(int x); }", [
-      ParserErrorCode.TYPEDEF_IN_CLASS
-    ]);
+    ParserTestCase.parseCompilationUnit("class C { typedef int F(int x); }",
+        [ParserErrorCode.TYPEDEF_IN_CLASS]);
   }
 
   void test_unexpectedTerminatorForParameterGroup_named() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, b})", [
-      ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP
-    ]);
+    parse4("parseFormalParameterList", "(a, b})",
+        [ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP]);
   }
 
   void test_unexpectedTerminatorForParameterGroup_optional() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, b])", [
-      ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP
-    ]);
+    parse4("parseFormalParameterList", "(a, b])",
+        [ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP]);
   }
 
   void test_unexpectedToken_endOfFieldDeclarationStatement() {
@@ -2042,7 +1877,7 @@
   }
 
   void test_unexpectedToken_semicolonBetweenClassMembers() {
-    ParserTestCase.parse3("parseClassDeclaration", <Object>[
+    parse3("parseClassDeclaration", <Object>[
       emptyCommentAndMetadata(),
       null
     ], "class C { int x; ; int y;}", [ParserErrorCode.UNEXPECTED_TOKEN]);
@@ -2054,7 +1889,7 @@
   }
 
   void test_useOfUnaryPlusOperator() {
-    SimpleIdentifier expression = ParserTestCase.parse4(
+    SimpleIdentifier expression = parse4(
         "parseUnaryExpression", "+x", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(
         (obj) => obj is SimpleIdentifier, SimpleIdentifier, expression);
@@ -2072,8 +1907,7 @@
   }
 
   void test_varAsTypeName_as() {
-    ParserTestCase.parseExpression(
-        "x as var", [ParserErrorCode.VAR_AS_TYPE_NAME]);
+    parseExpression("x as var", [ParserErrorCode.VAR_AS_TYPE_NAME]);
   }
 
   void test_varClass() {
@@ -2087,9 +1921,8 @@
   }
 
   void test_varReturnType() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "var m() {}", [
-      ParserErrorCode.VAR_RETURN_TYPE
-    ]);
+    parse3("parseClassMember", <Object>["C"], "var m() {}",
+        [ParserErrorCode.VAR_RETURN_TYPE]);
   }
 
   void test_varTypedef() {
@@ -2098,21 +1931,18 @@
   }
 
   void test_voidParameter() {
-    ParserTestCase.parse4("parseNormalFormalParameter", "void a)", [
-      ParserErrorCode.VOID_PARAMETER
-    ]);
+    parse4("parseNormalFormalParameter", "void a)",
+        [ParserErrorCode.VOID_PARAMETER]);
   }
 
   void test_voidVariable_parseClassMember_initializer() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "void x = 0;", [
-      ParserErrorCode.VOID_VARIABLE
-    ]);
+    parse3("parseClassMember", <Object>["C"], "void x = 0;",
+        [ParserErrorCode.VOID_VARIABLE]);
   }
 
   void test_voidVariable_parseClassMember_noInitializer() {
-    ParserTestCase.parse3("parseClassMember", <Object>["C"], "void x;", [
-      ParserErrorCode.VOID_VARIABLE
-    ]);
+    parse3("parseClassMember", <Object>["C"], "void x;",
+        [ParserErrorCode.VOID_VARIABLE]);
   }
 
   void test_voidVariable_parseCompilationUnit_initializer() {
@@ -2126,15 +1956,13 @@
   }
 
   void test_voidVariable_parseCompilationUnitMember_initializer() {
-    ParserTestCase.parse3("parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "void a = 0;", [ParserErrorCode.VOID_VARIABLE]);
+    parse3("parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "void a = 0;", [ParserErrorCode.VOID_VARIABLE]);
   }
 
   void test_voidVariable_parseCompilationUnitMember_noInitializer() {
-    ParserTestCase.parse3("parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "void a;", [ParserErrorCode.VOID_VARIABLE]);
+    parse3("parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "void a;", [ParserErrorCode.VOID_VARIABLE]);
   }
 
   void test_voidVariable_statement_initializer() {
@@ -2157,34 +1985,30 @@
   }
 
   void test_withWithoutExtends() {
-    ParserTestCase.parse3("parseClassDeclaration", <Object>[
+    parse3("parseClassDeclaration", <Object>[
       emptyCommentAndMetadata(),
       null
     ], "class A with B, C {}", [ParserErrorCode.WITH_WITHOUT_EXTENDS]);
   }
 
   void test_wrongSeparatorForNamedParameter() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, {b = 0})", [
-      ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER
-    ]);
+    parse4("parseFormalParameterList", "(a, {b = 0})",
+        [ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER]);
   }
 
   void test_wrongSeparatorForPositionalParameter() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, [b : 0])", [
-      ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER
-    ]);
+    parse4("parseFormalParameterList", "(a, [b : 0])",
+        [ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER]);
   }
 
   void test_wrongTerminatorForParameterGroup_named() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, {b, c])", [
-      ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP
-    ]);
+    parse4("parseFormalParameterList", "(a, {b, c])",
+        [ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP]);
   }
 
   void test_wrongTerminatorForParameterGroup_optional() {
-    ParserTestCase.parse4("parseFormalParameterList", "(a, [b, c})", [
-      ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP
-    ]);
+    parse4("parseFormalParameterList", "(a, [b, c})",
+        [ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP]);
   }
 }
 
@@ -2559,8 +2383,7 @@
 @reflectiveTest
 class NonErrorParserTest extends ParserTestCase {
   void test_constFactory_external() {
-    ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "external const factory C();");
+    parse("parseClassMember", <Object>["C"], "external const factory C();");
   }
 }
 
@@ -2595,22 +2418,6 @@
   CommentAndMetadata emptyCommentAndMetadata() =>
       new CommentAndMetadata(null, null);
 
-  @override
-  void setUp() {
-    super.setUp();
-    parseFunctionBodies = true;
-  }
-
-  /**
-   * Create a parser.
-   *
-   * @param listener the listener to be passed to the parser
-   * @return the parser that was created
-   */
-  static Parser createParser(GatheringErrorListener listener) {
-    return new Parser(null, listener);
-  }
-
   /**
    * Invoke a method in [Parser]. The method is assumed to have the given number and type of
    * parameters and will be invoked with the given arguments.
@@ -2627,7 +2434,7 @@
    * @throws AssertionFailedError if the result is `null` or the errors produced while
    *           scanning and parsing the source do not match the expected errors
    */
-  static Object invokeParserMethod(String methodName, List<Object> objects,
+  Object invokeParserMethod(String methodName, List<Object> objects,
       String source, GatheringErrorListener listener) {
     //
     // Scan the source.
@@ -2666,7 +2473,7 @@
    * @throws AssertionFailedError if the result is `null` or the errors produced while
    *           scanning and parsing the source do not match the expected errors
    */
-  static Object invokeParserMethod2(
+  Object invokeParserMethod2(
           String methodName, String source, GatheringErrorListener listener) =>
       invokeParserMethod(methodName, _EMPTY_ARGUMENTS, source, listener);
 
@@ -2684,7 +2491,7 @@
    * @throws Exception if the method could not be invoked or throws an exception
    * @throws AssertionFailedError if the result is `null` or if any errors are produced
    */
-  static Object parse(String methodName, List<Object> objects, String source) =>
+  Object parse(String methodName, List<Object> objects, String source) =>
       parse2(methodName, objects, source);
 
   /**
@@ -2703,7 +2510,7 @@
    * @throws AssertionFailedError if the result is `null` or the errors produced while
    *           scanning and parsing the source do not match the expected errors
    */
-  static Object parse2(String methodName, List<Object> objects, String source,
+  Object parse2(String methodName, List<Object> objects, String source,
       [List<AnalysisError> errors = AnalysisError.NO_ERRORS]) {
     GatheringErrorListener listener = new GatheringErrorListener();
     Object result = invokeParserMethod(methodName, objects, source, listener);
@@ -2727,7 +2534,7 @@
    * @throws AssertionFailedError if the result is `null` or the errors produced while
    *           scanning and parsing the source do not match the expected errors
    */
-  static Object parse3(String methodName, List<Object> objects, String source,
+  Object parse3(String methodName, List<Object> objects, String source,
       [List<ErrorCode> errorCodes = ErrorCode.EMPTY_LIST]) {
     GatheringErrorListener listener = new GatheringErrorListener();
     Object result = invokeParserMethod(methodName, objects, source, listener);
@@ -2749,11 +2556,50 @@
    * @throws AssertionFailedError if the result is `null` or the errors produced while
    *           scanning and parsing the source do not match the expected errors
    */
-  static Object parse4(String methodName, String source,
+  Object parse4(String methodName, String source,
           [List<ErrorCode> errorCodes = ErrorCode.EMPTY_LIST]) =>
       parse3(methodName, _EMPTY_ARGUMENTS, source, errorCodes);
 
   /**
+   * Parse the given source as an expression.
+   *
+   * @param source the source to be parsed
+   * @param errorCodes the error codes of the errors that are expected to be found
+   * @return the expression that was parsed
+   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
+   *           not match those that are expected, or if the result would have been `null`
+   */
+  Expression parseExpression(String source,
+      [List<ErrorCode> errorCodes = ErrorCode.EMPTY_LIST]) {
+    GatheringErrorListener listener = new GatheringErrorListener();
+    Scanner scanner =
+        new Scanner(null, new CharSequenceReader(source), listener);
+    listener.setLineInfo(new TestSource(), scanner.lineStarts);
+    Token token = scanner.tokenize();
+    Parser parser = createParser(listener);
+    Expression expression = parser.parseExpression(token);
+    expect(expression, isNotNull);
+    listener.assertErrorsWithCodes(errorCodes);
+    return expression;
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    parseFunctionBodies = true;
+  }
+
+  /**
+   * Create a parser.
+   *
+   * @param listener the listener to be passed to the parser
+   * @return the parser that was created
+   */
+  static Parser createParser(GatheringErrorListener listener) {
+    return new Parser(null, listener);
+  }
+
+  /**
    * Parse the given source as a compilation unit.
    *
    * @param source the source to be parsed
@@ -2777,29 +2623,6 @@
   }
 
   /**
-   * Parse the given source as an expression.
-   *
-   * @param source the source to be parsed
-   * @param errorCodes the error codes of the errors that are expected to be found
-   * @return the expression that was parsed
-   * @throws Exception if the source could not be parsed, if the compilation errors in the source do
-   *           not match those that are expected, or if the result would have been `null`
-   */
-  static Expression parseExpression(String source,
-      [List<ErrorCode> errorCodes = ErrorCode.EMPTY_LIST]) {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    Scanner scanner =
-        new Scanner(null, new CharSequenceReader(source), listener);
-    listener.setLineInfo(new TestSource(), scanner.lineStarts);
-    Token token = scanner.tokenize();
-    Parser parser = createParser(listener);
-    Expression expression = parser.parseExpression(token);
-    expect(expression, isNotNull);
-    listener.assertErrorsWithCodes(errorCodes);
-    return expression;
-  }
-
-  /**
    * Parse the given source as a statement.
    *
    * @param source the source to be parsed
@@ -2867,15 +2690,15 @@
   }
 
   void test_additiveExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "+ y", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("+ y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftOperand);
     expect(expression.leftOperand.isSynthetic, isTrue);
   }
 
   void test_additiveExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("+", [
+    BinaryExpression expression = parseExpression("+", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -2888,23 +2711,23 @@
   }
 
   void test_additiveExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "x +", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("x +", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_additiveExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "super +", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("super +", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_additiveExpression_precedence_multiplicative_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("* +", [
+    BinaryExpression expression = parseExpression("* +", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -2914,7 +2737,7 @@
   }
 
   void test_additiveExpression_precedence_multiplicative_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("+ *", [
+    BinaryExpression expression = parseExpression("+ *", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -2924,7 +2747,7 @@
   }
 
   void test_additiveExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super + +", [
+    BinaryExpression expression = parseExpression("super + +", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -2933,8 +2756,8 @@
   }
 
   void test_assignmentExpression_missing_compound1() {
-    AssignmentExpression expression = ParserTestCase.parseExpression(
-        "= y = 0", [ParserErrorCode.MISSING_IDENTIFIER]);
+    AssignmentExpression expression =
+        parseExpression("= y = 0", [ParserErrorCode.MISSING_IDENTIFIER]);
     Expression syntheticExpression = expression.leftHandSide;
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, syntheticExpression);
@@ -2942,8 +2765,8 @@
   }
 
   void test_assignmentExpression_missing_compound2() {
-    AssignmentExpression expression = ParserTestCase.parseExpression(
-        "x = = 0", [ParserErrorCode.MISSING_IDENTIFIER]);
+    AssignmentExpression expression =
+        parseExpression("x = = 0", [ParserErrorCode.MISSING_IDENTIFIER]);
     Expression syntheticExpression =
         (expression.rightHandSide as AssignmentExpression).leftHandSide;
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
@@ -2952,8 +2775,8 @@
   }
 
   void test_assignmentExpression_missing_compound3() {
-    AssignmentExpression expression = ParserTestCase.parseExpression(
-        "x = y =", [ParserErrorCode.MISSING_IDENTIFIER]);
+    AssignmentExpression expression =
+        parseExpression("x = y =", [ParserErrorCode.MISSING_IDENTIFIER]);
     Expression syntheticExpression =
         (expression.rightHandSide as AssignmentExpression).rightHandSide;
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
@@ -2962,31 +2785,31 @@
   }
 
   void test_assignmentExpression_missing_LHS() {
-    AssignmentExpression expression = ParserTestCase.parseExpression(
-        "= 0", [ParserErrorCode.MISSING_IDENTIFIER]);
+    AssignmentExpression expression =
+        parseExpression("= 0", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftHandSide);
     expect(expression.leftHandSide.isSynthetic, isTrue);
   }
 
   void test_assignmentExpression_missing_RHS() {
-    AssignmentExpression expression = ParserTestCase.parseExpression(
-        "x =", [ParserErrorCode.MISSING_IDENTIFIER]);
+    AssignmentExpression expression =
+        parseExpression("x =", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftHandSide);
     expect(expression.rightHandSide.isSynthetic, isTrue);
   }
 
   void test_bitwiseAndExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "& y", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("& y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftOperand);
     expect(expression.leftOperand.isSynthetic, isTrue);
   }
 
   void test_bitwiseAndExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("&", [
+    BinaryExpression expression = parseExpression("&", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -2999,23 +2822,23 @@
   }
 
   void test_bitwiseAndExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "x &", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("x &", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_bitwiseAndExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "super &", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("super &", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_bitwiseAndExpression_precedence_equality_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("== &&", [
+    BinaryExpression expression = parseExpression("== &&", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3025,7 +2848,7 @@
   }
 
   void test_bitwiseAndExpression_precedence_equality_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("&& ==", [
+    BinaryExpression expression = parseExpression("&& ==", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3035,7 +2858,7 @@
   }
 
   void test_bitwiseAndExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super &  &", [
+    BinaryExpression expression = parseExpression("super &  &", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3044,15 +2867,15 @@
   }
 
   void test_bitwiseOrExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "| y", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("| y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftOperand);
     expect(expression.leftOperand.isSynthetic, isTrue);
   }
 
   void test_bitwiseOrExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("|", [
+    BinaryExpression expression = parseExpression("|", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3065,23 +2888,23 @@
   }
 
   void test_bitwiseOrExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "x |", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("x |", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_bitwiseOrExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "super |", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("super |", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_bitwiseOrExpression_precedence_xor_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("^ |", [
+    BinaryExpression expression = parseExpression("^ |", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3091,7 +2914,7 @@
   }
 
   void test_bitwiseOrExpression_precedence_xor_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("| ^", [
+    BinaryExpression expression = parseExpression("| ^", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3101,7 +2924,7 @@
   }
 
   void test_bitwiseOrExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super |  |", [
+    BinaryExpression expression = parseExpression("super |  |", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3110,15 +2933,15 @@
   }
 
   void test_bitwiseXorExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "^ y", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("^ y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftOperand);
     expect(expression.leftOperand.isSynthetic, isTrue);
   }
 
   void test_bitwiseXorExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("^", [
+    BinaryExpression expression = parseExpression("^", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3131,23 +2954,23 @@
   }
 
   void test_bitwiseXorExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "x ^", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("x ^", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_bitwiseXorExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "super ^", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("super ^", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_bitwiseXorExpression_precedence_and_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("& ^", [
+    BinaryExpression expression = parseExpression("& ^", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3157,7 +2980,7 @@
   }
 
   void test_bitwiseXorExpression_precedence_and_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("^ &", [
+    BinaryExpression expression = parseExpression("^ &", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3167,7 +2990,7 @@
   }
 
   void test_bitwiseXorExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super ^  ^", [
+    BinaryExpression expression = parseExpression("super ^  ^", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3182,35 +3005,31 @@
   }
 
   void test_conditionalExpression_missingElse() {
-    ConditionalExpression expression = ParserTestCase.parse4(
-        "parseConditionalExpression", "x ? y :", [
-      ParserErrorCode.MISSING_IDENTIFIER
-    ]);
+    ConditionalExpression expression = parse4("parseConditionalExpression",
+        "x ? y :", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.elseExpression);
     expect(expression.elseExpression.isSynthetic, isTrue);
   }
 
   void test_conditionalExpression_missingThen() {
-    ConditionalExpression expression = ParserTestCase.parse4(
-        "parseConditionalExpression", "x ? : z", [
-      ParserErrorCode.MISSING_IDENTIFIER
-    ]);
+    ConditionalExpression expression = parse4("parseConditionalExpression",
+        "x ? : z", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.thenExpression);
     expect(expression.thenExpression.isSynthetic, isTrue);
   }
 
   void test_equalityExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "== y", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("== y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftOperand);
     expect(expression.leftOperand.isSynthetic, isTrue);
   }
 
   void test_equalityExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("==", [
+    BinaryExpression expression = parseExpression("==", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3223,23 +3042,23 @@
   }
 
   void test_equalityExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "x ==", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("x ==", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_equalityExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "super ==", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("super ==", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_equalityExpression_precedence_relational_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("is ==", [
+    BinaryExpression expression = parseExpression("is ==", [
       ParserErrorCode.EXPECTED_TYPE_NAME,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3249,7 +3068,7 @@
   }
 
   void test_equalityExpression_precedence_relational_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("== is", [
+    BinaryExpression expression = parseExpression("== is", [
       ParserErrorCode.EXPECTED_TYPE_NAME,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3259,8 +3078,7 @@
   }
 
   void test_equalityExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super ==  ==",
-        [
+    BinaryExpression expression = parseExpression("super ==  ==", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND
@@ -3270,8 +3088,8 @@
   }
 
   void test_expressionList_multiple_end() {
-    List<Expression> result = ParserTestCase.parse4("parseExpressionList",
-        ", 2, 3, 4", [ParserErrorCode.MISSING_IDENTIFIER]);
+    List<Expression> result = parse4("parseExpressionList", ", 2, 3, 4",
+        [ParserErrorCode.MISSING_IDENTIFIER]);
     expect(result, hasLength(4));
     Expression syntheticExpression = result[0];
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
@@ -3280,8 +3098,8 @@
   }
 
   void test_expressionList_multiple_middle() {
-    List<Expression> result = ParserTestCase.parse4("parseExpressionList",
-        "1, 2, , 4", [ParserErrorCode.MISSING_IDENTIFIER]);
+    List<Expression> result = parse4("parseExpressionList", "1, 2, , 4",
+        [ParserErrorCode.MISSING_IDENTIFIER]);
     expect(result, hasLength(4));
     Expression syntheticExpression = result[2];
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
@@ -3290,8 +3108,8 @@
   }
 
   void test_expressionList_multiple_start() {
-    List<Expression> result = ParserTestCase.parse4("parseExpressionList",
-        "1, 2, 3,", [ParserErrorCode.MISSING_IDENTIFIER]);
+    List<Expression> result = parse4("parseExpressionList", "1, 2, 3,",
+        [ParserErrorCode.MISSING_IDENTIFIER]);
     expect(result, hasLength(4));
     Expression syntheticExpression = result[3];
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
@@ -3318,27 +3136,24 @@
   }
 
   void test_functionExpression_named() {
-    ParserTestCase.parseExpression(
-        "m(f() => 0);", [ParserErrorCode.EXPECTED_TOKEN]);
+    parseExpression("m(f() => 0);", [ParserErrorCode.EXPECTED_TOKEN]);
   }
 
   void test_incomplete_conditionalExpression() {
-    ParserTestCase.parseExpression("x ? 0", [
+    parseExpression("x ? 0", [
       ParserErrorCode.EXPECTED_TOKEN,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
   }
 
   void test_incomplete_constructorInitializers_empty() {
-    ParserTestCase.parse3("parseClassMember", ["C"], "C() : {}", [
-      ParserErrorCode.MISSING_INITIALIZER
-    ]);
+    parse3("parseClassMember", ["C"], "C() : {}",
+        [ParserErrorCode.MISSING_INITIALIZER]);
   }
 
   void test_incomplete_constructorInitializers_missingEquals() {
-    ClassMember member = ParserTestCase.parse3("parseClassMember", [
-      "C"
-    ], "C() : x(3) {}", [ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER]);
+    ClassMember member = parse3("parseClassMember", ["C"], "C() : x(3) {}",
+        [ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER]);
     expect(member, new isInstanceOf<ConstructorDeclaration>());
     NodeList<ConstructorInitializer> initializers =
         (member as ConstructorDeclaration).initializers;
@@ -3352,9 +3167,8 @@
   }
 
   void test_incomplete_constructorInitializers_variable() {
-    ParserTestCase.parse3("parseClassMember", ["C"], "C() : x {}", [
-      ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER
-    ]);
+    parse3("parseClassMember", ["C"], "C() : x {}",
+        [ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER]);
   }
 
   void test_incomplete_topLevelFunction() {
@@ -3536,15 +3350,15 @@
   }
 
   void test_logicalAndExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "&& y", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("&& y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftOperand);
     expect(expression.leftOperand.isSynthetic, isTrue);
   }
 
   void test_logicalAndExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("&&", [
+    BinaryExpression expression = parseExpression("&&", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3557,15 +3371,15 @@
   }
 
   void test_logicalAndExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "x &&", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("x &&", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_logicalAndExpression_precedence_bitwiseOr_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("| &&", [
+    BinaryExpression expression = parseExpression("| &&", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3575,7 +3389,7 @@
   }
 
   void test_logicalAndExpression_precedence_bitwiseOr_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("&& |", [
+    BinaryExpression expression = parseExpression("&& |", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3585,15 +3399,15 @@
   }
 
   void test_logicalOrExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "|| y", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("|| y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftOperand);
     expect(expression.leftOperand.isSynthetic, isTrue);
   }
 
   void test_logicalOrExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("||", [
+    BinaryExpression expression = parseExpression("||", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3606,15 +3420,15 @@
   }
 
   void test_logicalOrExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "x ||", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("x ||", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_logicalOrExpression_precedence_logicalAnd_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("&& ||", [
+    BinaryExpression expression = parseExpression("&& ||", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3624,7 +3438,7 @@
   }
 
   void test_logicalOrExpression_precedence_logicalAnd_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("|| &&", [
+    BinaryExpression expression = parseExpression("|| &&", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3634,8 +3448,7 @@
   }
 
   void test_missing_commaInArgumentList() {
-    ParserTestCase.parseExpression(
-        "f(x: 1 y: 2)", [ParserErrorCode.EXPECTED_TOKEN]);
+    parseExpression("f(x: 1 y: 2)", [ParserErrorCode.EXPECTED_TOKEN]);
   }
 
   void test_missingGet() {
@@ -3658,8 +3471,8 @@
   }
 
   void test_missingIdentifier_afterAnnotation() {
-    MethodDeclaration method = ParserTestCase.parse3("parseClassMember",
-        <Object>["C"], "@override }", [ParserErrorCode.EXPECTED_CLASS_MEMBER]);
+    MethodDeclaration method = parse3("parseClassMember", <Object>["C"],
+        "@override }", [ParserErrorCode.EXPECTED_CLASS_MEMBER]);
     expect(method.documentationComment, isNull);
     NodeList<Annotation> metadata = method.metadata;
     expect(metadata, hasLength(1));
@@ -3667,15 +3480,15 @@
   }
 
   void test_multiplicativeExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "* y", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("* y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftOperand);
     expect(expression.leftOperand.isSynthetic, isTrue);
   }
 
   void test_multiplicativeExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("*", [
+    BinaryExpression expression = parseExpression("*", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3688,38 +3501,37 @@
   }
 
   void test_multiplicativeExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "x *", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("x *", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_multiplicativeExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "super *", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("super *", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_multiplicativeExpression_precedence_unary_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "-x *", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("-x *", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is PrefixExpression,
         PrefixExpression, expression.leftOperand);
   }
 
   void test_multiplicativeExpression_precedence_unary_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "* -y", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("* -y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is PrefixExpression,
         PrefixExpression, expression.rightOperand);
   }
 
   void test_multiplicativeExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super ==  ==",
-        [
+    BinaryExpression expression = parseExpression("super ==  ==", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND
@@ -3729,14 +3541,13 @@
   }
 
   void test_nonStringLiteralUri_import() {
-    ParserTestCase.parseCompilationUnit("import dart:io; class C {}", [
-      ParserErrorCode.NON_STRING_LITERAL_AS_URI
-    ]);
+    ParserTestCase.parseCompilationUnit("import dart:io; class C {}",
+        [ParserErrorCode.NON_STRING_LITERAL_AS_URI]);
   }
 
   void test_prefixExpression_missing_operand_minus() {
-    PrefixExpression expression = ParserTestCase.parseExpression(
-        "-", [ParserErrorCode.MISSING_IDENTIFIER]);
+    PrefixExpression expression =
+        parseExpression("-", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf(
         (obj) => obj is SimpleIdentifier, SimpleIdentifier, expression.operand);
     expect(expression.operand.isSynthetic, isTrue);
@@ -3744,22 +3555,22 @@
   }
 
   void test_primaryExpression_argumentDefinitionTest() {
-    Expression expression = ParserTestCase.parse4(
+    Expression expression = parse4(
         "parsePrimaryExpression", "?a", [ParserErrorCode.UNEXPECTED_TOKEN]);
     EngineTestCase.assertInstanceOf(
         (obj) => obj is SimpleIdentifier, SimpleIdentifier, expression);
   }
 
   void test_relationalExpression_missing_LHS() {
-    IsExpression expression = ParserTestCase.parseExpression(
-        "is y", [ParserErrorCode.MISSING_IDENTIFIER]);
+    IsExpression expression =
+        parseExpression("is y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.expression);
     expect(expression.expression.isSynthetic, isTrue);
   }
 
   void test_relationalExpression_missing_LHS_RHS() {
-    IsExpression expression = ParserTestCase.parseExpression("is", [
+    IsExpression expression = parseExpression("is", [
       ParserErrorCode.EXPECTED_TYPE_NAME,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3772,15 +3583,15 @@
   }
 
   void test_relationalExpression_missing_RHS() {
-    IsExpression expression = ParserTestCase.parseExpression(
-        "x is", [ParserErrorCode.EXPECTED_TYPE_NAME]);
+    IsExpression expression =
+        parseExpression("x is", [ParserErrorCode.EXPECTED_TYPE_NAME]);
     EngineTestCase.assertInstanceOf(
         (obj) => obj is TypeName, TypeName, expression.type);
     expect(expression.type.isSynthetic, isTrue);
   }
 
   void test_relationalExpression_precedence_shift_right() {
-    IsExpression expression = ParserTestCase.parseExpression("<< is", [
+    IsExpression expression = parseExpression("<< is", [
       ParserErrorCode.EXPECTED_TYPE_NAME,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3790,15 +3601,15 @@
   }
 
   void test_shiftExpression_missing_LHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "<< y", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("<< y", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.leftOperand);
     expect(expression.leftOperand.isSynthetic, isTrue);
   }
 
   void test_shiftExpression_missing_LHS_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression("<<", [
+    BinaryExpression expression = parseExpression("<<", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3811,23 +3622,23 @@
   }
 
   void test_shiftExpression_missing_RHS() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "x <<", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("x <<", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_shiftExpression_missing_RHS_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression(
-        "super <<", [ParserErrorCode.MISSING_IDENTIFIER]);
+    BinaryExpression expression =
+        parseExpression("super <<", [ParserErrorCode.MISSING_IDENTIFIER]);
     EngineTestCase.assertInstanceOf((obj) => obj is SimpleIdentifier,
         SimpleIdentifier, expression.rightOperand);
     expect(expression.rightOperand.isSynthetic, isTrue);
   }
 
   void test_shiftExpression_precedence_unary_left() {
-    BinaryExpression expression = ParserTestCase.parseExpression("+ <<", [
+    BinaryExpression expression = parseExpression("+ <<", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3837,7 +3648,7 @@
   }
 
   void test_shiftExpression_precedence_unary_right() {
-    BinaryExpression expression = ParserTestCase.parseExpression("<< +", [
+    BinaryExpression expression = parseExpression("<< +", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
@@ -3847,8 +3658,7 @@
   }
 
   void test_shiftExpression_super() {
-    BinaryExpression expression = ParserTestCase.parseExpression("super << <<",
-        [
+    BinaryExpression expression = parseExpression("super << <<", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.MISSING_IDENTIFIER
     ]);
@@ -3869,7 +3679,7 @@
   }
 
   void test_unaryPlus() {
-    ParserTestCase.parseExpression("+2", [ParserErrorCode.MISSING_IDENTIFIER]);
+    parseExpression("+2", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
 }
 
@@ -4041,7 +3851,7 @@
 
   void test_visitExportDirective() {
     ExportDirective fromNode = AstFactory.exportDirective2("dart:uri");
-    ExportElement element = new ExportElementImpl();
+    ExportElement element = new ExportElementImpl(-1);
     fromNode.element = element;
     ExportDirective toNode = AstFactory.exportDirective2("dart:uri");
     ResolutionCopier.copyResolutionData(fromNode, toNode);
@@ -4506,7 +4316,7 @@
     // This test requires better error recovery than we currently have. In
     // particular, we need to be able to distinguish between an await expression
     // in the wrong context, and the use of 'await' as an identifier.
-    MethodDeclaration method = ParserTestCase.parse(
+    MethodDeclaration method = parse(
         "parseClassMember", <Object>["C"], "m() { return await x + await y; }");
     FunctionBody body = method.body;
     EngineTestCase.assertInstanceOf(
@@ -4527,7 +4337,7 @@
     // This fails because we are returning null from the method and asserting
     // that the return value is not null.
     CommentReference reference =
-        ParserTestCase.parse("parseCommentReference", <Object>["this", 5], "");
+        parse("parseCommentReference", <Object>["this", 5], "");
     SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
         (obj) => obj is SimpleIdentifier, SimpleIdentifier,
         reference.identifier);
@@ -4617,8 +4427,7 @@
   }
 
   void test_constFactory() {
-    ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "const factory C() = A;");
+    parse("parseClassMember", <Object>["C"], "const factory C() = A;");
   }
 
   void test_createSyntheticIdentifier() {
@@ -4823,8 +4632,7 @@
   }
 
   void test_parseAdditiveExpression_normal() {
-    BinaryExpression expression =
-        ParserTestCase.parse4("parseAdditiveExpression", "x + y");
+    BinaryExpression expression = parse4("parseAdditiveExpression", "x + y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.PLUS);
@@ -4833,7 +4641,7 @@
 
   void test_parseAdditiveExpression_super() {
     BinaryExpression expression =
-        ParserTestCase.parse4("parseAdditiveExpression", "super + y");
+        parse4("parseAdditiveExpression", "super + y");
     EngineTestCase.assertInstanceOf((obj) => obj is SuperExpression,
         SuperExpression, expression.leftOperand);
     expect(expression.operator, isNotNull);
@@ -4842,7 +4650,7 @@
   }
 
   void test_parseAnnotation_n1() {
-    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A");
+    Annotation annotation = parse4("parseAnnotation", "@A");
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNull);
@@ -4851,7 +4659,7 @@
   }
 
   void test_parseAnnotation_n1_a() {
-    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A(x,y)");
+    Annotation annotation = parse4("parseAnnotation", "@A(x,y)");
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNull);
@@ -4860,7 +4668,7 @@
   }
 
   void test_parseAnnotation_n2() {
-    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B");
+    Annotation annotation = parse4("parseAnnotation", "@A.B");
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNull);
@@ -4869,8 +4677,7 @@
   }
 
   void test_parseAnnotation_n2_a() {
-    Annotation annotation =
-        ParserTestCase.parse4("parseAnnotation", "@A.B(x,y)");
+    Annotation annotation = parse4("parseAnnotation", "@A.B(x,y)");
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNull);
@@ -4879,7 +4686,7 @@
   }
 
   void test_parseAnnotation_n3() {
-    Annotation annotation = ParserTestCase.parse4("parseAnnotation", "@A.B.C");
+    Annotation annotation = parse4("parseAnnotation", "@A.B.C");
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNotNull);
@@ -4888,8 +4695,7 @@
   }
 
   void test_parseAnnotation_n3_a() {
-    Annotation annotation =
-        ParserTestCase.parse4("parseAnnotation", "@A.B.C(x,y)");
+    Annotation annotation = parse4("parseAnnotation", "@A.B.C(x,y)");
     expect(annotation.atSign, isNotNull);
     expect(annotation.name, isNotNull);
     expect(annotation.period, isNotNull);
@@ -4898,7 +4704,7 @@
   }
 
   void test_parseArgument_named() {
-    NamedExpression expression = ParserTestCase.parse4("parseArgument", "n: x");
+    NamedExpression expression = parse4("parseArgument", "n: x");
     Label name = expression.name;
     expect(name, isNotNull);
     expect(name.label, isNotNull);
@@ -4908,42 +4714,37 @@
 
   void test_parseArgument_unnamed() {
     String lexeme = "x";
-    SimpleIdentifier identifier =
-        ParserTestCase.parse4("parseArgument", lexeme);
+    SimpleIdentifier identifier = parse4("parseArgument", lexeme);
     expect(identifier.name, lexeme);
   }
 
   void test_parseArgumentList_empty() {
-    ArgumentList argumentList =
-        ParserTestCase.parse4("parseArgumentList", "()");
+    ArgumentList argumentList = parse4("parseArgumentList", "()");
     NodeList<Expression> arguments = argumentList.arguments;
     expect(arguments, hasLength(0));
   }
 
   void test_parseArgumentList_mixed() {
     ArgumentList argumentList =
-        ParserTestCase.parse4("parseArgumentList", "(w, x, y: y, z: z)");
+        parse4("parseArgumentList", "(w, x, y: y, z: z)");
     NodeList<Expression> arguments = argumentList.arguments;
     expect(arguments, hasLength(4));
   }
 
   void test_parseArgumentList_noNamed() {
-    ArgumentList argumentList =
-        ParserTestCase.parse4("parseArgumentList", "(x, y, z)");
+    ArgumentList argumentList = parse4("parseArgumentList", "(x, y, z)");
     NodeList<Expression> arguments = argumentList.arguments;
     expect(arguments, hasLength(3));
   }
 
   void test_parseArgumentList_onlyNamed() {
-    ArgumentList argumentList =
-        ParserTestCase.parse4("parseArgumentList", "(x: x, y: y)");
+    ArgumentList argumentList = parse4("parseArgumentList", "(x: x, y: y)");
     NodeList<Expression> arguments = argumentList.arguments;
     expect(arguments, hasLength(2));
   }
 
   void test_parseAssertStatement() {
-    AssertStatement statement =
-        ParserTestCase.parse4("parseAssertStatement", "assert (x);");
+    AssertStatement statement = parse4("parseAssertStatement", "assert (x);");
     expect(statement.assertKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.condition, isNotNull);
@@ -4952,8 +4753,8 @@
   }
 
   void test_parseAssignableExpression_expression_args_dot() {
-    PropertyAccess propertyAccess = ParserTestCase.parse(
-        "parseAssignableExpression", <Object>[false], "(x)(y).z");
+    PropertyAccess propertyAccess =
+        parse("parseAssignableExpression", <Object>[false], "(x)(y).z");
     FunctionExpressionInvocation invocation =
         propertyAccess.target as FunctionExpressionInvocation;
     expect(invocation.function, isNotNull);
@@ -4965,16 +4766,16 @@
   }
 
   void test_parseAssignableExpression_expression_dot() {
-    PropertyAccess propertyAccess = ParserTestCase.parse(
-        "parseAssignableExpression", <Object>[false], "(x).y");
+    PropertyAccess propertyAccess =
+        parse("parseAssignableExpression", <Object>[false], "(x).y");
     expect(propertyAccess.target, isNotNull);
     expect(propertyAccess.operator, isNotNull);
     expect(propertyAccess.propertyName, isNotNull);
   }
 
   void test_parseAssignableExpression_expression_index() {
-    IndexExpression expression = ParserTestCase.parse(
-        "parseAssignableExpression", <Object>[false], "(x)[y]");
+    IndexExpression expression =
+        parse("parseAssignableExpression", <Object>[false], "(x)[y]");
     expect(expression.target, isNotNull);
     expect(expression.leftBracket, isNotNull);
     expect(expression.index, isNotNull);
@@ -4983,13 +4784,13 @@
 
   void test_parseAssignableExpression_identifier() {
     SimpleIdentifier identifier =
-        ParserTestCase.parse("parseAssignableExpression", <Object>[false], "x");
+        parse("parseAssignableExpression", <Object>[false], "x");
     expect(identifier, isNotNull);
   }
 
   void test_parseAssignableExpression_identifier_args_dot() {
-    PropertyAccess propertyAccess = ParserTestCase.parse(
-        "parseAssignableExpression", <Object>[false], "x(y).z");
+    PropertyAccess propertyAccess =
+        parse("parseAssignableExpression", <Object>[false], "x(y).z");
     MethodInvocation invocation = propertyAccess.target as MethodInvocation;
     expect(invocation.methodName.name, "x");
     ArgumentList argumentList = invocation.argumentList;
@@ -5000,16 +4801,16 @@
   }
 
   void test_parseAssignableExpression_identifier_dot() {
-    PropertyAccess propertyAccess = ParserTestCase.parse(
-        "parseAssignableExpression", <Object>[false], "x.y");
+    PropertyAccess propertyAccess =
+        parse("parseAssignableExpression", <Object>[false], "x.y");
     expect(propertyAccess.target, isNotNull);
     expect(propertyAccess.operator, isNotNull);
     expect(propertyAccess.propertyName, isNotNull);
   }
 
   void test_parseAssignableExpression_identifier_index() {
-    IndexExpression expression = ParserTestCase.parse(
-        "parseAssignableExpression", <Object>[false], "x[y]");
+    IndexExpression expression =
+        parse("parseAssignableExpression", <Object>[false], "x[y]");
     expect(expression.target, isNotNull);
     expect(expression.leftBracket, isNotNull);
     expect(expression.index, isNotNull);
@@ -5017,8 +4818,8 @@
   }
 
   void test_parseAssignableExpression_super_dot() {
-    PropertyAccess propertyAccess = ParserTestCase.parse(
-        "parseAssignableExpression", <Object>[false], "super.y");
+    PropertyAccess propertyAccess =
+        parse("parseAssignableExpression", <Object>[false], "super.y");
     EngineTestCase.assertInstanceOf((obj) => obj is SuperExpression,
         SuperExpression, propertyAccess.target);
     expect(propertyAccess.operator, isNotNull);
@@ -5026,8 +4827,8 @@
   }
 
   void test_parseAssignableExpression_super_index() {
-    IndexExpression expression = ParserTestCase.parse(
-        "parseAssignableExpression", <Object>[false], "super[y]");
+    IndexExpression expression =
+        parse("parseAssignableExpression", <Object>[false], "super[y]");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is SuperExpression, SuperExpression, expression.target);
     expect(expression.leftBracket, isNotNull);
@@ -5036,36 +4837,37 @@
   }
 
   void test_parseAssignableSelector_dot() {
-    PropertyAccess selector = ParserTestCase.parse(
-        "parseAssignableSelector", <Object>[null, true], ".x");
+    PropertyAccess selector =
+        parse("parseAssignableSelector", <Object>[null, true], ".x");
     expect(selector.operator, isNotNull);
     expect(selector.propertyName, isNotNull);
   }
 
   void test_parseAssignableSelector_index() {
-    IndexExpression selector = ParserTestCase.parse(
-        "parseAssignableSelector", <Object>[null, true], "[x]");
+    IndexExpression selector =
+        parse("parseAssignableSelector", <Object>[null, true], "[x]");
     expect(selector.leftBracket, isNotNull);
     expect(selector.index, isNotNull);
     expect(selector.rightBracket, isNotNull);
   }
 
   void test_parseAssignableSelector_none() {
-    SimpleIdentifier selector = ParserTestCase.parse("parseAssignableSelector",
-        <Object>[new SimpleIdentifier(null), true], ";");
+    SimpleIdentifier selector = parse("parseAssignableSelector", <Object>[
+      new SimpleIdentifier(null),
+      true
+    ], ";");
     expect(selector, isNotNull);
   }
 
   void test_parseAwaitExpression() {
-    AwaitExpression expression =
-        ParserTestCase.parse4("parseAwaitExpression", "await x;");
+    AwaitExpression expression = parse4("parseAwaitExpression", "await x;");
     expect(expression.awaitKeyword, isNotNull);
     expect(expression.expression, isNotNull);
   }
 
   void test_parseAwaitExpression_asStatement_inAsync() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "m() async { await x; }");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "m() async { await x; }");
     FunctionBody body = method.body;
     EngineTestCase.assertInstanceOf(
         (obj) => obj is BlockFunctionBody, BlockFunctionBody, body);
@@ -5080,8 +4882,8 @@
   }
 
   void test_parseAwaitExpression_asStatement_inSync() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "m() { await x; }");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "m() { await x; }");
     FunctionBody body = method.body;
     EngineTestCase.assertInstanceOf(
         (obj) => obj is BlockFunctionBody, BlockFunctionBody, body);
@@ -5092,8 +4894,7 @@
   }
 
   void test_parseBitwiseAndExpression_normal() {
-    BinaryExpression expression =
-        ParserTestCase.parse4("parseBitwiseAndExpression", "x & y");
+    BinaryExpression expression = parse4("parseBitwiseAndExpression", "x & y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.AMPERSAND);
@@ -5102,7 +4903,7 @@
 
   void test_parseBitwiseAndExpression_super() {
     BinaryExpression expression =
-        ParserTestCase.parse4("parseBitwiseAndExpression", "super & y");
+        parse4("parseBitwiseAndExpression", "super & y");
     EngineTestCase.assertInstanceOf((obj) => obj is SuperExpression,
         SuperExpression, expression.leftOperand);
     expect(expression.operator, isNotNull);
@@ -5111,8 +4912,7 @@
   }
 
   void test_parseBitwiseOrExpression_normal() {
-    BinaryExpression expression =
-        ParserTestCase.parse4("parseBitwiseOrExpression", "x | y");
+    BinaryExpression expression = parse4("parseBitwiseOrExpression", "x | y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.BAR);
@@ -5121,7 +4921,7 @@
 
   void test_parseBitwiseOrExpression_super() {
     BinaryExpression expression =
-        ParserTestCase.parse4("parseBitwiseOrExpression", "super | y");
+        parse4("parseBitwiseOrExpression", "super | y");
     EngineTestCase.assertInstanceOf((obj) => obj is SuperExpression,
         SuperExpression, expression.leftOperand);
     expect(expression.operator, isNotNull);
@@ -5130,8 +4930,7 @@
   }
 
   void test_parseBitwiseXorExpression_normal() {
-    BinaryExpression expression =
-        ParserTestCase.parse4("parseBitwiseXorExpression", "x ^ y");
+    BinaryExpression expression = parse4("parseBitwiseXorExpression", "x ^ y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.CARET);
@@ -5140,7 +4939,7 @@
 
   void test_parseBitwiseXorExpression_super() {
     BinaryExpression expression =
-        ParserTestCase.parse4("parseBitwiseXorExpression", "super ^ y");
+        parse4("parseBitwiseXorExpression", "super ^ y");
     EngineTestCase.assertInstanceOf((obj) => obj is SuperExpression,
         SuperExpression, expression.leftOperand);
     expect(expression.operator, isNotNull);
@@ -5149,38 +4948,36 @@
   }
 
   void test_parseBlock_empty() {
-    Block block = ParserTestCase.parse4("parseBlock", "{}");
+    Block block = parse4("parseBlock", "{}");
     expect(block.leftBracket, isNotNull);
     expect(block.statements, hasLength(0));
     expect(block.rightBracket, isNotNull);
   }
 
   void test_parseBlock_nonEmpty() {
-    Block block = ParserTestCase.parse4("parseBlock", "{;}");
+    Block block = parse4("parseBlock", "{;}");
     expect(block.leftBracket, isNotNull);
     expect(block.statements, hasLength(1));
     expect(block.rightBracket, isNotNull);
   }
 
   void test_parseBreakStatement_label() {
-    BreakStatement statement =
-        ParserTestCase.parse4("parseBreakStatement", "break foo;");
+    BreakStatement statement = parse4("parseBreakStatement", "break foo;");
     expect(statement.breakKeyword, isNotNull);
     expect(statement.label, isNotNull);
     expect(statement.semicolon, isNotNull);
   }
 
   void test_parseBreakStatement_noLabel() {
-    BreakStatement statement = ParserTestCase.parse4("parseBreakStatement",
-        "break;", [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
+    BreakStatement statement = parse4("parseBreakStatement", "break;",
+        [ParserErrorCode.BREAK_OUTSIDE_OF_LOOP]);
     expect(statement.breakKeyword, isNotNull);
     expect(statement.label, isNull);
     expect(statement.semicolon, isNotNull);
   }
 
   void test_parseCascadeSection_i() {
-    IndexExpression section =
-        ParserTestCase.parse4("parseCascadeSection", "..[i]");
+    IndexExpression section = parse4("parseCascadeSection", "..[i]");
     expect(section.target, isNull);
     expect(section.leftBracket, isNotNull);
     expect(section.index, isNotNull);
@@ -5189,15 +4986,14 @@
 
   void test_parseCascadeSection_ia() {
     FunctionExpressionInvocation section =
-        ParserTestCase.parse4("parseCascadeSection", "..[i](b)");
+        parse4("parseCascadeSection", "..[i](b)");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is IndexExpression, IndexExpression, section.function);
     expect(section.argumentList, isNotNull);
   }
 
   void test_parseCascadeSection_ii() {
-    MethodInvocation section =
-        ParserTestCase.parse4("parseCascadeSection", "..a(b).c(d)");
+    MethodInvocation section = parse4("parseCascadeSection", "..a(b).c(d)");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is MethodInvocation, MethodInvocation, section.target);
     expect(section.period, isNotNull);
@@ -5207,16 +5003,14 @@
   }
 
   void test_parseCascadeSection_p() {
-    PropertyAccess section =
-        ParserTestCase.parse4("parseCascadeSection", "..a");
+    PropertyAccess section = parse4("parseCascadeSection", "..a");
     expect(section.target, isNull);
     expect(section.operator, isNotNull);
     expect(section.propertyName, isNotNull);
   }
 
   void test_parseCascadeSection_p_assign() {
-    AssignmentExpression section =
-        ParserTestCase.parse4("parseCascadeSection", "..a = 3");
+    AssignmentExpression section = parse4("parseCascadeSection", "..a = 3");
     expect(section.leftHandSide, isNotNull);
     expect(section.operator, isNotNull);
     Expression rhs = section.rightHandSide;
@@ -5225,25 +5019,23 @@
 
   void test_parseCascadeSection_p_assign_withCascade() {
     AssignmentExpression section =
-        ParserTestCase.parse4("parseCascadeSection", "..a = 3..m()");
+        parse4("parseCascadeSection", "..a = 3..m()");
     expect(section.leftHandSide, isNotNull);
     expect(section.operator, isNotNull);
     Expression rhs = section.rightHandSide;
-    EngineTestCase
-        .assertInstanceOf((obj) => obj is IntegerLiteral, IntegerLiteral, rhs);
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is IntegerLiteral, IntegerLiteral, rhs);
   }
 
   void test_parseCascadeSection_p_builtIn() {
-    PropertyAccess section =
-        ParserTestCase.parse4("parseCascadeSection", "..as");
+    PropertyAccess section = parse4("parseCascadeSection", "..as");
     expect(section.target, isNull);
     expect(section.operator, isNotNull);
     expect(section.propertyName, isNotNull);
   }
 
   void test_parseCascadeSection_pa() {
-    MethodInvocation section =
-        ParserTestCase.parse4("parseCascadeSection", "..a(b)");
+    MethodInvocation section = parse4("parseCascadeSection", "..a(b)");
     expect(section.target, isNull);
     expect(section.period, isNotNull);
     expect(section.methodName, isNotNull);
@@ -5253,7 +5045,7 @@
 
   void test_parseCascadeSection_paa() {
     FunctionExpressionInvocation section =
-        ParserTestCase.parse4("parseCascadeSection", "..a(b)(c)");
+        parse4("parseCascadeSection", "..a(b)(c)");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is MethodInvocation, MethodInvocation, section.function);
     expect(section.argumentList, isNotNull);
@@ -5262,7 +5054,7 @@
 
   void test_parseCascadeSection_paapaa() {
     FunctionExpressionInvocation section =
-        ParserTestCase.parse4("parseCascadeSection", "..a(b)(c).d(e)(f)");
+        parse4("parseCascadeSection", "..a(b)(c).d(e)(f)");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is MethodInvocation, MethodInvocation, section.function);
     expect(section.argumentList, isNotNull);
@@ -5270,16 +5062,14 @@
   }
 
   void test_parseCascadeSection_pap() {
-    PropertyAccess section =
-        ParserTestCase.parse4("parseCascadeSection", "..a(b).c");
+    PropertyAccess section = parse4("parseCascadeSection", "..a(b).c");
     expect(section.target, isNotNull);
     expect(section.operator, isNotNull);
     expect(section.propertyName, isNotNull);
   }
 
   void test_parseClassDeclaration_abstract() {
-    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[
+    ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
       emptyCommentAndMetadata(),
       TokenFactory.tokenFromKeyword(Keyword.ABSTRACT)
     ], "class A {}");
@@ -5296,8 +5086,10 @@
   }
 
   void test_parseClassDeclaration_empty() {
-    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[emptyCommentAndMetadata(), null], "class A {}");
+    ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
+      emptyCommentAndMetadata(),
+      null
+    ], "class A {}");
     expect(declaration.documentationComment, isNull);
     expect(declaration.abstractKeyword, isNull);
     expect(declaration.extendsClause, isNull);
@@ -5311,8 +5103,10 @@
   }
 
   void test_parseClassDeclaration_extends() {
-    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[emptyCommentAndMetadata(), null], "class A extends B {}");
+    ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
+      emptyCommentAndMetadata(),
+      null
+    ], "class A extends B {}");
     expect(declaration.documentationComment, isNull);
     expect(declaration.abstractKeyword, isNull);
     expect(declaration.extendsClause, isNotNull);
@@ -5326,8 +5120,7 @@
   }
 
   void test_parseClassDeclaration_extendsAndImplements() {
-    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[
+    ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
       emptyCommentAndMetadata(),
       null
     ], "class A extends B implements C {}");
@@ -5344,8 +5137,7 @@
   }
 
   void test_parseClassDeclaration_extendsAndWith() {
-    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[
+    ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
       emptyCommentAndMetadata(),
       null
     ], "class A extends B with C {}");
@@ -5363,8 +5155,7 @@
   }
 
   void test_parseClassDeclaration_extendsAndWithAndImplements() {
-    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[
+    ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
       emptyCommentAndMetadata(),
       null
     ], "class A extends B with C implements D {}");
@@ -5382,8 +5173,10 @@
   }
 
   void test_parseClassDeclaration_implements() {
-    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[emptyCommentAndMetadata(), null], "class A implements C {}");
+    ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
+      emptyCommentAndMetadata(),
+      null
+    ], "class A implements C {}");
     expect(declaration.documentationComment, isNull);
     expect(declaration.abstractKeyword, isNull);
     expect(declaration.extendsClause, isNull);
@@ -5397,8 +5190,7 @@
   }
 
   void test_parseClassDeclaration_native() {
-    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[
+    ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
       emptyCommentAndMetadata(),
       null
     ], "class A native 'nativeValue' {}");
@@ -5411,8 +5203,10 @@
   }
 
   void test_parseClassDeclaration_nonEmpty() {
-    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[emptyCommentAndMetadata(), null], "class A {var f;}");
+    ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
+      emptyCommentAndMetadata(),
+      null
+    ], "class A {var f;}");
     expect(declaration.documentationComment, isNull);
     expect(declaration.abstractKeyword, isNull);
     expect(declaration.extendsClause, isNull);
@@ -5426,8 +5220,7 @@
   }
 
   void test_parseClassDeclaration_typeAlias_implementsC() {
-    ClassTypeAlias typeAlias = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[
+    ClassTypeAlias typeAlias = parse("parseClassDeclaration", <Object>[
       emptyCommentAndMetadata(),
       null
     ], "class A = Object with B implements C;");
@@ -5442,8 +5235,10 @@
   }
 
   void test_parseClassDeclaration_typeAlias_withB() {
-    ClassTypeAlias typeAlias = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[emptyCommentAndMetadata(), null], "class A = Object with B;");
+    ClassTypeAlias typeAlias = parse("parseClassDeclaration", <Object>[
+      emptyCommentAndMetadata(),
+      null
+    ], "class A = Object with B;");
     expect(typeAlias.typedefKeyword, isNotNull);
     expect(typeAlias.name, isNotNull);
     expect(typeAlias.typeParameters, isNull);
@@ -5455,8 +5250,10 @@
   }
 
   void test_parseClassDeclaration_typeParameters() {
-    ClassDeclaration declaration = ParserTestCase.parse("parseClassDeclaration",
-        <Object>[emptyCommentAndMetadata(), null], "class A<B> {}");
+    ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
+      emptyCommentAndMetadata(),
+      null
+    ], "class A<B> {}");
     expect(declaration.documentationComment, isNull);
     expect(declaration.abstractKeyword, isNull);
     expect(declaration.extendsClause, isNull);
@@ -5473,10 +5270,8 @@
   void test_parseClassMember_constructor_withInitializers() {
     // TODO(brianwilkerson) Test other kinds of class members: fields, getters
     // and setters.
-    ConstructorDeclaration constructor = ParserTestCase.parse(
-        "parseClassMember", <Object>[
-      "C"
-    ], "C(_, _\$, this.__) : _a = _ + _\$ {}");
+    ConstructorDeclaration constructor = parse("parseClassMember",
+        <Object>["C"], "C(_, _\$, this.__) : _a = _ + _\$ {}");
     expect(constructor.body, isNotNull);
     expect(constructor.separator, isNotNull);
     expect(constructor.externalKeyword, isNull);
@@ -5490,8 +5285,7 @@
   }
 
   void test_parseClassMember_field_instance_prefixedType() {
-    FieldDeclaration field =
-        ParserTestCase.parse("parseClassMember", <Object>["C"], "p.A f;");
+    FieldDeclaration field = parse("parseClassMember", <Object>["C"], "p.A f;");
     expect(field.documentationComment, isNull);
     expect(field.metadata, hasLength(0));
     expect(field.staticKeyword, isNull);
@@ -5505,7 +5299,7 @@
 
   void test_parseClassMember_field_namedGet() {
     FieldDeclaration field =
-        ParserTestCase.parse("parseClassMember", <Object>["C"], "var get;");
+        parse("parseClassMember", <Object>["C"], "var get;");
     expect(field.documentationComment, isNull);
     expect(field.metadata, hasLength(0));
     expect(field.staticKeyword, isNull);
@@ -5518,8 +5312,8 @@
   }
 
   void test_parseClassMember_field_namedOperator() {
-    FieldDeclaration field = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "var operator;");
+    FieldDeclaration field =
+        parse("parseClassMember", <Object>["C"], "var operator;");
     expect(field.documentationComment, isNull);
     expect(field.metadata, hasLength(0));
     expect(field.staticKeyword, isNull);
@@ -5532,8 +5326,8 @@
   }
 
   void test_parseClassMember_field_namedOperator_withAssignment() {
-    FieldDeclaration field = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "var operator = (5);");
+    FieldDeclaration field =
+        parse("parseClassMember", <Object>["C"], "var operator = (5);");
     expect(field.documentationComment, isNull);
     expect(field.metadata, hasLength(0));
     expect(field.staticKeyword, isNull);
@@ -5548,7 +5342,7 @@
 
   void test_parseClassMember_field_namedSet() {
     FieldDeclaration field =
-        ParserTestCase.parse("parseClassMember", <Object>["C"], "var set;");
+        parse("parseClassMember", <Object>["C"], "var set;");
     expect(field.documentationComment, isNull);
     expect(field.metadata, hasLength(0));
     expect(field.staticKeyword, isNull);
@@ -5561,8 +5355,8 @@
   }
 
   void test_parseClassMember_getter_void() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "void get g {}");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "void get g {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5574,8 +5368,8 @@
   }
 
   void test_parseClassMember_method_external() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "external m();");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "external m();");
     expect(method.body, isNotNull);
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNotNull);
@@ -5588,8 +5382,8 @@
   }
 
   void test_parseClassMember_method_external_withTypeAndArgs() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "external int m(int a);");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "external int m(int a);");
     expect(method.body, isNotNull);
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNotNull);
@@ -5603,7 +5397,7 @@
 
   void test_parseClassMember_method_get_noType() {
     MethodDeclaration method =
-        ParserTestCase.parse("parseClassMember", <Object>["C"], "get() {}");
+        parse("parseClassMember", <Object>["C"], "get() {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5617,7 +5411,7 @@
 
   void test_parseClassMember_method_get_type() {
     MethodDeclaration method =
-        ParserTestCase.parse("parseClassMember", <Object>["C"], "int get() {}");
+        parse("parseClassMember", <Object>["C"], "int get() {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5630,8 +5424,8 @@
   }
 
   void test_parseClassMember_method_get_void() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "void get() {}");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "void get() {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5644,8 +5438,8 @@
   }
 
   void test_parseClassMember_method_operator_noType() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "operator() {}");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "operator() {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5658,8 +5452,8 @@
   }
 
   void test_parseClassMember_method_operator_type() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "int operator() {}");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "int operator() {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5672,8 +5466,8 @@
   }
 
   void test_parseClassMember_method_operator_void() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "void operator() {}");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "void operator() {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5687,7 +5481,7 @@
 
   void test_parseClassMember_method_returnType_parameterized() {
     MethodDeclaration method =
-        ParserTestCase.parse("parseClassMember", <Object>["C"], "p.A m() {}");
+        parse("parseClassMember", <Object>["C"], "p.A m() {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5701,7 +5495,7 @@
 
   void test_parseClassMember_method_set_noType() {
     MethodDeclaration method =
-        ParserTestCase.parse("parseClassMember", <Object>["C"], "set() {}");
+        parse("parseClassMember", <Object>["C"], "set() {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5715,7 +5509,7 @@
 
   void test_parseClassMember_method_set_type() {
     MethodDeclaration method =
-        ParserTestCase.parse("parseClassMember", <Object>["C"], "int set() {}");
+        parse("parseClassMember", <Object>["C"], "int set() {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5728,8 +5522,8 @@
   }
 
   void test_parseClassMember_method_set_void() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "void set() {}");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "void set() {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5742,8 +5536,8 @@
   }
 
   void test_parseClassMember_operator_index() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "int operator [](int i) {}");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "int operator [](int i) {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5756,8 +5550,8 @@
   }
 
   void test_parseClassMember_operator_indexAssign() {
-    MethodDeclaration method = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "int operator []=(int i) {}");
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "int operator []=(int i) {}");
     expect(method.documentationComment, isNull);
     expect(method.externalKeyword, isNull);
     expect(method.modifierKeyword, isNull);
@@ -5770,8 +5564,8 @@
   }
 
   void test_parseClassMember_redirectingFactory_const() {
-    ConstructorDeclaration constructor = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "const factory C() = B;");
+    ConstructorDeclaration constructor =
+        parse("parseClassMember", <Object>["C"], "const factory C() = B;");
     expect(constructor.externalKeyword, isNull);
     expect(constructor.constKeyword, isNotNull);
     expect(constructor.factoryKeyword, isNotNull);
@@ -5786,8 +5580,8 @@
   }
 
   void test_parseClassMember_redirectingFactory_nonConst() {
-    ConstructorDeclaration constructor = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "factory C() = B;");
+    ConstructorDeclaration constructor =
+        parse("parseClassMember", <Object>["C"], "factory C() = B;");
     expect(constructor.externalKeyword, isNull);
     expect(constructor.constKeyword, isNull);
     expect(constructor.factoryKeyword, isNotNull);
@@ -5804,8 +5598,7 @@
   void test_parseClassTypeAlias_abstract() {
     Token classToken = TokenFactory.tokenFromKeyword(Keyword.CLASS);
     Token abstractToken = TokenFactory.tokenFromKeyword(Keyword.ABSTRACT);
-    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias",
-        <Object>[
+    ClassTypeAlias classTypeAlias = parse("parseClassTypeAlias", <Object>[
       emptyCommentAndMetadata(),
       abstractToken,
       classToken
@@ -5822,8 +5615,7 @@
 
   void test_parseClassTypeAlias_implements() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.CLASS);
-    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias",
-        <Object>[
+    ClassTypeAlias classTypeAlias = parse("parseClassTypeAlias", <Object>[
       emptyCommentAndMetadata(),
       null,
       token
@@ -5840,8 +5632,11 @@
 
   void test_parseClassTypeAlias_with() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.CLASS);
-    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias",
-        <Object>[emptyCommentAndMetadata(), null, token], "A = B with C;");
+    ClassTypeAlias classTypeAlias = parse("parseClassTypeAlias", <Object>[
+      emptyCommentAndMetadata(),
+      null,
+      token
+    ], "A = B with C;");
     expect(classTypeAlias.typedefKeyword, isNotNull);
     expect(classTypeAlias.name.name, "A");
     expect(classTypeAlias.equals, isNotNull);
@@ -5854,8 +5649,7 @@
 
   void test_parseClassTypeAlias_with_implements() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.CLASS);
-    ClassTypeAlias classTypeAlias = ParserTestCase.parse("parseClassTypeAlias",
-        <Object>[
+    ClassTypeAlias classTypeAlias = parse("parseClassTypeAlias", <Object>[
       emptyCommentAndMetadata(),
       null,
       token
@@ -5871,24 +5665,21 @@
   }
 
   void test_parseCombinator_hide() {
-    HideCombinator combinator =
-        ParserTestCase.parse4('parseCombinator', 'hide a;');
+    HideCombinator combinator = parse4('parseCombinator', 'hide a;');
     expect(combinator, new isInstanceOf<HideCombinator>());
     expect(combinator.keyword, isNotNull);
     expect(combinator.hiddenNames, hasLength(1));
   }
 
   void test_parseCombinator_show() {
-    ShowCombinator combinator =
-        ParserTestCase.parse4('parseCombinator', 'show a;');
+    ShowCombinator combinator = parse4('parseCombinator', 'show a;');
     expect(combinator, new isInstanceOf<ShowCombinator>());
     expect(combinator.keyword, isNotNull);
     expect(combinator.shownNames, hasLength(1));
   }
 
   void test_parseCombinators_h() {
-    List<Combinator> combinators =
-        ParserTestCase.parse4("parseCombinators", "hide a;");
+    List<Combinator> combinators = parse4("parseCombinators", "hide a;");
     expect(combinators, hasLength(1));
     HideCombinator combinator = combinators[0] as HideCombinator;
     expect(combinator, isNotNull);
@@ -5897,8 +5688,7 @@
   }
 
   void test_parseCombinators_hs() {
-    List<Combinator> combinators =
-        ParserTestCase.parse4("parseCombinators", "hide a show b;");
+    List<Combinator> combinators = parse4("parseCombinators", "hide a show b;");
     expect(combinators, hasLength(2));
     HideCombinator hideCombinator = combinators[0] as HideCombinator;
     expect(hideCombinator, isNotNull);
@@ -5911,14 +5701,13 @@
   }
 
   void test_parseCombinators_hshs() {
-    List<Combinator> combinators = ParserTestCase.parse4(
-        "parseCombinators", "hide a show b hide c show d;");
+    List<Combinator> combinators =
+        parse4("parseCombinators", "hide a show b hide c show d;");
     expect(combinators, hasLength(4));
   }
 
   void test_parseCombinators_s() {
-    List<Combinator> combinators =
-        ParserTestCase.parse4("parseCombinators", "show a;");
+    List<Combinator> combinators = parse4("parseCombinators", "show a;");
     expect(combinators, hasLength(1));
     ShowCombinator combinator = combinators[0] as ShowCombinator;
     expect(combinator, isNotNull);
@@ -5928,70 +5717,70 @@
 
   void test_parseCommentAndMetadata_c() {
     CommentAndMetadata commentAndMetadata =
-        ParserTestCase.parse4("parseCommentAndMetadata", "/** 1 */ void");
+        parse4("parseCommentAndMetadata", "/** 1 */ void");
     expect(commentAndMetadata.comment, isNotNull);
     expect(commentAndMetadata.metadata, hasLength(0));
   }
 
   void test_parseCommentAndMetadata_cmc() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4(
-        "parseCommentAndMetadata", "/** 1 */ @A /** 2 */ void");
+    CommentAndMetadata commentAndMetadata =
+        parse4("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ void");
     expect(commentAndMetadata.comment, isNotNull);
     expect(commentAndMetadata.metadata, hasLength(1));
   }
 
   void test_parseCommentAndMetadata_cmcm() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4(
-        "parseCommentAndMetadata", "/** 1 */ @A /** 2 */ @B void");
+    CommentAndMetadata commentAndMetadata =
+        parse4("parseCommentAndMetadata", "/** 1 */ @A /** 2 */ @B void");
     expect(commentAndMetadata.comment, isNotNull);
     expect(commentAndMetadata.metadata, hasLength(2));
   }
 
   void test_parseCommentAndMetadata_cmm() {
     CommentAndMetadata commentAndMetadata =
-        ParserTestCase.parse4("parseCommentAndMetadata", "/** 1 */ @A @B void");
+        parse4("parseCommentAndMetadata", "/** 1 */ @A @B void");
     expect(commentAndMetadata.comment, isNotNull);
     expect(commentAndMetadata.metadata, hasLength(2));
   }
 
   void test_parseCommentAndMetadata_m() {
     CommentAndMetadata commentAndMetadata =
-        ParserTestCase.parse4("parseCommentAndMetadata", "@A void");
+        parse4("parseCommentAndMetadata", "@A void");
     expect(commentAndMetadata.comment, isNull);
     expect(commentAndMetadata.metadata, hasLength(1));
   }
 
   void test_parseCommentAndMetadata_mcm() {
     CommentAndMetadata commentAndMetadata =
-        ParserTestCase.parse4("parseCommentAndMetadata", "@A /** 1 */ @B void");
+        parse4("parseCommentAndMetadata", "@A /** 1 */ @B void");
     expect(commentAndMetadata.comment, isNotNull);
     expect(commentAndMetadata.metadata, hasLength(2));
   }
 
   void test_parseCommentAndMetadata_mcmc() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4(
-        "parseCommentAndMetadata", "@A /** 1 */ @B /** 2 */ void");
+    CommentAndMetadata commentAndMetadata =
+        parse4("parseCommentAndMetadata", "@A /** 1 */ @B /** 2 */ void");
     expect(commentAndMetadata.comment, isNotNull);
     expect(commentAndMetadata.metadata, hasLength(2));
   }
 
   void test_parseCommentAndMetadata_mm() {
     CommentAndMetadata commentAndMetadata =
-        ParserTestCase.parse4("parseCommentAndMetadata", "@A @B(x) void");
+        parse4("parseCommentAndMetadata", "@A @B(x) void");
     expect(commentAndMetadata.comment, isNull);
     expect(commentAndMetadata.metadata, hasLength(2));
   }
 
   void test_parseCommentAndMetadata_none() {
     CommentAndMetadata commentAndMetadata =
-        ParserTestCase.parse4("parseCommentAndMetadata", "void");
+        parse4("parseCommentAndMetadata", "void");
     expect(commentAndMetadata.comment, isNull);
     expect(commentAndMetadata.metadata, hasLength(0));
   }
 
   void test_parseCommentAndMetadata_singleLine() {
-    CommentAndMetadata commentAndMetadata = ParserTestCase.parse4(
-        "parseCommentAndMetadata", r'''
+    CommentAndMetadata commentAndMetadata = parse4("parseCommentAndMetadata",
+        r'''
 /// 1
 /// 2
 void''');
@@ -6000,8 +5789,8 @@
   }
 
   void test_parseCommentReference_new_prefixed() {
-    CommentReference reference = ParserTestCase.parse(
-        "parseCommentReference", <Object>["new a.b", 7], "");
+    CommentReference reference =
+        parse("parseCommentReference", <Object>["new a.b", 7], "");
     PrefixedIdentifier prefixedIdentifier = EngineTestCase.assertInstanceOf(
         (obj) => obj is PrefixedIdentifier, PrefixedIdentifier,
         reference.identifier);
@@ -6018,7 +5807,7 @@
 
   void test_parseCommentReference_new_simple() {
     CommentReference reference =
-        ParserTestCase.parse("parseCommentReference", <Object>["new a", 5], "");
+        parse("parseCommentReference", <Object>["new a", 5], "");
     SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
         (obj) => obj is SimpleIdentifier, SimpleIdentifier,
         reference.identifier);
@@ -6029,7 +5818,7 @@
 
   void test_parseCommentReference_prefixed() {
     CommentReference reference =
-        ParserTestCase.parse("parseCommentReference", <Object>["a.b", 7], "");
+        parse("parseCommentReference", <Object>["a.b", 7], "");
     PrefixedIdentifier prefixedIdentifier = EngineTestCase.assertInstanceOf(
         (obj) => obj is PrefixedIdentifier, PrefixedIdentifier,
         reference.identifier);
@@ -6046,7 +5835,7 @@
 
   void test_parseCommentReference_simple() {
     CommentReference reference =
-        ParserTestCase.parse("parseCommentReference", <Object>["a", 5], "");
+        parse("parseCommentReference", <Object>["a", 5], "");
     SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
         (obj) => obj is SimpleIdentifier, SimpleIdentifier,
         reference.identifier);
@@ -6057,7 +5846,7 @@
 
   void test_parseCommentReference_synthetic() {
     CommentReference reference =
-        ParserTestCase.parse("parseCommentReference", <Object>["", 5], "");
+        parse("parseCommentReference", <Object>["", 5], "");
     SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
         (obj) => obj is SimpleIdentifier, SimpleIdentifier,
         reference.identifier);
@@ -6073,7 +5862,7 @@
         TokenType.MULTI_LINE_COMMENT, "/** xxx [a] yyy [bb] zzz */", 3);
     List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[token];
     List<CommentReference> references =
-        ParserTestCase.parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "");
     List<Token> tokenReferences = token.references;
     expect(references, hasLength(2));
     expect(tokenReferences, hasLength(2));
@@ -6105,7 +5894,7 @@
           TokenType.MULTI_LINE_COMMENT, "/** [ some text", 5)
     ];
     List<CommentReference> references =
-        ParserTestCase.parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "");
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6120,7 +5909,7 @@
           TokenType.MULTI_LINE_COMMENT, "/** [namePrefix some text", 5)
     ];
     List<CommentReference> references =
-        ParserTestCase.parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "");
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6137,7 +5926,7 @@
           TokenType.SINGLE_LINE_COMMENT, "/// x [c]", 28)
     ];
     List<CommentReference> references =
-        ParserTestCase.parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "");
     expect(references, hasLength(3));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6159,7 +5948,7 @@
           TokenType.MULTI_LINE_COMMENT, "/** [:xxx [a] yyy:] [b] zzz */", 3)
     ];
     List<CommentReference> references =
-        ParserTestCase.parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "");
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6173,7 +5962,7 @@
           "/**\n *     a[i]\n * xxx [i] zzz\n */", 3)
     ];
     List<CommentReference> references =
-        ParserTestCase.parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "");
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6187,7 +5976,7 @@
           "/** [a]: http://www.google.com (Google) [b] zzz */", 3)
     ];
     List<CommentReference> references =
-        ParserTestCase.parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "");
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6201,7 +5990,7 @@
           "/** [a](http://www.google.com) [b] zzz */", 3)
     ];
     List<CommentReference> references =
-        ParserTestCase.parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "");
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6215,7 +6004,7 @@
           TokenType.MULTI_LINE_COMMENT, "/** [a][c] [b] zzz */", 3)
     ];
     List<CommentReference> references =
-        ParserTestCase.parse("parseCommentReferences", <Object>[tokens], "");
+        parse("parseCommentReferences", <Object>[tokens], "");
     expect(references, hasLength(1));
     CommentReference reference = references[0];
     expect(reference, isNotNull);
@@ -6224,7 +6013,7 @@
   }
 
   void test_parseCompilationUnit_abstractAsPrefix_parameterized() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit",
+    CompilationUnit unit = parse4("parseCompilationUnit",
         "abstract<dynamic> _abstract = new abstract.A();");
     expect(unit.scriptTag, isNull);
     expect(unit.directives, hasLength(0));
@@ -6232,56 +6021,55 @@
   }
 
   void test_parseCompilationUnit_builtIn_asFunctionName() {
-    ParserTestCase.parse4("parseCompilationUnit", "abstract(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "as(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "dynamic(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "export(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "external(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "factory(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "get(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "implements(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "import(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "library(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "operator(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "part(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "set(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "static(x) => 0;");
-    ParserTestCase.parse4("parseCompilationUnit", "typedef(x) => 0;");
+    parse4("parseCompilationUnit", "abstract(x) => 0;");
+    parse4("parseCompilationUnit", "as(x) => 0;");
+    parse4("parseCompilationUnit", "dynamic(x) => 0;");
+    parse4("parseCompilationUnit", "export(x) => 0;");
+    parse4("parseCompilationUnit", "external(x) => 0;");
+    parse4("parseCompilationUnit", "factory(x) => 0;");
+    parse4("parseCompilationUnit", "get(x) => 0;");
+    parse4("parseCompilationUnit", "implements(x) => 0;");
+    parse4("parseCompilationUnit", "import(x) => 0;");
+    parse4("parseCompilationUnit", "library(x) => 0;");
+    parse4("parseCompilationUnit", "operator(x) => 0;");
+    parse4("parseCompilationUnit", "part(x) => 0;");
+    parse4("parseCompilationUnit", "set(x) => 0;");
+    parse4("parseCompilationUnit", "static(x) => 0;");
+    parse4("parseCompilationUnit", "typedef(x) => 0;");
   }
 
   void test_parseCompilationUnit_directives_multiple() {
-    CompilationUnit unit = ParserTestCase.parse4(
-        "parseCompilationUnit", "library l;\npart 'a.dart';");
+    CompilationUnit unit =
+        parse4("parseCompilationUnit", "library l;\npart 'a.dart';");
     expect(unit.scriptTag, isNull);
     expect(unit.directives, hasLength(2));
     expect(unit.declarations, hasLength(0));
   }
 
   void test_parseCompilationUnit_directives_single() {
-    CompilationUnit unit =
-        ParserTestCase.parse4("parseCompilationUnit", "library l;");
+    CompilationUnit unit = parse4("parseCompilationUnit", "library l;");
     expect(unit.scriptTag, isNull);
     expect(unit.directives, hasLength(1));
     expect(unit.declarations, hasLength(0));
   }
 
   void test_parseCompilationUnit_empty() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit", "");
+    CompilationUnit unit = parse4("parseCompilationUnit", "");
     expect(unit.scriptTag, isNull);
     expect(unit.directives, hasLength(0));
     expect(unit.declarations, hasLength(0));
   }
 
   void test_parseCompilationUnit_exportAsPrefix() {
-    CompilationUnit unit = ParserTestCase.parse4(
-        "parseCompilationUnit", "export.A _export = new export.A();");
+    CompilationUnit unit =
+        parse4("parseCompilationUnit", "export.A _export = new export.A();");
     expect(unit.scriptTag, isNull);
     expect(unit.directives, hasLength(0));
     expect(unit.declarations, hasLength(1));
   }
 
   void test_parseCompilationUnit_exportAsPrefix_parameterized() {
-    CompilationUnit unit = ParserTestCase.parse4(
+    CompilationUnit unit = parse4(
         "parseCompilationUnit", "export<dynamic> _export = new export.A();");
     expect(unit.scriptTag, isNull);
     expect(unit.directives, hasLength(0));
@@ -6289,7 +6077,7 @@
   }
 
   void test_parseCompilationUnit_operatorAsPrefix_parameterized() {
-    CompilationUnit unit = ParserTestCase.parse4("parseCompilationUnit",
+    CompilationUnit unit = parse4("parseCompilationUnit",
         "operator<dynamic> _operator = new operator.A();");
     expect(unit.scriptTag, isNull);
     expect(unit.directives, hasLength(0));
@@ -6297,8 +6085,7 @@
   }
 
   void test_parseCompilationUnit_script() {
-    CompilationUnit unit =
-        ParserTestCase.parse4("parseCompilationUnit", "#! /bin/dart");
+    CompilationUnit unit = parse4("parseCompilationUnit", "#! /bin/dart");
     expect(unit.scriptTag, isNotNull);
     expect(unit.directives, hasLength(0));
     expect(unit.declarations, hasLength(0));
@@ -6306,199 +6093,164 @@
 
   void test_parseCompilationUnit_skipFunctionBody_withInterpolation() {
     ParserTestCase.parseFunctionBodies = false;
-    CompilationUnit unit =
-        ParserTestCase.parse4("parseCompilationUnit", "f() { '\${n}'; }");
+    CompilationUnit unit = parse4("parseCompilationUnit", "f() { '\${n}'; }");
     expect(unit.scriptTag, isNull);
     expect(unit.declarations, hasLength(1));
   }
 
   void test_parseCompilationUnit_topLevelDeclaration() {
-    CompilationUnit unit =
-        ParserTestCase.parse4("parseCompilationUnit", "class A {}");
+    CompilationUnit unit = parse4("parseCompilationUnit", "class A {}");
     expect(unit.scriptTag, isNull);
     expect(unit.directives, hasLength(0));
     expect(unit.declarations, hasLength(1));
   }
 
   void test_parseCompilationUnit_typedefAsPrefix() {
-    CompilationUnit unit = ParserTestCase.parse4(
-        "parseCompilationUnit", "typedef.A _typedef = new typedef.A();");
+    CompilationUnit unit =
+        parse4("parseCompilationUnit", "typedef.A _typedef = new typedef.A();");
     expect(unit.scriptTag, isNull);
     expect(unit.directives, hasLength(0));
     expect(unit.declarations, hasLength(1));
   }
 
   void test_parseCompilationUnitMember_abstractAsPrefix() {
-    TopLevelVariableDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "abstract.A _abstract = new abstract.A();");
+    TopLevelVariableDeclaration declaration = parse(
+        "parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "abstract.A _abstract = new abstract.A();");
     expect(declaration.semicolon, isNotNull);
     expect(declaration.variables, isNotNull);
   }
 
   void test_parseCompilationUnitMember_class() {
-    ClassDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "class A {}");
+    ClassDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "class A {}");
     expect(declaration.name.name, "A");
     expect(declaration.members, hasLength(0));
   }
 
   void test_parseCompilationUnitMember_classTypeAlias() {
-    ClassTypeAlias alias = ParserTestCase.parse("parseCompilationUnitMember",
+    ClassTypeAlias alias = parse("parseCompilationUnitMember",
         <Object>[emptyCommentAndMetadata()], "abstract class A = B with C;");
     expect(alias.name.name, "A");
     expect(alias.abstractKeyword, isNotNull);
   }
 
   void test_parseCompilationUnitMember_constVariable() {
-    TopLevelVariableDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "const int x = 0;");
+    TopLevelVariableDeclaration declaration = parse(
+        "parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "const int x = 0;");
     expect(declaration.semicolon, isNotNull);
     expect(declaration.variables, isNotNull);
   }
 
   void test_parseCompilationUnitMember_finalVariable() {
-    TopLevelVariableDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "final x = 0;");
+    TopLevelVariableDeclaration declaration = parse(
+        "parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "final x = 0;");
     expect(declaration.semicolon, isNotNull);
     expect(declaration.variables, isNotNull);
   }
 
   void test_parseCompilationUnitMember_function_external_noType() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "external f();");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "external f();");
     expect(declaration.externalKeyword, isNotNull);
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNull);
   }
 
   void test_parseCompilationUnitMember_function_external_type() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "external int f();");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "external int f();");
     expect(declaration.externalKeyword, isNotNull);
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNull);
   }
 
   void test_parseCompilationUnitMember_function_noType() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "f() {}");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "f() {}");
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNull);
   }
 
   void test_parseCompilationUnitMember_function_type() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "int f() {}");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "int f() {}");
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNull);
   }
 
   void test_parseCompilationUnitMember_function_void() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "void f() {}");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "void f() {}");
     expect(declaration.returnType, isNotNull);
   }
 
   void test_parseCompilationUnitMember_getter_external_noType() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "external get p;");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "external get p;");
     expect(declaration.externalKeyword, isNotNull);
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNotNull);
   }
 
   void test_parseCompilationUnitMember_getter_external_type() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "external int get p;");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "external int get p;");
     expect(declaration.externalKeyword, isNotNull);
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNotNull);
   }
 
   void test_parseCompilationUnitMember_getter_noType() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "get p => 0;");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "get p => 0;");
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNotNull);
   }
 
   void test_parseCompilationUnitMember_getter_type() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "int get p => 0;");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "int get p => 0;");
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNotNull);
   }
 
   void test_parseCompilationUnitMember_setter_external_noType() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "external set p(v);");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "external set p(v);");
     expect(declaration.externalKeyword, isNotNull);
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNotNull);
   }
 
   void test_parseCompilationUnitMember_setter_external_type() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "external void set p(int v);");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "external void set p(int v);");
     expect(declaration.externalKeyword, isNotNull);
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNotNull);
   }
 
   void test_parseCompilationUnitMember_setter_noType() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "set p(v) {}");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "set p(v) {}");
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNotNull);
   }
 
   void test_parseCompilationUnitMember_setter_type() {
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "void set p(int v) {}");
+    FunctionDeclaration declaration = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "void set p(int v) {}");
     expect(declaration.functionExpression, isNotNull);
     expect(declaration.propertyKeyword, isNotNull);
     expect(declaration.returnType, isNotNull);
   }
 
   void test_parseCompilationUnitMember_typeAlias_abstract() {
-    ClassTypeAlias typeAlias = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "abstract class C = S with M;");
+    ClassTypeAlias typeAlias = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "abstract class C = S with M;");
     expect(typeAlias.typedefKeyword, isNotNull);
     expect(typeAlias.name.name, "C");
     expect(typeAlias.typeParameters, isNull);
@@ -6511,10 +6263,9 @@
   }
 
   void test_parseCompilationUnitMember_typeAlias_generic() {
-    ClassTypeAlias typeAlias = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "class C<E> = S<E> with M<E> implements I<E>;");
+    ClassTypeAlias typeAlias = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()],
+        "class C<E> = S<E> with M<E> implements I<E>;");
     expect(typeAlias.typedefKeyword, isNotNull);
     expect(typeAlias.name.name, "C");
     expect(typeAlias.typeParameters.typeParameters, hasLength(1));
@@ -6527,10 +6278,9 @@
   }
 
   void test_parseCompilationUnitMember_typeAlias_implements() {
-    ClassTypeAlias typeAlias = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "class C = S with M implements I;");
+    ClassTypeAlias typeAlias = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()],
+        "class C = S with M implements I;");
     expect(typeAlias.typedefKeyword, isNotNull);
     expect(typeAlias.name.name, "C");
     expect(typeAlias.typeParameters, isNull);
@@ -6543,10 +6293,8 @@
   }
 
   void test_parseCompilationUnitMember_typeAlias_noImplements() {
-    ClassTypeAlias typeAlias = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "class C = S with M;");
+    ClassTypeAlias typeAlias = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "class C = S with M;");
     expect(typeAlias.typedefKeyword, isNotNull);
     expect(typeAlias.name.name, "C");
     expect(typeAlias.typeParameters, isNull);
@@ -6559,44 +6307,39 @@
   }
 
   void test_parseCompilationUnitMember_typedef() {
-    FunctionTypeAlias typeAlias = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "typedef F();");
+    FunctionTypeAlias typeAlias = parse("parseCompilationUnitMember",
+        <Object>[emptyCommentAndMetadata()], "typedef F();");
     expect(typeAlias.name.name, "F");
     expect(typeAlias.parameters.parameters, hasLength(0));
   }
 
   void test_parseCompilationUnitMember_variable() {
-    TopLevelVariableDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "var x = 0;");
+    TopLevelVariableDeclaration declaration = parse(
+        "parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "var x = 0;");
     expect(declaration.semicolon, isNotNull);
     expect(declaration.variables, isNotNull);
   }
 
   void test_parseCompilationUnitMember_variableGet() {
-    TopLevelVariableDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "String get = null;");
+    TopLevelVariableDeclaration declaration = parse(
+        "parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "String get = null;");
     expect(declaration.semicolon, isNotNull);
     expect(declaration.variables, isNotNull);
   }
 
   void test_parseCompilationUnitMember_variableSet() {
-    TopLevelVariableDeclaration declaration = ParserTestCase.parse(
-        "parseCompilationUnitMember", <Object>[
-      emptyCommentAndMetadata()
-    ], "String set = null;");
+    TopLevelVariableDeclaration declaration = parse(
+        "parseCompilationUnitMember", <Object>[emptyCommentAndMetadata()],
+        "String set = null;");
     expect(declaration.semicolon, isNotNull);
     expect(declaration.variables, isNotNull);
   }
 
   void test_parseConditionalExpression() {
     ConditionalExpression expression =
-        ParserTestCase.parse4("parseConditionalExpression", "x ? y : z");
+        parse4("parseConditionalExpression", "x ? y : z");
     expect(expression.condition, isNotNull);
     expect(expression.question, isNotNull);
     expect(expression.thenExpression, isNotNull);
@@ -6606,7 +6349,7 @@
 
   void test_parseConstExpression_instanceCreation() {
     InstanceCreationExpression expression =
-        ParserTestCase.parse4("parseConstExpression", "const A()");
+        parse4("parseConstExpression", "const A()");
     expect(expression.keyword, isNotNull);
     ConstructorName name = expression.constructorName;
     expect(name, isNotNull);
@@ -6617,8 +6360,7 @@
   }
 
   void test_parseConstExpression_listLiteral_typed() {
-    ListLiteral literal =
-        ParserTestCase.parse4("parseConstExpression", "const <A> []");
+    ListLiteral literal = parse4("parseConstExpression", "const <A> []");
     expect(literal.constKeyword, isNotNull);
     expect(literal.typeArguments, isNotNull);
     expect(literal.leftBracket, isNotNull);
@@ -6627,8 +6369,7 @@
   }
 
   void test_parseConstExpression_listLiteral_untyped() {
-    ListLiteral literal =
-        ParserTestCase.parse4("parseConstExpression", "const []");
+    ListLiteral literal = parse4("parseConstExpression", "const []");
     expect(literal.constKeyword, isNotNull);
     expect(literal.typeArguments, isNull);
     expect(literal.leftBracket, isNotNull);
@@ -6637,8 +6378,7 @@
   }
 
   void test_parseConstExpression_mapLiteral_typed() {
-    MapLiteral literal =
-        ParserTestCase.parse4("parseConstExpression", "const <A, B> {}");
+    MapLiteral literal = parse4("parseConstExpression", "const <A, B> {}");
     expect(literal.leftBracket, isNotNull);
     expect(literal.entries, hasLength(0));
     expect(literal.rightBracket, isNotNull);
@@ -6646,8 +6386,7 @@
   }
 
   void test_parseConstExpression_mapLiteral_untyped() {
-    MapLiteral literal =
-        ParserTestCase.parse4("parseConstExpression", "const {}");
+    MapLiteral literal = parse4("parseConstExpression", "const {}");
     expect(literal.leftBracket, isNotNull);
     expect(literal.entries, hasLength(0));
     expect(literal.rightBracket, isNotNull);
@@ -6665,8 +6404,8 @@
   void test_parseConstructor_with_pseudo_function_literal() {
     // "(b) {}" should not be misinterpreted as a function literal even though
     // it looks like one.
-    ClassMember classMember = ParserTestCase.parse(
-        "parseClassMember", <Object>["C"], "C() : a = (b) {}");
+    ClassMember classMember =
+        parse("parseClassMember", <Object>["C"], "C() : a = (b) {}");
     EngineTestCase.assertInstanceOf((obj) => obj is ConstructorDeclaration,
         ConstructorDeclaration, classMember);
     ConstructorDeclaration constructor = classMember as ConstructorDeclaration;
@@ -6684,7 +6423,7 @@
 
   void test_parseConstructorFieldInitializer_qualified() {
     ConstructorFieldInitializer invocation =
-        ParserTestCase.parse4("parseConstructorFieldInitializer", "this.a = b");
+        parse4("parseConstructorFieldInitializer", "this.a = b");
     expect(invocation.equals, isNotNull);
     expect(invocation.expression, isNotNull);
     expect(invocation.fieldName, isNotNull);
@@ -6694,7 +6433,7 @@
 
   void test_parseConstructorFieldInitializer_unqualified() {
     ConstructorFieldInitializer invocation =
-        ParserTestCase.parse4("parseConstructorFieldInitializer", "a = b");
+        parse4("parseConstructorFieldInitializer", "a = b");
     expect(invocation.equals, isNotNull);
     expect(invocation.expression, isNotNull);
     expect(invocation.fieldName, isNotNull);
@@ -6703,60 +6442,52 @@
   }
 
   void test_parseConstructorName_named_noPrefix() {
-    ConstructorName name =
-        ParserTestCase.parse4("parseConstructorName", "A.n;");
+    ConstructorName name = parse4("parseConstructorName", "A.n;");
     expect(name.type, isNotNull);
     expect(name.period, isNull);
     expect(name.name, isNull);
   }
 
   void test_parseConstructorName_named_prefixed() {
-    ConstructorName name =
-        ParserTestCase.parse4("parseConstructorName", "p.A.n;");
+    ConstructorName name = parse4("parseConstructorName", "p.A.n;");
     expect(name.type, isNotNull);
     expect(name.period, isNotNull);
     expect(name.name, isNotNull);
   }
 
   void test_parseConstructorName_unnamed_noPrefix() {
-    ConstructorName name = ParserTestCase.parse4("parseConstructorName", "A;");
+    ConstructorName name = parse4("parseConstructorName", "A;");
     expect(name.type, isNotNull);
     expect(name.period, isNull);
     expect(name.name, isNull);
   }
 
   void test_parseConstructorName_unnamed_prefixed() {
-    ConstructorName name =
-        ParserTestCase.parse4("parseConstructorName", "p.A;");
+    ConstructorName name = parse4("parseConstructorName", "p.A;");
     expect(name.type, isNotNull);
     expect(name.period, isNull);
     expect(name.name, isNull);
   }
 
   void test_parseContinueStatement_label() {
-    ContinueStatement statement = ParserTestCase.parse4(
-        "parseContinueStatement", "continue foo;", [
-      ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP
-    ]);
+    ContinueStatement statement = parse4("parseContinueStatement",
+        "continue foo;", [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
     expect(statement.continueKeyword, isNotNull);
     expect(statement.label, isNotNull);
     expect(statement.semicolon, isNotNull);
   }
 
   void test_parseContinueStatement_noLabel() {
-    ContinueStatement statement = ParserTestCase.parse4(
-        "parseContinueStatement", "continue;", [
-      ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP
-    ]);
+    ContinueStatement statement = parse4("parseContinueStatement", "continue;",
+        [ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP]);
     expect(statement.continueKeyword, isNotNull);
     expect(statement.label, isNull);
     expect(statement.semicolon, isNotNull);
   }
 
   void test_parseDirective_export() {
-    ExportDirective directive = ParserTestCase.parse("parseDirective", <Object>[
-      emptyCommentAndMetadata()
-    ], "export 'lib/lib.dart';");
+    ExportDirective directive = parse("parseDirective",
+        <Object>[emptyCommentAndMetadata()], "export 'lib/lib.dart';");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.combinators, hasLength(0));
@@ -6764,9 +6495,8 @@
   }
 
   void test_parseDirective_import() {
-    ImportDirective directive = ParserTestCase.parse("parseDirective", <Object>[
-      emptyCommentAndMetadata()
-    ], "import 'lib/lib.dart';");
+    ImportDirective directive = parse("parseDirective",
+        <Object>[emptyCommentAndMetadata()], "import 'lib/lib.dart';");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.asKeyword, isNull);
@@ -6776,7 +6506,7 @@
   }
 
   void test_parseDirective_library() {
-    LibraryDirective directive = ParserTestCase.parse(
+    LibraryDirective directive = parse(
         "parseDirective", <Object>[emptyCommentAndMetadata()], "library l;");
     expect(directive.libraryKeyword, isNotNull);
     expect(directive.name, isNotNull);
@@ -6784,16 +6514,15 @@
   }
 
   void test_parseDirective_part() {
-    PartDirective directive = ParserTestCase.parse("parseDirective", <Object>[
-      emptyCommentAndMetadata()
-    ], "part 'lib/lib.dart';");
+    PartDirective directive = parse("parseDirective",
+        <Object>[emptyCommentAndMetadata()], "part 'lib/lib.dart';");
     expect(directive.partKeyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.semicolon, isNotNull);
   }
 
   void test_parseDirective_partOf() {
-    PartOfDirective directive = ParserTestCase.parse(
+    PartOfDirective directive = parse(
         "parseDirective", <Object>[emptyCommentAndMetadata()], "part of l;");
     expect(directive.partKeyword, isNotNull);
     expect(directive.ofKeyword, isNotNull);
@@ -6846,16 +6575,14 @@
   }
 
   void test_parseDocumentationComment_block() {
-    Comment comment =
-        ParserTestCase.parse4("parseDocumentationComment", "/** */ class");
+    Comment comment = parse4("parseDocumentationComment", "/** */ class");
     expect(comment.isBlock, isFalse);
     expect(comment.isDocumentation, isTrue);
     expect(comment.isEndOfLine, isFalse);
   }
 
   void test_parseDocumentationComment_block_withReference() {
-    Comment comment =
-        ParserTestCase.parse4("parseDocumentationComment", "/** [a] */ class");
+    Comment comment = parse4("parseDocumentationComment", "/** [a] */ class");
     expect(comment.isBlock, isFalse);
     expect(comment.isDocumentation, isTrue);
     expect(comment.isEndOfLine, isFalse);
@@ -6867,16 +6594,14 @@
   }
 
   void test_parseDocumentationComment_endOfLine() {
-    Comment comment = ParserTestCase.parse4(
-        "parseDocumentationComment", "/// \n/// \n class");
+    Comment comment = parse4("parseDocumentationComment", "/// \n/// \n class");
     expect(comment.isBlock, isFalse);
     expect(comment.isDocumentation, isTrue);
     expect(comment.isEndOfLine, isFalse);
   }
 
   void test_parseDoStatement() {
-    DoStatement statement =
-        ParserTestCase.parse4("parseDoStatement", "do {} while (x);");
+    DoStatement statement = parse4("parseDoStatement", "do {} while (x);");
     expect(statement.doKeyword, isNotNull);
     expect(statement.body, isNotNull);
     expect(statement.whileKeyword, isNotNull);
@@ -6887,13 +6612,12 @@
   }
 
   void test_parseEmptyStatement() {
-    EmptyStatement statement =
-        ParserTestCase.parse4("parseEmptyStatement", ";");
+    EmptyStatement statement = parse4("parseEmptyStatement", ";");
     expect(statement.semicolon, isNotNull);
   }
 
   void test_parseEnumDeclaration_one() {
-    EnumDeclaration declaration = ParserTestCase.parse("parseEnumDeclaration",
+    EnumDeclaration declaration = parse("parseEnumDeclaration",
         <Object>[emptyCommentAndMetadata()], "enum E {ONE}");
     expect(declaration.documentationComment, isNull);
     expect(declaration.enumKeyword, isNotNull);
@@ -6904,7 +6628,7 @@
   }
 
   void test_parseEnumDeclaration_trailingComma() {
-    EnumDeclaration declaration = ParserTestCase.parse("parseEnumDeclaration",
+    EnumDeclaration declaration = parse("parseEnumDeclaration",
         <Object>[emptyCommentAndMetadata()], "enum E {ONE,}");
     expect(declaration.documentationComment, isNull);
     expect(declaration.enumKeyword, isNotNull);
@@ -6915,7 +6639,7 @@
   }
 
   void test_parseEnumDeclaration_two() {
-    EnumDeclaration declaration = ParserTestCase.parse("parseEnumDeclaration",
+    EnumDeclaration declaration = parse("parseEnumDeclaration",
         <Object>[emptyCommentAndMetadata()], "enum E {ONE, TWO}");
     expect(declaration.documentationComment, isNull);
     expect(declaration.enumKeyword, isNotNull);
@@ -6926,8 +6650,7 @@
   }
 
   void test_parseEqualityExpression_normal() {
-    BinaryExpression expression =
-        ParserTestCase.parse4("parseEqualityExpression", "x == y");
+    BinaryExpression expression = parse4("parseEqualityExpression", "x == y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.EQ_EQ);
@@ -6936,7 +6659,7 @@
 
   void test_parseEqualityExpression_super() {
     BinaryExpression expression =
-        ParserTestCase.parse4("parseEqualityExpression", "super == y");
+        parse4("parseEqualityExpression", "super == y");
     EngineTestCase.assertInstanceOf((obj) => obj is SuperExpression,
         SuperExpression, expression.leftOperand);
     expect(expression.operator, isNotNull);
@@ -6945,10 +6668,9 @@
   }
 
   void test_parseExportDirective_hide() {
-    ExportDirective directive = ParserTestCase.parse("parseExportDirective",
-        <Object>[
-      emptyCommentAndMetadata()
-    ], "export 'lib/lib.dart' hide A, B;");
+    ExportDirective directive = parse("parseExportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "export 'lib/lib.dart' hide A, B;");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.combinators, hasLength(1));
@@ -6956,10 +6678,9 @@
   }
 
   void test_parseExportDirective_hide_show() {
-    ExportDirective directive = ParserTestCase.parse("parseExportDirective",
-        <Object>[
-      emptyCommentAndMetadata()
-    ], "export 'lib/lib.dart' hide A show B;");
+    ExportDirective directive = parse("parseExportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "export 'lib/lib.dart' hide A show B;");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.combinators, hasLength(2));
@@ -6967,7 +6688,7 @@
   }
 
   void test_parseExportDirective_noCombinator() {
-    ExportDirective directive = ParserTestCase.parse("parseExportDirective",
+    ExportDirective directive = parse("parseExportDirective",
         <Object>[emptyCommentAndMetadata()], "export 'lib/lib.dart';");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
@@ -6976,10 +6697,9 @@
   }
 
   void test_parseExportDirective_show() {
-    ExportDirective directive = ParserTestCase.parse("parseExportDirective",
-        <Object>[
-      emptyCommentAndMetadata()
-    ], "export 'lib/lib.dart' show A, B;");
+    ExportDirective directive = parse("parseExportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "export 'lib/lib.dart' show A, B;");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.combinators, hasLength(1));
@@ -6987,10 +6707,9 @@
   }
 
   void test_parseExportDirective_show_hide() {
-    ExportDirective directive = ParserTestCase.parse("parseExportDirective",
-        <Object>[
-      emptyCommentAndMetadata()
-    ], "export 'lib/lib.dart' show B hide A;");
+    ExportDirective directive = parse("parseExportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "export 'lib/lib.dart' show B hide A;");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.combinators, hasLength(2));
@@ -6999,8 +6718,7 @@
 
   void test_parseExpression_assign() {
     // TODO(brianwilkerson) Implement more tests for this method.
-    AssignmentExpression expression =
-        ParserTestCase.parse4("parseExpression", "x = y");
+    AssignmentExpression expression = parse4("parseExpression", "x = y");
     expect(expression.leftHandSide, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.EQ);
@@ -7008,8 +6726,7 @@
   }
 
   void test_parseExpression_comparison() {
-    BinaryExpression expression =
-        ParserTestCase.parse4("parseExpression", "--a.b == c");
+    BinaryExpression expression = parse4("parseExpression", "--a.b == c");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.EQ_EQ);
@@ -7017,8 +6734,7 @@
   }
 
   void test_parseExpression_function_async() {
-    FunctionExpression expression =
-        ParserTestCase.parseExpression("() async {}");
+    FunctionExpression expression = parseExpression("() async {}");
     expect(expression.body, isNotNull);
     expect(expression.body.isAsynchronous, isTrue);
     expect(expression.body.isGenerator, isFalse);
@@ -7026,8 +6742,7 @@
   }
 
   void test_parseExpression_function_asyncStar() {
-    FunctionExpression expression =
-        ParserTestCase.parseExpression("() async* {}");
+    FunctionExpression expression = parseExpression("() async* {}");
     expect(expression.body, isNotNull);
     expect(expression.body.isAsynchronous, isTrue);
     expect(expression.body.isGenerator, isTrue);
@@ -7035,7 +6750,7 @@
   }
 
   void test_parseExpression_function_sync() {
-    FunctionExpression expression = ParserTestCase.parseExpression("() {}");
+    FunctionExpression expression = parseExpression("() {}");
     expect(expression.body, isNotNull);
     expect(expression.body.isAsynchronous, isFalse);
     expect(expression.body.isGenerator, isFalse);
@@ -7043,8 +6758,7 @@
   }
 
   void test_parseExpression_function_syncStar() {
-    FunctionExpression expression =
-        ParserTestCase.parseExpression("() sync* {}");
+    FunctionExpression expression = parseExpression("() sync* {}");
     expect(expression.body, isNotNull);
     expect(expression.body.isAsynchronous, isFalse);
     expect(expression.body.isGenerator, isTrue);
@@ -7053,7 +6767,7 @@
 
   void test_parseExpression_invokeFunctionExpression() {
     FunctionExpressionInvocation invocation =
-        ParserTestCase.parse4("parseExpression", "(a) {return a + a;} (3)");
+        parse4("parseExpression", "(a) {return a + a;} (3)");
     EngineTestCase.assertInstanceOf((obj) => obj is FunctionExpression,
         FunctionExpression, invocation.function);
     FunctionExpression expression = invocation.function as FunctionExpression;
@@ -7065,33 +6779,31 @@
   }
 
   void test_parseExpression_nonAwait() {
-    MethodInvocation expression = ParserTestCase.parseExpression("await()");
+    MethodInvocation expression = parseExpression("await()");
     expect(expression.methodName.name, 'await');
   }
 
   void test_parseExpression_superMethodInvocation() {
-    MethodInvocation invocation =
-        ParserTestCase.parse4("parseExpression", "super.m()");
+    MethodInvocation invocation = parse4("parseExpression", "super.m()");
     expect(invocation.target, isNotNull);
     expect(invocation.methodName, isNotNull);
     expect(invocation.argumentList, isNotNull);
   }
 
   void test_parseExpressionList_multiple() {
-    List<Expression> result =
-        ParserTestCase.parse4("parseExpressionList", "1, 2, 3");
+    List<Expression> result = parse4("parseExpressionList", "1, 2, 3");
     expect(result, hasLength(3));
   }
 
   void test_parseExpressionList_single() {
-    List<Expression> result = ParserTestCase.parse4("parseExpressionList", "1");
+    List<Expression> result = parse4("parseExpressionList", "1");
     expect(result, hasLength(1));
   }
 
   void test_parseExpressionWithoutCascade_assign() {
     // TODO(brianwilkerson) Implement more tests for this method.
     AssignmentExpression expression =
-        ParserTestCase.parse4("parseExpressionWithoutCascade", "x = y");
+        parse4("parseExpressionWithoutCascade", "x = y");
     expect(expression.leftHandSide, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.EQ);
@@ -7100,7 +6812,7 @@
 
   void test_parseExpressionWithoutCascade_comparison() {
     BinaryExpression expression =
-        ParserTestCase.parse4("parseExpressionWithoutCascade", "--a.b == c");
+        parse4("parseExpressionWithoutCascade", "--a.b == c");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.EQ_EQ);
@@ -7109,15 +6821,14 @@
 
   void test_parseExpressionWithoutCascade_superMethodInvocation() {
     MethodInvocation invocation =
-        ParserTestCase.parse4("parseExpressionWithoutCascade", "super.m()");
+        parse4("parseExpressionWithoutCascade", "super.m()");
     expect(invocation.target, isNotNull);
     expect(invocation.methodName, isNotNull);
     expect(invocation.argumentList, isNotNull);
   }
 
   void test_parseExtendsClause() {
-    ExtendsClause clause =
-        ParserTestCase.parse4("parseExtendsClause", "extends B");
+    ExtendsClause clause = parse4("parseExtendsClause", "extends B");
     expect(clause.extendsKeyword, isNotNull);
     expect(clause.superclass, isNotNull);
     EngineTestCase.assertInstanceOf(
@@ -7125,8 +6836,8 @@
   }
 
   void test_parseFinalConstVarOrType_const_noType() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "const");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "const");
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type, TokenType.KEYWORD);
@@ -7135,8 +6846,8 @@
   }
 
   void test_parseFinalConstVarOrType_const_type() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "const A a");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "const A a");
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type, TokenType.KEYWORD);
@@ -7145,8 +6856,8 @@
   }
 
   void test_parseFinalConstVarOrType_final_noType() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "final");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "final");
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type, TokenType.KEYWORD);
@@ -7155,8 +6866,8 @@
   }
 
   void test_parseFinalConstVarOrType_final_prefixedType() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "final p.A a");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "final p.A a");
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type, TokenType.KEYWORD);
@@ -7165,8 +6876,8 @@
   }
 
   void test_parseFinalConstVarOrType_final_type() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "final A a");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "final A a");
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type, TokenType.KEYWORD);
@@ -7175,43 +6886,43 @@
   }
 
   void test_parseFinalConstVarOrType_type_parameterized() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "A<B> a");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "A<B> a");
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
 
   void test_parseFinalConstVarOrType_type_prefixed() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "p.A a");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "p.A a");
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
 
   void test_parseFinalConstVarOrType_type_prefixed_noIdentifier() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "p.A,");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "p.A,");
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
 
   void test_parseFinalConstVarOrType_type_prefixedAndParameterized() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "p.A<B> a");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "p.A<B> a");
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
 
   void test_parseFinalConstVarOrType_type_simple() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "A a");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "A a");
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
 
   void test_parseFinalConstVarOrType_var() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "var");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "var");
     Token keyword = result.keyword;
     expect(keyword, isNotNull);
     expect(keyword.type, TokenType.KEYWORD);
@@ -7220,23 +6931,23 @@
   }
 
   void test_parseFinalConstVarOrType_void() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "void f()");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "void f()");
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
 
   void test_parseFinalConstVarOrType_void_noIdentifier() {
-    FinalConstVarOrType result = ParserTestCase.parse(
-        "parseFinalConstVarOrType", <Object>[false], "void,");
+    FinalConstVarOrType result =
+        parse("parseFinalConstVarOrType", <Object>[false], "void,");
     expect(result.keyword, isNull);
     expect(result.type, isNotNull);
   }
 
   void test_parseFormalParameter_final_withType_named() {
     ParameterKind kind = ParameterKind.NAMED;
-    DefaultFormalParameter parameter = ParserTestCase.parse(
-        "parseFormalParameter", <Object>[kind], "final A a : null");
+    DefaultFormalParameter parameter =
+        parse("parseFormalParameter", <Object>[kind], "final A a : null");
     SimpleFormalParameter simpleParameter =
         parameter.parameter as SimpleFormalParameter;
     expect(simpleParameter.identifier, isNotNull);
@@ -7250,8 +6961,8 @@
 
   void test_parseFormalParameter_final_withType_normal() {
     ParameterKind kind = ParameterKind.REQUIRED;
-    SimpleFormalParameter parameter = ParserTestCase.parse(
-        "parseFormalParameter", <Object>[kind], "final A a");
+    SimpleFormalParameter parameter =
+        parse("parseFormalParameter", <Object>[kind], "final A a");
     expect(parameter.identifier, isNotNull);
     expect(parameter.keyword, isNotNull);
     expect(parameter.type, isNotNull);
@@ -7260,8 +6971,8 @@
 
   void test_parseFormalParameter_final_withType_positional() {
     ParameterKind kind = ParameterKind.POSITIONAL;
-    DefaultFormalParameter parameter = ParserTestCase.parse(
-        "parseFormalParameter", <Object>[kind], "final A a = null");
+    DefaultFormalParameter parameter =
+        parse("parseFormalParameter", <Object>[kind], "final A a = null");
     SimpleFormalParameter simpleParameter =
         parameter.parameter as SimpleFormalParameter;
     expect(simpleParameter.identifier, isNotNull);
@@ -7275,8 +6986,8 @@
 
   void test_parseFormalParameter_nonFinal_withType_named() {
     ParameterKind kind = ParameterKind.NAMED;
-    DefaultFormalParameter parameter = ParserTestCase.parse(
-        "parseFormalParameter", <Object>[kind], "A a : null");
+    DefaultFormalParameter parameter =
+        parse("parseFormalParameter", <Object>[kind], "A a : null");
     SimpleFormalParameter simpleParameter =
         parameter.parameter as SimpleFormalParameter;
     expect(simpleParameter.identifier, isNotNull);
@@ -7291,7 +7002,7 @@
   void test_parseFormalParameter_nonFinal_withType_normal() {
     ParameterKind kind = ParameterKind.REQUIRED;
     SimpleFormalParameter parameter =
-        ParserTestCase.parse("parseFormalParameter", <Object>[kind], "A a");
+        parse("parseFormalParameter", <Object>[kind], "A a");
     expect(parameter.identifier, isNotNull);
     expect(parameter.keyword, isNull);
     expect(parameter.type, isNotNull);
@@ -7300,8 +7011,8 @@
 
   void test_parseFormalParameter_nonFinal_withType_positional() {
     ParameterKind kind = ParameterKind.POSITIONAL;
-    DefaultFormalParameter parameter = ParserTestCase.parse(
-        "parseFormalParameter", <Object>[kind], "A a = null");
+    DefaultFormalParameter parameter =
+        parse("parseFormalParameter", <Object>[kind], "A a = null");
     SimpleFormalParameter simpleParameter =
         parameter.parameter as SimpleFormalParameter;
     expect(simpleParameter.identifier, isNotNull);
@@ -7316,7 +7027,7 @@
   void test_parseFormalParameter_var() {
     ParameterKind kind = ParameterKind.REQUIRED;
     SimpleFormalParameter parameter =
-        ParserTestCase.parse("parseFormalParameter", <Object>[kind], "var a");
+        parse("parseFormalParameter", <Object>[kind], "var a");
     expect(parameter.identifier, isNotNull);
     expect(parameter.keyword, isNotNull);
     expect(parameter.type, isNull);
@@ -7325,8 +7036,8 @@
 
   void test_parseFormalParameter_var_named() {
     ParameterKind kind = ParameterKind.NAMED;
-    DefaultFormalParameter parameter = ParserTestCase.parse(
-        "parseFormalParameter", <Object>[kind], "var a : null");
+    DefaultFormalParameter parameter =
+        parse("parseFormalParameter", <Object>[kind], "var a : null");
     SimpleFormalParameter simpleParameter =
         parameter.parameter as SimpleFormalParameter;
     expect(simpleParameter.identifier, isNotNull);
@@ -7340,8 +7051,8 @@
 
   void test_parseFormalParameter_var_positional() {
     ParameterKind kind = ParameterKind.POSITIONAL;
-    DefaultFormalParameter parameter = ParserTestCase.parse(
-        "parseFormalParameter", <Object>[kind], "var a = null");
+    DefaultFormalParameter parameter =
+        parse("parseFormalParameter", <Object>[kind], "var a = null");
     SimpleFormalParameter simpleParameter =
         parameter.parameter as SimpleFormalParameter;
     expect(simpleParameter.identifier, isNotNull);
@@ -7355,7 +7066,7 @@
 
   void test_parseFormalParameterList_empty() {
     FormalParameterList parameterList =
-        ParserTestCase.parse4("parseFormalParameterList", "()");
+        parse4("parseFormalParameterList", "()");
     expect(parameterList.leftParenthesis, isNotNull);
     expect(parameterList.leftDelimiter, isNull);
     expect(parameterList.parameters, hasLength(0));
@@ -7364,8 +7075,8 @@
   }
 
   void test_parseFormalParameterList_named_multiple() {
-    FormalParameterList parameterList = ParserTestCase.parse4(
-        "parseFormalParameterList", "({A a : 1, B b, C c : 3})");
+    FormalParameterList parameterList =
+        parse4("parseFormalParameterList", "({A a : 1, B b, C c : 3})");
     expect(parameterList.leftParenthesis, isNotNull);
     expect(parameterList.leftDelimiter, isNotNull);
     expect(parameterList.parameters, hasLength(3));
@@ -7375,7 +7086,7 @@
 
   void test_parseFormalParameterList_named_single() {
     FormalParameterList parameterList =
-        ParserTestCase.parse4("parseFormalParameterList", "({A a})");
+        parse4("parseFormalParameterList", "({A a})");
     expect(parameterList.leftParenthesis, isNotNull);
     expect(parameterList.leftDelimiter, isNotNull);
     expect(parameterList.parameters, hasLength(1));
@@ -7385,7 +7096,7 @@
 
   void test_parseFormalParameterList_normal_multiple() {
     FormalParameterList parameterList =
-        ParserTestCase.parse4("parseFormalParameterList", "(A a, B b, C c)");
+        parse4("parseFormalParameterList", "(A a, B b, C c)");
     expect(parameterList.leftParenthesis, isNotNull);
     expect(parameterList.leftDelimiter, isNull);
     expect(parameterList.parameters, hasLength(3));
@@ -7395,7 +7106,7 @@
 
   void test_parseFormalParameterList_normal_named() {
     FormalParameterList parameterList =
-        ParserTestCase.parse4("parseFormalParameterList", "(A a, {B b})");
+        parse4("parseFormalParameterList", "(A a, {B b})");
     expect(parameterList.leftParenthesis, isNotNull);
     expect(parameterList.leftDelimiter, isNotNull);
     expect(parameterList.parameters, hasLength(2));
@@ -7405,7 +7116,7 @@
 
   void test_parseFormalParameterList_normal_positional() {
     FormalParameterList parameterList =
-        ParserTestCase.parse4("parseFormalParameterList", "(A a, [B b])");
+        parse4("parseFormalParameterList", "(A a, [B b])");
     expect(parameterList.leftParenthesis, isNotNull);
     expect(parameterList.leftDelimiter, isNotNull);
     expect(parameterList.parameters, hasLength(2));
@@ -7415,7 +7126,7 @@
 
   void test_parseFormalParameterList_normal_single() {
     FormalParameterList parameterList =
-        ParserTestCase.parse4("parseFormalParameterList", "(A a)");
+        parse4("parseFormalParameterList", "(A a)");
     expect(parameterList.leftParenthesis, isNotNull);
     expect(parameterList.leftDelimiter, isNull);
     expect(parameterList.parameters, hasLength(1));
@@ -7424,8 +7135,8 @@
   }
 
   void test_parseFormalParameterList_positional_multiple() {
-    FormalParameterList parameterList = ParserTestCase.parse4(
-        "parseFormalParameterList", "([A a = null, B b, C c = null])");
+    FormalParameterList parameterList =
+        parse4("parseFormalParameterList", "([A a = null, B b, C c = null])");
     expect(parameterList.leftParenthesis, isNotNull);
     expect(parameterList.leftDelimiter, isNotNull);
     expect(parameterList.parameters, hasLength(3));
@@ -7435,7 +7146,7 @@
 
   void test_parseFormalParameterList_positional_single() {
     FormalParameterList parameterList =
-        ParserTestCase.parse4("parseFormalParameterList", "([A a = null])");
+        parse4("parseFormalParameterList", "([A a = null])");
     expect(parameterList.leftParenthesis, isNotNull);
     expect(parameterList.leftDelimiter, isNotNull);
     expect(parameterList.parameters, hasLength(1));
@@ -7444,8 +7155,8 @@
   }
 
   void test_parseForStatement_each_await() {
-    ForEachStatement statement = ParserTestCase.parse4(
-        "parseForStatement", "await for (element in list) {}");
+    ForEachStatement statement =
+        parse4("parseForStatement", "await for (element in list) {}");
     expect(statement.awaitKeyword, isNotNull);
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
@@ -7459,7 +7170,7 @@
 
   void test_parseForStatement_each_identifier() {
     ForEachStatement statement =
-        ParserTestCase.parse4("parseForStatement", "for (element in list) {}");
+        parse4("parseForStatement", "for (element in list) {}");
     expect(statement.awaitKeyword, isNull);
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
@@ -7472,8 +7183,8 @@
   }
 
   void test_parseForStatement_each_noType_metadata() {
-    ForEachStatement statement = ParserTestCase.parse4(
-        "parseForStatement", "for (@A var element in list) {}");
+    ForEachStatement statement =
+        parse4("parseForStatement", "for (@A var element in list) {}");
     expect(statement.awaitKeyword, isNull);
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
@@ -7487,8 +7198,8 @@
   }
 
   void test_parseForStatement_each_type() {
-    ForEachStatement statement = ParserTestCase.parse4(
-        "parseForStatement", "for (A element in list) {}");
+    ForEachStatement statement =
+        parse4("parseForStatement", "for (A element in list) {}");
     expect(statement.awaitKeyword, isNull);
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
@@ -7501,8 +7212,8 @@
   }
 
   void test_parseForStatement_each_var() {
-    ForEachStatement statement = ParserTestCase.parse4(
-        "parseForStatement", "for (var element in list) {}");
+    ForEachStatement statement =
+        parse4("parseForStatement", "for (var element in list) {}");
     expect(statement.awaitKeyword, isNull);
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
@@ -7516,7 +7227,7 @@
 
   void test_parseForStatement_loop_c() {
     ForStatement statement =
-        ParserTestCase.parse4("parseForStatement", "for (; i < count;) {}");
+        parse4("parseForStatement", "for (; i < count;) {}");
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.variables, isNull);
@@ -7531,7 +7242,7 @@
 
   void test_parseForStatement_loop_cu() {
     ForStatement statement =
-        ParserTestCase.parse4("parseForStatement", "for (; i < count; i++) {}");
+        parse4("parseForStatement", "for (; i < count; i++) {}");
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.variables, isNull);
@@ -7545,8 +7256,8 @@
   }
 
   void test_parseForStatement_loop_ecu() {
-    ForStatement statement = ParserTestCase.parse4(
-        "parseForStatement", "for (i--; i < count; i++) {}");
+    ForStatement statement =
+        parse4("parseForStatement", "for (i--; i < count; i++) {}");
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.variables, isNull);
@@ -7561,7 +7272,7 @@
 
   void test_parseForStatement_loop_i() {
     ForStatement statement =
-        ParserTestCase.parse4("parseForStatement", "for (var i = 0;;) {}");
+        parse4("parseForStatement", "for (var i = 0;;) {}");
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     VariableDeclarationList variables = statement.variables;
@@ -7579,7 +7290,7 @@
 
   void test_parseForStatement_loop_i_withMetadata() {
     ForStatement statement =
-        ParserTestCase.parse4("parseForStatement", "for (@A var i = 0;;) {}");
+        parse4("parseForStatement", "for (@A var i = 0;;) {}");
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     VariableDeclarationList variables = statement.variables;
@@ -7596,8 +7307,8 @@
   }
 
   void test_parseForStatement_loop_ic() {
-    ForStatement statement = ParserTestCase.parse4(
-        "parseForStatement", "for (var i = 0; i < count;) {}");
+    ForStatement statement =
+        parse4("parseForStatement", "for (var i = 0; i < count;) {}");
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     VariableDeclarationList variables = statement.variables;
@@ -7613,8 +7324,8 @@
   }
 
   void test_parseForStatement_loop_icu() {
-    ForStatement statement = ParserTestCase.parse4(
-        "parseForStatement", "for (var i = 0; i < count; i++) {}");
+    ForStatement statement =
+        parse4("parseForStatement", "for (var i = 0; i < count; i++) {}");
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     VariableDeclarationList variables = statement.variables;
@@ -7630,7 +7341,7 @@
   }
 
   void test_parseForStatement_loop_iicuu() {
-    ForStatement statement = ParserTestCase.parse4(
+    ForStatement statement = parse4(
         "parseForStatement", "for (int i = 0, j = count; i < j; i++, j--) {}");
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
@@ -7648,7 +7359,7 @@
 
   void test_parseForStatement_loop_iu() {
     ForStatement statement =
-        ParserTestCase.parse4("parseForStatement", "for (var i = 0;; i++) {}");
+        parse4("parseForStatement", "for (var i = 0;; i++) {}");
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     VariableDeclarationList variables = statement.variables;
@@ -7664,8 +7375,7 @@
   }
 
   void test_parseForStatement_loop_u() {
-    ForStatement statement =
-        ParserTestCase.parse4("parseForStatement", "for (;; i++) {}");
+    ForStatement statement = parse4("parseForStatement", "for (;; i++) {}");
     expect(statement.forKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.variables, isNull);
@@ -7679,8 +7389,8 @@
   }
 
   void test_parseFunctionBody_block() {
-    BlockFunctionBody functionBody = ParserTestCase.parse(
-        "parseFunctionBody", <Object>[false, null, false], "{}");
+    BlockFunctionBody functionBody =
+        parse("parseFunctionBody", <Object>[false, null, false], "{}");
     expect(functionBody.keyword, isNull);
     expect(functionBody.star, isNull);
     expect(functionBody.block, isNotNull);
@@ -7690,8 +7400,8 @@
   }
 
   void test_parseFunctionBody_block_async() {
-    BlockFunctionBody functionBody = ParserTestCase.parse(
-        "parseFunctionBody", <Object>[false, null, false], "async {}");
+    BlockFunctionBody functionBody =
+        parse("parseFunctionBody", <Object>[false, null, false], "async {}");
     expect(functionBody.keyword, isNotNull);
     expect(functionBody.keyword.lexeme, Parser.ASYNC);
     expect(functionBody.star, isNull);
@@ -7702,8 +7412,8 @@
   }
 
   void test_parseFunctionBody_block_asyncGenerator() {
-    BlockFunctionBody functionBody = ParserTestCase.parse(
-        "parseFunctionBody", <Object>[false, null, false], "async* {}");
+    BlockFunctionBody functionBody =
+        parse("parseFunctionBody", <Object>[false, null, false], "async* {}");
     expect(functionBody.keyword, isNotNull);
     expect(functionBody.keyword.lexeme, Parser.ASYNC);
     expect(functionBody.star, isNotNull);
@@ -7714,8 +7424,8 @@
   }
 
   void test_parseFunctionBody_block_syncGenerator() {
-    BlockFunctionBody functionBody = ParserTestCase.parse(
-        "parseFunctionBody", <Object>[false, null, false], "sync* {}");
+    BlockFunctionBody functionBody =
+        parse("parseFunctionBody", <Object>[false, null, false], "sync* {}");
     expect(functionBody.keyword, isNotNull);
     expect(functionBody.keyword.lexeme, Parser.SYNC);
     expect(functionBody.star, isNotNull);
@@ -7726,14 +7436,14 @@
   }
 
   void test_parseFunctionBody_empty() {
-    EmptyFunctionBody functionBody = ParserTestCase.parse(
-        "parseFunctionBody", <Object>[true, null, false], ";");
+    EmptyFunctionBody functionBody =
+        parse("parseFunctionBody", <Object>[true, null, false], ";");
     expect(functionBody.semicolon, isNotNull);
   }
 
   void test_parseFunctionBody_expression() {
-    ExpressionFunctionBody functionBody = ParserTestCase.parse(
-        "parseFunctionBody", <Object>[false, null, false], "=> y;");
+    ExpressionFunctionBody functionBody =
+        parse("parseFunctionBody", <Object>[false, null, false], "=> y;");
     expect(functionBody.keyword, isNull);
     expect(functionBody.functionDefinition, isNotNull);
     expect(functionBody.expression, isNotNull);
@@ -7744,8 +7454,8 @@
   }
 
   void test_parseFunctionBody_expression_async() {
-    ExpressionFunctionBody functionBody = ParserTestCase.parse(
-        "parseFunctionBody", <Object>[false, null, false], "async => y;");
+    ExpressionFunctionBody functionBody =
+        parse("parseFunctionBody", <Object>[false, null, false], "async => y;");
     expect(functionBody.keyword, isNotNull);
     expect(functionBody.keyword.lexeme, Parser.ASYNC);
     expect(functionBody.functionDefinition, isNotNull);
@@ -7757,7 +7467,7 @@
   }
 
   void test_parseFunctionBody_nativeFunctionBody() {
-    NativeFunctionBody functionBody = ParserTestCase.parse(
+    NativeFunctionBody functionBody = parse(
         "parseFunctionBody", <Object>[false, null, false], "native 'str';");
     expect(functionBody.nativeKeyword, isNotNull);
     expect(functionBody.stringLiteral, isNotNull);
@@ -7766,32 +7476,35 @@
 
   void test_parseFunctionBody_skip_block() {
     ParserTestCase.parseFunctionBodies = false;
-    FunctionBody functionBody = ParserTestCase.parse(
-        "parseFunctionBody", <Object>[false, null, false], "{}");
+    FunctionBody functionBody =
+        parse("parseFunctionBody", <Object>[false, null, false], "{}");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is EmptyFunctionBody, EmptyFunctionBody, functionBody);
   }
 
   void test_parseFunctionBody_skip_block_invalid() {
     ParserTestCase.parseFunctionBodies = false;
-    FunctionBody functionBody = ParserTestCase.parse3("parseFunctionBody",
-        <Object>[false, null, false], "{", [ParserErrorCode.EXPECTED_TOKEN]);
+    FunctionBody functionBody = parse3("parseFunctionBody", <Object>[
+      false,
+      null,
+      false
+    ], "{", [ParserErrorCode.EXPECTED_TOKEN]);
     EngineTestCase.assertInstanceOf(
         (obj) => obj is EmptyFunctionBody, EmptyFunctionBody, functionBody);
   }
 
   void test_parseFunctionBody_skip_blocks() {
     ParserTestCase.parseFunctionBodies = false;
-    FunctionBody functionBody = ParserTestCase.parse(
-        "parseFunctionBody", <Object>[false, null, false], "{ {} }");
+    FunctionBody functionBody =
+        parse("parseFunctionBody", <Object>[false, null, false], "{ {} }");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is EmptyFunctionBody, EmptyFunctionBody, functionBody);
   }
 
   void test_parseFunctionBody_skip_expression() {
     ParserTestCase.parseFunctionBodies = false;
-    FunctionBody functionBody = ParserTestCase.parse(
-        "parseFunctionBody", <Object>[false, null, false], "=> y;");
+    FunctionBody functionBody =
+        parse("parseFunctionBody", <Object>[false, null, false], "=> y;");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is EmptyFunctionBody, EmptyFunctionBody, functionBody);
   }
@@ -7799,12 +7512,8 @@
   void test_parseFunctionDeclaration_function() {
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseFunctionDeclaration", <Object>[
-      commentAndMetadata(comment),
-      null,
-      returnType
-    ], "f() {}");
+    FunctionDeclaration declaration = parse("parseFunctionDeclaration",
+        <Object>[commentAndMetadata(comment), null, returnType], "f() {}");
     expect(declaration.documentationComment, comment);
     expect(declaration.returnType, returnType);
     expect(declaration.name, isNotNull);
@@ -7818,12 +7527,8 @@
   void test_parseFunctionDeclaration_getter() {
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseFunctionDeclaration", <Object>[
-      commentAndMetadata(comment),
-      null,
-      returnType
-    ], "get p => 0;");
+    FunctionDeclaration declaration = parse("parseFunctionDeclaration",
+        <Object>[commentAndMetadata(comment), null, returnType], "get p => 0;");
     expect(declaration.documentationComment, comment);
     expect(declaration.returnType, returnType);
     expect(declaration.name, isNotNull);
@@ -7837,12 +7542,8 @@
   void test_parseFunctionDeclaration_setter() {
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
-    FunctionDeclaration declaration = ParserTestCase.parse(
-        "parseFunctionDeclaration", <Object>[
-      commentAndMetadata(comment),
-      null,
-      returnType
-    ], "set p(v) {}");
+    FunctionDeclaration declaration = parse("parseFunctionDeclaration",
+        <Object>[commentAndMetadata(comment), null, returnType], "set p(v) {}");
     expect(declaration.documentationComment, comment);
     expect(declaration.returnType, returnType);
     expect(declaration.name, isNotNull);
@@ -7854,14 +7555,14 @@
   }
 
   void test_parseFunctionDeclarationStatement() {
-    FunctionDeclarationStatement statement = ParserTestCase.parse4(
-        "parseFunctionDeclarationStatement", "void f(int p) => p * 2;");
+    FunctionDeclarationStatement statement =
+        parse4("parseFunctionDeclarationStatement", "void f(int p) => p * 2;");
     expect(statement.functionDeclaration, isNotNull);
   }
 
   void test_parseFunctionExpression_body_inExpression() {
     FunctionExpression expression =
-        ParserTestCase.parse4("parseFunctionExpression", "(int i) => i++");
+        parse4("parseFunctionExpression", "(int i) => i++");
     expect(expression.body, isNotNull);
     expect(expression.parameters, isNotNull);
     expect((expression.body as ExpressionFunctionBody).semicolon, isNull);
@@ -7870,7 +7571,7 @@
   void test_parseGetter_nonStatic() {
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
-    MethodDeclaration method = ParserTestCase.parse("parseGetter", <Object>[
+    MethodDeclaration method = parse("parseGetter", <Object>[
       commentAndMetadata(comment),
       null,
       null,
@@ -7891,7 +7592,7 @@
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     Token staticKeyword = TokenFactory.tokenFromKeyword(Keyword.STATIC);
     TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
-    MethodDeclaration method = ParserTestCase.parse("parseGetter", <Object>[
+    MethodDeclaration method = parse("parseGetter", <Object>[
       commentAndMetadata(comment),
       null,
       staticKeyword,
@@ -7909,20 +7610,17 @@
   }
 
   void test_parseIdentifierList_multiple() {
-    List<SimpleIdentifier> list =
-        ParserTestCase.parse4("parseIdentifierList", "a, b, c");
+    List<SimpleIdentifier> list = parse4("parseIdentifierList", "a, b, c");
     expect(list, hasLength(3));
   }
 
   void test_parseIdentifierList_single() {
-    List<SimpleIdentifier> list =
-        ParserTestCase.parse4("parseIdentifierList", "a");
+    List<SimpleIdentifier> list = parse4("parseIdentifierList", "a");
     expect(list, hasLength(1));
   }
 
   void test_parseIfStatement_else_block() {
-    IfStatement statement =
-        ParserTestCase.parse4("parseIfStatement", "if (x) {} else {}");
+    IfStatement statement = parse4("parseIfStatement", "if (x) {} else {}");
     expect(statement.ifKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.condition, isNotNull);
@@ -7934,7 +7632,7 @@
 
   void test_parseIfStatement_else_statement() {
     IfStatement statement =
-        ParserTestCase.parse4("parseIfStatement", "if (x) f(x); else f(y);");
+        parse4("parseIfStatement", "if (x) f(x); else f(y);");
     expect(statement.ifKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.condition, isNotNull);
@@ -7945,8 +7643,7 @@
   }
 
   void test_parseIfStatement_noElse_block() {
-    IfStatement statement =
-        ParserTestCase.parse4("parseIfStatement", "if (x) {}");
+    IfStatement statement = parse4("parseIfStatement", "if (x) {}");
     expect(statement.ifKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.condition, isNotNull);
@@ -7957,8 +7654,7 @@
   }
 
   void test_parseIfStatement_noElse_statement() {
-    IfStatement statement =
-        ParserTestCase.parse4("parseIfStatement", "if (x) f(x);");
+    IfStatement statement = parse4("parseIfStatement", "if (x) f(x);");
     expect(statement.ifKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.condition, isNotNull);
@@ -7970,23 +7666,21 @@
 
   void test_parseImplementsClause_multiple() {
     ImplementsClause clause =
-        ParserTestCase.parse4("parseImplementsClause", "implements A, B, C");
+        parse4("parseImplementsClause", "implements A, B, C");
     expect(clause.interfaces, hasLength(3));
     expect(clause.implementsKeyword, isNotNull);
   }
 
   void test_parseImplementsClause_single() {
-    ImplementsClause clause =
-        ParserTestCase.parse4("parseImplementsClause", "implements A");
+    ImplementsClause clause = parse4("parseImplementsClause", "implements A");
     expect(clause.interfaces, hasLength(1));
     expect(clause.implementsKeyword, isNotNull);
   }
 
   void test_parseImportDirective_deferred() {
-    ImportDirective directive = ParserTestCase.parse("parseImportDirective",
-        <Object>[
-      emptyCommentAndMetadata()
-    ], "import 'lib/lib.dart' deferred as a;");
+    ImportDirective directive = parse("parseImportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "import 'lib/lib.dart' deferred as a;");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.deferredKeyword, isNotNull);
@@ -7997,10 +7691,9 @@
   }
 
   void test_parseImportDirective_hide() {
-    ImportDirective directive = ParserTestCase.parse("parseImportDirective",
-        <Object>[
-      emptyCommentAndMetadata()
-    ], "import 'lib/lib.dart' hide A, B;");
+    ImportDirective directive = parse("parseImportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "import 'lib/lib.dart' hide A, B;");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.deferredKeyword, isNull);
@@ -8011,7 +7704,7 @@
   }
 
   void test_parseImportDirective_noCombinator() {
-    ImportDirective directive = ParserTestCase.parse("parseImportDirective",
+    ImportDirective directive = parse("parseImportDirective",
         <Object>[emptyCommentAndMetadata()], "import 'lib/lib.dart';");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
@@ -8023,7 +7716,7 @@
   }
 
   void test_parseImportDirective_prefix() {
-    ImportDirective directive = ParserTestCase.parse("parseImportDirective",
+    ImportDirective directive = parse("parseImportDirective",
         <Object>[emptyCommentAndMetadata()], "import 'lib/lib.dart' as a;");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
@@ -8035,10 +7728,9 @@
   }
 
   void test_parseImportDirective_prefix_hide_show() {
-    ImportDirective directive = ParserTestCase.parse("parseImportDirective",
-        <Object>[
-      emptyCommentAndMetadata()
-    ], "import 'lib/lib.dart' as a hide A show B;");
+    ImportDirective directive = parse("parseImportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "import 'lib/lib.dart' as a hide A show B;");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.deferredKeyword, isNull);
@@ -8049,10 +7741,9 @@
   }
 
   void test_parseImportDirective_prefix_show_hide() {
-    ImportDirective directive = ParserTestCase.parse("parseImportDirective",
-        <Object>[
-      emptyCommentAndMetadata()
-    ], "import 'lib/lib.dart' as a show B hide A;");
+    ImportDirective directive = parse("parseImportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "import 'lib/lib.dart' as a show B hide A;");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.deferredKeyword, isNull);
@@ -8063,10 +7754,9 @@
   }
 
   void test_parseImportDirective_show() {
-    ImportDirective directive = ParserTestCase.parse("parseImportDirective",
-        <Object>[
-      emptyCommentAndMetadata()
-    ], "import 'lib/lib.dart' show A, B;");
+    ImportDirective directive = parse("parseImportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "import 'lib/lib.dart' show A, B;");
     expect(directive.keyword, isNotNull);
     expect(directive.uri, isNotNull);
     expect(directive.deferredKeyword, isNull);
@@ -8080,8 +7770,8 @@
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     Token staticKeyword = TokenFactory.tokenFromKeyword(Keyword.STATIC);
     TypeName type = new TypeName(new SimpleIdentifier(null), null);
-    FieldDeclaration declaration = ParserTestCase.parse(
-        "parseInitializedIdentifierList", <Object>[
+    FieldDeclaration declaration = parse("parseInitializedIdentifierList",
+        <Object>[
       commentAndMetadata(comment),
       staticKeyword,
       null,
@@ -8101,8 +7791,8 @@
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     Token staticKeyword = TokenFactory.tokenFromKeyword(Keyword.STATIC);
     Token varKeyword = TokenFactory.tokenFromKeyword(Keyword.VAR);
-    FieldDeclaration declaration = ParserTestCase.parse(
-        "parseInitializedIdentifierList", <Object>[
+    FieldDeclaration declaration = parse("parseInitializedIdentifierList",
+        <Object>[
       commentAndMetadata(comment),
       staticKeyword,
       varKeyword,
@@ -8120,8 +7810,8 @@
 
   void test_parseInstanceCreationExpression_qualifiedType() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.NEW);
-    InstanceCreationExpression expression = ParserTestCase.parse(
-        "parseInstanceCreationExpression", <Object>[token], "A.B()");
+    InstanceCreationExpression expression =
+        parse("parseInstanceCreationExpression", <Object>[token], "A.B()");
     expect(expression.keyword, token);
     ConstructorName name = expression.constructorName;
     expect(name, isNotNull);
@@ -8133,8 +7823,8 @@
 
   void test_parseInstanceCreationExpression_qualifiedType_named() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.NEW);
-    InstanceCreationExpression expression = ParserTestCase.parse(
-        "parseInstanceCreationExpression", <Object>[token], "A.B.c()");
+    InstanceCreationExpression expression =
+        parse("parseInstanceCreationExpression", <Object>[token], "A.B.c()");
     expect(expression.keyword, token);
     ConstructorName name = expression.constructorName;
     expect(name, isNotNull);
@@ -8146,8 +7836,8 @@
 
   void test_parseInstanceCreationExpression_type() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.NEW);
-    InstanceCreationExpression expression = ParserTestCase.parse(
-        "parseInstanceCreationExpression", <Object>[token], "A()");
+    InstanceCreationExpression expression =
+        parse("parseInstanceCreationExpression", <Object>[token], "A()");
     expect(expression.keyword, token);
     ConstructorName name = expression.constructorName;
     expect(name, isNotNull);
@@ -8159,8 +7849,8 @@
 
   void test_parseInstanceCreationExpression_type_named() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.NEW);
-    InstanceCreationExpression expression = ParserTestCase.parse(
-        "parseInstanceCreationExpression", <Object>[token], "A<B>.c()");
+    InstanceCreationExpression expression =
+        parse("parseInstanceCreationExpression", <Object>[token], "A<B>.c()");
     expect(expression.keyword, token);
     ConstructorName name = expression.constructorName;
     expect(name, isNotNull);
@@ -8171,7 +7861,7 @@
   }
 
   void test_parseLibraryDirective() {
-    LibraryDirective directive = ParserTestCase.parse("parseLibraryDirective",
+    LibraryDirective directive = parse("parseLibraryDirective",
         <Object>[emptyCommentAndMetadata()], "library l;");
     expect(directive.libraryKeyword, isNotNull);
     expect(directive.name, isNotNull);
@@ -8180,23 +7870,21 @@
 
   void test_parseLibraryIdentifier_multiple() {
     String name = "a.b.c";
-    LibraryIdentifier identifier =
-        ParserTestCase.parse4("parseLibraryIdentifier", name);
+    LibraryIdentifier identifier = parse4("parseLibraryIdentifier", name);
     expect(identifier.name, name);
   }
 
   void test_parseLibraryIdentifier_single() {
     String name = "a";
-    LibraryIdentifier identifier =
-        ParserTestCase.parse4("parseLibraryIdentifier", name);
+    LibraryIdentifier identifier = parse4("parseLibraryIdentifier", name);
     expect(identifier.name, name);
   }
 
   void test_parseListLiteral_empty_oneToken() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.CONST);
     TypeArgumentList typeArguments = null;
-    ListLiteral literal = ParserTestCase.parse(
-        "parseListLiteral", <Object>[token, typeArguments], "[]");
+    ListLiteral literal =
+        parse("parseListLiteral", <Object>[token, typeArguments], "[]");
     expect(literal.constKeyword, token);
     expect(literal.typeArguments, typeArguments);
     expect(literal.leftBracket, isNotNull);
@@ -8207,7 +7895,7 @@
   void test_parseListLiteral_empty_oneToken_withComment() {
     Token constToken = null;
     TypeArgumentList typeArguments = null;
-    ListLiteral literal = ParserTestCase.parse(
+    ListLiteral literal = parse(
         "parseListLiteral", <Object>[constToken, typeArguments], "/* 0 */ []");
     expect(literal.constKeyword, constToken);
     expect(literal.typeArguments, typeArguments);
@@ -8221,8 +7909,8 @@
   void test_parseListLiteral_empty_twoTokens() {
     Token token = TokenFactory.tokenFromKeyword(Keyword.CONST);
     TypeArgumentList typeArguments = null;
-    ListLiteral literal = ParserTestCase.parse(
-        "parseListLiteral", <Object>[token, typeArguments], "[ ]");
+    ListLiteral literal =
+        parse("parseListLiteral", <Object>[token, typeArguments], "[ ]");
     expect(literal.constKeyword, token);
     expect(literal.typeArguments, typeArguments);
     expect(literal.leftBracket, isNotNull);
@@ -8231,8 +7919,8 @@
   }
 
   void test_parseListLiteral_multiple() {
-    ListLiteral literal = ParserTestCase.parse(
-        "parseListLiteral", <Object>[null, null], "[1, 2, 3]");
+    ListLiteral literal =
+        parse("parseListLiteral", <Object>[null, null], "[1, 2, 3]");
     expect(literal.constKeyword, isNull);
     expect(literal.typeArguments, isNull);
     expect(literal.leftBracket, isNotNull);
@@ -8242,7 +7930,7 @@
 
   void test_parseListLiteral_single() {
     ListLiteral literal =
-        ParserTestCase.parse("parseListLiteral", <Object>[null, null], "[1]");
+        parse("parseListLiteral", <Object>[null, null], "[1]");
     expect(literal.constKeyword, isNull);
     expect(literal.typeArguments, isNull);
     expect(literal.leftBracket, isNotNull);
@@ -8251,8 +7939,7 @@
   }
 
   void test_parseListOrMapLiteral_list_noType() {
-    ListLiteral literal =
-        ParserTestCase.parse("parseListOrMapLiteral", <Object>[null], "[1]");
+    ListLiteral literal = parse("parseListOrMapLiteral", <Object>[null], "[1]");
     expect(literal.constKeyword, isNull);
     expect(literal.typeArguments, isNull);
     expect(literal.leftBracket, isNotNull);
@@ -8261,8 +7948,8 @@
   }
 
   void test_parseListOrMapLiteral_list_type() {
-    ListLiteral literal = ParserTestCase.parse(
-        "parseListOrMapLiteral", <Object>[null], "<int> [1]");
+    ListLiteral literal =
+        parse("parseListOrMapLiteral", <Object>[null], "<int> [1]");
     expect(literal.constKeyword, isNull);
     expect(literal.typeArguments, isNotNull);
     expect(literal.leftBracket, isNotNull);
@@ -8271,8 +7958,8 @@
   }
 
   void test_parseListOrMapLiteral_map_noType() {
-    MapLiteral literal = ParserTestCase.parse(
-        "parseListOrMapLiteral", <Object>[null], "{'1' : 1}");
+    MapLiteral literal =
+        parse("parseListOrMapLiteral", <Object>[null], "{'1' : 1}");
     expect(literal.constKeyword, isNull);
     expect(literal.typeArguments, isNull);
     expect(literal.leftBracket, isNotNull);
@@ -8281,7 +7968,7 @@
   }
 
   void test_parseListOrMapLiteral_map_type() {
-    MapLiteral literal = ParserTestCase.parse(
+    MapLiteral literal = parse(
         "parseListOrMapLiteral", <Object>[null], "<String, int> {'1' : 1}");
     expect(literal.constKeyword, isNull);
     expect(literal.typeArguments, isNotNull);
@@ -8291,8 +7978,7 @@
   }
 
   void test_parseLogicalAndExpression() {
-    BinaryExpression expression =
-        ParserTestCase.parse4("parseLogicalAndExpression", "x && y");
+    BinaryExpression expression = parse4("parseLogicalAndExpression", "x && y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.AMPERSAND_AMPERSAND);
@@ -8300,8 +7986,7 @@
   }
 
   void test_parseLogicalOrExpression() {
-    BinaryExpression expression =
-        ParserTestCase.parse4("parseLogicalOrExpression", "x || y");
+    BinaryExpression expression = parse4("parseLogicalOrExpression", "x || y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.BAR_BAR);
@@ -8312,8 +7997,8 @@
     Token token = TokenFactory.tokenFromKeyword(Keyword.CONST);
     TypeArgumentList typeArguments = AstFactory.typeArgumentList(
         [AstFactory.typeName4("String"), AstFactory.typeName4("int")]);
-    MapLiteral literal = ParserTestCase.parse(
-        "parseMapLiteral", <Object>[token, typeArguments], "{}");
+    MapLiteral literal =
+        parse("parseMapLiteral", <Object>[token, typeArguments], "{}");
     expect(literal.constKeyword, token);
     expect(literal.typeArguments, typeArguments);
     expect(literal.leftBracket, isNotNull);
@@ -8322,83 +8007,80 @@
   }
 
   void test_parseMapLiteral_multiple() {
-    MapLiteral literal = ParserTestCase.parse(
-        "parseMapLiteral", <Object>[null, null], "{'a' : b, 'x' : y}");
+    MapLiteral literal =
+        parse("parseMapLiteral", <Object>[null, null], "{'a' : b, 'x' : y}");
     expect(literal.leftBracket, isNotNull);
     expect(literal.entries, hasLength(2));
     expect(literal.rightBracket, isNotNull);
   }
 
   void test_parseMapLiteral_single() {
-    MapLiteral literal = ParserTestCase.parse(
-        "parseMapLiteral", <Object>[null, null], "{'x' : y}");
+    MapLiteral literal =
+        parse("parseMapLiteral", <Object>[null, null], "{'x' : y}");
     expect(literal.leftBracket, isNotNull);
     expect(literal.entries, hasLength(1));
     expect(literal.rightBracket, isNotNull);
   }
 
   void test_parseMapLiteralEntry_complex() {
-    MapLiteralEntry entry =
-        ParserTestCase.parse4("parseMapLiteralEntry", "2 + 2 : y");
+    MapLiteralEntry entry = parse4("parseMapLiteralEntry", "2 + 2 : y");
     expect(entry.key, isNotNull);
     expect(entry.separator, isNotNull);
     expect(entry.value, isNotNull);
   }
 
   void test_parseMapLiteralEntry_int() {
-    MapLiteralEntry entry =
-        ParserTestCase.parse4("parseMapLiteralEntry", "0 : y");
+    MapLiteralEntry entry = parse4("parseMapLiteralEntry", "0 : y");
     expect(entry.key, isNotNull);
     expect(entry.separator, isNotNull);
     expect(entry.value, isNotNull);
   }
 
   void test_parseMapLiteralEntry_string() {
-    MapLiteralEntry entry =
-        ParserTestCase.parse4("parseMapLiteralEntry", "'x' : y");
+    MapLiteralEntry entry = parse4("parseMapLiteralEntry", "'x' : y");
     expect(entry.key, isNotNull);
     expect(entry.separator, isNotNull);
     expect(entry.value, isNotNull);
   }
 
   void test_parseModifiers_abstract() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "abstract A");
+    Modifiers modifiers = parse4("parseModifiers", "abstract A");
     expect(modifiers.abstractKeyword, isNotNull);
   }
 
   void test_parseModifiers_const() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "const A");
+    Modifiers modifiers = parse4("parseModifiers", "const A");
     expect(modifiers.constKeyword, isNotNull);
   }
 
   void test_parseModifiers_external() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "external A");
+    Modifiers modifiers = parse4("parseModifiers", "external A");
     expect(modifiers.externalKeyword, isNotNull);
   }
 
   void test_parseModifiers_factory() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "factory A");
+    Modifiers modifiers = parse4("parseModifiers", "factory A");
     expect(modifiers.factoryKeyword, isNotNull);
   }
 
   void test_parseModifiers_final() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "final A");
+    Modifiers modifiers = parse4("parseModifiers", "final A");
     expect(modifiers.finalKeyword, isNotNull);
   }
 
   void test_parseModifiers_static() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "static A");
+    Modifiers modifiers = parse4("parseModifiers", "static A");
     expect(modifiers.staticKeyword, isNotNull);
   }
 
   void test_parseModifiers_var() {
-    Modifiers modifiers = ParserTestCase.parse4("parseModifiers", "var A");
+    Modifiers modifiers = parse4("parseModifiers", "var A");
     expect(modifiers.varKeyword, isNotNull);
   }
 
   void test_parseMultiplicativeExpression_normal() {
     BinaryExpression expression =
-        ParserTestCase.parse4("parseMultiplicativeExpression", "x * y");
+        parse4("parseMultiplicativeExpression", "x * y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.STAR);
@@ -8407,7 +8089,7 @@
 
   void test_parseMultiplicativeExpression_super() {
     BinaryExpression expression =
-        ParserTestCase.parse4("parseMultiplicativeExpression", "super * y");
+        parse4("parseMultiplicativeExpression", "super * y");
     EngineTestCase.assertInstanceOf((obj) => obj is SuperExpression,
         SuperExpression, expression.leftOperand);
     expect(expression.operator, isNotNull);
@@ -8417,7 +8099,7 @@
 
   void test_parseNewExpression() {
     InstanceCreationExpression expression =
-        ParserTestCase.parse4("parseNewExpression", "new A()");
+        parse4("parseNewExpression", "new A()");
     expect(expression.keyword, isNotNull);
     ConstructorName name = expression.constructorName;
     expect(name, isNotNull);
@@ -8429,74 +8111,73 @@
 
   void test_parseNonLabeledStatement_const_list_empty() {
     ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "const [];");
+        parse4("parseNonLabeledStatement", "const [];");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_const_list_nonEmpty() {
     ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "const [1, 2];");
+        parse4("parseNonLabeledStatement", "const [1, 2];");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_const_map_empty() {
     ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "const {};");
+        parse4("parseNonLabeledStatement", "const {};");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_const_map_nonEmpty() {
     // TODO(brianwilkerson) Implement more tests for this method.
     ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "const {'a' : 1};");
+        parse4("parseNonLabeledStatement", "const {'a' : 1};");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_const_object() {
     ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "const A();");
+        parse4("parseNonLabeledStatement", "const A();");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_const_object_named_typeParameters() {
     ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "const A<B>.c();");
+        parse4("parseNonLabeledStatement", "const A<B>.c();");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_constructorInvocation() {
     ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "new C().m();");
+        parse4("parseNonLabeledStatement", "new C().m();");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_false() {
     ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "false;");
+        parse4("parseNonLabeledStatement", "false;");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_functionDeclaration() {
-    ParserTestCase.parse4("parseNonLabeledStatement", "f() {};");
+    parse4("parseNonLabeledStatement", "f() {};");
   }
 
   void test_parseNonLabeledStatement_functionDeclaration_arguments() {
-    ParserTestCase.parse4("parseNonLabeledStatement", "f(void g()) {};");
+    parse4("parseNonLabeledStatement", "f(void g()) {};");
   }
 
   void test_parseNonLabeledStatement_functionExpressionIndex() {
-    ParserTestCase.parse4("parseNonLabeledStatement", "() {}[0] = null;");
+    parse4("parseNonLabeledStatement", "() {}[0] = null;");
   }
 
   void test_parseNonLabeledStatement_functionInvocation() {
-    ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "f();");
+    ExpressionStatement statement = parse4("parseNonLabeledStatement", "f();");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_invokeFunctionExpression() {
-    ExpressionStatement statement = ParserTestCase.parse4(
-        "parseNonLabeledStatement", "(a) {return a + a;} (3);");
+    ExpressionStatement statement =
+        parse4("parseNonLabeledStatement", "(a) {return a + a;} (3);");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is FunctionExpressionInvocation,
         FunctionExpressionInvocation, statement.expression);
@@ -8513,32 +8194,30 @@
   }
 
   void test_parseNonLabeledStatement_null() {
-    ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "null;");
+    ExpressionStatement statement = parse4("parseNonLabeledStatement", "null;");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_startingWithBuiltInIdentifier() {
     ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "library.getName();");
+        parse4("parseNonLabeledStatement", "library.getName();");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_true() {
-    ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "true;");
+    ExpressionStatement statement = parse4("parseNonLabeledStatement", "true;");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNonLabeledStatement_typeCast() {
     ExpressionStatement statement =
-        ParserTestCase.parse4("parseNonLabeledStatement", "double.NAN as num;");
+        parse4("parseNonLabeledStatement", "double.NAN as num;");
     expect(statement.expression, isNotNull);
   }
 
   void test_parseNormalFormalParameter_field_const_noType() {
     FieldFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "const this.a)");
+        parse4("parseNormalFormalParameter", "const this.a)");
     expect(parameter.keyword, isNotNull);
     expect(parameter.type, isNull);
     expect(parameter.identifier, isNotNull);
@@ -8547,7 +8226,7 @@
 
   void test_parseNormalFormalParameter_field_const_type() {
     FieldFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "const A this.a)");
+        parse4("parseNormalFormalParameter", "const A this.a)");
     expect(parameter.keyword, isNotNull);
     expect(parameter.type, isNotNull);
     expect(parameter.identifier, isNotNull);
@@ -8556,7 +8235,7 @@
 
   void test_parseNormalFormalParameter_field_final_noType() {
     FieldFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "final this.a)");
+        parse4("parseNormalFormalParameter", "final this.a)");
     expect(parameter.keyword, isNotNull);
     expect(parameter.type, isNull);
     expect(parameter.identifier, isNotNull);
@@ -8565,7 +8244,7 @@
 
   void test_parseNormalFormalParameter_field_final_type() {
     FieldFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "final A this.a)");
+        parse4("parseNormalFormalParameter", "final A this.a)");
     expect(parameter.keyword, isNotNull);
     expect(parameter.type, isNotNull);
     expect(parameter.identifier, isNotNull);
@@ -8574,7 +8253,7 @@
 
   void test_parseNormalFormalParameter_field_function_nested() {
     FieldFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "this.a(B b))");
+        parse4("parseNormalFormalParameter", "this.a(B b))");
     expect(parameter.keyword, isNull);
     expect(parameter.type, isNull);
     expect(parameter.identifier, isNotNull);
@@ -8585,7 +8264,7 @@
 
   void test_parseNormalFormalParameter_field_function_noNested() {
     FieldFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "this.a())");
+        parse4("parseNormalFormalParameter", "this.a())");
     expect(parameter.keyword, isNull);
     expect(parameter.type, isNull);
     expect(parameter.identifier, isNotNull);
@@ -8596,7 +8275,7 @@
 
   void test_parseNormalFormalParameter_field_noType() {
     FieldFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "this.a)");
+        parse4("parseNormalFormalParameter", "this.a)");
     expect(parameter.keyword, isNull);
     expect(parameter.type, isNull);
     expect(parameter.identifier, isNotNull);
@@ -8605,7 +8284,7 @@
 
   void test_parseNormalFormalParameter_field_type() {
     FieldFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "A this.a)");
+        parse4("parseNormalFormalParameter", "A this.a)");
     expect(parameter.keyword, isNull);
     expect(parameter.type, isNotNull);
     expect(parameter.identifier, isNotNull);
@@ -8614,7 +8293,7 @@
 
   void test_parseNormalFormalParameter_field_var() {
     FieldFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "var this.a)");
+        parse4("parseNormalFormalParameter", "var this.a)");
     expect(parameter.keyword, isNotNull);
     expect(parameter.type, isNull);
     expect(parameter.identifier, isNotNull);
@@ -8623,7 +8302,7 @@
 
   void test_parseNormalFormalParameter_function_noType() {
     FunctionTypedFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "a())");
+        parse4("parseNormalFormalParameter", "a())");
     expect(parameter.returnType, isNull);
     expect(parameter.identifier, isNotNull);
     expect(parameter.parameters, isNotNull);
@@ -8631,7 +8310,7 @@
 
   void test_parseNormalFormalParameter_function_type() {
     FunctionTypedFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "A a())");
+        parse4("parseNormalFormalParameter", "A a())");
     expect(parameter.returnType, isNotNull);
     expect(parameter.identifier, isNotNull);
     expect(parameter.parameters, isNotNull);
@@ -8639,7 +8318,7 @@
 
   void test_parseNormalFormalParameter_function_void() {
     FunctionTypedFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "void a())");
+        parse4("parseNormalFormalParameter", "void a())");
     expect(parameter.returnType, isNotNull);
     expect(parameter.identifier, isNotNull);
     expect(parameter.parameters, isNotNull);
@@ -8647,7 +8326,7 @@
 
   void test_parseNormalFormalParameter_simple_const_noType() {
     SimpleFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "const a)");
+        parse4("parseNormalFormalParameter", "const a)");
     expect(parameter.keyword, isNotNull);
     expect(parameter.type, isNull);
     expect(parameter.identifier, isNotNull);
@@ -8655,7 +8334,7 @@
 
   void test_parseNormalFormalParameter_simple_const_type() {
     SimpleFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "const A a)");
+        parse4("parseNormalFormalParameter", "const A a)");
     expect(parameter.keyword, isNotNull);
     expect(parameter.type, isNotNull);
     expect(parameter.identifier, isNotNull);
@@ -8663,7 +8342,7 @@
 
   void test_parseNormalFormalParameter_simple_final_noType() {
     SimpleFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "final a)");
+        parse4("parseNormalFormalParameter", "final a)");
     expect(parameter.keyword, isNotNull);
     expect(parameter.type, isNull);
     expect(parameter.identifier, isNotNull);
@@ -8671,7 +8350,7 @@
 
   void test_parseNormalFormalParameter_simple_final_type() {
     SimpleFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "final A a)");
+        parse4("parseNormalFormalParameter", "final A a)");
     expect(parameter.keyword, isNotNull);
     expect(parameter.type, isNotNull);
     expect(parameter.identifier, isNotNull);
@@ -8679,7 +8358,7 @@
 
   void test_parseNormalFormalParameter_simple_noType() {
     SimpleFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "a)");
+        parse4("parseNormalFormalParameter", "a)");
     expect(parameter.keyword, isNull);
     expect(parameter.type, isNull);
     expect(parameter.identifier, isNotNull);
@@ -8687,7 +8366,7 @@
 
   void test_parseNormalFormalParameter_simple_type() {
     SimpleFormalParameter parameter =
-        ParserTestCase.parse4("parseNormalFormalParameter", "A a)");
+        parse4("parseNormalFormalParameter", "A a)");
     expect(parameter.keyword, isNull);
     expect(parameter.type, isNotNull);
     expect(parameter.identifier, isNotNull);
@@ -8696,7 +8375,7 @@
   void test_parseOperator() {
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
-    MethodDeclaration method = ParserTestCase.parse("parseOperator", <Object>[
+    MethodDeclaration method = parse("parseOperator", <Object>[
       commentAndMetadata(comment),
       null,
       returnType
@@ -8717,7 +8396,7 @@
   }
 
   void test_parsePartDirective_part() {
-    PartDirective directive = ParserTestCase.parse("parsePartDirective",
+    PartDirective directive = parse("parsePartDirective",
         <Object>[emptyCommentAndMetadata()], "part 'lib/lib.dart';");
     expect(directive.partKeyword, isNotNull);
     expect(directive.uri, isNotNull);
@@ -8725,7 +8404,7 @@
   }
 
   void test_parsePartDirective_partOf() {
-    PartOfDirective directive = ParserTestCase.parse("parsePartDirective",
+    PartOfDirective directive = parse("parsePartDirective",
         <Object>[emptyCommentAndMetadata()], "part of l;");
     expect(directive.partKeyword, isNotNull);
     expect(directive.ofKeyword, isNotNull);
@@ -8734,55 +8413,48 @@
   }
 
   void test_parsePostfixExpression_decrement() {
-    PostfixExpression expression =
-        ParserTestCase.parse4("parsePostfixExpression", "i--");
+    PostfixExpression expression = parse4("parsePostfixExpression", "i--");
     expect(expression.operand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.MINUS_MINUS);
   }
 
   void test_parsePostfixExpression_increment() {
-    PostfixExpression expression =
-        ParserTestCase.parse4("parsePostfixExpression", "i++");
+    PostfixExpression expression = parse4("parsePostfixExpression", "i++");
     expect(expression.operand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.PLUS_PLUS);
   }
 
   void test_parsePostfixExpression_none_indexExpression() {
-    IndexExpression expression =
-        ParserTestCase.parse4("parsePostfixExpression", "a[0]");
+    IndexExpression expression = parse4("parsePostfixExpression", "a[0]");
     expect(expression.target, isNotNull);
     expect(expression.index, isNotNull);
   }
 
   void test_parsePostfixExpression_none_methodInvocation() {
-    MethodInvocation expression =
-        ParserTestCase.parse4("parsePostfixExpression", "a.m()");
+    MethodInvocation expression = parse4("parsePostfixExpression", "a.m()");
     expect(expression.target, isNotNull);
     expect(expression.methodName, isNotNull);
     expect(expression.argumentList, isNotNull);
   }
 
   void test_parsePostfixExpression_none_propertyAccess() {
-    PrefixedIdentifier expression =
-        ParserTestCase.parse4("parsePostfixExpression", "a.b");
+    PrefixedIdentifier expression = parse4("parsePostfixExpression", "a.b");
     expect(expression.prefix, isNotNull);
     expect(expression.identifier, isNotNull);
   }
 
   void test_parsePrefixedIdentifier_noPrefix() {
     String lexeme = "bar";
-    SimpleIdentifier identifier =
-        ParserTestCase.parse4("parsePrefixedIdentifier", lexeme);
+    SimpleIdentifier identifier = parse4("parsePrefixedIdentifier", lexeme);
     expect(identifier.token, isNotNull);
     expect(identifier.name, lexeme);
   }
 
   void test_parsePrefixedIdentifier_prefix() {
     String lexeme = "foo.bar";
-    PrefixedIdentifier identifier =
-        ParserTestCase.parse4("parsePrefixedIdentifier", lexeme);
+    PrefixedIdentifier identifier = parse4("parsePrefixedIdentifier", lexeme);
     expect(identifier.prefix.name, "foo");
     expect(identifier.period, isNotNull);
     expect(identifier.identifier.name, "bar");
@@ -8790,112 +8462,103 @@
 
   void test_parsePrimaryExpression_const() {
     InstanceCreationExpression expression =
-        ParserTestCase.parse4("parsePrimaryExpression", "const A()");
+        parse4("parsePrimaryExpression", "const A()");
     expect(expression, isNotNull);
   }
 
   void test_parsePrimaryExpression_double() {
     String doubleLiteral = "3.2e4";
-    DoubleLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", doubleLiteral);
+    DoubleLiteral literal = parse4("parsePrimaryExpression", doubleLiteral);
     expect(literal.literal, isNotNull);
     expect(literal.value, double.parse(doubleLiteral));
   }
 
   void test_parsePrimaryExpression_false() {
-    BooleanLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", "false");
+    BooleanLiteral literal = parse4("parsePrimaryExpression", "false");
     expect(literal.literal, isNotNull);
     expect(literal.value, isFalse);
   }
 
   void test_parsePrimaryExpression_function_arguments() {
     FunctionExpression expression =
-        ParserTestCase.parse4("parsePrimaryExpression", "(int i) => i + 1");
+        parse4("parsePrimaryExpression", "(int i) => i + 1");
     expect(expression.parameters, isNotNull);
     expect(expression.body, isNotNull);
   }
 
   void test_parsePrimaryExpression_function_noArguments() {
     FunctionExpression expression =
-        ParserTestCase.parse4("parsePrimaryExpression", "() => 42");
+        parse4("parsePrimaryExpression", "() => 42");
     expect(expression.parameters, isNotNull);
     expect(expression.body, isNotNull);
   }
 
   void test_parsePrimaryExpression_hex() {
     String hexLiteral = "3F";
-    IntegerLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", "0x$hexLiteral");
+    IntegerLiteral literal = parse4("parsePrimaryExpression", "0x$hexLiteral");
     expect(literal.literal, isNotNull);
     expect(literal.value, int.parse(hexLiteral, radix: 16));
   }
 
   void test_parsePrimaryExpression_identifier() {
-    SimpleIdentifier identifier =
-        ParserTestCase.parse4("parsePrimaryExpression", "a");
+    SimpleIdentifier identifier = parse4("parsePrimaryExpression", "a");
     expect(identifier, isNotNull);
   }
 
   void test_parsePrimaryExpression_int() {
     String intLiteral = "472";
-    IntegerLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", intLiteral);
+    IntegerLiteral literal = parse4("parsePrimaryExpression", intLiteral);
     expect(literal.literal, isNotNull);
     expect(literal.value, int.parse(intLiteral));
   }
 
   void test_parsePrimaryExpression_listLiteral() {
-    ListLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", "[ ]");
+    ListLiteral literal = parse4("parsePrimaryExpression", "[ ]");
     expect(literal, isNotNull);
   }
 
   void test_parsePrimaryExpression_listLiteral_index() {
-    ListLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "[]");
+    ListLiteral literal = parse4("parsePrimaryExpression", "[]");
     expect(literal, isNotNull);
   }
 
   void test_parsePrimaryExpression_listLiteral_typed() {
-    ListLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", "<A>[ ]");
+    ListLiteral literal = parse4("parsePrimaryExpression", "<A>[ ]");
     expect(literal.typeArguments, isNotNull);
     expect(literal.typeArguments.arguments, hasLength(1));
   }
 
   void test_parsePrimaryExpression_mapLiteral() {
-    MapLiteral literal = ParserTestCase.parse4("parsePrimaryExpression", "{}");
+    MapLiteral literal = parse4("parsePrimaryExpression", "{}");
     expect(literal, isNotNull);
   }
 
   void test_parsePrimaryExpression_mapLiteral_typed() {
-    MapLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", "<A, B>{}");
+    MapLiteral literal = parse4("parsePrimaryExpression", "<A, B>{}");
     expect(literal.typeArguments, isNotNull);
     expect(literal.typeArguments.arguments, hasLength(2));
   }
 
   void test_parsePrimaryExpression_new() {
     InstanceCreationExpression expression =
-        ParserTestCase.parse4("parsePrimaryExpression", "new A()");
+        parse4("parsePrimaryExpression", "new A()");
     expect(expression, isNotNull);
   }
 
   void test_parsePrimaryExpression_null() {
-    NullLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", "null");
+    NullLiteral literal = parse4("parsePrimaryExpression", "null");
     expect(literal.literal, isNotNull);
   }
 
   void test_parsePrimaryExpression_parenthesized() {
     ParenthesizedExpression expression =
-        ParserTestCase.parse4("parsePrimaryExpression", "(x)");
+        parse4("parsePrimaryExpression", "(x)");
     expect(expression, isNotNull);
   }
 
   void test_parsePrimaryExpression_string() {
     SimpleStringLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", "\"string\"");
+        parse4("parsePrimaryExpression", "\"string\"");
     expect(literal.isMultiline, isFalse);
     expect(literal.isRaw, isFalse);
     expect(literal.value, "string");
@@ -8903,23 +8566,21 @@
 
   void test_parsePrimaryExpression_string_multiline() {
     SimpleStringLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", "'''string'''");
+        parse4("parsePrimaryExpression", "'''string'''");
     expect(literal.isMultiline, isTrue);
     expect(literal.isRaw, isFalse);
     expect(literal.value, "string");
   }
 
   void test_parsePrimaryExpression_string_raw() {
-    SimpleStringLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", "r'string'");
+    SimpleStringLiteral literal = parse4("parsePrimaryExpression", "r'string'");
     expect(literal.isMultiline, isFalse);
     expect(literal.isRaw, isTrue);
     expect(literal.value, "string");
   }
 
   void test_parsePrimaryExpression_super() {
-    PropertyAccess propertyAccess =
-        ParserTestCase.parse4("parsePrimaryExpression", "super.x");
+    PropertyAccess propertyAccess = parse4("parsePrimaryExpression", "super.x");
     expect(propertyAccess.target is SuperExpression, isTrue);
     expect(propertyAccess.operator, isNotNull);
     expect(propertyAccess.operator.type, TokenType.PERIOD);
@@ -8927,14 +8588,12 @@
   }
 
   void test_parsePrimaryExpression_this() {
-    ThisExpression expression =
-        ParserTestCase.parse4("parsePrimaryExpression", "this");
+    ThisExpression expression = parse4("parsePrimaryExpression", "this");
     expect(expression.thisKeyword, isNotNull);
   }
 
   void test_parsePrimaryExpression_true() {
-    BooleanLiteral literal =
-        ParserTestCase.parse4("parsePrimaryExpression", "true");
+    BooleanLiteral literal = parse4("parsePrimaryExpression", "true");
     expect(literal.literal, isNotNull);
     expect(literal.value, isTrue);
   }
@@ -8944,8 +8603,8 @@
   }
 
   void test_parseRedirectingConstructorInvocation_named() {
-    RedirectingConstructorInvocation invocation = ParserTestCase.parse4(
-        "parseRedirectingConstructorInvocation", "this.a()");
+    RedirectingConstructorInvocation invocation =
+        parse4("parseRedirectingConstructorInvocation", "this.a()");
     expect(invocation.argumentList, isNotNull);
     expect(invocation.constructorName, isNotNull);
     expect(invocation.thisKeyword, isNotNull);
@@ -8953,8 +8612,8 @@
   }
 
   void test_parseRedirectingConstructorInvocation_unnamed() {
-    RedirectingConstructorInvocation invocation = ParserTestCase.parse4(
-        "parseRedirectingConstructorInvocation", "this()");
+    RedirectingConstructorInvocation invocation =
+        parse4("parseRedirectingConstructorInvocation", "this()");
     expect(invocation.argumentList, isNotNull);
     expect(invocation.constructorName, isNull);
     expect(invocation.thisKeyword, isNotNull);
@@ -8962,16 +8621,14 @@
   }
 
   void test_parseRelationalExpression_as() {
-    AsExpression expression =
-        ParserTestCase.parse4("parseRelationalExpression", "x as Y");
+    AsExpression expression = parse4("parseRelationalExpression", "x as Y");
     expect(expression.expression, isNotNull);
     expect(expression.asOperator, isNotNull);
     expect(expression.type, isNotNull);
   }
 
   void test_parseRelationalExpression_is() {
-    IsExpression expression =
-        ParserTestCase.parse4("parseRelationalExpression", "x is y");
+    IsExpression expression = parse4("parseRelationalExpression", "x is y");
     expect(expression.expression, isNotNull);
     expect(expression.isOperator, isNotNull);
     expect(expression.notOperator, isNull);
@@ -8979,8 +8636,7 @@
   }
 
   void test_parseRelationalExpression_isNot() {
-    IsExpression expression =
-        ParserTestCase.parse4("parseRelationalExpression", "x is! y");
+    IsExpression expression = parse4("parseRelationalExpression", "x is! y");
     expect(expression.expression, isNotNull);
     expect(expression.isOperator, isNotNull);
     expect(expression.notOperator, isNotNull);
@@ -8988,8 +8644,7 @@
   }
 
   void test_parseRelationalExpression_normal() {
-    BinaryExpression expression =
-        ParserTestCase.parse4("parseRelationalExpression", "x < y");
+    BinaryExpression expression = parse4("parseRelationalExpression", "x < y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.LT);
@@ -8998,7 +8653,7 @@
 
   void test_parseRelationalExpression_super() {
     BinaryExpression expression =
-        ParserTestCase.parse4("parseRelationalExpression", "super < y");
+        parse4("parseRelationalExpression", "super < y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.LT);
@@ -9006,35 +8661,32 @@
   }
 
   void test_parseRethrowExpression() {
-    RethrowExpression expression =
-        ParserTestCase.parse4("parseRethrowExpression", "rethrow;");
+    RethrowExpression expression = parse4("parseRethrowExpression", "rethrow;");
     expect(expression.rethrowKeyword, isNotNull);
   }
 
   void test_parseReturnStatement_noValue() {
-    ReturnStatement statement =
-        ParserTestCase.parse4("parseReturnStatement", "return;");
+    ReturnStatement statement = parse4("parseReturnStatement", "return;");
     expect(statement.returnKeyword, isNotNull);
     expect(statement.expression, isNull);
     expect(statement.semicolon, isNotNull);
   }
 
   void test_parseReturnStatement_value() {
-    ReturnStatement statement =
-        ParserTestCase.parse4("parseReturnStatement", "return x;");
+    ReturnStatement statement = parse4("parseReturnStatement", "return x;");
     expect(statement.returnKeyword, isNotNull);
     expect(statement.expression, isNotNull);
     expect(statement.semicolon, isNotNull);
   }
 
   void test_parseReturnType_nonVoid() {
-    TypeName typeName = ParserTestCase.parse4("parseReturnType", "A<B>");
+    TypeName typeName = parse4("parseReturnType", "A<B>");
     expect(typeName.name, isNotNull);
     expect(typeName.typeArguments, isNotNull);
   }
 
   void test_parseReturnType_void() {
-    TypeName typeName = ParserTestCase.parse4("parseReturnType", "void");
+    TypeName typeName = parse4("parseReturnType", "void");
     expect(typeName.name, isNotNull);
     expect(typeName.typeArguments, isNull);
   }
@@ -9042,7 +8694,7 @@
   void test_parseSetter_nonStatic() {
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
-    MethodDeclaration method = ParserTestCase.parse("parseSetter", <Object>[
+    MethodDeclaration method = parse("parseSetter", <Object>[
       commentAndMetadata(comment),
       null,
       null,
@@ -9063,7 +8715,7 @@
     Comment comment = Comment.createDocumentationComment(new List<Token>(0));
     Token staticKeyword = TokenFactory.tokenFromKeyword(Keyword.STATIC);
     TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
-    MethodDeclaration method = ParserTestCase.parse("parseSetter", <Object>[
+    MethodDeclaration method = parse("parseSetter", <Object>[
       commentAndMetadata(comment),
       null,
       staticKeyword,
@@ -9081,8 +8733,7 @@
   }
 
   void test_parseShiftExpression_normal() {
-    BinaryExpression expression =
-        ParserTestCase.parse4("parseShiftExpression", "x << y");
+    BinaryExpression expression = parse4("parseShiftExpression", "x << y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.LT_LT);
@@ -9090,8 +8741,7 @@
   }
 
   void test_parseShiftExpression_super() {
-    BinaryExpression expression =
-        ParserTestCase.parse4("parseShiftExpression", "super << y");
+    BinaryExpression expression = parse4("parseShiftExpression", "super << y");
     expect(expression.leftOperand, isNotNull);
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.LT_LT);
@@ -9104,41 +8754,49 @@
 
   void test_parseSimpleIdentifier_builtInIdentifier() {
     String lexeme = "as";
-    SimpleIdentifier identifier =
-        ParserTestCase.parse4("parseSimpleIdentifier", lexeme);
+    SimpleIdentifier identifier = parse4("parseSimpleIdentifier", lexeme);
     expect(identifier.token, isNotNull);
     expect(identifier.name, lexeme);
   }
 
   void test_parseSimpleIdentifier_normalIdentifier() {
     String lexeme = "foo";
-    SimpleIdentifier identifier =
-        ParserTestCase.parse4("parseSimpleIdentifier", lexeme);
+    SimpleIdentifier identifier = parse4("parseSimpleIdentifier", lexeme);
     expect(identifier.token, isNotNull);
     expect(identifier.name, lexeme);
   }
 
+  void test_parseStatement_emptyTypeArgumentListt() {
+    VariableDeclarationStatement statement = parse4(
+        "parseStatement", "C<> c;", [ParserErrorCode.EXPECTED_TYPE_NAME]);
+    VariableDeclarationList variables = statement.variables;
+    TypeName type = variables.type;
+    TypeArgumentList argumentList = type.typeArguments;
+    expect(argumentList.leftBracket, isNotNull);
+    expect(argumentList.arguments, hasLength(1));
+    expect(argumentList.arguments[0].isSynthetic, isTrue);
+    expect(argumentList.rightBracket, isNotNull);
+  }
+
   void test_parseStatement_functionDeclaration() {
     // TODO(brianwilkerson) Implement more tests for this method.
     FunctionDeclarationStatement statement =
-        ParserTestCase.parse4("parseStatement", "int f(a, b) {};");
+        parse4("parseStatement", "int f(a, b) {};");
     expect(statement.functionDeclaration, isNotNull);
   }
 
   void test_parseStatement_mulipleLabels() {
-    LabeledStatement statement =
-        ParserTestCase.parse4("parseStatement", "l: m: return x;");
+    LabeledStatement statement = parse4("parseStatement", "l: m: return x;");
     expect(statement.labels, hasLength(2));
     expect(statement.statement, isNotNull);
   }
 
   void test_parseStatement_noLabels() {
-    ParserTestCase.parse4("parseStatement", "return x;");
+    parse4("parseStatement", "return x;");
   }
 
   void test_parseStatement_singleLabel() {
-    LabeledStatement statement =
-        ParserTestCase.parse4("parseStatement", "l: return x;");
+    LabeledStatement statement = parse4("parseStatement", "l: return x;");
     expect(statement.labels, hasLength(1));
     expect(statement.statement, isNotNull);
   }
@@ -9155,8 +8813,7 @@
   }
 
   void test_parseStringLiteral_adjacent() {
-    AdjacentStrings literal =
-        ParserTestCase.parse4("parseStringLiteral", "'a' 'b'");
+    AdjacentStrings literal = parse4("parseStringLiteral", "'a' 'b'");
     NodeList<StringLiteral> strings = literal.strings;
     expect(strings, hasLength(2));
     StringLiteral firstString = strings[0];
@@ -9167,7 +8824,7 @@
 
   void test_parseStringLiteral_interpolated() {
     StringInterpolation literal =
-        ParserTestCase.parse4("parseStringLiteral", "'a \${b} c \$this d'");
+        parse4("parseStringLiteral", "'a \${b} c \$this d'");
     NodeList<InterpolationElement> elements = literal.elements;
     expect(elements, hasLength(5));
     expect(elements[0] is InterpolationString, isTrue);
@@ -9178,15 +8835,14 @@
   }
 
   void test_parseStringLiteral_single() {
-    SimpleStringLiteral literal =
-        ParserTestCase.parse4("parseStringLiteral", "'a'");
+    SimpleStringLiteral literal = parse4("parseStringLiteral", "'a'");
     expect(literal.literal, isNotNull);
     expect(literal.value, "a");
   }
 
   void test_parseSuperConstructorInvocation_named() {
     SuperConstructorInvocation invocation =
-        ParserTestCase.parse4("parseSuperConstructorInvocation", "super.a()");
+        parse4("parseSuperConstructorInvocation", "super.a()");
     expect(invocation.argumentList, isNotNull);
     expect(invocation.constructorName, isNotNull);
     expect(invocation.superKeyword, isNotNull);
@@ -9195,7 +8851,7 @@
 
   void test_parseSuperConstructorInvocation_unnamed() {
     SuperConstructorInvocation invocation =
-        ParserTestCase.parse4("parseSuperConstructorInvocation", "super()");
+        parse4("parseSuperConstructorInvocation", "super()");
     expect(invocation.argumentList, isNotNull);
     expect(invocation.constructorName, isNull);
     expect(invocation.superKeyword, isNotNull);
@@ -9203,8 +8859,8 @@
   }
 
   void test_parseSwitchStatement_case() {
-    SwitchStatement statement = ParserTestCase.parse4(
-        "parseSwitchStatement", "switch (a) {case 1: return 'I';}");
+    SwitchStatement statement =
+        parse4("parseSwitchStatement", "switch (a) {case 1: return 'I';}");
     expect(statement.switchKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.expression, isNotNull);
@@ -9215,8 +8871,7 @@
   }
 
   void test_parseSwitchStatement_empty() {
-    SwitchStatement statement =
-        ParserTestCase.parse4("parseSwitchStatement", "switch (a) {}");
+    SwitchStatement statement = parse4("parseSwitchStatement", "switch (a) {}");
     expect(statement.switchKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.expression, isNotNull);
@@ -9227,8 +8882,8 @@
   }
 
   void test_parseSwitchStatement_labeledCase() {
-    SwitchStatement statement = ParserTestCase.parse4(
-        "parseSwitchStatement", "switch (a) {l1: l2: l3: case(1):}");
+    SwitchStatement statement =
+        parse4("parseSwitchStatement", "switch (a) {l1: l2: l3: case(1):}");
     expect(statement.switchKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.expression, isNotNull);
@@ -9240,7 +8895,7 @@
   }
 
   void test_parseSwitchStatement_labeledStatementInCase() {
-    SwitchStatement statement = ParserTestCase.parse4(
+    SwitchStatement statement = parse4(
         "parseSwitchStatement", "switch (a) {case 0: f(); l1: g(); break;}");
     expect(statement.switchKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
@@ -9254,7 +8909,7 @@
 
   void test_parseSymbolLiteral_builtInIdentifier() {
     SymbolLiteral literal =
-        ParserTestCase.parse4("parseSymbolLiteral", "#dynamic.static.abstract");
+        parse4("parseSymbolLiteral", "#dynamic.static.abstract");
     expect(literal.poundSign, isNotNull);
     List<Token> components = literal.components;
     expect(components, hasLength(3));
@@ -9264,8 +8919,7 @@
   }
 
   void test_parseSymbolLiteral_multiple() {
-    SymbolLiteral literal =
-        ParserTestCase.parse4("parseSymbolLiteral", "#a.b.c");
+    SymbolLiteral literal = parse4("parseSymbolLiteral", "#a.b.c");
     expect(literal.poundSign, isNotNull);
     List<Token> components = literal.components;
     expect(components, hasLength(3));
@@ -9275,7 +8929,7 @@
   }
 
   void test_parseSymbolLiteral_operator() {
-    SymbolLiteral literal = ParserTestCase.parse4("parseSymbolLiteral", "#==");
+    SymbolLiteral literal = parse4("parseSymbolLiteral", "#==");
     expect(literal.poundSign, isNotNull);
     List<Token> components = literal.components;
     expect(components, hasLength(1));
@@ -9283,7 +8937,7 @@
   }
 
   void test_parseSymbolLiteral_single() {
-    SymbolLiteral literal = ParserTestCase.parse4("parseSymbolLiteral", "#a");
+    SymbolLiteral literal = parse4("parseSymbolLiteral", "#a");
     expect(literal.poundSign, isNotNull);
     List<Token> components = literal.components;
     expect(components, hasLength(1));
@@ -9291,8 +8945,7 @@
   }
 
   void test_parseSymbolLiteral_void() {
-    SymbolLiteral literal =
-        ParserTestCase.parse4("parseSymbolLiteral", "#void");
+    SymbolLiteral literal = parse4("parseSymbolLiteral", "#void");
     expect(literal.poundSign, isNotNull);
     List<Token> components = literal.components;
     expect(components, hasLength(1));
@@ -9300,22 +8953,20 @@
   }
 
   void test_parseThrowExpression() {
-    ThrowExpression expression =
-        ParserTestCase.parse4("parseThrowExpression", "throw x;");
+    ThrowExpression expression = parse4("parseThrowExpression", "throw x;");
     expect(expression.throwKeyword, isNotNull);
     expect(expression.expression, isNotNull);
   }
 
   void test_parseThrowExpressionWithoutCascade() {
     ThrowExpression expression =
-        ParserTestCase.parse4("parseThrowExpressionWithoutCascade", "throw x;");
+        parse4("parseThrowExpressionWithoutCascade", "throw x;");
     expect(expression.throwKeyword, isNotNull);
     expect(expression.expression, isNotNull);
   }
 
   void test_parseTryStatement_catch() {
-    TryStatement statement =
-        ParserTestCase.parse4("parseTryStatement", "try {} catch (e) {}");
+    TryStatement statement = parse4("parseTryStatement", "try {} catch (e) {}");
     expect(statement.tryKeyword, isNotNull);
     expect(statement.body, isNotNull);
     NodeList<CatchClause> catchClauses = statement.catchClauses;
@@ -9333,8 +8984,8 @@
   }
 
   void test_parseTryStatement_catch_finally() {
-    TryStatement statement = ParserTestCase.parse4(
-        "parseTryStatement", "try {} catch (e, s) {} finally {}");
+    TryStatement statement =
+        parse4("parseTryStatement", "try {} catch (e, s) {} finally {}");
     expect(statement.tryKeyword, isNotNull);
     expect(statement.body, isNotNull);
     NodeList<CatchClause> catchClauses = statement.catchClauses;
@@ -9352,8 +9003,7 @@
   }
 
   void test_parseTryStatement_finally() {
-    TryStatement statement =
-        ParserTestCase.parse4("parseTryStatement", "try {} finally {}");
+    TryStatement statement = parse4("parseTryStatement", "try {} finally {}");
     expect(statement.tryKeyword, isNotNull);
     expect(statement.body, isNotNull);
     expect(statement.catchClauses, hasLength(0));
@@ -9362,7 +9012,7 @@
   }
 
   void test_parseTryStatement_multiple() {
-    TryStatement statement = ParserTestCase.parse4("parseTryStatement",
+    TryStatement statement = parse4("parseTryStatement",
         "try {} on NPE catch (e) {} on Error {} catch (e) {}");
     expect(statement.tryKeyword, isNotNull);
     expect(statement.body, isNotNull);
@@ -9372,8 +9022,7 @@
   }
 
   void test_parseTryStatement_on() {
-    TryStatement statement =
-        ParserTestCase.parse4("parseTryStatement", "try {} on Error {}");
+    TryStatement statement = parse4("parseTryStatement", "try {} on Error {}");
     expect(statement.tryKeyword, isNotNull);
     expect(statement.body, isNotNull);
     NodeList<CatchClause> catchClauses = statement.catchClauses;
@@ -9391,8 +9040,8 @@
   }
 
   void test_parseTryStatement_on_catch() {
-    TryStatement statement = ParserTestCase.parse4(
-        "parseTryStatement", "try {} on Error catch (e, s) {}");
+    TryStatement statement =
+        parse4("parseTryStatement", "try {} on Error catch (e, s) {}");
     expect(statement.tryKeyword, isNotNull);
     expect(statement.body, isNotNull);
     NodeList<CatchClause> catchClauses = statement.catchClauses;
@@ -9410,7 +9059,7 @@
   }
 
   void test_parseTryStatement_on_catch_finally() {
-    TryStatement statement = ParserTestCase.parse4(
+    TryStatement statement = parse4(
         "parseTryStatement", "try {} on Error catch (e, s) {} finally {}");
     expect(statement.tryKeyword, isNotNull);
     expect(statement.body, isNotNull);
@@ -9429,7 +9078,7 @@
   }
 
   void test_parseTypeAlias_function_noParameters() {
-    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias",
+    FunctionTypeAlias typeAlias = parse("parseTypeAlias",
         <Object>[emptyCommentAndMetadata()], "typedef bool F();");
     expect(typeAlias.typedefKeyword, isNotNull);
     expect(typeAlias.name, isNotNull);
@@ -9440,7 +9089,7 @@
   }
 
   void test_parseTypeAlias_function_noReturnType() {
-    FunctionTypeAlias typeAlias = ParserTestCase.parse(
+    FunctionTypeAlias typeAlias = parse(
         "parseTypeAlias", <Object>[emptyCommentAndMetadata()], "typedef F();");
     expect(typeAlias.typedefKeyword, isNotNull);
     expect(typeAlias.name, isNotNull);
@@ -9451,7 +9100,7 @@
   }
 
   void test_parseTypeAlias_function_parameterizedReturnType() {
-    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias",
+    FunctionTypeAlias typeAlias = parse("parseTypeAlias",
         <Object>[emptyCommentAndMetadata()], "typedef A<B> F();");
     expect(typeAlias.typedefKeyword, isNotNull);
     expect(typeAlias.name, isNotNull);
@@ -9462,7 +9111,7 @@
   }
 
   void test_parseTypeAlias_function_parameters() {
-    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias",
+    FunctionTypeAlias typeAlias = parse("parseTypeAlias",
         <Object>[emptyCommentAndMetadata()], "typedef bool F(Object value);");
     expect(typeAlias.typedefKeyword, isNotNull);
     expect(typeAlias.name, isNotNull);
@@ -9473,7 +9122,7 @@
   }
 
   void test_parseTypeAlias_function_typeParameters() {
-    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias",
+    FunctionTypeAlias typeAlias = parse("parseTypeAlias",
         <Object>[emptyCommentAndMetadata()], "typedef bool F<E>();");
     expect(typeAlias.typedefKeyword, isNotNull);
     expect(typeAlias.name, isNotNull);
@@ -9484,7 +9133,7 @@
   }
 
   void test_parseTypeAlias_function_voidReturnType() {
-    FunctionTypeAlias typeAlias = ParserTestCase.parse("parseTypeAlias",
+    FunctionTypeAlias typeAlias = parse("parseTypeAlias",
         <Object>[emptyCommentAndMetadata()], "typedef void F();");
     expect(typeAlias.typedefKeyword, isNotNull);
     expect(typeAlias.name, isNotNull);
@@ -9494,17 +9143,24 @@
     expect(typeAlias.typeParameters, isNull);
   }
 
+  void test_parseTypeArgumentList_empty() {
+    TypeArgumentList argumentList = parse4(
+        "parseTypeArgumentList", "<>", [ParserErrorCode.EXPECTED_TYPE_NAME]);
+    expect(argumentList.leftBracket, isNotNull);
+    expect(argumentList.arguments, hasLength(1));
+    expect(argumentList.rightBracket, isNotNull);
+  }
+
   void test_parseTypeArgumentList_multiple() {
     TypeArgumentList argumentList =
-        ParserTestCase.parse4("parseTypeArgumentList", "<int, int, int>");
+        parse4("parseTypeArgumentList", "<int, int, int>");
     expect(argumentList.leftBracket, isNotNull);
     expect(argumentList.arguments, hasLength(3));
     expect(argumentList.rightBracket, isNotNull);
   }
 
   void test_parseTypeArgumentList_nested() {
-    TypeArgumentList argumentList =
-        ParserTestCase.parse4("parseTypeArgumentList", "<A<B>>");
+    TypeArgumentList argumentList = parse4("parseTypeArgumentList", "<A<B>>");
     expect(argumentList.leftBracket, isNotNull);
     expect(argumentList.arguments, hasLength(1));
     TypeName argument = argumentList.arguments[0];
@@ -9517,7 +9173,7 @@
 
   void test_parseTypeArgumentList_nested_withComment_double() {
     TypeArgumentList argumentList =
-        ParserTestCase.parse4("parseTypeArgumentList", "<A<B /* 0 */ >>");
+        parse4("parseTypeArgumentList", "<A<B /* 0 */ >>");
     expect(argumentList.leftBracket, isNotNull);
     expect(argumentList.rightBracket, isNotNull);
     expect(argumentList.arguments, hasLength(1));
@@ -9535,7 +9191,7 @@
 
   void test_parseTypeArgumentList_nested_withComment_tripple() {
     TypeArgumentList argumentList =
-        ParserTestCase.parse4("parseTypeArgumentList", "<A<B<C /* 0 */ >>>");
+        parse4("parseTypeArgumentList", "<A<B<C /* 0 */ >>>");
     expect(argumentList.leftBracket, isNotNull);
     expect(argumentList.rightBracket, isNotNull);
     expect(argumentList.arguments, hasLength(1));
@@ -9561,35 +9217,33 @@
   }
 
   void test_parseTypeArgumentList_single() {
-    TypeArgumentList argumentList =
-        ParserTestCase.parse4("parseTypeArgumentList", "<int>");
+    TypeArgumentList argumentList = parse4("parseTypeArgumentList", "<int>");
     expect(argumentList.leftBracket, isNotNull);
     expect(argumentList.arguments, hasLength(1));
     expect(argumentList.rightBracket, isNotNull);
   }
 
   void test_parseTypeName_parameterized() {
-    TypeName typeName = ParserTestCase.parse4("parseTypeName", "List<int>");
+    TypeName typeName = parse4("parseTypeName", "List<int>");
     expect(typeName.name, isNotNull);
     expect(typeName.typeArguments, isNotNull);
   }
 
   void test_parseTypeName_simple() {
-    TypeName typeName = ParserTestCase.parse4("parseTypeName", "int");
+    TypeName typeName = parse4("parseTypeName", "int");
     expect(typeName.name, isNotNull);
     expect(typeName.typeArguments, isNull);
   }
 
   void test_parseTypeParameter_bounded() {
-    TypeParameter parameter =
-        ParserTestCase.parse4("parseTypeParameter", "A extends B");
+    TypeParameter parameter = parse4("parseTypeParameter", "A extends B");
     expect(parameter.bound, isNotNull);
     expect(parameter.extendsKeyword, isNotNull);
     expect(parameter.name, isNotNull);
   }
 
   void test_parseTypeParameter_simple() {
-    TypeParameter parameter = ParserTestCase.parse4("parseTypeParameter", "A");
+    TypeParameter parameter = parse4("parseTypeParameter", "A");
     expect(parameter.bound, isNull);
     expect(parameter.extendsKeyword, isNull);
     expect(parameter.name, isNotNull);
@@ -9597,7 +9251,7 @@
 
   void test_parseTypeParameterList_multiple() {
     TypeParameterList parameterList =
-        ParserTestCase.parse4("parseTypeParameterList", "<A, B extends C, D>");
+        parse4("parseTypeParameterList", "<A, B extends C, D>");
     expect(parameterList.leftBracket, isNotNull);
     expect(parameterList.rightBracket, isNotNull);
     expect(parameterList.typeParameters, hasLength(3));
@@ -9605,39 +9259,35 @@
 
   void test_parseTypeParameterList_parameterizedWithTrailingEquals() {
     TypeParameterList parameterList =
-        ParserTestCase.parse4("parseTypeParameterList", "<A extends B<E>>=");
+        parse4("parseTypeParameterList", "<A extends B<E>>=");
     expect(parameterList.leftBracket, isNotNull);
     expect(parameterList.rightBracket, isNotNull);
     expect(parameterList.typeParameters, hasLength(1));
   }
 
   void test_parseTypeParameterList_single() {
-    TypeParameterList parameterList =
-        ParserTestCase.parse4("parseTypeParameterList", "<A>");
+    TypeParameterList parameterList = parse4("parseTypeParameterList", "<A>");
     expect(parameterList.leftBracket, isNotNull);
     expect(parameterList.rightBracket, isNotNull);
     expect(parameterList.typeParameters, hasLength(1));
   }
 
   void test_parseTypeParameterList_withTrailingEquals() {
-    TypeParameterList parameterList =
-        ParserTestCase.parse4("parseTypeParameterList", "<A>=");
+    TypeParameterList parameterList = parse4("parseTypeParameterList", "<A>=");
     expect(parameterList.leftBracket, isNotNull);
     expect(parameterList.rightBracket, isNotNull);
     expect(parameterList.typeParameters, hasLength(1));
   }
 
   void test_parseUnaryExpression_decrement_normal() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "--x");
+    PrefixExpression expression = parse4("parseUnaryExpression", "--x");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.MINUS_MINUS);
     expect(expression.operand, isNotNull);
   }
 
   void test_parseUnaryExpression_decrement_super() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "--super");
+    PrefixExpression expression = parse4("parseUnaryExpression", "--super");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.MINUS);
     Expression innerExpression = expression.operand;
@@ -9650,8 +9300,7 @@
   }
 
   void test_parseUnaryExpression_decrement_super_propertyAccess() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "--super.x");
+    PrefixExpression expression = parse4("parseUnaryExpression", "--super.x");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.MINUS_MINUS);
     expect(expression.operand, isNotNull);
@@ -9662,7 +9311,7 @@
 
   void test_parseUnaryExpression_decrement_super_withComment() {
     PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "/* 0 */ --super");
+        parse4("parseUnaryExpression", "/* 0 */ --super");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.MINUS);
     expect(expression.operator.precedingComments, isNotNull);
@@ -9676,16 +9325,14 @@
   }
 
   void test_parseUnaryExpression_increment_normal() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "++x");
+    PrefixExpression expression = parse4("parseUnaryExpression", "++x");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.PLUS_PLUS);
     expect(expression.operand, isNotNull);
   }
 
   void test_parseUnaryExpression_increment_super_index() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "++super[0]");
+    PrefixExpression expression = parse4("parseUnaryExpression", "++super[0]");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.PLUS_PLUS);
     expect(expression.operand, isNotNull);
@@ -9695,8 +9342,7 @@
   }
 
   void test_parseUnaryExpression_increment_super_propertyAccess() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "++super.x");
+    PrefixExpression expression = parse4("parseUnaryExpression", "++super.x");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.PLUS_PLUS);
     expect(expression.operand, isNotNull);
@@ -9706,48 +9352,42 @@
   }
 
   void test_parseUnaryExpression_minus_normal() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "-x");
+    PrefixExpression expression = parse4("parseUnaryExpression", "-x");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.MINUS);
     expect(expression.operand, isNotNull);
   }
 
   void test_parseUnaryExpression_minus_super() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "-super");
+    PrefixExpression expression = parse4("parseUnaryExpression", "-super");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.MINUS);
     expect(expression.operand, isNotNull);
   }
 
   void test_parseUnaryExpression_not_normal() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "!x");
+    PrefixExpression expression = parse4("parseUnaryExpression", "!x");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.BANG);
     expect(expression.operand, isNotNull);
   }
 
   void test_parseUnaryExpression_not_super() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "!super");
+    PrefixExpression expression = parse4("parseUnaryExpression", "!super");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.BANG);
     expect(expression.operand, isNotNull);
   }
 
   void test_parseUnaryExpression_tilda_normal() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "~x");
+    PrefixExpression expression = parse4("parseUnaryExpression", "~x");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.TILDE);
     expect(expression.operand, isNotNull);
   }
 
   void test_parseUnaryExpression_tilda_super() {
-    PrefixExpression expression =
-        ParserTestCase.parse4("parseUnaryExpression", "~super");
+    PrefixExpression expression = parse4("parseUnaryExpression", "~super");
     expect(expression.operator, isNotNull);
     expect(expression.operator.type, TokenType.TILDE);
     expect(expression.operand, isNotNull);
@@ -9755,95 +9395,86 @@
 
   void test_parseVariableDeclaration_equals() {
     VariableDeclaration declaration =
-        ParserTestCase.parse4("parseVariableDeclaration", "a = b");
+        parse4("parseVariableDeclaration", "a = b");
     expect(declaration.name, isNotNull);
     expect(declaration.equals, isNotNull);
     expect(declaration.initializer, isNotNull);
   }
 
   void test_parseVariableDeclaration_noEquals() {
-    VariableDeclaration declaration =
-        ParserTestCase.parse4("parseVariableDeclaration", "a");
+    VariableDeclaration declaration = parse4("parseVariableDeclaration", "a");
     expect(declaration.name, isNotNull);
     expect(declaration.equals, isNull);
     expect(declaration.initializer, isNull);
   }
 
   void test_parseVariableDeclarationListAfterMetadata_const_noType() {
-    VariableDeclarationList declarationList = ParserTestCase.parse(
-        "parseVariableDeclarationListAfterMetadata", <Object>[
-      emptyCommentAndMetadata()
-    ], "const a");
+    VariableDeclarationList declarationList = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()], "const a");
     expect(declarationList.keyword, isNotNull);
     expect(declarationList.type, isNull);
     expect(declarationList.variables, hasLength(1));
   }
 
   void test_parseVariableDeclarationListAfterMetadata_const_type() {
-    VariableDeclarationList declarationList = ParserTestCase.parse(
-        "parseVariableDeclarationListAfterMetadata", <Object>[
-      emptyCommentAndMetadata()
-    ], "const A a");
+    VariableDeclarationList declarationList = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()], "const A a");
     expect(declarationList.keyword, isNotNull);
     expect(declarationList.type, isNotNull);
     expect(declarationList.variables, hasLength(1));
   }
 
   void test_parseVariableDeclarationListAfterMetadata_final_noType() {
-    VariableDeclarationList declarationList = ParserTestCase.parse(
-        "parseVariableDeclarationListAfterMetadata", <Object>[
-      emptyCommentAndMetadata()
-    ], "final a");
+    VariableDeclarationList declarationList = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()], "final a");
     expect(declarationList.keyword, isNotNull);
     expect(declarationList.type, isNull);
     expect(declarationList.variables, hasLength(1));
   }
 
   void test_parseVariableDeclarationListAfterMetadata_final_type() {
-    VariableDeclarationList declarationList = ParserTestCase.parse(
-        "parseVariableDeclarationListAfterMetadata", <Object>[
-      emptyCommentAndMetadata()
-    ], "final A a");
+    VariableDeclarationList declarationList = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()], "final A a");
     expect(declarationList.keyword, isNotNull);
     expect(declarationList.type, isNotNull);
     expect(declarationList.variables, hasLength(1));
   }
 
   void test_parseVariableDeclarationListAfterMetadata_type_multiple() {
-    VariableDeclarationList declarationList = ParserTestCase.parse(
-        "parseVariableDeclarationListAfterMetadata", <Object>[
-      emptyCommentAndMetadata()
-    ], "A a, b, c");
+    VariableDeclarationList declarationList = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()], "A a, b, c");
     expect(declarationList.keyword, isNull);
     expect(declarationList.type, isNotNull);
     expect(declarationList.variables, hasLength(3));
   }
 
   void test_parseVariableDeclarationListAfterMetadata_type_single() {
-    VariableDeclarationList declarationList = ParserTestCase.parse(
-        "parseVariableDeclarationListAfterMetadata", <Object>[
-      emptyCommentAndMetadata()
-    ], "A a");
+    VariableDeclarationList declarationList = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()], "A a");
     expect(declarationList.keyword, isNull);
     expect(declarationList.type, isNotNull);
     expect(declarationList.variables, hasLength(1));
   }
 
   void test_parseVariableDeclarationListAfterMetadata_var_multiple() {
-    VariableDeclarationList declarationList = ParserTestCase.parse(
-        "parseVariableDeclarationListAfterMetadata", <Object>[
-      emptyCommentAndMetadata()
-    ], "var a, b, c");
+    VariableDeclarationList declarationList = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()], "var a, b, c");
     expect(declarationList.keyword, isNotNull);
     expect(declarationList.type, isNull);
     expect(declarationList.variables, hasLength(3));
   }
 
   void test_parseVariableDeclarationListAfterMetadata_var_single() {
-    VariableDeclarationList declarationList = ParserTestCase.parse(
-        "parseVariableDeclarationListAfterMetadata", <Object>[
-      emptyCommentAndMetadata()
-    ], "var a");
+    VariableDeclarationList declarationList = parse(
+        "parseVariableDeclarationListAfterMetadata",
+        <Object>[emptyCommentAndMetadata()], "var a");
     expect(declarationList.keyword, isNotNull);
     expect(declarationList.type, isNull);
     expect(declarationList.variables, hasLength(1));
@@ -9851,7 +9482,7 @@
 
   void test_parseVariableDeclarationListAfterType_type() {
     TypeName type = new TypeName(new SimpleIdentifier(null), null);
-    VariableDeclarationList declarationList = ParserTestCase.parse(
+    VariableDeclarationList declarationList = parse(
         "parseVariableDeclarationListAfterType", <Object>[
       emptyCommentAndMetadata(),
       null,
@@ -9864,7 +9495,7 @@
 
   void test_parseVariableDeclarationListAfterType_var() {
     Token keyword = TokenFactory.tokenFromKeyword(Keyword.VAR);
-    VariableDeclarationList declarationList = ParserTestCase.parse(
+    VariableDeclarationList declarationList = parse(
         "parseVariableDeclarationListAfterType", <Object>[
       emptyCommentAndMetadata(),
       keyword,
@@ -9876,10 +9507,9 @@
   }
 
   void test_parseVariableDeclarationStatementAfterMetadata_multiple() {
-    VariableDeclarationStatement statement = ParserTestCase.parse(
-        "parseVariableDeclarationStatementAfterMetadata", <Object>[
-      emptyCommentAndMetadata()
-    ], "var x, y, z;");
+    VariableDeclarationStatement statement = parse(
+        "parseVariableDeclarationStatementAfterMetadata",
+        <Object>[emptyCommentAndMetadata()], "var x, y, z;");
     expect(statement.semicolon, isNotNull);
     VariableDeclarationList variableList = statement.variables;
     expect(variableList, isNotNull);
@@ -9887,10 +9517,9 @@
   }
 
   void test_parseVariableDeclarationStatementAfterMetadata_single() {
-    VariableDeclarationStatement statement = ParserTestCase.parse(
-        "parseVariableDeclarationStatementAfterMetadata", <Object>[
-      emptyCommentAndMetadata()
-    ], "var x;");
+    VariableDeclarationStatement statement = parse(
+        "parseVariableDeclarationStatementAfterMetadata",
+        <Object>[emptyCommentAndMetadata()], "var x;");
     expect(statement.semicolon, isNotNull);
     VariableDeclarationList variableList = statement.variables;
     expect(variableList, isNotNull);
@@ -9898,8 +9527,7 @@
   }
 
   void test_parseWhileStatement() {
-    WhileStatement statement =
-        ParserTestCase.parse4("parseWhileStatement", "while (x) {}");
+    WhileStatement statement = parse4("parseWhileStatement", "while (x) {}");
     expect(statement.whileKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.condition, isNotNull);
@@ -9908,21 +9536,19 @@
   }
 
   void test_parseWithClause_multiple() {
-    WithClause clause =
-        ParserTestCase.parse4("parseWithClause", "with A, B, C");
+    WithClause clause = parse4("parseWithClause", "with A, B, C");
     expect(clause.withKeyword, isNotNull);
     expect(clause.mixinTypes, hasLength(3));
   }
 
   void test_parseWithClause_single() {
-    WithClause clause = ParserTestCase.parse4("parseWithClause", "with M");
+    WithClause clause = parse4("parseWithClause", "with M");
     expect(clause.withKeyword, isNotNull);
     expect(clause.mixinTypes, hasLength(1));
   }
 
   void test_parseYieldStatement_each() {
-    YieldStatement statement =
-        ParserTestCase.parse4("parseYieldStatement", "yield* x;");
+    YieldStatement statement = parse4("parseYieldStatement", "yield* x;");
     expect(statement.yieldKeyword, isNotNull);
     expect(statement.star, isNotNull);
     expect(statement.expression, isNotNull);
@@ -9930,8 +9556,7 @@
   }
 
   void test_parseYieldStatement_normal() {
-    YieldStatement statement =
-        ParserTestCase.parse4("parseYieldStatement", "yield x;");
+    YieldStatement statement = parse4("parseYieldStatement", "yield x;");
     expect(statement.yieldKeyword, isNotNull);
     expect(statement.star, isNull);
     expect(statement.expression, isNotNull);
@@ -10076,8 +9701,7 @@
    */
   SimpleIdentifier _createSyntheticIdentifier() {
     GatheringErrorListener listener = new GatheringErrorListener();
-    return ParserTestCase.invokeParserMethod2(
-        "createSyntheticIdentifier", "", listener);
+    return invokeParserMethod2("createSyntheticIdentifier", "", listener);
   }
 
   /**
@@ -10090,8 +9714,7 @@
    */
   SimpleStringLiteral _createSyntheticStringLiteral() {
     GatheringErrorListener listener = new GatheringErrorListener();
-    return ParserTestCase.invokeParserMethod2(
-        "createSyntheticStringLiteral", "", listener);
+    return invokeParserMethod2("createSyntheticStringLiteral", "", listener);
   }
 
   /**
@@ -10104,7 +9727,7 @@
    */
   bool _isFunctionDeclaration(String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    return ParserTestCase.invokeParserMethod2(
+    return invokeParserMethod2(
         "isFunctionDeclaration", source, listener) as bool;
   }
 
@@ -10128,9 +9751,8 @@
     // Parse the source.
     //
     Parser parser = new Parser(null, listener);
-    return invokeParserMethodImpl(parser, "isFunctionExpression", <Object>[
-      tokenStream
-    ], tokenStream) as bool;
+    return invokeParserMethodImpl(parser, "isFunctionExpression",
+        <Object>[tokenStream], tokenStream) as bool;
   }
 
   /**
@@ -10143,7 +9765,7 @@
    */
   bool _isInitializedVariableDeclaration(String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    return ParserTestCase.invokeParserMethod2(
+    return invokeParserMethod2(
         "isInitializedVariableDeclaration", source, listener) as bool;
   }
 
@@ -10157,8 +9779,7 @@
    */
   bool _isSwitchMember(String source) {
     GatheringErrorListener listener = new GatheringErrorListener();
-    return ParserTestCase.invokeParserMethod2(
-        "isSwitchMember", source, listener) as bool;
+    return invokeParserMethod2("isSwitchMember", source, listener) as bool;
   }
 
   /**
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 21bc357..539bf0d 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -272,9 +272,9 @@
       ElementFactory.classElement("SelectElement", elementType)
     ];
     htmlUnit.functions = <FunctionElement>[
-      ElementFactory.functionElement3("query", elementElement, <ClassElement>[
-        provider.stringType.element
-      ], ClassElementImpl.EMPTY_ARRAY)
+      ElementFactory.functionElement3("query", elementElement,
+          <ClassElement>[provider.stringType.element],
+          ClassElementImpl.EMPTY_ARRAY)
     ];
     TopLevelVariableElementImpl document = ElementFactory
         .topLevelVariableElement3(
@@ -293,9 +293,8 @@
     coreContext.setContents(mathSource, "");
     mathUnit.source = mathSource;
     FunctionElement cosElement = ElementFactory.functionElement3("cos",
-        provider.doubleType.element, <ClassElement>[
-      provider.numType.element
-    ], ClassElementImpl.EMPTY_ARRAY);
+        provider.doubleType.element, <ClassElement>[provider.numType.element],
+        ClassElementImpl.EMPTY_ARRAY);
     TopLevelVariableElement ln10Element = ElementFactory
         .topLevelVariableElement3("LN10", true, false, provider.doubleType);
     TopLevelVariableElement piElement = ElementFactory.topLevelVariableElement3(
@@ -311,13 +310,11 @@
     randomConstructor.parameters = <ParameterElement>[seedParam];
     randomElement.constructors = <ConstructorElement>[randomConstructor];
     FunctionElement sinElement = ElementFactory.functionElement3("sin",
-        provider.doubleType.element, <ClassElement>[
-      provider.numType.element
-    ], ClassElementImpl.EMPTY_ARRAY);
+        provider.doubleType.element, <ClassElement>[provider.numType.element],
+        ClassElementImpl.EMPTY_ARRAY);
     FunctionElement sqrtElement = ElementFactory.functionElement3("sqrt",
-        provider.doubleType.element, <ClassElement>[
-      provider.numType.element
-    ], ClassElementImpl.EMPTY_ARRAY);
+        provider.doubleType.element, <ClassElement>[provider.numType.element],
+        ClassElementImpl.EMPTY_ARRAY);
     mathUnit.accessors = <PropertyAccessorElement>[
       ln10Element.getter,
       piElement.getter
@@ -367,7 +364,8 @@
         currentOptions.generateSdkErrors != options.generateSdkErrors ||
         currentOptions.dart2jsHint != options.dart2jsHint ||
         (currentOptions.hint && !options.hint) ||
-        currentOptions.preserveComments != options.preserveComments;
+        currentOptions.preserveComments != options.preserveComments ||
+        currentOptions.enableStrictCallChecks != options.enableStrictCallChecks;
     if (needsRecompute) {
       fail(
           "Cannot set options that cause the sources to be reanalyzed in a test context");
@@ -1536,9 +1534,8 @@
         AstFactory.typeName(classA), constructorName);
     name.staticElement = constructor;
     InstanceCreationExpression creation = AstFactory.instanceCreationExpression(
-        Keyword.NEW, name, [
-      AstFactory.namedExpression2(parameterName, AstFactory.integer(0))
-    ]);
+        Keyword.NEW, name,
+        [AstFactory.namedExpression2(parameterName, AstFactory.integer(0))]);
     _resolveNode(creation);
     expect(creation.staticElement, same(constructor));
     expect((creation.argumentList.arguments[
@@ -4158,11 +4155,38 @@
     Source source = addSource(r'''
 main() {
   try {
+  } on String catch (exception) {
+  }
+}''');
+    resolve(source);
+    assertErrors(source, [HintCode.UNUSED_CATCH_CLAUSE]);
+    verify([source]);
+  }
+
+  void test_unusedLocalVariable_inCatch_exception_hasStack() {
+    enableUnusedLocalVariable = true;
+    Source source = addSource(r'''
+main() {
+  try {
+  } catch (exception, stack) {
+    print(stack);
+  }
+}''');
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_unusedLocalVariable_inCatch_exception_noOnClause() {
+    enableUnusedLocalVariable = true;
+    Source source = addSource(r'''
+main() {
+  try {
   } catch (exception) {
   }
 }''');
     resolve(source);
-    assertErrors(source);
+    assertNoErrors(source);
     verify([source]);
   }
 
@@ -4175,7 +4199,7 @@
   }
 }''');
     resolve(source);
-    assertErrors(source, [HintCode.UNUSED_LOCAL_VARIABLE]);
+    assertErrors(source, [HintCode.UNUSED_CATCH_STACK]);
     verify([source]);
   }
 
@@ -4658,9 +4682,8 @@
         _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
     expect(mapA.size, _numOfMembersInObject);
     expect(mapA.get(methodName), isNull);
-    _assertErrors(classA, [
-      StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD
-    ]);
+    _assertErrors(classA,
+        [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
   }
 
   void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
@@ -4705,9 +4728,8 @@
         _inheritanceManager.getMapOfMembersInheritedFromInterfaces(classA);
     expect(mapA.size, _numOfMembersInObject);
     expect(mapA.get(methodName), isNull);
-    _assertErrors(classA, [
-      StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD
-    ]);
+    _assertErrors(classA,
+        [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
   }
 
   void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
@@ -7626,7 +7648,9 @@
         continue;
       }
       if (!enableUnusedLocalVariable &&
-          errorCode == HintCode.UNUSED_LOCAL_VARIABLE) {
+          (errorCode == HintCode.UNUSED_CATCH_CLAUSE ||
+              errorCode == HintCode.UNUSED_CATCH_STACK ||
+              errorCode == HintCode.UNUSED_LOCAL_VARIABLE)) {
         continue;
       }
       errorListener.onError(error);
@@ -9547,6 +9571,50 @@
   Source testSource;
   CompilationUnit testUnit;
 
+  void test_FunctionExpressionInvocation_block() {
+    String code = r'''
+main() {
+  var foo = (() { return 1; })();
+}
+''';
+    _resolveTestUnit(code);
+    SimpleIdentifier identifier = _findIdentifier('foo');
+    VariableDeclaration declaration =
+        identifier.getAncestor((node) => node is VariableDeclaration);
+    expect(declaration.initializer.staticType.isDynamic, isTrue);
+    expect(declaration.initializer.propagatedType, isNull);
+  }
+
+  void test_FunctionExpressionInvocation_curried() {
+    String code = r'''
+typedef int F();
+F f() => null;
+main() {
+  var foo = f()();
+}
+''';
+    _resolveTestUnit(code);
+    SimpleIdentifier identifier = _findIdentifier('foo');
+    VariableDeclaration declaration =
+        identifier.getAncestor((node) => node is VariableDeclaration);
+    expect(declaration.initializer.staticType.name, 'int');
+    expect(declaration.initializer.propagatedType, isNull);
+  }
+
+  void test_FunctionExpressionInvocation_expression() {
+    String code = r'''
+main() {
+  var foo = (() => 1)();
+}
+''';
+    _resolveTestUnit(code);
+    SimpleIdentifier identifier = _findIdentifier('foo');
+    VariableDeclaration declaration =
+        identifier.getAncestor((node) => node is VariableDeclaration);
+    expect(declaration.initializer.staticType.name, 'int');
+    expect(declaration.initializer.propagatedType, isNull);
+  }
+
   void test_MethodInvocation_nameType_localVariable() {
     String code = r"""
 typedef Foo();
@@ -9655,6 +9723,126 @@
     _analyzer = _createAnalyzer();
   }
 
+  void test_flatten_derived() {
+    // class Derived<T> extends Future<T> { ... }
+    ClassElementImpl derivedClass =
+        ElementFactory.classElement2('Derived', ['T']);
+    derivedClass.supertype = _typeProvider.futureType
+        .substitute4([derivedClass.typeParameters[0].type]);
+    InterfaceType intType = _typeProvider.intType;
+    DartType dynamicType = _typeProvider.dynamicType;
+    InterfaceType derivedIntType = derivedClass.type.substitute4([intType]);
+    // flatten(Derived) = dynamic
+    InterfaceType derivedDynamicType =
+        derivedClass.type.substitute4([dynamicType]);
+    expect(_flatten(derivedDynamicType), dynamicType);
+    // flatten(Derived<int>) = int
+    expect(_flatten(derivedIntType), intType);
+    // flatten(Derived<Derived>) = Derived
+    expect(_flatten(derivedClass.type.substitute4([derivedDynamicType])),
+        derivedDynamicType);
+    // flatten(Derived<Derived<int>>) = Derived<int>
+    expect(_flatten(derivedClass.type.substitute4([derivedIntType])),
+        derivedIntType);
+  }
+
+  void test_flatten_inhibit_recursion() {
+    // class A extends B
+    // class B extends A
+    ClassElementImpl classA = ElementFactory.classElement2('A', []);
+    ClassElementImpl classB = ElementFactory.classElement2('B', []);
+    classA.supertype = classB.type;
+    classB.supertype = classA.type;
+    // flatten(A) = A and flatten(B) = B, since neither class contains Future
+    // in its class hierarchy.  Even though there is a loop in the class
+    // hierarchy, flatten() should terminate.
+    expect(_flatten(classA.type), classA.type);
+    expect(_flatten(classB.type), classB.type);
+  }
+
+  void test_flatten_related_derived_types() {
+    InterfaceType intType = _typeProvider.intType;
+    InterfaceType numType = _typeProvider.numType;
+    // class Derived<T> extends Future<T>
+    ClassElementImpl derivedClass =
+        ElementFactory.classElement2('Derived', ['T']);
+    derivedClass.supertype = _typeProvider.futureType
+        .substitute4([derivedClass.typeParameters[0].type]);
+    InterfaceType derivedType = derivedClass.type;
+    // class A extends Derived<int> implements Derived<num> { ... }
+    ClassElementImpl classA =
+        ElementFactory.classElement('A', derivedType.substitute4([intType]));
+    classA.interfaces = <InterfaceType>[derivedType.substitute4([numType])];
+    // class B extends Future<num> implements Future<int> { ... }
+    ClassElementImpl classB =
+        ElementFactory.classElement('B', derivedType.substitute4([numType]));
+    classB.interfaces = <InterfaceType>[derivedType.substitute4([intType])];
+    // flatten(A) = flatten(B) = int, since int is more specific than num.
+    // The code in flatten() that inhibits infinite recursion shouldn't be
+    // fooled by the fact that Derived appears twice in the type hierarchy.
+    expect(_flatten(classA.type), intType);
+    expect(_flatten(classB.type), intType);
+  }
+
+  void test_flatten_related_types() {
+    InterfaceType futureType = _typeProvider.futureType;
+    InterfaceType intType = _typeProvider.intType;
+    InterfaceType numType = _typeProvider.numType;
+    // class A extends Future<int> implements Future<num> { ... }
+    ClassElementImpl classA =
+        ElementFactory.classElement('A', futureType.substitute4([intType]));
+    classA.interfaces = <InterfaceType>[futureType.substitute4([numType])];
+    // class B extends Future<num> implements Future<int> { ... }
+    ClassElementImpl classB =
+        ElementFactory.classElement('B', futureType.substitute4([numType]));
+    classB.interfaces = <InterfaceType>[futureType.substitute4([intType])];
+    // flatten(A) = flatten(B) = int, since int is more specific than num.
+    expect(_flatten(classA.type), intType);
+    expect(_flatten(classB.type), intType);
+  }
+
+  void test_flatten_simple() {
+    InterfaceType intType = _typeProvider.intType;
+    DartType dynamicType = _typeProvider.dynamicType;
+    InterfaceType futureDynamicType = _typeProvider.futureDynamicType;
+    InterfaceType futureIntType =
+        _typeProvider.futureType.substitute4([intType]);
+    InterfaceType futureFutureDynamicType =
+        _typeProvider.futureType.substitute4([futureDynamicType]);
+    InterfaceType futureFutureIntType =
+        _typeProvider.futureType.substitute4([futureIntType]);
+    // flatten(int) = int
+    expect(_flatten(intType), intType);
+    // flatten(dynamic) = dynamic
+    expect(_flatten(dynamicType), dynamicType);
+    // flatten(Future) = dynamic
+    expect(_flatten(futureDynamicType), dynamicType);
+    // flatten(Future<int>) = int
+    expect(_flatten(futureIntType), intType);
+    // flatten(Future<Future>) = dynamic
+    expect(_flatten(futureFutureDynamicType), dynamicType);
+    // flatten(Future<Future<int>>) = int
+    expect(_flatten(futureFutureIntType), intType);
+  }
+
+  void test_flatten_unrelated_types() {
+    InterfaceType futureType = _typeProvider.futureType;
+    InterfaceType intType = _typeProvider.intType;
+    InterfaceType stringType = _typeProvider.stringType;
+    // class A extends Future<int> implements Future<String> { ... }
+    ClassElementImpl classA =
+        ElementFactory.classElement('A', futureType.substitute4([intType]));
+    classA.interfaces = <InterfaceType>[futureType.substitute4([stringType])];
+    // class B extends Future<String> implements Future<int> { ... }
+    ClassElementImpl classB =
+        ElementFactory.classElement('B', futureType.substitute4([stringType]));
+    classB.interfaces = <InterfaceType>[futureType.substitute4([intType])];
+    // flatten(A) = A and flatten(B) = B, since neither string nor int is more
+    // specific than the other.
+    expect(_flatten(classA.type), classA.type);
+    expect(_flatten(classB.type), classB.type);
+  }
+
   void test_visitAdjacentStrings() {
     // "a" "b"
     Expression node = AstFactory
@@ -9994,8 +10182,10 @@
     _analyze5(p1);
     _analyze5(p2);
     DartType resultType = _analyze(node);
-    _assertFunctionType(dynamicType,
-        <DartType>[dynamicType, dynamicType], null, null, resultType);
+    _assertFunctionType(dynamicType, <DartType>[
+      dynamicType,
+      dynamicType
+    ], null, null, resultType);
     _listener.assertNoErrors();
   }
 
@@ -10029,8 +10219,8 @@
     DartType resultType = _analyze(node);
     Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
     expectedNamedTypes["p2"] = dynamicType;
-    _assertFunctionType(dynamicType,
-        <DartType>[dynamicType], null, expectedNamedTypes, resultType);
+    _assertFunctionType(dynamicType, <DartType>[dynamicType], null,
+        expectedNamedTypes, resultType);
     _listener.assertNoErrors();
   }
 
@@ -10049,8 +10239,8 @@
     DartType resultType = _analyze(node);
     Map<String, DartType> expectedNamedTypes = new HashMap<String, DartType>();
     expectedNamedTypes["p2"] = dynamicType;
-    _assertFunctionType(_typeProvider.intType,
-        <DartType>[dynamicType], null, expectedNamedTypes, resultType);
+    _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType], null,
+        expectedNamedTypes, resultType);
     _listener.assertNoErrors();
   }
 
@@ -10068,8 +10258,8 @@
     _analyze5(p1);
     _analyze5(p2);
     DartType resultType = _analyze(node);
-    _assertFunctionType(dynamicType,
-        <DartType>[dynamicType], <DartType>[dynamicType], null, resultType);
+    _assertFunctionType(dynamicType, <DartType>[dynamicType],
+        <DartType>[dynamicType], null, resultType);
     _listener.assertNoErrors();
   }
 
@@ -10087,8 +10277,8 @@
     _analyze5(p1);
     _analyze5(p2);
     DartType resultType = _analyze(node);
-    _assertFunctionType(_typeProvider.intType,
-        <DartType>[dynamicType], <DartType>[dynamicType], null, resultType);
+    _assertFunctionType(_typeProvider.intType, <DartType>[dynamicType],
+        <DartType>[dynamicType], null, resultType);
     _listener.assertNoErrors();
   }
 
@@ -10107,8 +10297,10 @@
     _analyze5(p1);
     _analyze5(p2);
     DartType resultType = _analyze(node);
-    _assertFunctionType(dynamicType,
-        null, <DartType>[dynamicType, dynamicType], null, resultType);
+    _assertFunctionType(dynamicType, null, <DartType>[
+      dynamicType,
+      dynamicType
+    ], null, resultType);
     _listener.assertNoErrors();
   }
 
@@ -10211,9 +10403,8 @@
     constructor.type = constructorType;
     classElement.constructors = <ConstructorElement>[constructor];
     InstanceCreationExpression node = AstFactory.instanceCreationExpression2(
-        null, AstFactory.typeName(classElement), [
-      AstFactory.identifier3(constructorName)
-    ]);
+        null, AstFactory.typeName(classElement),
+        [AstFactory.identifier3(constructorName)]);
     node.staticElement = constructor;
     expect(_analyze(node), same(classElement.type));
     _listener.assertNoErrors();
@@ -10303,10 +10494,9 @@
     // {}
     Expression node = AstFactory.mapLiteral2();
     DartType resultType = _analyze(node);
-    _assertType2(_typeProvider.mapType.substitute4(<DartType>[
-      _typeProvider.dynamicType,
-      _typeProvider.dynamicType
-    ]), resultType);
+    _assertType2(_typeProvider.mapType.substitute4(
+            <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
+        resultType);
     _listener.assertNoErrors();
   }
 
@@ -10315,10 +10505,9 @@
     Expression node = AstFactory
         .mapLiteral2([AstFactory.mapLiteralEntry("k", _resolvedInteger(0))]);
     DartType resultType = _analyze(node);
-    _assertType2(_typeProvider.mapType.substitute4(<DartType>[
-      _typeProvider.dynamicType,
-      _typeProvider.dynamicType
-    ]), resultType);
+    _assertType2(_typeProvider.mapType.substitute4(
+            <DartType>[_typeProvider.dynamicType, _typeProvider.dynamicType]),
+        resultType);
     _listener.assertNoErrors();
   }
 
@@ -10733,6 +10922,9 @@
     }
   }
 
+  DartType _flatten(DartType type) =>
+      StaticTypeAnalyzer.flattenFutures(_typeProvider, type);
+
   /**
    * Return an integer literal that has been resolved to the correct type.
    *
@@ -11306,7 +11498,7 @@
     try {
       manager.exitScope();
       fail("Expected IllegalStateException");
-    } on IllegalStateException catch (exception) {
+    } on IllegalStateException {
       // Expected
     }
   }
@@ -11318,7 +11510,7 @@
     try {
       manager.exitScope();
       fail("Expected IllegalStateException");
-    } on IllegalStateException catch (exception) {
+    } on IllegalStateException {
       // Expected
     }
   }
@@ -11332,7 +11524,7 @@
     try {
       manager.exitScope();
       fail("Expected IllegalStateException");
-    } on IllegalStateException catch (exception) {
+    } on IllegalStateException {
       // Expected
     }
   }
@@ -13032,8 +13224,7 @@
     _typeProvider = new TestTypeProvider();
     _visitor =
         new TypeResolverVisitor.con1(_library, librarySource, _typeProvider);
-    _implicitConstructorBuilder = new ImplicitConstructorBuilder(librarySource,
-        _library.libraryElement, _library.libraryScope, _typeProvider,
+    _implicitConstructorBuilder = new ImplicitConstructorBuilder(_listener,
         (ClassElement classElement, ClassElement superclassElement,
             void computation()) {
       // For these tests, we assume the classes for which implicit
@@ -13195,7 +13386,7 @@
     ClassElement classM = ElementFactory.classElement2('M', []);
     WithClause withClause =
         AstFactory.withClause([AstFactory.typeName(classM, [])]);
-    ClassElement classC = ElementFactory.classElement2('C', []);
+    ClassElement classC = ElementFactory.classTypeAlias2('C', []);
     ClassTypeAlias alias = AstFactory.classTypeAlias(
         'C', null, null, AstFactory.typeName(classB, []), withClause, null);
     alias.name.staticElement = classC;
@@ -13226,7 +13417,7 @@
     ClassElement classM = ElementFactory.classElement2('M', []);
     WithClause withClause =
         AstFactory.withClause([AstFactory.typeName(classM, [])]);
-    ClassElement classC = ElementFactory.classElement2('C', []);
+    ClassElement classC = ElementFactory.classTypeAlias2('C', []);
     ClassTypeAlias alias = AstFactory.classTypeAlias(
         'C', null, null, AstFactory.typeName(classB, []), withClause, null);
     alias.name.staticElement = classC;
@@ -13257,7 +13448,7 @@
     ClassElement classM = ElementFactory.classElement2('M', []);
     WithClause withClause =
         AstFactory.withClause([AstFactory.typeName(classM, [])]);
-    ClassElement classC = ElementFactory.classElement2('C', []);
+    ClassElement classC = ElementFactory.classTypeAlias2('C', []);
     ClassTypeAlias alias = AstFactory.classTypeAlias(
         'C', null, null, AstFactory.typeName(classB, []), withClause, null);
     alias.name.staticElement = classC;
@@ -13440,7 +13631,9 @@
       }
     }
     node.accept(_visitor);
-    node.accept(_implicitConstructorBuilder);
+    if (node is Declaration) {
+      node.element.accept(_implicitConstructorBuilder);
+    }
   }
 }
 
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index fc712ce..019c07e 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -4,6 +4,7 @@
 
 library engine.static_type_warning_code_test;
 
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:unittest/unittest.dart';
@@ -344,6 +345,16 @@
     verify([source]);
   }
 
+  void test_invalidAssignment_functionExpressionInvocation() {
+    Source source = addSource('''
+main() {
+  String x = (() => 5)();
+}''');
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+    verify([source]);
+  }
+
   void test_invalidAssignment_instanceVariable() {
     Source source = addSource(r'''
 class A {
@@ -435,6 +446,36 @@
     assertErrors(source, [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
   }
 
+  void test_invocationOfNonFunction_localGenericFunction() {
+    // Objects having a specific function type may be invoked, but objects
+    // having type Function may not, because type Function lacks a call method
+    // (this is because it is impossible to know what signature the call should
+    // have).
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableStrictCallChecks = true;
+    resetWithOptions(options);
+    Source source = addSource('''
+f(Function f) {
+  return f();
+}''');
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
+    verify([source]);
+  }
+
+  void test_invocationOfNonFunction_localObject() {
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableStrictCallChecks = true;
+    resetWithOptions(options);
+    Source source = addSource('''
+f(Object o) {
+  return o();
+}''');
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION]);
+    verify([source]);
+  }
+
   void test_invocationOfNonFunction_localVariable() {
     Source source = addSource(r'''
 f() {
@@ -1289,6 +1330,35 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
   }
 
+  void test_undefinedGetter_generic_function_call() {
+    // Objects having a specific function type have a call() method, but
+    // objects having type Function do not (this is because it is impossible to
+    // know what signature the call should have).
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableStrictCallChecks = true;
+    resetWithOptions(options);
+    Source source = addSource('''
+f(Function f) {
+  return f.call;
+}
+''');
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
+  void test_undefinedGetter_object_call() {
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableStrictCallChecks = true;
+    resetWithOptions(options);
+    Source source = addSource('''
+f(Object o) {
+  return o.call;
+}
+''');
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
   void test_undefinedGetter_proxy_annotation_fakeProxy() {
     Source source = addSource(r'''
 library L;
@@ -1387,6 +1457,22 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
   }
 
+  void test_undefinedMethod_generic_function_call() {
+    // Objects having a specific function type have a call() method, but
+    // objects having type Function do not (this is because it is impossible to
+    // know what signature the call should have).
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableStrictCallChecks = true;
+    resetWithOptions(options);
+    Source source = addSource('''
+f(Function f) {
+  f.call();
+}
+''');
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
+
   void test_undefinedMethod_ignoreTypePropagation() {
     Source source = addSource(r'''
 class A {}
@@ -1403,6 +1489,19 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
   }
 
+  void test_undefinedMethod_object_call() {
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.enableStrictCallChecks = true;
+    resetWithOptions(options);
+    Source source = addSource('''
+f(Object o) {
+  o.call();
+}
+''');
+    resolve(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
+
   void test_undefinedMethod_private() {
     addNamedSource("/lib.dart", r'''
 library lib;
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index 06124d6..0ad381f 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -882,9 +882,8 @@
   var v;
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
     verify([source]);
   }
 
@@ -897,9 +896,8 @@
   get v => 0;
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
     verify([source]);
   }
 
@@ -912,9 +910,8 @@
   get v => 0;
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
     verify([source]);
   }
 
@@ -927,9 +924,8 @@
   get v => 0;
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
     verify([source]);
   }
 
@@ -943,9 +939,8 @@
   get v => 0;
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
     verify([source]);
   }
 
@@ -958,9 +953,8 @@
   get v => 0;
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
     verify([source]);
   }
 
@@ -973,9 +967,8 @@
   get v => 0;
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER]);
     verify([source]);
   }
 
@@ -1040,9 +1033,8 @@
   set v(x) {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER]);
     verify([source]);
   }
 
@@ -1055,9 +1047,8 @@
   static get x => 0;
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
     verify([source]);
   }
 
@@ -1070,9 +1061,8 @@
   static get x => 0;
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
     verify([source]);
   }
 
@@ -1083,9 +1073,8 @@
   set x(int p) {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]);
     verify([source]);
   }
 
@@ -1096,9 +1085,8 @@
   static set x(int p) {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]);
     verify([source]);
   }
 
@@ -1109,9 +1097,8 @@
   static set x(int p) {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]);
     verify([source]);
   }
 
@@ -1211,9 +1198,8 @@
   A() : x = 1 {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION]);
     verify([source]);
   }
 
@@ -1256,9 +1242,8 @@
   A() : x = 0 {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION]);
     verify([source]);
   }
 
@@ -1269,20 +1254,47 @@
   A(this.x) {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR]);
     verify([source]);
   }
 
-  void test_finalNotInitialized_inConstructor() {
+  void test_finalNotInitialized_inConstructor_1() {
     Source source = addSource(r'''
 class A {
   final int x;
   A() {}
 }''');
     resolve(source);
-    assertErrors(source, [StaticWarningCode.FINAL_NOT_INITIALIZED]);
+    assertErrors(
+        source, [StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1]);
+    verify([source]);
+  }
+
+  void test_finalNotInitialized_inConstructor_2() {
+    Source source = addSource(r'''
+class A {
+  final int a;
+  final int b;
+  A() {}
+}''');
+    resolve(source);
+    assertErrors(
+        source, [StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2]);
+    verify([source]);
+  }
+
+  void test_finalNotInitialized_inConstructor_3() {
+    Source source = addSource(r'''
+class A {
+  final int a;
+  final int b;
+  final int c;
+  A() {}
+}''');
+    resolve(source);
+    assertErrors(
+        source, [StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS]);
     verify([source]);
   }
 
@@ -1409,9 +1421,8 @@
 class C implements A, B {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
     verify([source]);
   }
 
@@ -1732,9 +1743,8 @@
   m([String a]) {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE]);
     verify([source]);
   }
 
@@ -1751,9 +1761,8 @@
   m([String n]) {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE]);
     verify([source]);
   }
 
@@ -1895,9 +1904,8 @@
 }
 ''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED]);
     verify([source]);
   }
 
@@ -1980,9 +1988,8 @@
   m({int p : 1}) {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED]);
     verify([source]);
   }
 
@@ -2189,9 +2196,8 @@
   set g(String v) {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE]);
     verify([source]);
   }
 
@@ -2204,9 +2210,8 @@
   String get g { return ''; }
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE]);
     verify([source]);
   }
 
@@ -2399,9 +2404,8 @@
 class C extends A {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR]);
     verify([source]);
   }
 
@@ -2415,9 +2419,8 @@
 }
 class B = A with M implements I;''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2430,9 +2433,8 @@
 abstract class A {}
 class B = A with M;''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2445,9 +2447,8 @@
 }
 class B = A with M;''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2462,9 +2463,8 @@
 }
 class E extends C implements D {}''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2476,9 +2476,8 @@
 class C implements I {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2490,9 +2489,8 @@
 class C extends A {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2504,9 +2502,8 @@
 class C implements I {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2518,9 +2515,8 @@
 class C extends A {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2536,9 +2532,8 @@
 class C implements A, B {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2549,9 +2544,8 @@
 abstract class B implements A { get g1 => 1; }
 class C extends Object with B {}''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
   }
 
   void test_nonAbstractClassInheritsAbstractMemberOne_mixinInherits_method() {
@@ -2561,9 +2555,8 @@
 abstract class B implements A { m1() => 1; }
 class C extends Object with B {}''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
   }
 
   void test_nonAbstractClassInheritsAbstractMemberOne_mixinInherits_setter() {
@@ -2573,9 +2566,8 @@
 abstract class B implements A { set s1(v) {} }
 class C extends Object with B {}''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
   }
 
   void test_nonAbstractClassInheritsAbstractMemberOne_setter_and_implicitSetter() {
@@ -2591,9 +2583,8 @@
   get field => 0;
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2605,9 +2596,8 @@
 class C implements I {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2619,9 +2609,8 @@
 class C extends A {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2637,9 +2626,8 @@
 class C extends B {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2653,9 +2641,8 @@
   set v(_) {}
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2669,9 +2656,8 @@
   get v => 1;
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE]);
     verify([source]);
   }
 
@@ -2685,9 +2671,8 @@
 class C extends A {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE]);
     verify([source]);
   }
 
@@ -2700,9 +2685,8 @@
 class C extends A {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO]);
     verify([source]);
   }
 
@@ -2715,9 +2699,8 @@
 class C implements I {
 }''');
     resolve(source);
-    assertErrors(source, [
-      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO
-    ]);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO]);
     verify([source]);
   }
 
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index fec0743..d6a6ac5 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1589,7 +1589,7 @@
     try {
       BooleanArray.get(0, -1);
       fail("Expected ");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
@@ -1598,7 +1598,7 @@
     try {
       BooleanArray.get(0, 31);
       fail("Expected ");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
@@ -1614,7 +1614,7 @@
     try {
       BooleanArray.set(0, -1, true);
       fail("Expected ");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
@@ -1623,7 +1623,7 @@
     try {
       BooleanArray.set(0, 32, true);
       fail("Expected ");
-    } on RangeError catch (exception) {
+    } on RangeError {
       // Expected
     }
   }
@@ -1771,7 +1771,7 @@
     try {
       graph.findCycleContaining(null);
       fail("Expected IllegalArgumentException");
-    } on IllegalArgumentException catch (exception) {
+    } on IllegalArgumentException {
       // Expected
     }
   }
@@ -2790,7 +2790,7 @@
     try {
       new LineInfo(<int>[]);
       fail("Expected IllegalArgumentException");
-    } on IllegalArgumentException catch (exception) {
+    } on IllegalArgumentException {
       // Expected
     }
   }
@@ -2799,7 +2799,7 @@
     try {
       new LineInfo(null);
       fail("Expected IllegalArgumentException");
-    } on IllegalArgumentException catch (exception) {
+    } on IllegalArgumentException {
       // Expected
     }
   }
@@ -3194,19 +3194,19 @@
     try {
       iterator.key;
       fail("Expected NoSuchElementException");
-    } on NoSuchElementException catch (exception) {
+    } on NoSuchElementException {
       // Expected
     }
     try {
       iterator.value;
       fail("Expected NoSuchElementException");
-    } on NoSuchElementException catch (exception) {
+    } on NoSuchElementException {
       // Expected
     }
     try {
       iterator.value = "x";
       fail("Expected NoSuchElementException");
-    } on NoSuchElementException catch (exception) {
+    } on NoSuchElementException {
       // Expected
     }
   }
@@ -4151,19 +4151,19 @@
     try {
       iterator.key;
       fail("Expected NoSuchElementException");
-    } on NoSuchElementException catch (exception) {
+    } on NoSuchElementException {
       // Expected
     }
     try {
       iterator.value;
       fail("Expected NoSuchElementException");
-    } on NoSuchElementException catch (exception) {
+    } on NoSuchElementException {
       // Expected
     }
     try {
       iterator.value = "x";
       fail("Expected NoSuchElementException");
-    } on NoSuchElementException catch (exception) {
+    } on NoSuchElementException {
       // Expected
     }
     expect(iterator.moveNext(), isFalse);
@@ -4446,7 +4446,7 @@
     try {
       StringUtilities.printListOfQuotedNames(new List<String>(0));
       fail("Expected IllegalArgumentException");
-    } on IllegalArgumentException catch (exception) {
+    } on IllegalArgumentException {
       // Expected
     }
   }
@@ -4461,7 +4461,7 @@
     try {
       StringUtilities.printListOfQuotedNames(null);
       fail("Expected IllegalArgumentException");
-    } on IllegalArgumentException catch (exception) {
+    } on IllegalArgumentException {
       // Expected
     }
   }
@@ -4470,7 +4470,7 @@
     try {
       StringUtilities.printListOfQuotedNames(<String>["a"]);
       fail("Expected IllegalArgumentException");
-    } on IllegalArgumentException catch (exception) {
+    } on IllegalArgumentException {
       // Expected
     }
   }
diff --git a/pkg/analyzer/test/options_test.dart b/pkg/analyzer/test/options_test.dart
index fcff6ef..006fd6b 100644
--- a/pkg/analyzer/test/options_test.dart
+++ b/pkg/analyzer/test/options_test.dart
@@ -19,6 +19,7 @@
       expect(options.dartSdkPath, isNotNull);
       expect(options.disableHints, isFalse);
       expect(options.displayVersion, isFalse);
+      expect(options.enableStrictCallChecks, isFalse);
       expect(options.enableTypeChecks, isFalse);
       expect(options.ignoreUnrecognizedFlags, isFalse);
       expect(options.log, isFalse);
@@ -48,6 +49,12 @@
       expect(options.definedVariables['bar'], isNull);
     });
 
+    test('enable strict call checks', () {
+      CommandLineOptions options = CommandLineOptions.parse(
+          ['--dart-sdk', '.', '--enable-strict-call-checks', 'foo.dart']);
+      expect(options.enableStrictCallChecks, isTrue);
+    });
+
     test('enable type checks', () {
       CommandLineOptions options = CommandLineOptions
           .parse(['--dart-sdk', '.', '--enable_type_checks', 'foo.dart']);
diff --git a/pkg/analysis_server/test/plugin/plugin_impl_test.dart b/pkg/analyzer/test/plugin/plugin_impl_test.dart
similarity index 97%
rename from pkg/analysis_server/test/plugin/plugin_impl_test.dart
rename to pkg/analyzer/test/plugin/plugin_impl_test.dart
index 3d55dc5..12d6d04 100644
--- a/pkg/analysis_server/test/plugin/plugin_impl_test.dart
+++ b/pkg/analyzer/test/plugin/plugin_impl_test.dart
@@ -4,8 +4,8 @@
 
 library test.operation;
 
-import 'package:analysis_server/plugin/plugin.dart';
-import 'package:analysis_server/src/plugin/plugin_impl.dart';
+import 'package:analyzer/plugin/plugin.dart';
+import 'package:analyzer/src/plugin/plugin_impl.dart';
 import 'package:unittest/unittest.dart';
 
 main() {
diff --git a/pkg/analysis_server/test/plugin/test_all.dart b/pkg/analyzer/test/plugin/test_all.dart
similarity index 100%
rename from pkg/analysis_server/test/plugin/test_all.dart
rename to pkg/analyzer/test/plugin/test_all.dart
diff --git a/pkg/analyzer/test/reflective_tests.dart b/pkg/analyzer/test/reflective_tests.dart
index f421e6c..8180cf7 100644
--- a/pkg/analyzer/test/reflective_tests.dart
+++ b/pkg/analyzer/test/reflective_tests.dart
@@ -75,7 +75,7 @@
   var invocationResult = null;
   try {
     invocationResult = instanceMirror.invoke(symbol, []).reflectee;
-  } on NoSuchMethodError catch (e) {}
+  } on NoSuchMethodError {}
   if (invocationResult is Future) {
     return invocationResult;
   } else {
diff --git a/pkg/analyzer/test/services/data/cu_tests.data b/pkg/analyzer/test/services/data/cu_tests.data
deleted file mode 100644
index 0c5ae6b..0000000
--- a/pkg/analyzer/test/services/data/cu_tests.data
+++ /dev/null
@@ -1,323 +0,0 @@
->>>
-class
-A
-{
-}
-<<<
-class A {
-}
->>> dartbug.com/15876
-// fisk
-import "dart:typed_data";
-
-main() {
-  ByteData byteData = new ByteData(1);
-  print(byteData is ByteData);
-  print(byteData.elementSizeInBytes);
-}
-<<<
-// fisk
-import "dart:typed_data";
-
-main() {
-  ByteData byteData = new ByteData(1);
-  print(byteData is ByteData);
-  print(byteData.elementSizeInBytes);
-}
->>>
-/**
- * Y.
- */
-abstract class Y = Foo with Bar;
-<<<
-/**
- * Y.
- */
-abstract class Y = Foo with Bar;
->>>
-external void printToConsole(String line);
-<<<
-external void printToConsole(String line);
->>>
-void set foo(int bar) {
-}
-
-int get baz => null;
-<<<
-void set foo(int bar) {
-}
-
-int get baz => null;
->>>
-@deprecated
-library foo;
-
-@deprecated
-import 'dart:io';
-
-@deprecated
-export 'dart:io';
-
-class NoInline {
-  const NoInline();
-}
-
-@NoInline()
-int foo(@NoInline() bar) => bar + 42;
-
-class Z<@NoInline() Y> {
-
-}
-
-@NoInline()
-typedef void X(y);
-
-@NoInline()
-class Y = X with Z;
-
-@NoInline()
-class X {
-
-  @NoInline()
-  var _x;
-
-  @NoInline()
-  X.y() {
-    @NoInline()
-    const y = null;
-  }
-
-  @NoInline()
-  factory X(@NoInline() x) => null;
-
-  @NoInline()
-  int x() => null;
-}
-<<<
-@deprecated
-library foo;
-
-@deprecated
-import 'dart:io';
-
-@deprecated
-export 'dart:io';
-
-class NoInline {
-  const NoInline();
-}
-
-@NoInline()
-int foo(@NoInline() bar) => bar + 42;
-
-class Z<@NoInline() Y> {
-
-}
-
-@NoInline()
-typedef void X(y);
-
-@NoInline()
-class Y = X with Z;
-
-@NoInline()
-class X {
-
-  @NoInline()
-  var _x;
-
-  @NoInline()
-  X.y() {
-    @NoInline()
-    const y = null;
-  }
-
-  @NoInline()
-  factory X(@NoInline() x) => null;
-
-  @NoInline()
-  int x() => null;
-}
->>>
-var x = #foo;
-var y=#foo.bar.baz;
-<<<
-var x = #foo;
-var y = #foo.bar.baz;
->>>
-class Zounds extends Object native "Zapp" {
-}
-<<<
-class Zounds extends Object native "Zapp" {
-}
->>>
-@DomName('DatabaseCallback')
-@Experimental() // deprecated
-typedef void DatabaseCallback(database);
-<<<
-@DomName('DatabaseCallback')
-@Experimental() // deprecated
-typedef void DatabaseCallback(database);
->>> dartbug.com/16366
-import 'package:sdasdsasadasd/ass/sadasdas/sadasdsad_asdasd_asdsada_adsasdasdsa.dart';
-<<<
-import 'package:sdasdsasadasd/ass/sadasdas/sadasdsad_asdasd_asdsada_adsasdasdsa.dart';
->>>
-import 'package:sdasdsasadasd/ass/sadasdas/sadasdsad_asdasd_asdsada_adsasdasdsa.dart' as sass;
-<<<
-import 'package:sdasdsasadasd/ass/sadasdas/sadasdsad_asdasd_asdsada_adsasdasdsa.dart'
-    as sass;
->>> dartbug.com/15912
-abstract class ListBase<E> = Object with ListMixin<E>;
-<<<
-abstract class ListBase<E> = Object with ListMixin<E>;
->>> dartbug.com/15914
-Object get _globalState => null;
-
-set _globalState(Object val) {
-}
-
-void setX(x) {
-}
-<<<
-Object get _globalState => null;
-
-set _globalState(Object val) {
-}
-
-void setX(x) {
-}
->>> dartbug.com/16405
-class ContactImpulse {
-  List<double> normalImpulses = new List<double>(Settings.MAX_MANIFOLD_POINTS);
-  List<double> tangentImpulses = new List<double>(Settings.MAX_MANIFOLD_POINTS);
-
-  ContactImpulse();
-}
-<<<
-class ContactImpulse {
-  List<double> normalImpulses = new List<double>(Settings.MAX_MANIFOLD_POINTS);
-  List<double> tangentImpulses = new List<double>(Settings.MAX_MANIFOLD_POINTS);
-
-  ContactImpulse();
-}
->>> Empty class bodies may be on one line (or more)
-class A extends B { }
-<<<
-class A extends B {}
->>>
-class A extends B {
-
-}
-<<<
-class A extends B {
-
-}
->>> Single initializers can be on one line
-class Foo extends Bar {
-  final int b;
-  Foo(int a, this.b) : super(a);
-}
-<<<
-class Foo extends Bar {
-  final int b;
-  Foo(int a, this.b) : super(a);
-}
->>> (or not)
-class Foo extends Bar {
-  final int b;
-  Foo(int a, this.b)
-      : super(a);
-}
-<<<
-class Foo extends Bar {
-  final int b;
-  Foo(int a, this.b)
-      : super(a);
-}
->>> Multiple initializers are one per line
-class Foo extends Bar {
-  final int b;
-  Foo(int a, int b) : super(a), this.b = b == null ? 0 : b;
-}
-<<<
-class Foo extends Bar {
-  final int b;
-  Foo(int a, int b)
-      : super(a),
-        this.b = b == null ? 0 : b;
-}
->>> dartbug.com/17837
-@meta class Foo {
-  @meta String foo;
-  @meta int bar() => 42;
-}
-@meta
-class Bar {
-  @meta
-  String foo;
-  @meta
-  int bar() => 42;
-}
-<<<
-@meta class Foo {
-  @meta String foo;
-  @meta int bar() => 42;
-}
-@meta
-class Bar {
-  @meta
-  String foo;
-  @meta
-  int bar() => 42;
-}
->>>
-import 'a.dart' deferred as a;
-<<<
-import 'a.dart' deferred as a;
->>> Long parameters list, place the opening curly brace ({) on the same line
-class Foo {
-  method(int a012345678901234567890123456789, int b012345678901234567890123456)
-  {
-    print('42');
-  }
-}
-<<<
-class Foo {
-  method(int a012345678901234567890123456789,
-      int b012345678901234567890123456) {
-    print('42');
-  }
-}
->>> Long parameters list, this.field
-class A {
-  int a0123456789012345678901234;
-  int b0123456789012345678901234;
-  int c0123456789012345678901234;
-  int d0123456789012345678901234;
-  A(this.a0123456789012345678901234, this.b0123456789012345678901234, this.c0123456789012345678901234,
-                    this.d0123456789012345678901234);
-}
-<<<
-class A {
-  int a0123456789012345678901234;
-  int b0123456789012345678901234;
-  int c0123456789012345678901234;
-  int d0123456789012345678901234;
-  A(this.a0123456789012345678901234, this.b0123456789012345678901234,
-      this.c0123456789012345678901234, this.d0123456789012345678901234);
-}
->>>
-enum Foo { BAR, BAZ }
-<<<
-enum Foo {
-  BAR, BAZ
-}
->>>
-get x sync* {}
-<<<
-get x sync* {}
->>>
-get x async* {}
-<<<
-get x async* {}
\ No newline at end of file
diff --git a/pkg/analyzer/test/services/data/stmt_tests.data b/pkg/analyzer/test/services/data/stmt_tests.data
deleted file mode 100644
index ef98247..0000000
--- a/pkg/analyzer/test/services/data/stmt_tests.data
+++ /dev/null
@@ -1,263 +0,0 @@
->>>
-if (x &&
-    y) {
-  print('!');
-}
-<<<
-if (x && y) {
-  print('!');
-}
->>>
-for (var a=0; a<100; ++a) { print(a); }
-<<<
-for (var a = 0; a < 100; ++a) {
-  print(a);
-}
->>>
-for(
-var a=0;
-a<100; 
-++a)
-{ 
-print(a);
-}
-<<<
-for (var a = 0; a < 100; ++a) {
-  print(a);
-}
->>>
-for (x in xs) {
-  print(x);
-}
-<<<
-for (x in xs) {
-  print(x);
-}
->>>
-List<int> numbers = <int>[a012345678901234567890123456789, b012345678901234567890123456789, c012345678901234567890123456789];
-<<<
-List<int> numbers = <int>[
-    a012345678901234567890123456789,
-    b012345678901234567890123456789,
-    c012345678901234567890123456789];
->>>
-blah() {
-  print('blah blah blah blah blah blah blah blah blah blah blah blah blah blah $foo');
-}
-<<<<
-blah() {
-  print(
-      'blah blah blah blah blah blah blah blah blah blah blah blah blah blah $foo');
-}
->>>
-assert(false);
-<<<
-assert(false);
->>> dartbug.com/16384
-fish() => []..add(1)..add(2);
-<<<
-fish() => []
-    ..add(1)
-    ..add(2);
->>>
-fish() => []..add(1);
-<<<
-fish() => []..add(1);
->>> dartbug.com/16382
-var m = { };
-<<<
-var m = {};
->>>
-var m = {};
-<<<
-var m = {};
->>> Indent cases two spaces and case bodies four spaces (dartbug.com/16406)
-switches() {
-  switch (fruit) {
-    case 'apple':
-    print('delish');
-    break;
-
-    case 'durian':
-    print('stinky');
-    break;
-    default:
-  print('nevermind');
-  break;
-  }
-}
-<<<
-switches() {
-  switch (fruit) {
-    case 'apple':
-      print('delish');
-      break;
-
-    case 'durian':
-      print('stinky');
-      break;
-    default:
-      print('nevermind');
-      break;
-  }
-}
->>> dartbug.com/16383
-main() {
-  //foo
-}
-<<<
-main() {
-  //foo
-}
->>> dartbug.com/16379
-var x = new XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX();
-<<<
-var x =
-    new XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX();
->>>
-main() {
-  throw new FormatException("This is a long exception message that puts this over 80 columns.");
-}
-<<<
-main() {
-  throw new FormatException(
-      "This is a long exception message that puts this over 80 columns.");
-}
->>> Empty method bodies may be on a single line (or more)
-void main() { }
-<<<
-void main() {}
->>>
-void main() {
-
-}
-<<<
-void main() {
-
-}
->>> Decls with initializers get their own lines (dartbug.com/16849)
-var x, y;
-<<<
-var x, y;
->>>
-var x = 3, y = 4;
-<<<
-var x = 3,
-    y = 4;
->>>
-var x = 2, y;
-<<<
-var x = 2,
-    y;
->>> dartbug.com/16810 [Note: transforms are enabled]
-void f() {
-  var a;;;
-}
-<<<
-void f() {
-  var a;
-}
->>>
-while (true);
-<<<
-while (true);
->>>
-for ( ; ; ) {
-  print('!');
-}
-<<<
-for ( ; ; ) {
-  print('!');
-}
->>>
-main() {
-  var zero = 0;
-  if (0 == 0) {
-    zero = 0;
-  } else if (0 == 1) {
-    zero = 1;
-  } else if (0 == 2) {
-    zero = 2;
-  }
-  print(0);
-}
-<<<
-main() {
-  var zero = 0;
-  if (0 == 0) {
-    zero = 0;
-  } else if (0 == 1) {
-    zero = 1;
-  } else if (0 == 2) {
-    zero = 2;
-  }
-  print(0);
-}
->>>
-main() {
-  printNumbers(a, b) {}
-  printNumbers(00000000000000000000000000000000000000000000000000000000000, 111);
-}
-<<<
-main() {
-  printNumbers(a, b) {}
-  printNumbers(
-      00000000000000000000000000000000000000000000000000000000000,
-      111);
-}
->>>
-foo() async => 42;
-<<<
-foo() async => 42;
->>>
-main() async {
-  await window.animationFrame;
-}
-<<<
-main() async {
-  await window.animationFrame;
-}
->>>
-main() async* {
-  await window.animationFrame;
-}
-<<<
-main() async* {
-  await window.animationFrame;
-}
->>>
-foo() async* {
-  var elements = await _post('elements', by);
-  int i = 0;
-  for (var element in elements) {
-    yield new WebElement._(driver, element['ELEMENT'], this, by, i);
-    i++;
-  }
-}
-<<<
-foo() async* {
-  var elements = await _post('elements', by);
-  int i = 0;
-  for (var element in elements) {
-    yield new WebElement._(driver, element['ELEMENT'], this, by, i);
-    i++;
-  }
-}
->>>
-b06a() async { await for (var o in st) {} } 
-<<<
-b06a() async {
-  await for (var o in st) {}
-}
->>>
-b07a() sync* { yield 0; }
-<<<
-b07a() sync* {
-  yield 0;
-}
->>>
-b08a() sync* { yield* []; } 
-<<<
-b08a() sync* {
-  yield* [];
-}
diff --git a/pkg/analyzer/test/services/data/style_guide_tests.data b/pkg/analyzer/test/services/data/style_guide_tests.data
deleted file mode 100644
index 7c29e6c..0000000
--- a/pkg/analyzer/test/services/data/style_guide_tests.data
+++ /dev/null
@@ -1,238 +0,0 @@
->>> DO use ; instead of {} for empty constructor bodies
-class Point {
-  int x, y;
-  Point(this.x, this.y) {}
-}
-<<<
-class Point {
-  int x, y;
-  Point(this.x, this.y);
-}
->>> DO indent block bodies two spaces.
-hi() {
-if (condition) { print('hi'); }
-}
-<<<
-hi() {
-  if (condition) {
-    print('hi');
-  }
-}
->>> DON'T indent lines that are continued with a function expression.
-var callback = new Future.delayed(const Duration(seconds: 1), () {
-      print('I am a callback');
-    });
-<<<
-var callback = new Future.delayed(const Duration(seconds: 1), () {
-  print('I am a callback');
-});
->>> DO place the opening curly brace ({) on the same line as what it follows.
-class Foo {
-  method() 
-  {
-    if (true) 
-    {
-      print('true');
-    } else {
-      print('false');
-    }
-  }
-}
-<<<
-class Foo {
-  method() {
-    if (true) {
-      print('true');
-    } else {
-      print('false');
-    }
-  }
-}
->>> DO use curly braces for all flow control structures.
-flow() {
-  if (true) print('sanity');
-  else
-    print('opposite day!');
-}
-<<<
-flow() {
-  if (true) {
-    print('sanity');
-  } else {
-    print('opposite day!');
-  }
-}
->>> ... short if statements with no else may omit the braces ...
-except() {
-  if (arg == null) return defaultValue;
-}
-<<<
-except() {
-  if (arg == null) return defaultValue;
-}
->>> DO indent switch cases two spaces and case bodies four spaces
-switches() {
-  switch (fruit) {
-    case 'apple':
-    print('delish');
-    break;
-
-    case 'durian':
-    print('stinky');
-    break;
-  }
-}
-<<<
-switches() {
-  switch (fruit) {
-    case 'apple':
-      print('delish');
-      break;
-
-    case 'durian':
-      print('stinky');
-      break;
-  }
-}
->>> DO use spaces around binary and ternary operators, etc...
-spaces() {
-  a=1+2/(3* - b);
-  c= ! condition==a>b;
-  d= condition?b:object.method(a,b,c);
-  if (obj is !SomeType) print('not SomeType');
-}
-<<<
-spaces() {
-  a = 1 + 2 / (3 * -b);
-  c = !condition == a > b;
-  d = condition ? b : object.method(a, b, c);
-  if (obj is! SomeType) print('not SomeType');
-}
->>> DO place spaces around in, and after each ; in a loop.
-loop() {
-  for (var i = 0;i<100;i++) {
-    print(i);
-  }
-  for (final item in  collection) {
-    print(item);
-  }
-}
-<<<
-loop() {
-  for (var i = 0; i < 100; i++) {
-    print(i);
-  }
-  for (final item in collection) {
-    print(item);
-  }
-}
->>> DO use a space after flow-control keywords.
-flow() {
-  while(foo) {
-    print(foo);
-  }
-
-  try{
-    flow();
-  }catch(e) {
-    print(e);
-  }
-}
-<<<
-flow() {
-  while (foo) {
-    print(foo);
-  }
-
-  try {
-    flow();
-  } catch (e) {
-    print(e);
-  }
-}
->>> DON'T use a space after (, [, and {, or before ), ], and }.
-spaces() {
-  var numbers = <int> [ 1, 2,( 3+4 ) ];
-  var mapLiteral = <int, int> {};
-}
-<<<
-spaces() {
-  var numbers = <int>[1, 2, (3 + 4)];
-  var mapLiteral = <int, int>{};
-}
->>> DO use a space before { in function and method bodies.
-getEmptyFn(a){
-  return (){};
-}
-<<<
-getEmptyFn(a) {
-  return () {};
-}
->>> DO format constructor initialization lists with each field on its own line.
-class MyClass {
-  var firstField, secondField, thirdField;
-  MyClass() : firstField = "some value", secondField = "another",
-        thirdField = "last";
-}
-<<<
-class MyClass {
-  var firstField, secondField, thirdField;
-  MyClass()
-      : firstField = "some value",
-        secondField = "another",
-        thirdField = "last";
-}
->>> DO format constructor initialization lists with each field on its own line.
-class MyClass {
-  MyClass(looooooooooooooonA, looooooooooooooonB) : super(looooooooooooooonA, looooooooooooooonB);
-  MyClass(looooooooooooooonA, looooooooooooooonB) : this(looooooooooooooonA, looooooooooooooonB);
-}
-<<<
-class MyClass {
-  MyClass(looooooooooooooonA, looooooooooooooonB)
-      : super(looooooooooooooonA, looooooooooooooonB);
-  MyClass(looooooooooooooonA, looooooooooooooonB)
-      : this(looooooooooooooonA, looooooooooooooonB);
-}
->>> DO use a space after : in named parameters and named arguments.
-class ListBox {
-  bool showScrollbars;
-
-  ListBox({this.showScrollbars: false});
-}
-
-main() {
-  new ListBox(showScrollbars:true);
-  new ListBox(showScrollbars : true);
-}
-<<<
-class ListBox {
-  bool showScrollbars;
-
-  ListBox({this.showScrollbars: false});
-}
-
-main() {
-  new ListBox(showScrollbars: true);
-  new ListBox(showScrollbars: true);
-}
->>> DO use a spaces around = in optional positional parameters.
-class HttpServer {
-  static Future<HttpServer> listen([int port=80]) {
-    print('hi!');
-  }
-}
-<<<
-class HttpServer {
-  static Future<HttpServer> listen([int port = 80]) {
-    print('hi!');
-  }
-}
->>> DO use four spaces for method cascades
-var list = new List()
-  ..addAll([1, 2, 3])
-  ..addAll([4, 5, 6]);
-<<<
-var list = new List()
-    ..addAll([1, 2, 3])
-    ..addAll([4, 5, 6]);
diff --git a/pkg/analyzer/test/services/data/wrap_tests.data b/pkg/analyzer/test/services/data/wrap_tests.data
deleted file mode 100644
index 87bcfab..0000000
--- a/pkg/analyzer/test/services/data/wrap_tests.data
+++ /dev/null
@@ -1,155 +0,0 @@
->>> list literal
-main() {
-  List<String> values = <String>[a0123456789012345, b0123456789012345, c0123456789012345, d0123456789012345];
-}
-<<<
-main() {
-  List<String> values = <String>[
-      a0123456789012345,
-      b0123456789012345,
-      c0123456789012345,
-      d0123456789012345];
-}
->>> assignment - initializer doesn't fit one line, wrap inside, keep name
-main() {
-  result = myFunction(a0123456789012345 * b0123456789012345, c0123456789012345 * d0123456789012345);
-}
-<<<
-main() {
-  result = myFunction(
-      a0123456789012345 * b0123456789012345,
-      c0123456789012345 * d0123456789012345);
-}
->>> assignment - initializer fits one line
-main() {
-  variableLoooooooooooooooong = functionLoooooooooooooooooooooooooooooooooooooong(1, 2, 3, 4);
-}
-<<<
-main() {
-  variableLoooooooooooooooong =
-      functionLoooooooooooooooooooooooooooooooooooooong(1, 2, 3, 4);
-}
->>> assignment - initializer doesn't fit one line, name too long
-main() {
-  variableLooooooooooooooooooong = functionLoooooooooooooooooooooooooooooooooooong(a0123456789012345 * b0123456789012345, c0123456789012345 * d0123456789012345);
-}
-<<<
-main() {
-  variableLooooooooooooooooooong =
-      functionLoooooooooooooooooooooooooooooooooooong(
-          a0123456789012345 * b0123456789012345,
-          c0123456789012345 * d0123456789012345);
-}
->>> variable declaration - initializer doesn't fit one line, wrap inside, keep name
-main() {
-  var result = myFunction(a0123456789012345 * b0123456789012345, c0123456789012345 * d0123456789012345);
-}
-<<<
-main() {
-  var result = myFunction(
-      a0123456789012345 * b0123456789012345,
-      c0123456789012345 * d0123456789012345);
-}
->>> variable declaration - initializer fits one line
-main() {
-  var variableLoooooooooooooooong = functionLoooooooooooooooooooooooooooooooooooong(1, 2, 3, 4);
-}
-<<<
-main() {
-  var variableLoooooooooooooooong =
-      functionLoooooooooooooooooooooooooooooooooooong(1, 2, 3, 4);
-}
->>> variable declaration - initializer doesn't fit one line, name too long
-main() {
-  var variableLoooooooooooooooong = functionLoooooooooooooooooooooooooooooooooooong(a0123456789012345 * b0123456789012345, c0123456789012345 * d0123456789012345);
-}
-<<<
-main() {
-  var variableLoooooooooooooooong =
-      functionLoooooooooooooooooooooooooooooooooooong(
-          a0123456789012345 * b0123456789012345,
-          c0123456789012345 * d0123456789012345);
-}
->>> variable declaration - with binary expression
-main() {
-  int result = a01234567890123456789 * b01234567890123456789 + c01234567890123456789 * d01234567890123456789;
-}
-<<<
-main() {
-  int result =
-      a01234567890123456789 * b01234567890123456789 +
-      c01234567890123456789 * d01234567890123456789;
-}
->>> arguments
-main() {
-  myFunction(a0123456789012345 * b0123456789012345, c0123456789012345 * d0123456789012345);
-}
-<<<
-main() {
-  myFunction(
-      a0123456789012345 * b0123456789012345,
-      c0123456789012345 * d0123456789012345);
-}
->>> arguments, nested
-main() {
-  someFunctionOne(a012345678901234567890123456789,
-    someFunctionTwo(ba01234567890123456789, bb01234567890123456789, bc01234567890123456789),
-    someFunctionTwo(ca01234567890123456789, cb01234567890123456789, cc01234567890123456789),
-    d012345678901234567890123456789, e012345678901234567890123456789);
-}
-<<<
-main() {
-  someFunctionOne(
-      a012345678901234567890123456789,
-      someFunctionTwo(
-          ba01234567890123456789,
-          bb01234567890123456789,
-          bc01234567890123456789),
-      someFunctionTwo(
-          ca01234567890123456789,
-          cb01234567890123456789,
-          cc01234567890123456789),
-      d012345678901234567890123456789,
-      e012345678901234567890123456789);
-}
->>> conditions, same operator
-main() {
-  if (a012345678901234567890123456789 || b012345678901234567890123456789 || c012345678901234567890123456789
-                  || d012345678901234567890123456789) {
-  }
-}
-<<<
-main() {
-  if (a012345678901234567890123456789 ||
-      b012345678901234567890123456789 ||
-      c012345678901234567890123456789 ||
-      d012345678901234567890123456789) {
-  }
-}
->>> conditions, different operators
-main() {
-  if (a012345678901234567890123456789 && b012345678901234567890123456789 || c012345678901234567890123456789
-                  && d012345678901234567890123456789) {
-  }
-}
-<<<
-main() {
-  if (a012345678901234567890123456789 && b012345678901234567890123456789 ||
-      c012345678901234567890123456789 && d012345678901234567890123456789) {
-  }
-}
->>> conditional expression
-main() {
-  MatchKind kind = element != null ? a012345678901234567890123456789 : b012345678901234567890123456789;
-}
-<<<
-main() {
-  MatchKind kind = element != null ?
-      a012345678901234567890123456789 :
-      b012345678901234567890123456789;
-}
->>> expression function body
-myFunction() => a012345678901234567890123456789 + b012345678901234567890123456789;
-<<<
-myFunction() =>
-    a012345678901234567890123456789 + b012345678901234567890123456789;
diff --git a/pkg/analyzer/test/services/formatter_test.dart b/pkg/analyzer/test/services/formatter_test.dart
deleted file mode 100644
index b039e06..0000000
--- a/pkg/analyzer/test/services/formatter_test.dart
+++ /dev/null
@@ -1,1416 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library formatter_test;
-
-import 'dart:io';
-
-import 'package:path/path.dart';
-import 'package:unittest/unittest.dart';
-
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/services/formatter_impl.dart';
-import 'package:analyzer/src/services/writer.dart';
-
-// Test data location ('pkg/analyzer/test/services/data')
-final TEST_DATA_DIR = join(dirname(fromUri(Platform.script)), 'data');
-
-main() {
-
-  /// Data-driven statement tests
-  group('stmt_tests.data', () {
-    // NOTE: statement tests are run with transforms enabled
-    runTests('stmt_tests.data', (input, expectedOutput) {
-      expect(formatStatement(input,
-              options: new FormatterOptions(codeTransforms: true)) +
-          '\n', equals(expectedOutput));
-    });
-  });
-
-  /// Data-driven compilation unit tests
-  group('cu_tests.data', () {
-    runTests('cu_tests.data', (input, expectedOutput) {
-      expectCUFormatsTo(input, expectedOutput);
-    });
-  });
-
-  /// Data-driven Style Guide acceptance tests
-  group('style_guide_tests.data', () {
-    runTests('style_guide_tests.data', (input, expectedOutput) {
-      expectCUFormatsTo(input, expectedOutput);
-    });
-  });
-
-  /// Data-driven wrapping tests
-  group('wrap_tests.data', () {
-    runTests('wrap_tests.data', (input, expectedOutput) {
-      expectCUFormatsTo(input, expectedOutput);
-    });
-  });
-
-  /// Formatter tests
-  group('formatter', () {
-    test('failed parse', () {
-      var formatter = new CodeFormatter();
-      expect(() => formatter.format(CodeKind.COMPILATION_UNIT, '~'),
-          throwsA(new isInstanceOf<FormatterException>()));
-    });
-
-    test('indent', () {
-      var original = 'class A {\n'
-          '  var z;\n'
-          '  inc(int x) => ++x;\n'
-          '  foo(int x) {\n'
-          '    if (x == 0) {\n'
-          '      return true;\n'
-          '    }\n'
-          '  }\n'
-          '}\n';
-      expectCUFormatsTo(original, original);
-      expectIndentFormatsTo(3, false, original, 'class A {\n'
-          '   var z;\n'
-          '   inc(int x) => ++x;\n'
-          '   foo(int x) {\n'
-          '      if (x == 0) {\n'
-          '         return true;\n'
-          '      }\n'
-          '   }\n'
-          '}\n');
-      expectIndentFormatsTo(1, true, original, 'class A {\n'
-          '\tvar z;\n'
-          '\tinc(int x) => ++x;\n'
-          '\tfoo(int x) {\n'
-          '\t\tif (x == 0) {\n'
-          '\t\t\treturn true;\n'
-          '\t\t}\n'
-          '\t}\n'
-          '}\n');
-    });
-
-    test('CU (1)', () {
-      expectCUFormatsTo('class A {\n'
-          '  var z;\n'
-          '  inc(int x) => ++x;\n'
-          '}\n', 'class A {\n'
-          '  var z;\n'
-          '  inc(int x) => ++x;\n'
-          '}\n');
-    });
-
-    test('CU (2)', () {
-      expectCUFormatsTo('class      A  {  \n'
-          '}\n', 'class A {\n'
-          '}\n');
-    });
-
-    test('CU (3)', () {
-      expectCUFormatsTo('class A {\n'
-          '  }', 'class A {\n'
-          '}\n');
-    });
-
-    test('CU (4)', () {
-      expectCUFormatsTo(' class A {\n'
-          '}\n', 'class A {\n'
-          '}\n');
-    });
-
-    test('CU (5)', () {
-      expectCUFormatsTo('class A  { int meaningOfLife() => 42; }', 'class A {\n'
-          '  int meaningOfLife() => 42;\n'
-          '}\n');
-    });
-
-    test('CU - EOL comments', () {
-      expectCUFormatsTo('//comment one\n\n'
-          '//comment two\n\n', '//comment one\n\n'
-          '//comment two\n\n');
-      expectCUFormatsTo('var x;   //x\n', 'var x; //x\n');
-      expectCUFormatsTo('library foo;\n'
-          '\n'
-          '//comment one\n'
-          '\n'
-          'class C {\n'
-          '}\n', 'library foo;\n'
-          '\n'
-          '//comment one\n'
-          '\n'
-          'class C {\n'
-          '}\n');
-      expectCUFormatsTo('library foo;\n'
-          '\n'
-          '//comment one\n'
-          '\n'
-          '//comment two\n'
-          '\n'
-          'class C {\n'
-          '}\n', 'library foo;\n'
-          '\n'
-          '//comment one\n'
-          '\n'
-          '//comment two\n'
-          '\n'
-          'class C {\n'
-          '}\n');
-      expectCUFormatsTo('main() {\n'
-          '//  print(1);\n'
-          '//  print(2);\n'
-          '  print(3);\n'
-          '}\n', 'main() {\n'
-          '//  print(1);\n'
-          '//  print(2);\n'
-          '  print(3);\n'
-          '}\n');
-      expectCUFormatsTo('class A {\n'
-          '//  int a;\n'
-          '//  int b;\n'
-          '  int c;\n'
-          '}\n', 'class A {\n'
-          '//  int a;\n'
-          '//  int b;\n'
-          '  int c;\n'
-          '}\n');
-    });
-
-    test('CU - nested functions', () {
-      expectCUFormatsTo('x() {\n'
-          '  y() {\n'
-          '  }\n'
-          '}\n', 'x() {\n'
-          '  y() {\n'
-          '  }\n'
-          '}\n');
-    });
-
-    test('CU - top level', () {
-      expectCUFormatsTo('\n\n'
-          'foo() {\n'
-          '}\n'
-          'bar() {\n'
-          '}\n', '\n\n'
-          'foo() {\n'
-          '}\n'
-          'bar() {\n'
-          '}\n');
-      expectCUFormatsTo('const A = 42;\n'
-          'final foo = 32;\n', 'const A = 42;\n'
-          'final foo = 32;\n');
-    });
-
-    test('CU - imports', () {
-      expectCUFormatsTo('import "dart:io";\n\n'
-          'import "package:unittest/unittest.dart";\n'
-          'foo() {\n'
-          '}\n', 'import "dart:io";\n\n'
-          'import "package:unittest/unittest.dart";\n'
-          'foo() {\n'
-          '}\n');
-      expectCUFormatsTo('library a; class B { }', 'library a;\n'
-          'class B {}\n');
-    });
-
-    test('CU - method invocations', () {
-      expectCUFormatsTo('class A {\n'
-          '  foo() {\n'
-          '    bar();\n'
-          '    for (int i = 0; i < 42; i++) {\n'
-          '      baz();\n'
-          '    }\n'
-          '  }\n'
-          '}\n', 'class A {\n'
-          '  foo() {\n'
-          '    bar();\n'
-          '    for (int i = 0; i < 42; i++) {\n'
-          '      baz();\n'
-          '    }\n'
-          '  }\n'
-          '}\n');
-    });
-
-    test('CU w/class decl comment', () {
-      expectCUFormatsTo('import "foo";\n\n'
-          '//Killer class\n'
-          'class A {\n'
-          '}', 'import "foo";\n\n'
-          '//Killer class\n'
-          'class A {\n'
-          '}\n');
-    });
-
-    test('CU (method body)', () {
-      expectCUFormatsTo('class A {\n'
-          '  foo(path) {\n'
-          '    var buffer = new StringBuffer();\n'
-          '    var file = new File(path);\n'
-          '    return file;\n'
-          '  }\n'
-          '}\n', 'class A {\n'
-          '  foo(path) {\n'
-          '    var buffer = new StringBuffer();\n'
-          '    var file = new File(path);\n'
-          '    return file;\n'
-          '  }\n'
-          '}\n');
-      expectCUFormatsTo('class A {\n'
-          '  foo(files) {\n'
-          '    for (var  file in files) {\n'
-          '      print(file);\n'
-          '    }\n'
-          '  }\n'
-          '}\n', 'class A {\n'
-          '  foo(files) {\n'
-          '    for (var file in files) {\n'
-          '      print(file);\n'
-          '    }\n'
-          '  }\n'
-          '}\n');
-    });
-
-    test('CU (method indent)', () {
-      expectCUFormatsTo('class A {\n'
-          'void x(){\n'
-          '}\n'
-          '}\n', 'class A {\n'
-          '  void x() {\n'
-          '  }\n'
-          '}\n');
-    });
-
-    test('CU (method indent - 2)', () {
-      expectCUFormatsTo('class A {\n'
-          ' static  bool x(){\n'
-          'return true; }\n'
-          ' }\n', 'class A {\n'
-          '  static bool x() {\n'
-          '    return true;\n'
-          '  }\n'
-          '}\n');
-    });
-
-    test('CU (method indent - 3)', () {
-      expectCUFormatsTo('class A {\n'
-          ' int x() =>   42   + 3 ;  \n'
-          '   }\n', 'class A {\n'
-          '  int x() => 42 + 3;\n'
-          '}\n');
-    });
-
-    test('CU (method indent - 4)', () {
-      expectCUFormatsTo('class A {\n'
-          ' int x() { \n'
-          'if (true) {\n'
-          'return 42;\n'
-          '} else {\n'
-          'return 13;\n }\n'
-          '   }'
-          '}\n', 'class A {\n'
-          '  int x() {\n'
-          '    if (true) {\n'
-          '      return 42;\n'
-          '    } else {\n'
-          '      return 13;\n'
-          '    }\n'
-          '  }\n'
-          '}\n');
-    });
-
-    test('CU (multiple members)', () {
-      expectCUFormatsTo('class A {\n'
-          '}\n'
-          'class B {\n'
-          '}\n', 'class A {\n'
-          '}\n'
-          'class B {\n'
-          '}\n');
-    });
-
-    test('CU (multiple members w/blanks)', () {
-      expectCUFormatsTo('class A {\n'
-          '}\n\n'
-          'class B {\n\n\n'
-          '  int b() => 42;\n\n'
-          '  int c() => b();\n\n'
-          '}\n', 'class A {\n'
-          '}\n\n'
-          'class B {\n\n\n'
-          '  int b() => 42;\n\n'
-          '  int c() => b();\n\n'
-          '}\n');
-    });
-
-    test('CU - Block comments', () {
-      expectCUFormatsTo('/** Old school class comment */\n'
-          'class C {\n'
-          '  /** Foo! */ int foo() => 42;\n'
-          '}\n', '/** Old school class comment */\n'
-          'class C {\n'
-          '  /** Foo! */\n'
-          '  int foo() => 42;\n'
-          '}\n');
-      expectCUFormatsTo('library foo;\n'
-          'class C /* is cool */ {\n'
-          '  /* int */ foo() => 42;\n'
-          '}\n', 'library foo;\n'
-          'class C /* is cool */ {\n'
-          '  /* int */ foo() => 42;\n'
-          '}\n');
-      expectCUFormatsTo('library foo;\n'
-          '/* A long\n'
-          ' * Comment\n'
-          '*/\n'
-          'class C /* is cool */ {\n'
-          '  /* int */ foo() => 42;\n'
-          '}\n', 'library foo;\n'
-          '/* A long\n'
-          ' * Comment\n'
-          '*/\n'
-          'class C /* is cool */ {\n'
-          '  /* int */ foo() => 42;\n'
-          '}\n');
-      expectCUFormatsTo('library foo;\n'
-          '/* A long\n'
-          ' * Comment\n'
-          '*/\n'
-          '\n'
-          '/* And\n'
-          ' * another...\n'
-          '*/\n'
-          '\n'
-          '// Mixing it up\n'
-          '\n'
-          'class C /* is cool */ {\n'
-          '  /* int */ foo() => 42;\n'
-          '}\n', 'library foo;\n'
-          '/* A long\n'
-          ' * Comment\n'
-          '*/\n'
-          '\n'
-          '/* And\n'
-          ' * another...\n'
-          '*/\n'
-          '\n'
-          '// Mixing it up\n'
-          '\n'
-          'class C /* is cool */ {\n'
-          '  /* int */ foo() => 42;\n'
-          '}\n');
-      expectCUFormatsTo('/// Copyright info\n'
-          '\n'
-          'library foo;\n'
-          '/// Class comment\n'
-          '//TODO: implement\n'
-          'class C {\n'
-          '}\n', '/// Copyright info\n'
-          '\n'
-          'library foo;\n'
-          '/// Class comment\n'
-          '//TODO: implement\n'
-          'class C {\n'
-          '}\n');
-    });
-
-    test('CU - mixed comments', () {
-      expectCUFormatsTo('library foo;\n'
-          '\n'
-          '\n'
-          '/* Comment 1 */\n'
-          '\n'
-          '// Comment 2\n'
-          '\n'
-          '/* Comment 3 */', 'library foo;\n'
-          '\n'
-          '\n'
-          '/* Comment 1 */\n'
-          '\n'
-          '// Comment 2\n'
-          '\n'
-          '/* Comment 3 */\n');
-    });
-
-    test('CU - comments (EOF)', () {
-      expectCUFormatsTo('library foo; //zamm',
-          'library foo; //zamm\n' //<-- note extra NEWLINE
-          );
-    });
-
-    test('CU - comments (0)', () {
-      expectCUFormatsTo('library foo; //zamm\n'
-          '\n'
-          'class A {\n'
-          '}\n', 'library foo; //zamm\n'
-          '\n'
-          'class A {\n'
-          '}\n');
-    });
-
-    test('CU - comments (1)', () {
-      expectCUFormatsTo('/* foo */ /* bar */\n', '/* foo */ /* bar */\n');
-    });
-
-    test('CU - comments (2)', () {
-      expectCUFormatsTo('/** foo */ /** bar */\n', '/** foo */\n'
-          '/** bar */\n');
-    });
-
-    test('CU - comments (3)', () {
-      expectCUFormatsTo('var x;   //x\n', 'var x; //x\n');
-    });
-
-    test('CU - comments (4)', () {
-      expectCUFormatsTo('class X { //X!\n'
-          '}', 'class X { //X!\n'
-          '}\n');
-    });
-
-    test('CU - comments (5)', () {
-      expectCUFormatsTo('//comment one\n\n'
-          '//comment two\n\n', '//comment one\n\n'
-          '//comment two\n\n');
-    });
-
-    test('CU - comments (6)', () {
-      expectCUFormatsTo('var x;   //x\n', 'var x; //x\n');
-    });
-
-    test('CU - comments (6)', () {
-      expectCUFormatsTo('var /* int */ x; //x\n', 'var /* int */ x; //x\n');
-    });
-
-    test('CU - comments (7)', () {
-      expectCUFormatsTo('library foo;\n'
-          '\n'
-          '/// Docs\n'
-          '/// spanning\n'
-          '/// lines.\n'
-          'class A {\n'
-          '}\n'
-          '\n'
-          '/// ... and\n'
-          '\n'
-          '/// Dangling ones too\n'
-          'int x;\n', 'library foo;\n'
-          '\n'
-          '/// Docs\n'
-          '/// spanning\n'
-          '/// lines.\n'
-          'class A {\n'
-          '}\n'
-          '\n'
-          '/// ... and\n'
-          '\n'
-          '/// Dangling ones too\n'
-          'int x;\n');
-    });
-
-    test('CU - comments (8)', () {
-      expectCUFormatsTo('var x /* X */, y;\n', 'var x /* X */, y;\n');
-    });
-
-    test('CU - comments (9)', () {
-      expectCUFormatsTo('main() {\n'
-          '  foo(1 /* bang */, 2);\n'
-          '}\n'
-          'foo(x, y) => null;\n', 'main() {\n'
-          '  foo(1 /* bang */, 2);\n'
-          '}\n'
-          'foo(x, y) => null;\n');
-    });
-
-    test('CU - comments (10)', () {
-      expectCUFormatsTo(
-          'var l = [1 /* bang */, 2];\n', 'var l = [1 /* bang */, 2];\n');
-    });
-
-    test('CU - comments (11)', () {
-      expectCUFormatsTo('var m = {1: 2 /* bang */, 3: 4};\n', 'var m = {\n'
-          '  1: 2 /* bang */,\n'
-          '  3: 4\n'
-          '};\n');
-    });
-
-    test('CU - EOF nl', () {
-      expectCUFormatsTo('var x = 1;', 'var x = 1;\n');
-    });
-
-    test('CU - constructor', () {
-      expectCUFormatsTo('class A {\n'
-          '  const _a;\n'
-          '  A();\n'
-          '  int a() => _a;\n'
-          '}\n', 'class A {\n'
-          '  const _a;\n'
-          '  A();\n'
-          '  int a() => _a;\n'
-          '}\n');
-    });
-
-    test('CU - method decl w/ named params', () {
-      expectCUFormatsTo('class A {\n'
-          '  int a(var x, {optional: null}) => null;\n'
-          '}\n', 'class A {\n'
-          '  int a(var x, {optional: null}) => null;\n'
-          '}\n');
-    });
-
-    test('CU - method decl w/ optional params', () {
-      expectCUFormatsTo('class A {\n'
-          '  int a(var x, [optional = null]) => null;\n'
-          '}\n', 'class A {\n'
-          '  int a(var x, [optional = null]) => null;\n'
-          '}\n');
-    });
-
-    test('CU - factory constructor redirects', () {
-      expectCUFormatsTo('class A {\n'
-          '  const factory A() = B;\n'
-          '}\n', 'class A {\n'
-          '  const factory A() = B;\n'
-          '}\n');
-    });
-
-    test('CU - constructor auto field inits', () {
-      expectCUFormatsTo('class A {\n'
-          '  int _a;\n'
-          '  A(this._a);\n'
-          '}\n', 'class A {\n'
-          '  int _a;\n'
-          '  A(this._a);\n'
-          '}\n');
-    });
-
-    test('CU - parts', () {
-      expectCUFormatsTo('part of foo;', 'part of foo;\n');
-    });
-
-    test('CU (cons inits)', () {
-      expectCUFormatsTo('class X {\n'
-          '  var x, y;\n'
-          '  X() : x = 1, y = 2;\n'
-          '}\n', 'class X {\n'
-          '  var x, y;\n'
-          '  X()\n'
-          '      : x = 1,\n'
-          '        y = 2;\n'
-          '}\n');
-    });
-
-    test('CU (empty cons bodies)', () {
-      expectCUFormatsTo('class A {\n'
-          '  A() {\n'
-          '  }\n'
-          '}\n', 'class A {\n'
-          '  A();\n'
-          '}\n', transforms: true);
-      expectCUFormatsTo('class A {\n'
-          '  A() {\n'
-          '  }\n'
-          '}\n', 'class A {\n'
-          '  A() {\n'
-          '  }\n'
-          '}\n', transforms: false);
-    });
-
-    test('stmt', () {
-      expectStmtFormatsTo('if (true){\n'
-          'if (true){\n'
-          'if (true){\n'
-          'return true;\n'
-          '} else{\n'
-          'return false;\n'
-          '}\n'
-          '}\n'
-          '}else{\n'
-          'return false;\n'
-          '}', 'if (true) {\n'
-          '  if (true) {\n'
-          '    if (true) {\n'
-          '      return true;\n'
-          '    } else {\n'
-          '      return false;\n'
-          '    }\n'
-          '  }\n'
-          '} else {\n'
-          '  return false;\n'
-          '}');
-    });
-
-    test('stmt (switch)', () {
-      expectStmtFormatsTo('switch (fruit) {\n'
-          'case "apple":\n'
-          'print("delish");\n'
-          'break;\n'
-          'case "fig":\n'
-          'print("bleh");\n'
-          'break;\n'
-          '}', 'switch (fruit) {\n'
-          '  case "apple":\n'
-          '    print("delish");\n'
-          '    break;\n'
-          '  case "fig":\n'
-          '    print("bleh");\n'
-          '    break;\n'
-          '}');
-    });
-
-    test('stmt (empty while body)', () {
-      expectStmtFormatsTo('while (true);', 'while (true);');
-    });
-
-    test('stmt (empty for body)', () {
-      expectStmtFormatsTo('for ( ; ; );', 'for ( ; ; );');
-    });
-
-    test('stmt (cascades)', () {
-      expectStmtFormatsTo('"foo"\n'
-          '..toString()\n'
-          '..toString();', '"foo"\n'
-          '    ..toString()\n'
-          '    ..toString();');
-    });
-
-    test('stmt (generics)', () {
-      expectStmtFormatsTo('var numbers = <int>[1, 2, (3 + 4)];',
-          'var numbers = <int>[1, 2, (3 + 4)];');
-    });
-
-    test('stmt (lists)', () {
-      expectStmtFormatsTo('var l = [1,2,3,4];', 'var l = [1, 2, 3, 4];');
-      expectStmtFormatsTo('var l = [\n'
-          '1,\n'
-          '2,\n'
-          '];', 'var l = [1, 2,];');
-      //Dangling ','
-      expectStmtFormatsTo('var l = [1,];', 'var l = [1,];');
-    });
-
-    test('stmt (maps)', () {
-      expectStmtFormatsTo('var map = const {"foo": "bar", "fuz": null};',
-          'var map = const {\n'
-          '  "foo": "bar",\n'
-          '  "fuz": null\n'
-          '};');
-
-      expectStmtFormatsTo('var map = {\n'
-          '"foo": "bar",\n'
-          '"bar": "baz"\n'
-          '};', 'var map = {\n'
-          '  "foo": "bar",\n'
-          '  "bar": "baz"\n'
-          '};');
-
-      //Dangling ','
-      expectStmtFormatsTo('var map = {"foo": "bar",};', 'var map = {\n'
-          '  "foo": "bar",\n'
-          '};');
-    });
-
-    test('stmt (try/catch)', () {
-      expectStmtFormatsTo('try {\n'
-          'doSomething();\n'
-          '} catch (e) {\n'
-          'print(e);\n'
-          '}', 'try {\n'
-          '  doSomething();\n'
-          '} catch (e) {\n'
-          '  print(e);\n'
-          '}');
-      expectStmtFormatsTo('try{\n'
-          'doSomething();\n'
-          '}on Exception catch (e){\n'
-          'print(e);\n'
-          '}', 'try {\n'
-          '  doSomething();\n'
-          '} on Exception catch (e) {\n'
-          '  print(e);\n'
-          '}');
-    });
-
-    test('stmt (binary/ternary ops)', () {
-      expectStmtFormatsTo(
-          'var a = 1 + 2 / (3 * -b);', 'var a = 1 + 2 / (3 * -b);');
-      expectStmtFormatsTo(
-          'var c = !condition == a > b;', 'var c = !condition == a > b;');
-      expectStmtFormatsTo('var d = condition ? b : object.method(a, b, c);',
-          'var d = condition ? b : object.method(a, b, c);');
-      expectStmtFormatsTo(
-          'var d = obj is! SomeType;', 'var d = obj is! SomeType;');
-    });
-
-    test('stmt (for in)', () {
-      expectStmtFormatsTo('for (Foo foo in bar.foos) {\n'
-          '  print(foo);\n'
-          '}', 'for (Foo foo in bar.foos) {\n'
-          '  print(foo);\n'
-          '}');
-      expectStmtFormatsTo('for (final Foo foo in bar.foos) {\n'
-          '  print(foo);\n'
-          '}', 'for (final Foo foo in bar.foos) {\n'
-          '  print(foo);\n'
-          '}');
-      expectStmtFormatsTo('for (final foo in bar.foos) {\n'
-          '  print(foo);\n'
-          '}', 'for (final foo in bar.foos) {\n'
-          '  print(foo);\n'
-          '}');
-    });
-
-    test('Statement (if)', () {
-      expectStmtFormatsTo(
-          'if (true) print("true!");', 'if (true) print("true!");');
-      expectStmtFormatsTo('if (true) { print("true!"); }', 'if (true) {\n'
-          '  print("true!");\n'
-          '}');
-      expectStmtFormatsTo('if (true) print("true!"); else print("false!");',
-          'if (true) {\n'
-          '  print("true!");\n'
-          '} else {\n'
-          '  print("false!");\n'
-          '}');
-      expectStmtFormatsTo('if (true) print("true!"); else print("false!");',
-          'if (true) print("true!"); else print("false!");', transforms: false);
-    });
-
-    test('String - multiline - short - same line', () {
-      expectCUFormatsTo('main() {\n'
-          '  print("""01234567890123456789012345678901234567890123456789""");\n'
-          '}\n', 'main() {\n'
-          '  print("""01234567890123456789012345678901234567890123456789""");\n'
-          '}\n');
-    });
-
-    test('String - multiline - short - next line', () {
-      expectCUFormatsTo('main() {\n'
-          '  print("""\n'
-          '01234567890123456789012345678901234567890123456789\n'
-          '""");\n'
-          '}\n', 'main() {\n'
-          '  print("""\n'
-          '01234567890123456789012345678901234567890123456789\n'
-          '""");\n'
-          '}\n');
-    });
-
-    test('String - multiline - long', () {
-      expectCUFormatsTo('main() {\n'
-          '  print("""\n'
-          '01234567890123456789012345678901234567890123456789\n'
-          '01234567890123456789012345678901234567890123456789\n'
-          '01234567890123456789012345678901234567890123456789\n'
-          '""");\n'
-          '}\n', 'main() {\n'
-          '  print("""\n'
-          '01234567890123456789012345678901234567890123456789\n'
-          '01234567890123456789012345678901234567890123456789\n'
-          '01234567890123456789012345678901234567890123456789\n'
-          '""");\n'
-          '}\n');
-    });
-
-    // smoketest to ensure we're enforcing the 'no gratuitous linebreaks'
-    // opinion
-    test('CU (eat newlines)', () {
-      expectCUFormatsTo('abstract\n'
-          'class\n'
-          'A{}', 'abstract class A {}\n');
-    });
-
-//    test('line continuations - 1', () {
-//      expectStmtFormatsTo(
-//          'if (x &&\n'
-//          '    y) {\n'
-//          '  print("yes!");\n'
-//          '}',
-//          'if (x &&\n'
-//          '    y) {\n'
-//          '  print("yes!");\n'
-//          '}'
-//      );
-//      expectStmtFormatsTo(
-//          'var x =\n'
-//          '    1234567890;',
-//          'var x =\n'
-//          '    1234567890;'
-//      );
-//      expectStmtFormatsTo(
-//          'foo() {\n'
-//          '  var x = 0;\n'
-//          '  x =\n'
-//          '      1234567890;\n'
-//          '}',
-//          'foo() {\n'
-//          '  var x = 0;\n'
-//          '  x =\n'
-//          '      1234567890;\n'
-//          '}'
-//      );
-//      expectStmtFormatsTo(
-//          'foo() {\n'
-//          '  while (true &&\n'
-//          '      true) {\n'
-//          '    print("!");\n'
-//          '  }\n'
-//          '}',
-//          'foo() {\n'
-//          '  while (true &&\n'
-//          '      true) {\n'
-//          '    print("!");\n'
-//          '  }\n'
-//          '}'
-//      );
-//      expectStmtFormatsTo(
-//          'foo() {\n'
-//          '  do {\n'
-//          '    print("!");\n'
-//          '  } while (true &&\n'
-//          '      true);\n'
-//          '}',
-//          'foo() {\n'
-//          '  do {\n'
-//          '    print("!");\n'
-//          '  } while (true &&\n'
-//          '      true);\n'
-//          '}'
-//      );
-//      expectStmtFormatsTo(
-//          'int foo() {\n'
-//          '  return\n'
-//          '      foo();\n'
-//          '}',
-//          'int foo() {\n'
-//          '  return\n'
-//          '      foo();\n'
-//          '}'
-//      );
-//      expectStmtFormatsTo(
-//          'int foo() {\n'
-//          '  return\n'
-//          '      13;\n'
-//          '}',
-//          'int foo() {\n'
-//          '  return\n'
-//          '      13;\n'
-//          '}'
-//      );
-//      expectStmtFormatsTo(
-//          'foo(fn()) {\n'
-//          '  return foo(() {\n'
-//          '    return 1;\n'
-//          '});\n'
-//          '}',
-//          'foo(fn()) {\n'
-//          '  return foo(() {\n'
-//          '    return 1;\n'
-//          '});\n'
-//          '}'
-//      );
-//      expectStmtFormatsTo(
-//          'true ? foo() :\n'
-//          '    bar();',
-//          'true ? foo() :\n'
-//          '    bar();'
-//      );
-//      expectCUFormatsTo(
-//          'import "dart:core" as\n'
-//          '    core;\n',
-//          'import "dart:core" as\n'
-//          '    core;\n'
-//      );
-//      expectCUFormatsTo(
-//          'export "package:foo/foo.dart" show\n'
-//          '    Foo;\n',
-//          'export "package:foo/foo.dart" show\n'
-//          '    Foo;\n'
-//      );
-//      expectCUFormatsTo(
-//          'class Foo extends Bar implements\n'
-//          '    Baz {\n'
-//          '}\n',
-//          'class Foo extends Bar implements\n'
-//          '    Baz {\n'
-//          '}\n'
-//      );
-//    });
-
-    test('initialIndent', () {
-      var formatter =
-          new CodeFormatter(new FormatterOptions(initialIndentationLevel: 2));
-      var formattedSource =
-          formatter.format(CodeKind.STATEMENT, 'var x;').source;
-      expect(formattedSource, startsWith('    '));
-    });
-
-    test('selections', () {
-      expectSelectedPostFormat('class X {}', '}');
-      expectSelectedPostFormat('class X{}', '{');
-      expectSelectedPostFormat('class X{int y;}', ';');
-      expectSelectedPostFormat('class X{int y;}', '}');
-      expectSelectedPostFormat('class X {}', ' {');
-    });
-  });
-
-  /// Token streams
-  group('token streams', () {
-    test('string tokens', () {
-      expectTokenizedEqual('class A{}', 'class A{ }');
-      expectTokenizedEqual('class A{}', 'class A{\n  }\n');
-      expectTokenizedEqual('class A {}', 'class A{ }');
-      expectTokenizedEqual('  class A {}', 'class A{ }');
-    });
-
-    test('string tokens - w/ comments', () {
-      expectTokenizedEqual('//foo\nint bar;', '//foo\nint bar;');
-      expectTokenizedNotEqual('int bar;', '//foo\nint bar;');
-      expectTokenizedNotEqual('//foo\nint bar;', 'int bar;');
-    });
-
-    test('INDEX', () {
-      /// '[' ']' => '[]'
-      var t1 = openSqBracket()..setNext(closeSqBracket()..setNext(eof()));
-      var t2 = index()..setNext(eof());
-      expectStreamsEqual(t1, t2);
-    });
-
-    test('GT_GT', () {
-      /// '>' '>' => '>>'
-      var t1 = gt()..setNext(gt()..setNext(eof()));
-      var t2 = gt_gt()..setNext(eof());
-      expectStreamsEqual(t1, t2);
-    });
-
-    test('t1 < t2', () {
-      var t1 = string('foo')..setNext(eof());
-      var t2 = string('foo')..setNext(string('bar')..setNext(eof()));
-      expectStreamsNotEqual(t1, t2);
-    });
-
-    test('t1 > t2', () {
-      var t1 = string('foo')..setNext(string('bar')..setNext(eof()));
-      var t2 = string('foo')..setNext(eof());
-      expectStreamsNotEqual(t1, t2);
-    });
-  });
-
-  /// Line tests
-  group('line', () {
-    test('space', () {
-      var line = new Line(indentLevel: 0);
-      line.addSpaces(2);
-      expect(line.toString(), equals('  '));
-    });
-
-    test('initial indent', () {
-      var line = new Line(indentLevel: 2);
-      expect(line.toString(), equals('    '));
-    });
-
-    test('initial indent (tabbed)', () {
-      var line = new Line(indentLevel: 1, useTabs: true);
-      expect(line.toString(), equals('\t'));
-    });
-
-    test('addToken', () {
-      var line = new Line();
-      line.addToken(new LineToken('foo'));
-      expect(line.toString(), equals('foo'));
-    });
-
-    test('addToken (2)', () {
-      var line = new Line(indentLevel: 1);
-      line.addToken(new LineToken('foo'));
-      expect(line.toString(), equals('  foo'));
-    });
-
-    test('isWhitespace', () {
-      var line = new Line(indentLevel: 1);
-      expect(line.isWhitespace(), isTrue);
-    });
-  });
-
-  /// Writer tests
-  group('writer', () {
-    test('basic print', () {
-      var writer = new SourceWriter();
-      writer.write('foo');
-      writer.write(' ');
-      writer.write('bar');
-      expect(writer.toString(), equals('foo bar'));
-    });
-
-    test('newline', () {
-      var writer = new SourceWriter();
-      writer.write('foo');
-      writer.newline();
-      expect(writer.toString(), equals('foo\n'));
-    });
-
-    test('newline trims whitespace', () {
-      var writer = new SourceWriter(indentCount: 2);
-      writer.newline();
-      expect(writer.toString(), equals('\n'));
-    });
-
-    test('basic print (with indents)', () {
-      var writer = new SourceWriter();
-      writer.write('foo');
-      writer.indent();
-      writer.newline();
-      writer.write('bar');
-      writer.unindent();
-      writer.newline();
-      writer.write('baz');
-      expect(writer.toString(), equals('foo\n  bar\nbaz'));
-    });
-
-    test('write - multiline', () {
-      var writer = new SourceWriter();
-      writer.indent();
-      writer.newline();
-      writer.write('aaa\nbbb\nccc');
-      expect(writer.toString(), equals('\n  aaa\nbbb\nccc'));
-      expect(writer.currentLine.toString(), equals('ccc'));
-    });
-  });
-
-  /// Line breaker tests
-  group('linebreaker', () {
-    List<Chunk> breakLine(Line line, int maxLength) =>
-        new SimpleLineBreaker(maxLength).breakLine(line);
-
-    String printLine(Line line, int maxLength) =>
-        new SimpleLineBreaker(maxLength, (n) => new List.filled(n, '  ').join())
-            .printLine(line);
-
-    Line line(List tokens) {
-      var line = new Line();
-      tokens
-          .forEach((t) => line.addToken(t is LineToken ? t : new LineToken(t)));
-      return line;
-    }
-
-    expectTextsEqual(List<Chunk> chunks, List<String> texts) {
-      expect(chunks.map((chunk) => chunk.toString()), orderedEquals(texts));
-    }
-
-    expectTokensEqual(List<LineToken> tokens, List<String> texts) {
-      expect(tokens.map((token) => token.toString()), orderedEquals(texts));
-    }
-
-    final SP_1 = new SpaceToken(1, breakWeight: DEFAULT_SPACE_WEIGHT);
-    final SP_w1 = new SpaceToken(1, breakWeight: 1);
-    final SP_w2 = new SpaceToken(1, breakWeight: 2);
-    final SP_i = new SpaceToken(1, breakWeight: SINGLE_SPACE_WEIGHT);
-
-    // 'foo|1|bar|1|baz|1|foo|1|bar|1|baz'
-    final LINE_1 = line([
-      'foo',
-      SP_1,
-      'bar',
-      SP_1,
-      'baz',
-      SP_1,
-      'foo',
-      SP_1,
-      'bar',
-      SP_1,
-      'baz'
-    ]);
-
-    // '  foo|1|bar|1|baz|1|foo|1|bar|1|baz'
-    final LINE_2 = line([
-      '  foo',
-      SP_1,
-      'bar',
-      SP_1,
-      'baz',
-      SP_1,
-      'foo',
-      SP_1,
-      'bar',
-      SP_1,
-      'baz'
-    ]);
-
-    test('breakLine - 0', () {
-      var chunks = breakLine(line(['  foo']), 8);
-      expectTextsEqual(chunks, ['  foo']);
-    });
-
-    test('breakLine - 1', () {
-      var chunks = breakLine(LINE_1, 1);
-      expectTextsEqual(chunks, ['foo', 'bar', 'baz', 'foo', 'bar', 'baz']);
-    });
-
-    test('breakLine - 2', () {
-      var chunks = breakLine(LINE_1, 4);
-      expectTextsEqual(chunks, ['foo', 'bar', 'baz', 'foo', 'bar', 'baz']);
-    });
-
-    test('breakLine - 3', () {
-      var chunks = breakLine(LINE_1, 8);
-      expectTextsEqual(chunks, ['foo bar', 'baz foo', 'bar baz']);
-    });
-
-    test('breakLine - 4', () {
-      var chunks = breakLine(LINE_1, 12);
-      expectTextsEqual(chunks, ['foo bar baz', 'foo bar baz']);
-    });
-
-    test('breakLine - 5', () {
-      var chunks = breakLine(LINE_2, 16);
-      expectTextsEqual(chunks, ['  foo bar baz', 'foo bar baz']);
-    });
-
-    test('breakLine - use weights - 1', () {
-      var source = line([
-        '111',
-        SP_w2,
-        '222',
-        SP_w1,
-        '333',
-        SP_w2,
-        '444',
-        SP_w1,
-        '555',
-        SP_w2,
-        '666'
-      ]);
-      var chunks = breakLine(source, 12);
-      expectTextsEqual(chunks, ['111 222', '333 444', '555 666']);
-    });
-
-    test('printLine - 1', () {
-      var line = printLine(LINE_1, 1);
-      expect(line, 'foo\n    bar\n    baz\n    foo\n    bar\n    baz');
-    });
-
-    test('printLine - 2', () {
-      var line = printLine(LINE_1, 4);
-      expect(line, 'foo\n    bar\n    baz\n    foo\n    bar\n    baz');
-    });
-
-    test('printLine - 3', () {
-      var line = printLine(LINE_1, 8);
-      expect(line, 'foo bar\n    baz foo\n    bar baz');
-    });
-
-    test('printLine - 4', () {
-      var line = printLine(LINE_1, 12);
-      expect(line, 'foo bar baz\n    foo bar baz');
-    });
-
-    test('printLine - use weight - 1', () {
-      var source = line([
-        '111111',
-        SP_w2,
-        '222222',
-        SP_w1,
-        '333333',
-        SP_w2,
-        '444444',
-        SP_w1,
-        '555555',
-        SP_w2,
-        '666666'
-      ]);
-      var result = printLine(source, 20);
-      expect(result, '111111 222222\n    333333 444444\n    555555 666666');
-    });
-
-    test('printLine - use weight - initializer - success', () {
-      var source = line(['111111', SP_i, '2222', SP_w1, '3333', SP_w1, '4444']);
-      var result = printLine(source, 20);
-      expect(result, '111111\n    2222 3333 4444');
-    });
-
-    test('printLine - use weight - initializer - rest too long', () {
-      var source = line([
-        '111',
-        SP_i,
-        '222',
-        SP_w1,
-        '333',
-        SP_w1,
-        '444',
-        SP_w1,
-        '555',
-        SP_w1,
-        '666'
-      ]);
-      var result = printLine(source, 15);
-      expect(result, '111 222\n    333\n    444\n    555\n    666');
-    });
-
-    test('printLine - use weight - initializer - decl/rest too long', () {
-      var source = line([
-        '111',
-        SP_i,
-        '2222222222222',
-        SP_w1,
-        '333',
-        SP_w1,
-        '444',
-        SP_w1,
-        '555',
-        SP_w1,
-        '666'
-      ]);
-      var result = printLine(source, 15);
-      expect(result, '111\n    2222222222222\n'
-          '        333\n        444\n        555\n        666');
-    });
-
-    test('isWhitespace', () {
-      expect(isWhitespace('foo'), false);
-      expect(isWhitespace('  foo'), false);
-      expect(isWhitespace('foo  '), false);
-      expect(isWhitespace(' foo '), false);
-      expect(isWhitespace(' '), true);
-      expect(isWhitespace('  '), true);
-      expect(isWhitespace('\t'), true);
-      expect(isWhitespace('\t\t'), true);
-      expect(isWhitespace('\n'), true);
-      expect(isWhitespace('\r'), true);
-    });
-
-    test('preprocess - 1', () {
-      var tokens = line(['f', 'o', 'o', SP_1, 'b', 'a', 'r']).tokens;
-      var processed = SimpleLineBreaker.preprocess(tokens);
-      expectTokensEqual(processed, ['foo', ' ', 'bar']);
-    });
-
-    test('preprocess - 2', () {
-      var tokens = line(['f', 'o', 'o', SP_1, SP_1, 'b', 'a', 'r']).tokens;
-      var processed = SimpleLineBreaker.preprocess(tokens);
-      expectTokensEqual(processed, ['foo', ' ', ' ', 'bar']);
-    });
-
-    test('preprocess - 3', () {
-      var tokens = line(['f', 'o', 'o', SP_1, 'b', 'a', 'r', SP_1]).tokens;
-      var processed = SimpleLineBreaker.preprocess(tokens);
-      expectTokensEqual(processed, ['foo', ' ', 'bar', ' ']);
-    });
-  });
-
-  /// Helper method tests
-  group('helpers', () {
-    test('indentString', () {
-      expect(getIndentString(0), '');
-      expect(getIndentString(1), '  ');
-      expect(getIndentString(4), '        ');
-    });
-
-    test('indentString (tabbed)', () {
-      expect(getIndentString(0, useTabs: true), '');
-      expect(getIndentString(1, useTabs: true), '\t');
-      expect(getIndentString(3, useTabs: true), '\t\t\t');
-    });
-
-    test('repeat', () {
-      expect(repeat('x', 0), '');
-      expect(repeat('x', 1), 'x');
-      expect(repeat('x', 4), 'xxxx');
-    });
-  });
-}
-
-Token closeSqBracket() => new Token(TokenType.CLOSE_SQUARE_BRACKET, 0);
-
-Token eof() => new Token(TokenType.EOF, 0);
-
-Token gt() => new Token(TokenType.GT, 0);
-
-Token gt_gt() => new Token(TokenType.GT_GT, 0);
-
-Token index() => new Token(TokenType.INDEX, 0);
-
-Token openSqBracket() => new BeginToken(TokenType.OPEN_SQUARE_BRACKET, 0);
-
-Token string(String lexeme) => new StringToken(TokenType.STRING, lexeme, 0);
-
-Token classKeyword(int offset) => new KeywordToken(Keyword.CLASS, offset);
-
-Token identifier(String value, int offset) =>
-    new StringToken(TokenType.IDENTIFIER, value, offset);
-
-Token openParen(int offset) =>
-    new StringToken(TokenType.OPEN_PAREN, '{', offset);
-
-Token closeParen(int offset) =>
-    new StringToken(TokenType.CLOSE_PAREN, '}', offset);
-
-Token chain(List<Token> tokens) {
-  for (var i = 0; i < tokens.length - 1; ++i) {
-    tokens[i].setNext(tokens[i + 1]);
-  }
-  return tokens[0];
-}
-
-FormattedSource formatCU(src, {options: const FormatterOptions(), selection}) =>
-    new CodeFormatter(options).format(CodeKind.COMPILATION_UNIT, src,
-        selection: selection);
-
-String formatStatement(src, {options: const FormatterOptions()}) =>
-    new CodeFormatter(options).format(CodeKind.STATEMENT, src).source;
-
-Token tokenize(String str) {
-  var reader = new CharSequenceReader(str);
-  return new Scanner(null, reader, null).tokenize();
-}
-
-expectSelectedPostFormat(src, token) {
-  var preOffset = src.indexOf(token);
-  var length = token.length;
-  var formatted = formatCU(src, selection: new Selection(preOffset, length));
-  var postOffset = formatted.selection.offset;
-  expect(formatted.source.substring(postOffset, postOffset + length),
-      equals(src.substring(preOffset, preOffset + length)));
-}
-
-expectTokenizedEqual(String s1, String s2) =>
-    expectStreamsEqual(tokenize(s1), tokenize(s2));
-
-expectTokenizedNotEqual(String s1, String s2) => expect(
-    () => expectStreamsEqual(tokenize(s1), tokenize(s2)),
-    throwsA(new isInstanceOf<FormatterException>()));
-
-expectStreamsEqual(Token t1, Token t2) =>
-    new TokenStreamComparator(null, t1, t2).verifyEquals();
-
-expectStreamsNotEqual(Token t1, Token t2) => expect(
-    () => new TokenStreamComparator(null, t1, t2).verifyEquals(),
-    throwsA(new isInstanceOf<FormatterException>()));
-
-expectCUFormatsTo(src, expected, {transforms: true}) => expect(formatCU(src,
-        options: new FormatterOptions(codeTransforms: transforms)).source,
-    equals(expected));
-
-expectIndentFormatsTo(spacesPerIndent, tabsForIndent, src, expected) => expect(
-    formatCU(src,
-        options: new FormatterOptions(
-            spacesPerIndent: spacesPerIndent,
-            tabsForIndent: tabsForIndent)).source, equals(expected));
-
-expectStmtFormatsTo(src, expected, {transforms: true}) => expect(
-    formatStatement(src,
-        options: new FormatterOptions(codeTransforms: transforms)),
-    equals(expected));
-
-runTests(testFileName, expectClause(String input, String output)) {
-  var testIndex = 1;
-  var testFile = new File(join(TEST_DATA_DIR, testFileName));
-  var lines = testFile.readAsLinesSync();
-  for (var i = 1; i < lines.length; ++i) {
-    var input = '',
-        expectedOutput = '';
-    while (!lines[i].startsWith('<<<')) {
-      input += lines[i++] + '\n';
-    }
-    while (++i < lines.length && !lines[i].startsWith('>>>')) {
-      expectedOutput += lines[i] + '\n';
-    }
-    test('test - (${testIndex++})', () {
-      expectClause(input, expectedOutput);
-    });
-  }
-}
diff --git a/pkg/analyzer/test/services/test_utils.dart b/pkg/analyzer/test/services/test_utils.dart
deleted file mode 100644
index 5773d4d..0000000
--- a/pkg/analyzer/test/services/test_utils.dart
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test_utils;
-
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/parser.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:unittest/unittest.dart';
-
-/// Parse the given [source] as a statement and assert, if provided, that
-/// exactly a given set of [expectedErrorCodes] are encountered.
-Statement parseStatement(String source, [List<ErrorCode> expectedErrorCodes]) {
-  var listener = new _GatheringErrorListener();
-  var reader = new CharSequenceReader(source);
-  var scanner = new Scanner(null, reader, listener);
-  listener.setLineInfo(new _TestSource(), scanner.lineStarts);
-
-  var token = scanner.tokenize();
-  var parser = new Parser(null, listener);
-  var statement = parser.parseStatement(token);
-  expect(statement, isNotNull);
-
-  if (expectedErrorCodes != null) {
-    listener.expectErrors(expectedErrorCodes);
-  }
-
-  return statement;
-}
-
-Set<_MapEntry> _getMapEntrySet(Map m) {
-  var result = new Set();
-  m.forEach((k, v) {
-    result.add(new _MapEntry(k, v));
-  });
-  return result;
-}
-
-_unsupported() => throw new _UnsupportedOperationException();
-
-/// Instances of the class [_GatheringErrorListener] implement an error listener
-/// that collects all of the errors passed to it for later examination.
-class _GatheringErrorListener implements AnalysisErrorListener {
-  /// A list containing the errors that were collected.
-  final List<AnalysisError> _errors = new List<AnalysisError>();
-
-  /// A table mapping sources to the line information for the source.
-  final Map<Source, LineInfo> _lineInfoMap = new Map<Source, LineInfo>();
-
-  /// Asserts that the number of errors that have been gathered matches the
-  /// number of errors that are given and that they have the expected error
-  /// codes. The order in which the errors were gathered is ignored.
-  void expectErrors(List<ErrorCode> expectedErrorCodes) {
-    var builder = new StringBuffer();
-    var expectedCounts = new Map<ErrorCode, int>();
-
-    for (var code in expectedErrorCodes) {
-      var count = expectedCounts[code];
-      if (count == null) {
-        count = 1;
-      } else {
-        count = count + 1;
-      }
-      expectedCounts[code] = count;
-    }
-
-    var errorsByCode = new Map<ErrorCode, List<AnalysisError>>();
-    for (var error in _errors) {
-      var code = error.errorCode;
-      var list = errorsByCode[code];
-      if (list == null) {
-        list = new List<AnalysisError>();
-        errorsByCode[code] = list;
-      }
-      list.add(error);
-    }
-
-    for (var entry in _getMapEntrySet(expectedCounts)) {
-      var code = entry.getKey();
-      var expectedCount = entry.getValue();
-      var actualCount;
-
-      var list = errorsByCode.remove(code);
-      if (list == null) {
-        actualCount = 0;
-      } else {
-        actualCount = list.length;
-      }
-
-      if (actualCount != expectedCount) {
-        if (builder.length == 0) {
-          builder.write('Expected ');
-        } else {
-          builder.write('; ');
-        }
-        builder.write(expectedCount);
-        builder.write(' errors of type ');
-        builder.write(code);
-        builder.write(', found ');
-        builder.write(actualCount);
-      }
-    }
-
-    for (var entry in _getMapEntrySet(errorsByCode)) {
-      var code = entry.getKey();
-      var actualErrors = entry.getValue();
-      var actualCount = actualErrors.length;
-
-      if (builder.length == 0) {
-        builder.write('Expected ');
-      } else {
-        builder.write('; ');
-      }
-
-      builder.write('0 errors of type ');
-      builder.write(code);
-      builder.write(', found ');
-      builder.write(actualCount);
-      builder.write(' (');
-
-      for (int i = 0; i < actualErrors.length; i++) {
-        var error = actualErrors[i];
-        if (i > 0) {
-          builder.write(', ');
-        }
-        builder.write(error.offset);
-      }
-
-      builder.write(')');
-    }
-
-    if (builder.length > 0) {
-      fail(builder.toString());
-    }
-  }
-
-  void onError(AnalysisError error) {
-    _errors.add(error);
-  }
-
-  /// Sets the line information associated with the given source to the given
-  /// information.
-  void setLineInfo(Source source, List<int> lineStarts) {
-    _lineInfoMap[source] = new LineInfo(lineStarts);
-  }
-}
-
-class _MapEntry<K, V> {
-  K _key;
-  V _value;
-  _MapEntry(this._key, this._value);
-  K getKey() => _key;
-  V getValue() => _value;
-}
-
-class _TestSource extends Source {
-  TimestampedData<String> get contents => _unsupported();
-
-  AnalysisContext get context => _unsupported();
-
-  String get encoding => _unsupported();
-
-  String get fullName => _unsupported();
-
-  bool get isInSystemLibrary => _unsupported();
-
-  int get modificationStamp => _unsupported();
-
-  String get shortName => _unsupported();
-
-  Uri get uri => _unsupported();
-
-  UriKind get uriKind => _unsupported();
-
-  bool operator ==(Object object) => object is _TestSource;
-
-  bool exists() => true;
-
-  void getContentsToReceiver(Source_ContentReceiver receiver) => _unsupported();
-
-  Source resolve(String uri) => _unsupported();
-
-  Uri resolveRelativeUri(Uri uri) => _unsupported();
-}
-
-class _UnsupportedOperationException implements Exception {
-  String toString() => 'UnsupportedOperationException';
-}
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index b5ff24a..2be2125 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -159,28 +159,22 @@
     ResultDescriptor result = new ResultDescriptor('test', null);
     CaughtException exception = new CaughtException(null, null);
     CacheEntry entry = new CacheEntry();
-    entry.setState(result, CacheState.ERROR);
-    entry.exception = exception;
+    entry.setErrorState(exception, <ResultDescriptor>[result]);
     entry.fixExceptionState();
     expect(entry.getState(result), CacheState.ERROR);
     expect(entry.exception, exception);
   }
 
-  test_fixExceptionState_error_noException() {
-    ResultDescriptor result = new ResultDescriptor('test', null);
-    CacheEntry entry = new CacheEntry();
-    entry.setState(result, CacheState.ERROR);
-    entry.fixExceptionState();
-    expect(entry.getState(result), CacheState.ERROR);
-    expect(entry.exception, isNotNull);
-  }
-
   test_fixExceptionState_noError_exception() {
     ResultDescriptor result = new ResultDescriptor('test', null);
     CacheEntry entry = new CacheEntry();
-    entry.exception = new CaughtException(null, null);
+    // set one result to ERROR
+    CaughtException exception = new CaughtException(null, null);
+    entry.setErrorState(exception, <ResultDescriptor>[result]);
+    // set the same result to VALID
+    entry.setValue(result, 1);
+    // fix the exception state
     entry.fixExceptionState();
-    expect(entry.getState(result), CacheState.INVALID);
     expect(entry.exception, isNull);
   }
 
@@ -233,8 +227,9 @@
 
   test_hasErrorState_true() {
     ResultDescriptor result = new ResultDescriptor('test', null);
+    CaughtException exception = new CaughtException(null, null);
     CacheEntry entry = new CacheEntry();
-    entry.setState(result, CacheState.ERROR);
+    entry.setErrorState(exception, <ResultDescriptor>[result]);
     expect(entry.hasErrorState(), true);
   }
 
@@ -247,20 +242,102 @@
     expect(entry.getValue(result), isNull);
   }
 
+  test_setErrorState() {
+    ResultDescriptor result1 = new ResultDescriptor('res1', 1);
+    ResultDescriptor result2 = new ResultDescriptor('res2', 2);
+    ResultDescriptor result3 = new ResultDescriptor('res3', 3);
+    // prepare some good state
+    CacheEntry entry = new CacheEntry();
+    entry.setValue(result1, 10);
+    entry.setValue(result2, 20);
+    entry.setValue(result3, 30);
+    // set error state
+    CaughtException exception = new CaughtException(null, null);
+    entry.setErrorState(exception, <ResultDescriptor>[result1, result2]);
+    // verify
+    expect(entry.exception, exception);
+    expect(entry.getState(result1), CacheState.ERROR);
+    expect(entry.getState(result2), CacheState.ERROR);
+    expect(entry.getState(result3), CacheState.VALID);
+    expect(entry.getValue(result1), 1);
+    expect(entry.getValue(result2), 2);
+    expect(entry.getValue(result3), 30);
+  }
+
+  test_setErrorState_noDescriptors() {
+    CaughtException exception = new CaughtException(null, null);
+    CacheEntry entry = new CacheEntry();
+    expect(() {
+      entry.setErrorState(exception, <ResultDescriptor>[]);
+    }, throwsArgumentError);
+  }
+
+  test_setErrorState_noException() {
+    ResultDescriptor result = new ResultDescriptor('test', null);
+    CacheEntry entry = new CacheEntry();
+    expect(() {
+      entry.setErrorState(null, <ResultDescriptor>[result]);
+    }, throwsArgumentError);
+  }
+
+  test_setErrorState_nullDescriptors() {
+    CaughtException exception = new CaughtException(null, null);
+    CacheEntry entry = new CacheEntry();
+    expect(() {
+      entry.setErrorState(exception, null);
+    }, throwsArgumentError);
+  }
+
   test_setState_error() {
     ResultDescriptor result = new ResultDescriptor('test', null);
     CacheEntry entry = new CacheEntry();
-    entry.setState(result, CacheState.ERROR);
-    expect(entry.getState(result), CacheState.ERROR);
-    expect(entry.getValue(result), isNull);
+    entry.setValue(result, 42);
+    // an invalid state change
+    expect(() {
+      entry.setState(result, CacheState.ERROR);
+    }, throwsArgumentError);
+    // no changes
+    expect(entry.getState(result), CacheState.VALID);
+    expect(entry.getValue(result), 42);
+  }
+
+  test_setState_flushed() {
+    ResultDescriptor result = new ResultDescriptor('test', 1);
+    CacheEntry entry = new CacheEntry();
+    // set VALID
+    entry.setValue(result, 10);
+    expect(entry.getState(result), CacheState.VALID);
+    expect(entry.getValue(result), 10);
+    // set FLUSHED
+    entry.setState(result, CacheState.FLUSHED);
+    expect(entry.getState(result), CacheState.FLUSHED);
+    expect(entry.getValue(result), 1);
+  }
+
+  test_setState_inProcess() {
+    ResultDescriptor result = new ResultDescriptor('test', 1);
+    CacheEntry entry = new CacheEntry();
+    // set VALID
+    entry.setValue(result, 10);
+    expect(entry.getState(result), CacheState.VALID);
+    expect(entry.getValue(result), 10);
+    // set IN_PROCESS
+    entry.setState(result, CacheState.IN_PROCESS);
+    expect(entry.getState(result), CacheState.IN_PROCESS);
+    expect(entry.getValue(result), 10);
   }
 
   test_setState_invalid() {
-    ResultDescriptor result = new ResultDescriptor('test', null);
+    ResultDescriptor result = new ResultDescriptor('test', 1);
     CacheEntry entry = new CacheEntry();
+    // set VALID
+    entry.setValue(result, 10);
+    expect(entry.getState(result), CacheState.VALID);
+    expect(entry.getValue(result), 10);
+    // set INVALID
     entry.setState(result, CacheState.INVALID);
     expect(entry.getState(result), CacheState.INVALID);
-    expect(entry.getValue(result), isNull);
+    expect(entry.getValue(result), 1);
   }
 
   test_setState_valid() {
diff --git a/pkg/analyzer/test/src/mock_sdk.dart b/pkg/analyzer/test/src/mock_sdk.dart
new file mode 100644
index 0000000..6716801
--- /dev/null
+++ b/pkg/analyzer/test/src/mock_sdk.dart
@@ -0,0 +1,310 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.src.mock_sdk;
+
+import 'package:analyzer/file_system/file_system.dart' as resource;
+import 'package:analyzer/file_system/memory_file_system.dart' as resource;
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+class MockSdk implements DartSdk {
+  static const _MockSdkLibrary LIB_CORE = const _MockSdkLibrary('dart:core',
+      '/lib/core/core.dart', '''
+library dart.core;
+
+import 'dart:async';
+
+class Object {
+  bool operator ==(other) => identical(this, other);
+  String toString() => 'a string';
+  int get hashCode => 0;
+}
+
+class Function {}
+class StackTrace {}
+class Symbol {}
+class Type {}
+
+abstract class Comparable<T> {
+  int compareTo(T other);
+}
+
+abstract class String implements Comparable<String> {
+  external factory String.fromCharCodes(Iterable<int> charCodes,
+                                        [int start = 0, int end]);
+  bool get isEmpty => false;
+  bool get isNotEmpty => false;
+  int get length => 0;
+  String toUpperCase();
+  List<int> get codeUnits;
+}
+
+class bool extends Object {}
+abstract class num implements Comparable<num> {
+  bool operator <(num other);
+  bool operator <=(num other);
+  bool operator >(num other);
+  bool operator >=(num other);
+  num operator +(num other);
+  num operator -(num other);
+  num operator *(num other);
+  num operator /(num other);
+  int toInt();
+  num abs();
+  int round();
+}
+abstract class int extends num {
+  bool get isEven => false;
+  int operator -();
+  external static int parse(String source,
+                            { int radix,
+                              int onError(String source) });
+}
+class double extends num {}
+class DateTime extends Object {}
+class Null extends Object {}
+
+class Deprecated extends Object {
+  final String expires;
+  const Deprecated(this.expires);
+}
+const Object deprecated = const Deprecated("next release");
+
+class Iterator<E> {
+  bool moveNext();
+  E get current;
+}
+
+abstract class Iterable<E> {
+  Iterator<E> get iterator;
+  bool get isEmpty;
+}
+
+abstract class List<E> implements Iterable<E> {
+  void add(E value);
+  E operator [](int index);
+  void operator []=(int index, E value);
+  Iterator<E> get iterator => null;
+  void clear();
+}
+
+abstract class Map<K, V> extends Object {
+  Iterable<K> get keys;
+}
+
+external bool identical(Object a, Object b);
+
+void print(Object object) {}
+''');
+
+  static const _MockSdkLibrary LIB_ASYNC = const _MockSdkLibrary('dart:async',
+      '/lib/async/async.dart', '''
+library dart.async;
+
+import 'dart:math';
+
+class Future<T> {
+  factory Future.delayed(Duration duration, [T computation()]) => null;
+  factory Future.value([value]) => null;
+  static Future wait(List<Future> futures) => null;
+}
+
+class Stream<T> {}
+abstract class StreamTransformer<S, T> {}
+''');
+
+  static const _MockSdkLibrary LIB_COLLECTION = const _MockSdkLibrary(
+      'dart:collection', '/lib/collection/collection.dart', '''
+library dart.collection;
+
+abstract class HashMap<K, V> implements Map<K, V> {}
+''');
+
+  static const _MockSdkLibrary LIB_CONVERT = const _MockSdkLibrary(
+      'dart:convert', '/lib/convert/convert.dart', '''
+library dart.convert;
+
+import 'dart:async';
+
+abstract class Converter<S, T> implements StreamTransformer {}
+class JsonDecoder extends Converter<String, Object> {}
+''');
+
+  static const _MockSdkLibrary LIB_MATH = const _MockSdkLibrary('dart:math',
+      '/lib/math/math.dart', '''
+library dart.math;
+const double E = 2.718281828459045;
+const double PI = 3.1415926535897932;
+const double LN10 =  2.302585092994046;
+num min(num a, num b) => 0;
+num max(num a, num b) => 0;
+external double cos(num x);
+external double sin(num x);
+external double sqrt(num x);
+class Random {
+  bool nextBool() => true;
+  double nextDouble() => 2.0;
+  int nextInt() => 1;
+}
+''');
+
+  static const _MockSdkLibrary LIB_HTML = const _MockSdkLibrary('dart:html',
+      '/lib/html/dartium/html_dartium.dart', '''
+library dart.html;
+class HtmlElement {}
+''');
+
+  static const List<SdkLibrary> LIBRARIES = const [
+    LIB_CORE,
+    LIB_ASYNC,
+    LIB_COLLECTION,
+    LIB_CONVERT,
+    LIB_MATH,
+    LIB_HTML,
+  ];
+
+  final resource.MemoryResourceProvider provider =
+      new resource.MemoryResourceProvider();
+
+  /**
+   * The [AnalysisContext] which is used for all of the sources.
+   */
+  InternalAnalysisContext _analysisContext;
+
+  MockSdk() {
+    LIBRARIES.forEach((_MockSdkLibrary library) {
+      provider.newFile(library.path, library.content);
+    });
+  }
+
+  @override
+  AnalysisContext get context {
+    if (_analysisContext == null) {
+      _analysisContext = new SdkAnalysisContext();
+      SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
+      _analysisContext.sourceFactory = factory;
+      ChangeSet changeSet = new ChangeSet();
+      for (String uri in uris) {
+        Source source = factory.forUri(uri);
+        changeSet.addedSource(source);
+      }
+      _analysisContext.applyChanges(changeSet);
+    }
+    return _analysisContext;
+  }
+
+  @override
+  List<SdkLibrary> get sdkLibraries => LIBRARIES;
+
+  @override
+  String get sdkVersion => throw unimplemented;
+
+  UnimplementedError get unimplemented => new UnimplementedError();
+
+  @override
+  List<String> get uris {
+    List<String> uris = <String>[];
+    for (SdkLibrary library in LIBRARIES) {
+      uris.add(library.shortName);
+    }
+    return uris;
+  }
+
+  @override
+  Source fromFileUri(Uri uri) {
+    String filePath = uri.path;
+    String libPath = '/lib';
+    if (!filePath.startsWith("$libPath/")) {
+      return null;
+    }
+    for (SdkLibrary library in LIBRARIES) {
+      String libraryPath = library.path;
+      if (filePath.replaceAll('\\', '/') == libraryPath) {
+        try {
+          resource.File file = provider.getResource(uri.path);
+          Uri dartUri = Uri.parse(library.shortName);
+          return file.createSource(dartUri);
+        } catch (exception) {
+          return null;
+        }
+      }
+      if (filePath.startsWith("$libraryPath/")) {
+        String pathInLibrary = filePath.substring(libraryPath.length + 1);
+        String path = '${library.shortName}/${pathInLibrary}';
+        try {
+          resource.File file = provider.getResource(uri.path);
+          Uri dartUri = new Uri(scheme: 'dart', path: path);
+          return file.createSource(dartUri);
+        } catch (exception) {
+          return null;
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
+  SdkLibrary getSdkLibrary(String dartUri) {
+    // getSdkLibrary() is only used to determine whether a library is internal
+    // to the SDK.  The mock SDK doesn't have any internals, so it's safe to
+    // return null.
+    return null;
+  }
+
+  @override
+  Source mapDartUri(String dartUri) {
+    const Map<String, String> uriToPath = const {
+      "dart:core": "/lib/core/core.dart",
+      "dart:html": "/lib/html/dartium/html_dartium.dart",
+      "dart:async": "/lib/async/async.dart",
+      "dart:collection": "/lib/collection/collection.dart",
+      "dart:convert": "/lib/convert/convert.dart",
+      "dart:math": "/lib/math/math.dart"
+    };
+
+    String path = uriToPath[dartUri];
+    if (path != null) {
+      resource.File file = provider.getResource(path);
+      Uri uri = new Uri(scheme: 'dart', path: dartUri.substring(5));
+      return file.createSource(uri);
+    }
+
+    // If we reach here then we tried to use a dartUri that's not in the
+    // table above.
+    return null;
+  }
+}
+
+class _MockSdkLibrary implements SdkLibrary {
+  final String shortName;
+  final String path;
+  final String content;
+
+  const _MockSdkLibrary(this.shortName, this.path, this.content);
+
+  @override
+  String get category => throw unimplemented;
+
+  @override
+  bool get isDart2JsLibrary => throw unimplemented;
+
+  @override
+  bool get isDocumented => throw unimplemented;
+
+  @override
+  bool get isImplementation => throw unimplemented;
+
+  @override
+  bool get isInternal => throw unimplemented;
+
+  @override
+  bool get isShared => throw unimplemented;
+
+  @override
+  bool get isVmLibrary => throw unimplemented;
+
+  UnimplementedError get unimplemented => new UnimplementedError();
+}
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 7f34808..c03b51d 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -4,62 +4,186 @@
 
 library test.src.task.dart_test;
 
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart'
-    hide AnalysisTask, ParseDartTask, ScanDartTask;
+    hide AnalysisTask, GetContentTask, ParseDartTask, ScanDartTask;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/task/driver.dart';
+import 'package:analyzer/src/task/general.dart';
+import 'package:analyzer/src/task/manager.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
+import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
 
-import '../../generated/resolver_test.dart';
 import '../../generated/test_support.dart';
 import '../../reflective_tests.dart';
+import '../mock_sdk.dart';
 
 main() {
   groupSep = ' | ';
+  runReflectiveTests(BuildClassConstructorsTaskTest);
   runReflectiveTests(BuildCompilationUnitElementTaskTest);
+  runReflectiveTests(BuildDirectiveElementsTaskTest);
+  runReflectiveTests(BuildEnumMemberElementsTaskTest);
+  runReflectiveTests(BuildExportSourceClosureTaskTest);
+  runReflectiveTests(BuildExportNamespaceTaskTest);
+  runReflectiveTests(BuildFunctionTypeAliasesTaskTest);
+  runReflectiveTests(BuildLibraryConstructorsTaskTest);
+  runReflectiveTests(BuildLibraryElementTaskTest);
+  runReflectiveTests(BuildPublicNamespaceTaskTest);
+  runReflectiveTests(BuildTypeProviderTaskTest);
   runReflectiveTests(ParseDartTaskTest);
+  runReflectiveTests(ResolveUnitTypeNamesTaskTest);
+  runReflectiveTests(ResolveLibraryTypeNamesTaskTest);
   runReflectiveTests(ScanDartTaskTest);
 }
 
 @reflectiveTest
-class BuildCompilationUnitElementTaskTest extends EngineTestCase {
+class BuildClassConstructorsTaskTest extends _AbstractDartTaskTest {
+  test_perform_ClassDeclaration_errors_mixinHasNoConstructors() {
+    Source source = _newSource('/test.dart', '''
+class B {
+  B({x});
+}
+class M {}
+class C extends B with M {}
+''');
+    LibraryElement libraryElement;
+    {
+      _computeResult(source, LIBRARY_ELEMENT5);
+      libraryElement = outputs[LIBRARY_ELEMENT5];
+    }
+    // prepare C
+    ClassElement c = libraryElement.getType('C');
+    expect(c, isNotNull);
+    // build constructors
+    _computeResult(c, CONSTRUCTORS);
+    expect(task, new isInstanceOf<BuildClassConstructorsTask>());
+    _fillErrorListener(CONSTRUCTORS_ERRORS);
+    errorListener.assertErrorsWithCodes(
+        <ErrorCode>[CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS]);
+  }
+
+  test_perform_ClassDeclaration_explicitConstructors() {
+    Source source = _newSource('/test.dart', '''
+class B {
+  B(p);
+}
+class C extends B {
+  C(int a, String b) {}
+}
+''');
+    LibraryElement libraryElement;
+    {
+      _computeResult(source, LIBRARY_ELEMENT5);
+      libraryElement = outputs[LIBRARY_ELEMENT5];
+    }
+    // prepare C
+    ClassElement c = libraryElement.getType('C');
+    expect(c, isNotNull);
+    // build constructors
+    _computeResult(c, CONSTRUCTORS);
+    expect(task, new isInstanceOf<BuildClassConstructorsTask>());
+    // no errors
+    expect(outputs[CONSTRUCTORS_ERRORS], isEmpty);
+    // explicit constructor
+    List<ConstructorElement> constructors = outputs[CONSTRUCTORS];
+    expect(constructors, hasLength(1));
+    expect(constructors[0].parameters, hasLength(2));
+  }
+
+  test_perform_ClassTypeAlias() {
+    Source source = _newSource('/test.dart', '''
+class B {
+  B(int i);
+}
+class M1 {}
+class M2 {}
+
+class C2 = C1 with M2;
+class C1 = B with M1;
+''');
+    LibraryElement libraryElement;
+    {
+      _computeResult(source, LIBRARY_ELEMENT5);
+      libraryElement = outputs[LIBRARY_ELEMENT5];
+    }
+    // prepare C2
+    ClassElement class2 = libraryElement.getType('C2');
+    expect(class2, isNotNull);
+    // build constructors
+    _computeResult(class2, CONSTRUCTORS);
+    expect(task, new isInstanceOf<BuildClassConstructorsTask>());
+    List<ConstructorElement> constructors = outputs[CONSTRUCTORS];
+    expect(constructors, hasLength(1));
+    expect(constructors[0].parameters, hasLength(1));
+  }
+
+  test_perform_ClassTypeAlias_errors_mixinHasNoConstructors() {
+    Source source = _newSource('/test.dart', '''
+class B {
+  B({x});
+}
+class M {}
+class C = B with M;
+''');
+    LibraryElement libraryElement;
+    {
+      _computeResult(source, LIBRARY_ELEMENT5);
+      libraryElement = outputs[LIBRARY_ELEMENT5];
+    }
+    // prepare C
+    ClassElement c = libraryElement.getType('C');
+    expect(c, isNotNull);
+    // build constructors
+    _computeResult(c, CONSTRUCTORS);
+    expect(task, new isInstanceOf<BuildClassConstructorsTask>());
+    _fillErrorListener(CONSTRUCTORS_ERRORS);
+    errorListener.assertErrorsWithCodes(
+        <ErrorCode>[CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS]);
+  }
+}
+
+@reflectiveTest
+class BuildCompilationUnitElementTaskTest extends _AbstractDartTaskTest {
   test_buildInputs() {
-    AnalysisTarget target = new TestSource();
+    LibraryUnitTarget target = new LibraryUnitTarget(emptySource, emptySource);
     Map<String, TaskInput> inputs =
         BuildCompilationUnitElementTask.buildInputs(target);
     expect(inputs, isNotNull);
-    expect(inputs, hasLength(1));
-    expect(inputs[BuildCompilationUnitElementTask.PARSED_UNIT_INPUT_NAME],
-        isNotNull);
+    expect(inputs.keys, unorderedEquals(
+        [BuildCompilationUnitElementTask.PARSED_UNIT_INPUT_NAME]));
   }
 
   test_constructor() {
-    AnalysisContext context = AnalysisContextFactory.contextWithCore();
-    AnalysisTarget target = new TestSource();
     BuildCompilationUnitElementTask task =
-        new BuildCompilationUnitElementTask(context, target);
+        new BuildCompilationUnitElementTask(context, emptySource);
     expect(task, isNotNull);
     expect(task.context, context);
-    expect(task.target, target);
+    expect(task.target, emptySource);
   }
 
   test_createTask() {
-    AnalysisContext context = AnalysisContextFactory.contextWithCore();
-    AnalysisTarget target = new TestSource();
     BuildCompilationUnitElementTask task =
-        BuildCompilationUnitElementTask.createTask(context, target);
+        BuildCompilationUnitElementTask.createTask(context, emptySource);
     expect(task, isNotNull);
     expect(task.context, context);
-    expect(task.target, target);
+    expect(task.target, emptySource);
   }
 
   test_description() {
-    AnalysisTarget target = new TestSource();
     BuildCompilationUnitElementTask task =
-        new BuildCompilationUnitElementTask(null, target);
+        new BuildCompilationUnitElementTask(null, emptySource);
     expect(task.description, isNotNull);
   }
 
@@ -69,81 +193,910 @@
   }
 
   test_perform_library() {
-    BuildCompilationUnitElementTask task = _performBuildTask(r'''
+    _performBuildTask(r'''
 library lib;
 import 'lib2.dart';
 export 'lib3.dart';
 part 'part.dart';
-class A {''');
-
-    expect(task.caughtException, isNull);
-    Map<ResultDescriptor<dynamic>, dynamic> outputs = task.outputs;
-    expect(outputs, hasLength(2));
+class A {}
+class B = Object with A;
+''');
+    expect(outputs, hasLength(3));
+    expect(outputs[CLASS_ELEMENTS], hasLength(2));
     expect(outputs[COMPILATION_UNIT_ELEMENT], isNotNull);
-    expect(outputs[BUILT_UNIT], isNotNull);
+    expect(outputs[RESOLVED_UNIT1], isNotNull);
   }
 
-  BuildCompilationUnitElementTask _performBuildTask(String content) {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    AnalysisTarget target = new TestSource();
-
-    ScanDartTask scanTask = new ScanDartTask(context, target);
-    scanTask.inputs = {ScanDartTask.CONTENT_INPUT_NAME: content};
-    scanTask.perform();
-    Map<ResultDescriptor, dynamic> scanOutputs = scanTask.outputs;
-
-    ParseDartTask parseTask = new ParseDartTask(context, target);
-    parseTask.inputs = {
-      ParseDartTask.LINE_INFO_INPUT_NAME: scanOutputs[LINE_INFO],
-      ParseDartTask.TOKEN_STREAM_INPUT_NAME: scanOutputs[TOKEN_STREAM]
-    };
-    parseTask.perform();
-    Map<ResultDescriptor, dynamic> parseOutputs = parseTask.outputs;
-
-    BuildCompilationUnitElementTask buildTask =
-        new BuildCompilationUnitElementTask(context, target);
-    buildTask.inputs = {
-      BuildCompilationUnitElementTask.PARSED_UNIT_INPUT_NAME:
-          parseOutputs[PARSED_UNIT]
-    };
-    buildTask.perform();
-
-    return buildTask;
+  void _performBuildTask(String content) {
+    Source source = _newSource('/test.dart', content);
+    AnalysisTarget target = new LibraryUnitTarget(source, source);
+    _computeResult(target, RESOLVED_UNIT1);
+    expect(task, new isInstanceOf<BuildCompilationUnitElementTask>());
   }
 }
 
 @reflectiveTest
-class ParseDartTaskTest extends EngineTestCase {
-  test_buildInputs() {
-    AnalysisTarget target = new TestSource();
-    Map<String, TaskInput> inputs = ParseDartTask.buildInputs(target);
-    expect(inputs, isNotNull);
-    expect(inputs, hasLength(2));
-    expect(inputs[ParseDartTask.LINE_INFO_INPUT_NAME], isNotNull);
-    expect(inputs[ParseDartTask.TOKEN_STREAM_INPUT_NAME], isNotNull);
-  }
-
+class BuildDirectiveElementsTaskTest extends _AbstractDartTaskTest {
   test_constructor() {
-    AnalysisContext context = AnalysisContextFactory.contextWithCore();
-    AnalysisTarget target = new TestSource();
-    ParseDartTask task = new ParseDartTask(context, target);
+    BuildDirectiveElementsTask task =
+        new BuildDirectiveElementsTask(context, emptySource);
     expect(task, isNotNull);
     expect(task.context, context);
-    expect(task.target, target);
+    expect(task.target, emptySource);
   }
 
   test_createTask() {
-    AnalysisContext context = AnalysisContextFactory.contextWithCore();
-    AnalysisTarget target = new TestSource();
-    ParseDartTask task = ParseDartTask.createTask(context, target);
+    BuildDirectiveElementsTask task =
+        BuildDirectiveElementsTask.createTask(context, emptySource);
     expect(task, isNotNull);
     expect(task.context, context);
-    expect(task.target, target);
+    expect(task.target, emptySource);
   }
 
   test_description() {
-    AnalysisTarget target = new TestSource();
-    ParseDartTask task = new ParseDartTask(null, target);
+    BuildDirectiveElementsTask task =
+        new BuildDirectiveElementsTask(null, emptySource);
+    expect(task.description, isNotNull);
+  }
+
+  test_descriptor() {
+    TaskDescriptor descriptor = BuildDirectiveElementsTask.DESCRIPTOR;
+    expect(descriptor, isNotNull);
+  }
+
+  test_perform() {
+    List<Source> sources = _newSources({
+      '/libA.dart': '''
+library libA;
+import 'libB.dart';
+export 'libC.dart';
+''',
+      '/libB.dart': '''
+library libB;
+''',
+      '/libC.dart': '''
+library libC;
+'''
+    });
+    Source sourceA = sources[0];
+    Source sourceB = sources[1];
+    Source sourceC = sources[2];
+    // perform task
+    _computeResult(sourceA, LIBRARY_ELEMENT2);
+    expect(task, new isInstanceOf<BuildDirectiveElementsTask>());
+    // prepare outputs
+    LibraryElement libraryElementA = outputs[LIBRARY_ELEMENT2];
+    LibraryElement libraryElementB = _getImportLibraryInput(sourceB);
+    LibraryElement libraryElementC = _getExportLibraryInput(sourceC);
+    // no errors
+    _assertErrorsWithCodes([]);
+    // validate directives
+    CompilationUnit libraryUnitA = context
+        .getCacheEntry(new LibraryUnitTarget(sourceA, sourceA))
+        .getValue(RESOLVED_UNIT1);
+    {
+      ImportDirective importNode = libraryUnitA.directives[1];
+      ImportElement importElement = importNode.element;
+      expect(importElement, isNotNull);
+      expect(importElement.importedLibrary, libraryElementB);
+      expect(importElement.prefix, isNull);
+      expect(importElement.nameOffset, 14);
+      expect(importElement.uriOffset, 21);
+      expect(importElement.uriEnd, 32);
+    }
+    {
+      ExportDirective exportNode = libraryUnitA.directives[2];
+      ExportElement exportElement = exportNode.element;
+      expect(exportElement, isNotNull);
+      expect(exportElement.exportedLibrary, libraryElementC);
+      expect(exportElement.nameOffset, 34);
+      expect(exportElement.uriOffset, 41);
+      expect(exportElement.uriEnd, 52);
+    }
+    // validate LibraryElement
+    expect(libraryElementA.hasExtUri, isFalse);
+    // has an artificial "dart:core" import
+    {
+      List<ImportElement> imports = libraryElementA.imports;
+      expect(imports, hasLength(2));
+      expect(imports[1].importedLibrary.isDartCore, isTrue);
+    }
+  }
+
+  test_perform_combinators() {
+    List<Source> sources = _newSources({
+      '/libA.dart': '''
+library libA;
+import 'libB.dart' show A, B hide C, D;
+''',
+      '/libB.dart': '''
+library libB;
+'''
+    });
+    Source sourceA = sources[0];
+    // perform task
+    _computeResult(sourceA, LIBRARY_ELEMENT2);
+    expect(task, new isInstanceOf<BuildDirectiveElementsTask>());
+    // prepare outputs
+    CompilationUnit libraryUnitA = context
+        .getCacheEntry(new LibraryUnitTarget(sourceA, sourceA))
+        .getValue(RESOLVED_UNIT1);
+    // no errors
+    _assertErrorsWithCodes([]);
+    // validate directives
+    ImportDirective importNode = libraryUnitA.directives[1];
+    ImportElement importElement = importNode.element;
+    List<NamespaceCombinator> combinators = importElement.combinators;
+    expect(combinators, hasLength(2));
+    {
+      ShowElementCombinator combinator = combinators[0];
+      expect(combinator.offset, 33);
+      expect(combinator.end, 42);
+      expect(combinator.shownNames, ['A', 'B']);
+    }
+    {
+      HideElementCombinator combinator = combinators[1];
+      expect(combinator.hiddenNames, ['C', 'D']);
+    }
+  }
+
+  test_perform_error_exportOfNonLibrary() {
+    List<Source> sources = _newSources({
+      '/libA.dart': '''
+library libA;
+export 'part.dart';
+''',
+      '/part.dart': '''
+part of notLib;
+'''
+    });
+    Source sourceA = sources[0];
+    // perform task
+    _computeResult(sourceA, LIBRARY_ELEMENT2);
+    expect(task, new isInstanceOf<BuildDirectiveElementsTask>());
+    // validate errors
+    _assertErrorsWithCodes([CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY]);
+  }
+
+  test_perform_error_importOfNonLibrary() {
+    List<Source> sources = _newSources({
+      '/libA.dart': '''
+library libA;
+import 'part.dart';
+''',
+      '/part.dart': '''
+part of notLib;
+'''
+    });
+    Source sourceA = sources[0];
+    // perform task
+    _computeResult(sourceA, LIBRARY_ELEMENT2);
+    expect(task, new isInstanceOf<BuildDirectiveElementsTask>());
+    // validate errors
+    _assertErrorsWithCodes([CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY]);
+  }
+
+  test_perform_hasExtUri() {
+    List<Source> sources = _newSources({
+      '/lib.dart': '''
+import 'dart-ext:doesNotExist.dart';
+'''
+    });
+    Source source = sources[0];
+    // perform task
+    _computeResult(source, LIBRARY_ELEMENT2);
+    expect(task, new isInstanceOf<BuildDirectiveElementsTask>());
+    // prepare outputs
+    LibraryElement libraryElement = outputs[LIBRARY_ELEMENT2];
+    expect(libraryElement.hasExtUri, isTrue);
+  }
+
+  test_perform_importPrefix() {
+    List<Source> sources = _newSources({
+      '/libA.dart': '''
+library libA;
+import 'libB.dart' as pref;
+import 'libC.dart' as pref;
+''',
+      '/libB.dart': '''
+library libB;
+''',
+      '/libC.dart': '''
+library libC;
+'''
+    });
+    Source sourceA = sources[0];
+    Source sourceB = sources[1];
+    // perform task
+    _computeResult(sourceA, LIBRARY_ELEMENT2);
+    expect(task, new isInstanceOf<BuildDirectiveElementsTask>());
+    // prepare outputs
+    CompilationUnit libraryUnitA = context
+        .getCacheEntry(new LibraryUnitTarget(sourceA, sourceA))
+        .getValue(RESOLVED_UNIT1);
+    // validate directives
+    {
+      ImportDirective importNodeB = libraryUnitA.directives[1];
+      SimpleIdentifier prefixNodeB = importNodeB.prefix;
+      ImportElement importElementB = importNodeB.element;
+      PrefixElement prefixElement = importElementB.prefix;
+      expect(importElementB, isNotNull);
+      expect(importElementB.importedLibrary, _getImportLibraryInput(sourceB));
+      expect(prefixElement, isNotNull);
+      expect(importElementB.prefixOffset, prefixElement.nameOffset);
+      expect(prefixNodeB.staticElement, prefixElement);
+      // PrefixElement "pref" is shared
+      ImportDirective importNodeC = libraryUnitA.directives[2];
+      SimpleIdentifier prefixNodeC = importNodeC.prefix;
+      ImportElement importElementC = importNodeC.element;
+      expect(prefixNodeC.staticElement, prefixElement);
+      expect(importElementC.prefix, prefixElement);
+    }
+  }
+
+  void _assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes) {
+    _fillErrorListener(BUILD_DIRECTIVES_ERRORS);
+    errorListener.assertErrorsWithCodes(expectedErrorCodes);
+  }
+
+  _getExportLibraryInput(Source source) {
+    var key = BuildDirectiveElementsTask.EXPORTS_LIBRARY_ELEMENT_INPUT_NAME;
+    return task.inputs[key][source];
+  }
+
+  _getImportLibraryInput(Source source) {
+    var key = BuildDirectiveElementsTask.IMPORTS_LIBRARY_ELEMENT_INPUT_NAME;
+    return task.inputs[key][source];
+  }
+}
+
+@reflectiveTest
+class BuildEnumMemberElementsTaskTest extends _AbstractDartTaskTest {
+  test_perform() {
+    Source source = _newSource('/test.dart', '''
+enum MyEnum {
+  A, B
+}
+''');
+    _computeResult(new LibraryUnitTarget(source, source), RESOLVED_UNIT2);
+    expect(task, new isInstanceOf<BuildEnumMemberElementsTask>());
+    CompilationUnit unit = outputs[RESOLVED_UNIT2];
+    // validate Element
+    ClassElement enumElement = unit.element.getEnum('MyEnum');
+    List<FieldElement> fields = enumElement.fields;
+    expect(fields, hasLength(4));
+    {
+      FieldElementImpl index = fields[0];
+      expect(index, isNotNull);
+      expect(index.name, 'index');
+      expect(index.isStatic, isFalse);
+      expect(index.evaluationResult, isNull);
+      _assertGetter(index);
+    }
+    {
+      ConstFieldElementImpl values = fields[1];
+      expect(values, isNotNull);
+      expect(values.name, 'values');
+      expect(values.isStatic, isTrue);
+      expect(values.evaluationResult, isNotNull);
+      _assertGetter(values);
+    }
+    {
+      ConstFieldElementImpl constant = fields[2];
+      expect(constant, isNotNull);
+      expect(constant.name, 'A');
+      expect(constant.isStatic, isTrue);
+      expect(constant.evaluationResult, isNotNull);
+      _assertGetter(constant);
+    }
+    {
+      ConstFieldElementImpl constant = fields[3];
+      expect(constant, isNotNull);
+      expect(constant.name, 'B');
+      expect(constant.isStatic, isTrue);
+      expect(constant.evaluationResult, isNotNull);
+      _assertGetter(constant);
+    }
+    // validate nodes
+    EnumDeclaration enumNode = unit.declarations[0];
+    expect(enumNode.name.staticElement, same(enumElement));
+    expect(enumNode.constants[0].element, same(enumElement.getField('A')));
+    expect(enumNode.constants[1].element, same(enumElement.getField('B')));
+  }
+
+  static void _assertGetter(FieldElement field) {
+    PropertyAccessorElement getter = field.getter;
+    expect(getter, isNotNull);
+    expect(getter.variable, same(field));
+    expect(getter.type, isNotNull);
+  }
+}
+
+@reflectiveTest
+class BuildExportNamespaceTaskTest extends _AbstractDartTaskTest {
+  test_perform_entryPoint() {
+    Source sourceA = _newSource('/a.dart', '''
+library lib_a;
+export 'b.dart';
+''');
+    Source sourceB = _newSource('/b.dart', '''
+library lib_b;
+main() {}
+''');
+    _computeResult(sourceA, LIBRARY_ELEMENT4);
+    expect(task, new isInstanceOf<BuildExportNamespaceTask>());
+    // validate
+    {
+      LibraryElement library = outputs[LIBRARY_ELEMENT4];
+      FunctionElement entryPoint = library.entryPoint;
+      expect(entryPoint, isNotNull);
+      expect(entryPoint.source, sourceB);
+    }
+  }
+
+  test_perform_hideCombinator() {
+    Source sourceA = _newSource('/a.dart', '''
+library lib_a;
+export 'b.dart' hide B1;
+class A1 {}
+class A2 {}
+class _A3 {}
+''');
+    _newSource('/b.dart', '''
+library lib_b;
+class B1 {}
+class B2 {}
+class B3 {}
+class _B4 {}
+''');
+    _newSource('/c.dart', '''
+library lib_c;
+class C1 {}
+class C2 {}
+class C3 {}
+''');
+    _computeResult(sourceA, LIBRARY_ELEMENT4);
+    expect(task, new isInstanceOf<BuildExportNamespaceTask>());
+    // validate
+    {
+      LibraryElement library = outputs[LIBRARY_ELEMENT4];
+      Namespace namespace = library.exportNamespace;
+      Iterable<String> definedKeys = namespace.definedNames.keys;
+      expect(definedKeys, unorderedEquals(['A1', 'A2', 'B2', 'B3']));
+    }
+  }
+
+  test_perform_showCombinator() {
+    Source sourceA = _newSource('/a.dart', '''
+library lib_a;
+export 'b.dart' show B1;
+class A1 {}
+class A2 {}
+class _A3 {}
+''');
+    _newSource('/b.dart', '''
+library lib_b;
+class B1 {}
+class B2 {}
+class _B3 {}
+''');
+    _computeResult(sourceA, LIBRARY_ELEMENT4);
+    expect(task, new isInstanceOf<BuildExportNamespaceTask>());
+    // validate
+    {
+      LibraryElement library = outputs[LIBRARY_ELEMENT4];
+      Namespace namespace = library.exportNamespace;
+      Iterable<String> definedKeys = namespace.definedNames.keys;
+      expect(definedKeys, unorderedEquals(['A1', 'A2', 'B1']));
+    }
+  }
+
+  test_perform_showCombinator_setter() {
+    Source sourceA = _newSource('/a.dart', '''
+library lib_a;
+export 'b.dart' show topLevelB;
+class A {}
+''');
+    _newSource('/b.dart', '''
+library lib_b;
+int topLevelB;
+''');
+    _computeResult(sourceA, LIBRARY_ELEMENT4);
+    expect(task, new isInstanceOf<BuildExportNamespaceTask>());
+    // validate
+    {
+      LibraryElement library = outputs[LIBRARY_ELEMENT4];
+      Namespace namespace = library.exportNamespace;
+      Iterable<String> definedKeys = namespace.definedNames.keys;
+      expect(definedKeys, unorderedEquals(['A', 'topLevelB', 'topLevelB=']));
+    }
+  }
+}
+
+@reflectiveTest
+class BuildExportSourceClosureTaskTest extends _AbstractDartTaskTest {
+  test_perform() {
+    Source sourceA = _newSource('/a.dart', '''
+library lib_a;
+export 'b.dart';
+''');
+    Source sourceB = _newSource('/b.dart', '''
+library lib_b;
+export 'b.dart';
+''');
+    Source sourceC = _newSource('/c.dart', '''
+library lib_c;
+export 'a.dart';
+''');
+    Source sourceD = _newSource('/d.dart', '''
+library lib_d;
+''');
+    // a.dart
+    {
+      _computeResult(sourceA, EXPORT_SOURCE_CLOSURE);
+      expect(task, new isInstanceOf<BuildExportSourceClosureTask>());
+      List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
+      expect(closure, unorderedEquals([sourceA, sourceB]));
+    }
+    // c.dart
+    {
+      _computeResult(sourceC, EXPORT_SOURCE_CLOSURE);
+      expect(task, new isInstanceOf<BuildExportSourceClosureTask>());
+      List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
+      expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
+    }
+    // d.dart
+    {
+      _computeResult(sourceD, EXPORT_SOURCE_CLOSURE);
+      expect(task, new isInstanceOf<BuildExportSourceClosureTask>());
+      List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
+      expect(closure, unorderedEquals([sourceD]));
+    }
+  }
+}
+
+@reflectiveTest
+class BuildFunctionTypeAliasesTaskTest extends _AbstractDartTaskTest {
+  test_perform() {
+    Source source = _newSource('/test.dart', '''
+typedef int F(G g);
+typedef String G(int p);
+''');
+    LibraryUnitTarget target = new LibraryUnitTarget(source, source);
+    _computeResult(target, RESOLVED_UNIT3);
+    expect(task, new isInstanceOf<BuildFunctionTypeAliasesTask>());
+    // validate
+    CompilationUnit unit = outputs[RESOLVED_UNIT3];
+    FunctionTypeAlias nodeF = unit.declarations[0];
+    FunctionTypeAlias nodeG = unit.declarations[1];
+    {
+      FormalParameter parameter = nodeF.parameters.parameters[0];
+      DartType parameterType = parameter.element.type;
+      Element returnTypeElement = nodeF.returnType.type.element;
+      expect(returnTypeElement.displayName, 'int');
+      expect(parameterType.element, nodeG.element);
+    }
+    {
+      FormalParameter parameter = nodeG.parameters.parameters[0];
+      DartType parameterType = parameter.element.type;
+      expect(nodeG.returnType.type.element.displayName, 'String');
+      expect(parameterType.element.displayName, 'int');
+    }
+  }
+
+  test_perform_errors() {
+    Source source = _newSource('/test.dart', '''
+typedef int F(NoSuchType p);
+''');
+    LibraryUnitTarget target = new LibraryUnitTarget(source, source);
+    _computeResult(target, BUILD_FUNCTION_TYPE_ALIASES_ERRORS);
+    expect(task, new isInstanceOf<BuildFunctionTypeAliasesTask>());
+    // validate
+    _fillErrorListener(BUILD_FUNCTION_TYPE_ALIASES_ERRORS);
+    errorListener
+        .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
+  }
+}
+
+@reflectiveTest
+class BuildLibraryConstructorsTaskTest extends _AbstractDartTaskTest {
+  test_perform() {
+    Source source = _newSource('/test.dart', '''
+class B {
+  B(int i);
+}
+class M1 {}
+class M2 {}
+
+class C2 = C1 with M2;
+class C1 = B with M1;
+class C3 = B with M2;
+''');
+    _computeResult(source, LIBRARY_ELEMENT6);
+    expect(task, new isInstanceOf<BuildLibraryConstructorsTask>());
+    LibraryElement libraryElement = outputs[LIBRARY_ELEMENT6];
+    // C1
+    {
+      ClassElement classElement = libraryElement.getType('C2');
+      List<ConstructorElement> constructors = classElement.constructors;
+      expect(constructors, hasLength(1));
+      expect(constructors[0].parameters, hasLength(1));
+    }
+    // C3
+    {
+      ClassElement classElement = libraryElement.getType('C3');
+      List<ConstructorElement> constructors = classElement.constructors;
+      expect(constructors, hasLength(1));
+      expect(constructors[0].parameters, hasLength(1));
+    }
+  }
+}
+
+@reflectiveTest
+class BuildLibraryElementTaskTest extends _AbstractDartTaskTest {
+  Source librarySource;
+  CompilationUnit libraryUnit;
+  CompilationUnitElement libraryUnitElement;
+  List<CompilationUnit> partUnits;
+
+  LibraryElement libraryElement;
+
+  test_constructor() {
+    BuildLibraryElementTask task =
+        new BuildLibraryElementTask(context, emptySource);
+    expect(task, isNotNull);
+    expect(task.context, context);
+    expect(task.target, emptySource);
+  }
+
+  test_createTask() {
+    BuildLibraryElementTask task =
+        BuildLibraryElementTask.createTask(context, emptySource);
+    expect(task, isNotNull);
+    expect(task.context, context);
+    expect(task.target, emptySource);
+  }
+
+  test_description() {
+    BuildLibraryElementTask task =
+        new BuildLibraryElementTask(null, emptySource);
+    expect(task.description, isNotNull);
+  }
+
+  test_descriptor() {
+    TaskDescriptor descriptor = BuildLibraryElementTask.DESCRIPTOR;
+    expect(descriptor, isNotNull);
+  }
+
+  test_perform() {
+    _performBuildTask({
+      '/lib.dart': '''
+library lib;
+part 'part1.dart';
+part 'part2.dart';
+''',
+      '/part1.dart': '''
+part of lib;
+''',
+      '/part2.dart': '''
+part of lib;
+'''
+    });
+    expect(outputs, hasLength(5));
+    // simple outputs
+    expect(outputs[BUILD_LIBRARY_ERRORS], isEmpty);
+    expect(outputs[IS_LAUNCHABLE], isFalse);
+    expect(outputs[HAS_HTML_IMPORT], isFalse);
+    // LibraryElement output
+    expect(libraryElement, isNotNull);
+    expect(libraryElement.entryPoint, isNull);
+    expect(libraryElement.source, same(librarySource));
+    expect(libraryElement.definingCompilationUnit, libraryUnitElement);
+    expect(libraryElement.parts,
+        unorderedEquals([partUnits[0].element, partUnits[1].element]));
+    // LibraryElement references
+    expect((libraryUnit.directives[0] as LibraryDirective).element,
+        same(libraryElement));
+    expect((partUnits[0].directives[0] as PartOfDirective).element,
+        same(libraryElement));
+    expect((partUnits[1].directives[0] as PartOfDirective).element,
+        same(libraryElement));
+    // CompilationUnitElement(s)
+    CompilationUnitElement firstPart;
+    CompilationUnitElement secondPart;
+    if (partUnits[0].element.uri == 'part1.dart') {
+      firstPart = partUnits[0].element;
+      secondPart = partUnits[1].element;
+    } else {
+      firstPart = partUnits[1].element;
+      secondPart = partUnits[0].element;
+    }
+    expect(firstPart.uri, 'part1.dart');
+    expect(firstPart.uriOffset, 18);
+    expect(firstPart.uriEnd, 30);
+    expect(
+        (libraryUnit.directives[1] as PartDirective).element, same(firstPart));
+
+    expect(secondPart.uri, 'part2.dart');
+    expect(secondPart.uriOffset, 37);
+    expect(secondPart.uriEnd, 49);
+    expect(
+        (libraryUnit.directives[2] as PartDirective).element, same(secondPart));
+  }
+
+  test_perform_classElements() {
+    _performBuildTask({
+      '/lib.dart': '''
+library lib;
+part 'part1.dart';
+part 'part2.dart';
+class A {}
+''',
+      '/part1.dart': '''
+part of lib;
+class B {}
+''',
+      '/part2.dart': '''
+part of lib;
+class C {}
+'''
+    });
+    List<ClassElement> classElements = outputs[CLASS_ELEMENTS];
+    List<String> classNames = classElements.map((c) => c.displayName).toList();
+    expect(classNames, unorderedEquals(['A', 'B', 'C']));
+  }
+
+  test_perform_error_missingLibraryDirectiveWithPart_hasCommon() {
+    _performBuildTask({
+      '/lib.dart': '''
+part 'partA.dart';
+part 'partB.dart';
+''',
+      '/partA.dart': '''
+part of my_lib;
+        ''',
+      '/partB.dart': '''
+part of my_lib;
+'''
+    });
+    _assertErrorsWithCodes(
+        [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
+    AnalysisError error = errorListener.errors[0];
+    expect(error.getProperty(ErrorProperty.PARTS_LIBRARY_NAME), 'my_lib');
+  }
+
+  test_perform_error_missingLibraryDirectiveWithPart_noCommon() {
+    _performBuildTask({
+      '/lib.dart': '''
+part 'partA.dart';
+part 'partB.dart';
+''',
+      '/partA.dart': '''
+part of libA;
+        ''',
+      '/partB.dart': '''
+part of libB;
+'''
+    });
+    _assertErrorsWithCodes(
+        [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
+    AnalysisError error = errorListener.errors[0];
+    expect(error.getProperty(ErrorProperty.PARTS_LIBRARY_NAME), isNull);
+  }
+
+  test_perform_error_partOfDifferentLibrary() {
+    _performBuildTask({
+      '/lib.dart': '''
+library lib;
+part 'part.dart';
+''',
+      '/part.dart': '''
+part of someOtherLib;
+'''
+    });
+    _assertErrorsWithCodes([StaticWarningCode.PART_OF_DIFFERENT_LIBRARY]);
+  }
+
+  test_perform_error_partOfNonPart() {
+    _performBuildTask({
+      '/lib.dart': '''
+library lib;
+part 'part.dart';
+''',
+      '/part.dart': '''
+// no part of
+'''
+    });
+    _assertErrorsWithCodes([CompileTimeErrorCode.PART_OF_NON_PART]);
+  }
+
+  test_perform_hasHtmlImport() {
+    _performBuildTask({
+      '/lib.dart': '''
+import 'dart:html';
+'''
+    });
+    expect(outputs[HAS_HTML_IMPORT], isTrue);
+  }
+
+  test_perform_isLaunchable_inDefiningUnit() {
+    _performBuildTask({
+      '/lib.dart': '''
+library lib;
+main() {
+}
+'''
+    });
+    expect(outputs[IS_LAUNCHABLE], isTrue);
+    expect(libraryElement.entryPoint, isNotNull);
+  }
+
+  test_perform_isLaunchable_inPartUnit() {
+    _performBuildTask({
+      '/lib.dart': '''
+library lib;
+part 'part.dart';
+''',
+      '/part.dart': '''
+part of lib;
+main() {
+}
+'''
+    });
+    expect(outputs[IS_LAUNCHABLE], isTrue);
+    expect(libraryElement.entryPoint, isNotNull);
+  }
+
+  test_perform_patchTopLevelAccessors() {
+    _performBuildTask({
+      '/lib.dart': '''
+library lib;
+part 'part1.dart';
+part 'part2.dart';
+''',
+      '/part1.dart': '''
+part of lib;
+int get test => 0;
+''',
+      '/part2.dart': '''
+part of lib;
+void set test(_) {}
+'''
+    });
+    CompilationUnitElement unitElement1 = partUnits[0].element;
+    CompilationUnitElement unitElement2 = partUnits[1].element;
+    PropertyAccessorElement getter = unitElement1.accessors[0];
+    PropertyAccessorElement setter = unitElement2.accessors[0];
+    PropertyInducingElement variable = getter.variable;
+    expect(getter.isGetter, isTrue);
+    expect(setter.isSetter, isTrue);
+    expect(variable, isNotNull);
+    expect(setter.variable, same(variable));
+    expect(unitElement1.topLevelVariables, [variable]);
+    expect(unitElement2.topLevelVariables, [variable]);
+  }
+
+  void _assertErrorsWithCodes(List<ErrorCode> expectedErrorCodes) {
+    _fillErrorListener(BUILD_LIBRARY_ERRORS);
+    errorListener.assertErrorsWithCodes(expectedErrorCodes);
+  }
+
+  void _performBuildTask(Map<String, String> sourceMap) {
+    List<Source> sources = _newSources(sourceMap);
+    Source libSource = sources.first;
+    _computeResult(libSource, LIBRARY_ELEMENT1);
+    expect(task, new isInstanceOf<BuildLibraryElementTask>());
+    libraryUnit = context
+        .getCacheEntry(new LibraryUnitTarget(libSource, libSource))
+        .getValue(RESOLVED_UNIT1);
+    libraryUnitElement = libraryUnit.element;
+    librarySource = libraryUnitElement.source;
+    libraryElement = outputs[LIBRARY_ELEMENT1];
+    partUnits = task.inputs[BuildLibraryElementTask.PARTS_UNIT_INPUT];
+  }
+}
+
+@reflectiveTest
+class BuildPublicNamespaceTaskTest extends _AbstractDartTaskTest {
+  test_buildInputs() {
+    Map<String, TaskInput> inputs =
+        BuildPublicNamespaceTask.buildInputs(emptySource);
+    expect(inputs, isNotNull);
+    expect(
+        inputs.keys, unorderedEquals([BuildPublicNamespaceTask.LIBRARY_INPUT]));
+  }
+
+  test_constructor() {
+    BuildPublicNamespaceTask task =
+        new BuildPublicNamespaceTask(context, emptySource);
+    expect(task, isNotNull);
+    expect(task.context, context);
+    expect(task.target, emptySource);
+  }
+
+  test_createTask() {
+    BuildPublicNamespaceTask task =
+        BuildPublicNamespaceTask.createTask(context, emptySource);
+    expect(task, isNotNull);
+    expect(task.context, context);
+    expect(task.target, emptySource);
+  }
+
+  test_description() {
+    BuildPublicNamespaceTask task =
+        new BuildPublicNamespaceTask(null, emptySource);
+    expect(task.description, isNotNull);
+  }
+
+  test_descriptor() {
+    TaskDescriptor descriptor = BuildPublicNamespaceTask.DESCRIPTOR;
+    expect(descriptor, isNotNull);
+  }
+
+  test_perform() {
+    List<Source> sources = _newSources({
+      '/lib.dart': '''
+library lib;
+part 'part.dart';
+a() {}
+_b() {}
+''',
+      '/part.dart': '''
+part of lib;
+_c() {}
+d() {}
+'''
+    });
+    _computeResult(sources.first, LIBRARY_ELEMENT3);
+    expect(task, new isInstanceOf<BuildPublicNamespaceTask>());
+    // validate
+    LibraryElement library = outputs[LIBRARY_ELEMENT3];
+    Namespace namespace = library.publicNamespace;
+    expect(namespace.definedNames.keys, unorderedEquals(['a', 'd']));
+  }
+}
+
+@reflectiveTest
+class BuildTypeProviderTaskTest extends _AbstractDartTaskTest {
+  test_perform() {
+    _computeResult(AnalysisContextTarget.request, TYPE_PROVIDER);
+    expect(task, new isInstanceOf<BuildTypeProviderTask>());
+    // validate
+    TypeProvider typeProvider = outputs[TYPE_PROVIDER];
+    expect(typeProvider, isNotNull);
+    expect(typeProvider.boolType, isNotNull);
+    expect(typeProvider.intType, isNotNull);
+    expect(typeProvider.futureType, isNotNull);
+  }
+}
+
+@reflectiveTest
+class ParseDartTaskTest extends _AbstractDartTaskTest {
+  test_buildInputs() {
+    Map<String, TaskInput> inputs = ParseDartTask.buildInputs(emptySource);
+    expect(inputs, isNotNull);
+    expect(inputs.keys, unorderedEquals([
+      ParseDartTask.LINE_INFO_INPUT_NAME,
+      ParseDartTask.TOKEN_STREAM_INPUT_NAME
+    ]));
+  }
+
+  test_constructor() {
+    ParseDartTask task = new ParseDartTask(context, emptySource);
+    expect(task, isNotNull);
+    expect(task.context, context);
+    expect(task.target, emptySource);
+  }
+
+  test_createTask() {
+    ParseDartTask task = ParseDartTask.createTask(context, emptySource);
+    expect(task, isNotNull);
+    expect(task.context, context);
+    expect(task.target, emptySource);
+  }
+
+  test_description() {
+    ParseDartTask task = new ParseDartTask(null, emptySource);
     expect(task.description, isNotNull);
   }
 
@@ -153,110 +1106,163 @@
   }
 
   test_perform() {
-    ParseDartTask task = _performParseTask(r'''
+    _performParseTask(r'''
 part of lib;
 class B {}''');
-
-    expect(task.caughtException, isNull);
-    Map<ResultDescriptor<dynamic>, dynamic> outputs = task.outputs;
-    expect(outputs, hasLength(6));
+    expect(outputs, hasLength(7));
     expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
-    expect(outputs[IMPORTED_LIBRARIES], hasLength(0));
+    _assertHasCore(outputs[IMPORTED_LIBRARIES], 1);
     expect(outputs[INCLUDED_PARTS], hasLength(0));
     expect(outputs[PARSE_ERRORS], hasLength(0));
     expect(outputs[PARSED_UNIT], isNotNull);
     expect(outputs[SOURCE_KIND], SourceKind.PART);
+    expect(outputs[UNITS], hasLength(1));
   }
 
   test_perform_invalidDirectives() {
-    ParseDartTask task = _performParseTask(r'''
+    _performParseTask(r'''
 library lib;
 import '/does/not/exist.dart';
 import '://invaliduri.dart';
 export '${a}lib3.dart';
 part 'part.dart';
 class A {}''');
-
-    expect(task.caughtException, isNull);
-    Map<ResultDescriptor<dynamic>, dynamic> outputs = task.outputs;
-    expect(outputs, hasLength(6));
+    expect(outputs, hasLength(7));
     expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
-    expect(outputs[IMPORTED_LIBRARIES], hasLength(1));
+    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
     expect(outputs[INCLUDED_PARTS], hasLength(1));
     expect(outputs[PARSE_ERRORS], hasLength(2));
     expect(outputs[PARSED_UNIT], isNotNull);
     expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
+    expect(outputs[UNITS], hasLength(2));
   }
 
   test_perform_library() {
-    ParseDartTask task = _performParseTask(r'''
+    _performParseTask(r'''
 library lib;
 import 'lib2.dart';
 export 'lib3.dart';
 part 'part.dart';
 class A {''');
-
-    expect(task.caughtException, isNull);
-    Map<ResultDescriptor<dynamic>, dynamic> outputs = task.outputs;
-    expect(outputs, hasLength(6));
+    expect(outputs, hasLength(7));
     expect(outputs[EXPORTED_LIBRARIES], hasLength(1));
-    expect(outputs[IMPORTED_LIBRARIES], hasLength(1));
+    _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
     expect(outputs[INCLUDED_PARTS], hasLength(1));
     expect(outputs[PARSE_ERRORS], hasLength(1));
     expect(outputs[PARSED_UNIT], isNotNull);
     expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
+    expect(outputs[UNITS], hasLength(2));
   }
 
-  ParseDartTask _performParseTask(String content) {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    AnalysisTarget target = new TestSource();
+  void _performParseTask(String content) {
+    AnalysisTarget target = _newSource('/test.dart', content);
+    _computeResult(target, PARSED_UNIT);
+    expect(task, new isInstanceOf<ParseDartTask>());
+  }
 
-    ScanDartTask scanTask = new ScanDartTask(context, target);
-    scanTask.inputs = {ScanDartTask.CONTENT_INPUT_NAME: content};
-    scanTask.perform();
-    Map<ResultDescriptor, dynamic> scanOutputs = scanTask.outputs;
-
-    ParseDartTask parseTask = new ParseDartTask(context, target);
-    parseTask.inputs = {
-      ParseDartTask.LINE_INFO_INPUT_NAME: scanOutputs[LINE_INFO],
-      ParseDartTask.TOKEN_STREAM_INPUT_NAME: scanOutputs[TOKEN_STREAM]
-    };
-    parseTask.perform();
-    return parseTask;
+  static void _assertHasCore(List<Source> sources, int lenght) {
+    expect(sources, hasLength(lenght));
+    expect(sources, contains(predicate((Source s) {
+      return s.fullName.endsWith('core.dart');
+    })));
   }
 }
 
 @reflectiveTest
-class ScanDartTaskTest extends EngineTestCase {
+class ResolveLibraryTypeNamesTaskTest extends _AbstractDartTaskTest {
+  test_perform() {
+    Source sourceLib = _newSource('/my_lib.dart', '''
+library my_lib;
+part 'my_part.dart';
+class A {}
+class B extends A {}
+''');
+    _newSource('/my_part.dart', '''
+part of my_lib;
+class C extends A {}
+''');
+    _computeResult(sourceLib, LIBRARY_ELEMENT5);
+    expect(task, new isInstanceOf<ResolveLibraryTypeNamesTask>());
+    // validate
+    LibraryElement library = outputs[LIBRARY_ELEMENT5];
+    {
+      ClassElement classB = library.getType('B');
+      expect(classB.supertype.displayName, 'A');
+    }
+    {
+      ClassElement classC = library.getType('C');
+      expect(classC.supertype.displayName, 'A');
+    }
+  }
+}
+
+@reflectiveTest
+class ResolveUnitTypeNamesTaskTest extends _AbstractDartTaskTest {
+  test_perform() {
+    Source source = _newSource('/test.dart', '''
+class A {}
+class B extends A {}
+int f(String p) => p.length;
+''');
+    LibraryUnitTarget target = new LibraryUnitTarget(source, source);
+    _computeResult(target, RESOLVED_UNIT4);
+    expect(task, new isInstanceOf<ResolveUnitTypeNamesTask>());
+    // validate
+    CompilationUnit unit = outputs[RESOLVED_UNIT4];
+    {
+      ClassDeclaration nodeA = unit.declarations[0];
+      ClassDeclaration nodeB = unit.declarations[1];
+      DartType extendsType = nodeB.extendsClause.superclass.type;
+      expect(extendsType, nodeA.element.type);
+    }
+    {
+      FunctionDeclaration functionNode = unit.declarations[2];
+      DartType returnType = functionNode.returnType.type;
+      List<FormalParameter> parameters =
+          functionNode.functionExpression.parameters.parameters;
+      expect(returnType.displayName, 'int');
+      expect(parameters[0].element.type.displayName, 'String');
+    }
+  }
+
+  test_perform_errors() {
+    Source source = _newSource('/test.dart', '''
+NoSuchClass f() => null;
+''');
+    LibraryUnitTarget target = new LibraryUnitTarget(source, source);
+    _computeResult(target, RESOLVE_TYPE_NAMES_ERRORS);
+    expect(task, new isInstanceOf<ResolveUnitTypeNamesTask>());
+    // validate
+    _fillErrorListener(RESOLVE_TYPE_NAMES_ERRORS);
+    errorListener
+        .assertErrorsWithCodes(<ErrorCode>[StaticWarningCode.UNDEFINED_CLASS]);
+  }
+}
+
+@reflectiveTest
+class ScanDartTaskTest extends _AbstractDartTaskTest {
   test_buildInputs() {
-    AnalysisTarget target = new TestSource();
-    Map<String, TaskInput> inputs = ScanDartTask.buildInputs(target);
+    Map<String, TaskInput> inputs = ScanDartTask.buildInputs(emptySource);
     expect(inputs, isNotNull);
-    expect(inputs, hasLength(1));
-    expect(inputs[ScanDartTask.CONTENT_INPUT_NAME], isNotNull);
+    expect(inputs.keys, unorderedEquals([ScanDartTask.CONTENT_INPUT_NAME]));
   }
 
   test_constructor() {
-    AnalysisContext context = AnalysisContextFactory.contextWithCore();
-    AnalysisTarget target = new TestSource();
-    ScanDartTask task = new ScanDartTask(context, target);
+    ScanDartTask task = new ScanDartTask(context, emptySource);
     expect(task, isNotNull);
     expect(task.context, context);
-    expect(task.target, target);
+    expect(task.target, emptySource);
   }
 
   test_createTask() {
-    AnalysisContext context = AnalysisContextFactory.contextWithCore();
-    AnalysisTarget target = new TestSource();
-    ScanDartTask task = ScanDartTask.createTask(context, target);
+    ScanDartTask task = ScanDartTask.createTask(context, emptySource);
     expect(task, isNotNull);
     expect(task.context, context);
-    expect(task.target, target);
+    expect(task.target, emptySource);
   }
 
   test_description() {
-    AnalysisTarget target = new TestSource();
-    ScanDartTask task = new ScanDartTask(null, target);
+    ScanDartTask task = new ScanDartTask(null, emptySource);
     expect(task.description, isNotNull);
   }
 
@@ -266,34 +1272,127 @@
   }
 
   test_perform_errors() {
-    ScanDartTask scanTask = _performScanTask('import "');
-
-    expect(scanTask.caughtException, isNull);
-    Map<ResultDescriptor, dynamic> scanOutputs = scanTask.outputs;
-    expect(scanOutputs, hasLength(3));
-    expect(scanOutputs[LINE_INFO], isNotNull);
-    expect(scanOutputs[SCAN_ERRORS], hasLength(1));
-    expect(scanOutputs[TOKEN_STREAM], isNotNull);
+    _performScanTask('import "');
+    expect(outputs, hasLength(3));
+    expect(outputs[LINE_INFO], isNotNull);
+    expect(outputs[SCAN_ERRORS], hasLength(1));
+    expect(outputs[TOKEN_STREAM], isNotNull);
   }
 
   test_perform_noErrors() {
-    ScanDartTask scanTask = _performScanTask('class A {}');
-
-    expect(scanTask.caughtException, isNull);
-    Map<ResultDescriptor, dynamic> scanOutputs = scanTask.outputs;
-    expect(scanOutputs, hasLength(3));
-    expect(scanOutputs[LINE_INFO], isNotNull);
-    expect(scanOutputs[SCAN_ERRORS], hasLength(0));
-    expect(scanOutputs[TOKEN_STREAM], isNotNull);
+    _performScanTask('class A {}');
+    expect(outputs, hasLength(3));
+    expect(outputs[LINE_INFO], isNotNull);
+    expect(outputs[SCAN_ERRORS], hasLength(0));
+    expect(outputs[TOKEN_STREAM], isNotNull);
   }
 
-  ScanDartTask _performScanTask(String content) {
-    AnalysisContext context = AnalysisContextFactory.contextWithCore();
-    AnalysisTarget target = new TestSource();
+  void _performScanTask(String content) {
+    AnalysisTarget target = _newSource('/test.dart', content);
+    _computeResult(target, TOKEN_STREAM);
+    expect(task, new isInstanceOf<ScanDartTask>());
+  }
+}
 
-    ScanDartTask scanTask = new ScanDartTask(context, target);
-    scanTask.inputs = {ScanDartTask.CONTENT_INPUT_NAME: content};
-    scanTask.perform();
-    return scanTask;
+class _AbstractDartTaskTest extends EngineTestCase {
+  MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
+  Source emptySource;
+
+  DartSdk sdk = new MockSdk();
+  _MockContext context = new _MockContext();
+  Map<AnalysisTarget, CacheEntry> entryMap = <AnalysisTarget, CacheEntry>{};
+
+  TaskManager taskManager = new TaskManager();
+  AnalysisDriver analysisDriver;
+
+  AnalysisTask task;
+  Map<ResultDescriptor<dynamic>, dynamic> outputs;
+  GatheringErrorListener errorListener = new GatheringErrorListener();
+
+  CacheEntry getCacheEntry(AnalysisTarget target) {
+    return entryMap.putIfAbsent(target, () => new CacheEntry());
+  }
+
+  void setUp() {
+    emptySource = _newSource('/test.dart');
+    // prepare AnalysisContext
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      new DartUriResolver(sdk),
+      new ResourceUriResolver(resourceProvider)
+    ]);
+    // prepare TaskManager
+    taskManager.addTaskDescriptor(GetContentTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(ScanDartTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(ParseDartTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(BuildClassConstructorsTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(BuildCompilationUnitElementTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(BuildLibraryConstructorsTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(BuildLibraryElementTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(BuildPublicNamespaceTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(BuildDirectiveElementsTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(BuildExportSourceClosureTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(BuildExportNamespaceTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(BuildTypeProviderTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(BuildEnumMemberElementsTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(BuildFunctionTypeAliasesTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(ResolveUnitTypeNamesTask.DESCRIPTOR);
+    taskManager.addTaskDescriptor(ResolveLibraryTypeNamesTask.DESCRIPTOR);
+    // prepare AnalysisDriver
+    analysisDriver = new AnalysisDriver(taskManager, context);
+  }
+
+  void _computeResult(AnalysisTarget target, ResultDescriptor result) {
+    task = analysisDriver.computeResult(target, result);
+    expect(task.caughtException, isNull);
+    outputs = task.outputs;
+  }
+
+  /**
+   * Fill [errorListener] with [result] errors in the current [task].
+   */
+  void _fillErrorListener(ResultDescriptor<List<AnalysisError>> result) {
+    List<AnalysisError> errors = task.outputs[result];
+    expect(errors, isNotNull, reason: result.name);
+    errorListener = new GatheringErrorListener();
+    errorListener.addAll(errors);
+  }
+
+  Source _newSource(String path, [String content = '']) {
+    File file = resourceProvider.newFile(path, content);
+    return file.createSource();
+  }
+
+  List<Source> _newSources(Map<String, String> sourceMap) {
+    List<Source> sources = <Source>[];
+    sourceMap.forEach((String path, String content) {
+      File file = resourceProvider.newFile(path, content);
+      Source source = file.createSource();
+      sources.add(source);
+    });
+    return sources;
+  }
+}
+
+class _MockContext extends TypedMock implements ExtendedAnalysisContext {
+  AnalysisOptionsImpl analysisOptions = new AnalysisOptionsImpl();
+  SourceFactory sourceFactory;
+  TypeProvider typeProvider;
+
+  Map<AnalysisTarget, CacheEntry> entryMap = <AnalysisTarget, CacheEntry>{};
+
+  String get name => '_MockContext';
+
+  bool exists(Source source) => source.exists();
+
+  @override
+  CacheEntry getCacheEntry(AnalysisTarget target) {
+    return entryMap.putIfAbsent(target, () => new CacheEntry());
+  }
+
+  TimestampedData<String> getContents(Source source) => source.contents;
+
+  noSuchMethod(Invocation invocation) {
+    print('noSuchMethod: ${invocation.memberName}');
+    return super.noSuchMethod(invocation);
   }
 }
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index 4eb0e0b..17e55db 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -19,6 +19,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/driver.dart';
+import 'package:analyzer/src/task/inputs.dart';
 import 'package:analyzer/src/task/manager.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:unittest/unittest.dart';
@@ -138,7 +139,9 @@
   test_createWorkOrderForResult_error() {
     AnalysisTarget target = new TestSource();
     ResultDescriptor result = new ResultDescriptor('result', null);
-    context.getCacheEntry(target).setState(result, CacheState.ERROR);
+    CaughtException exception = new CaughtException(null, null);
+    context.getCacheEntry(target).setErrorState(
+        exception, <ResultDescriptor>[result]);
 
     expect(driver.createWorkOrderForResult(target, result), isNull);
   }
@@ -220,6 +223,43 @@
     expect(driver.performAnalysisTask(), false);
   }
 
+  test_performAnalysisTask_inputsFirst() {
+    AnalysisTarget target = new TestSource();
+    ResultDescriptor resultA = new ResultDescriptor('resultA', -1);
+    ResultDescriptor resultB = new ResultDescriptor('resultB', -2);
+    // configure tasks
+    TestAnalysisTask task1;
+    TestAnalysisTask task2;
+    TaskDescriptor descriptor1 = new TaskDescriptor(
+        'task1', (context, target) => task1, (target) => {}, [resultA]);
+    TaskDescriptor descriptor2 = new TaskDescriptor('task2',
+        (context, target) => task2, (target) => {
+      'inputA': new SimpleTaskInput<int>(target, resultA)
+    }, [resultB]);
+    task1 = new TestAnalysisTask(context, target,
+        descriptor: descriptor1, results: [resultA], value: 10);
+    task2 = new TestAnalysisTask(context, target,
+        descriptor: descriptor2, value: 20);
+    manager.addTaskDescriptor(descriptor1);
+    manager.addTaskDescriptor(descriptor2);
+    context.explicitTargets.add(target);
+    manager.addGeneralResult(resultB);
+    // prepare work order
+    expect(driver.performAnalysisTask(), true);
+    expect(context.getCacheEntry(target).getValue(resultA), -1);
+    expect(context.getCacheEntry(target).getValue(resultB), -2);
+    // compute resultA
+    expect(driver.performAnalysisTask(), true);
+    expect(context.getCacheEntry(target).getValue(resultA), 10);
+    expect(context.getCacheEntry(target).getValue(resultB), -2);
+    // compute resultB
+    expect(driver.performAnalysisTask(), true);
+    expect(context.getCacheEntry(target).getValue(resultA), 10);
+    expect(context.getCacheEntry(target).getValue(resultB), 20);
+    // done
+    expect(driver.performAnalysisTask(), false);
+  }
+
   test_performWorkItem_exceptionInTask() {
     AnalysisTarget target = new TestSource();
     ResultDescriptor result = new ResultDescriptor('result', null);
@@ -274,9 +314,8 @@
     ResultDescriptor inputResult = new ResultDescriptor('input', null);
     TaskDescriptor descriptor = new TaskDescriptor('task',
         (context, target) => new TestAnalysisTask(context, target),
-        (target) => {'one': inputResult.inputFor(target)}, [
-      new ResultDescriptor('output', null)
-    ]);
+        (target) => {'one': inputResult.of(target)},
+        [new ResultDescriptor('output', null)]);
     driver.currentWorkOrder =
         new WorkOrder(manager, new WorkItem(null, null, descriptor));
 
@@ -344,12 +383,11 @@
     AnalysisContext context = new _TestContext();
     AnalysisTarget target = new TestSource();
     ResultDescriptor inputResult = new ResultDescriptor('input', null);
-    List<ResultDescriptor> outputResults = <ResultDescriptor>[
-      new ResultDescriptor('output', null)
-    ];
+    List<ResultDescriptor> outputResults =
+        <ResultDescriptor>[new ResultDescriptor('output', null)];
     TaskDescriptor descriptor = new TaskDescriptor('task', (context, target) =>
             new TestAnalysisTask(context, target, results: outputResults),
-        (target) => {'one': inputResult.inputFor(target)}, outputResults);
+        (target) => {'one': inputResult.of(target)}, outputResults);
     WorkItem item = new WorkItem(context, target, descriptor);
     expect(() => item.buildTask(), throwsStateError);
   }
@@ -390,7 +428,7 @@
         (target) => {}, [resultA]);
     TaskDescriptor task2 = new TaskDescriptor('task',
         (context, target) => new TestAnalysisTask(context, target),
-        (target) => {'one': resultA.inputFor(target)}, [resultB]);
+        (target) => {'one': resultA.of(target)}, [resultB]);
     manager.addTaskDescriptor(task1);
     manager.addTaskDescriptor(task2);
     WorkItem item = new WorkItem(context, target, task2);
@@ -404,9 +442,8 @@
     ResultDescriptor inputResult = new ResultDescriptor('input', null);
     TaskDescriptor descriptor = new TaskDescriptor('task',
         (context, target) => new TestAnalysisTask(context, target),
-        (target) => {'one': inputResult.inputFor(target)}, [
-      new ResultDescriptor('output', null)
-    ]);
+        (target) => {'one': inputResult.of(target)},
+        [new ResultDescriptor('output', null)]);
     WorkItem item = new WorkItem(context, target, descriptor);
     WorkItem result = item.gatherInputs(manager);
     expect(result, isNull);
@@ -434,8 +471,12 @@
         'task', null, (_) => {}, [new ResultDescriptor('result', null)]);
     WorkItem workItem = new WorkItem(null, null, descriptor);
     WorkOrder order = new WorkOrder(manager, workItem);
-    expect(order.moveNext(), true);
+    // "item" has no child items
+    expect(order.moveNext(), isTrue);
     expect(order.current, workItem);
+    // done
+    expect(order.moveNext(), isFalse);
+    expect(order.current, isNull);
   }
 }
 
@@ -523,6 +564,11 @@
   TypeProvider get typeProvider => baseContext.typeProvider;
 
   @override
+  void set typeProvider(TypeProvider typeProvider) {
+    baseContext.typeProvider = typeProvider;
+  }
+
+  @override
   TypeResolverVisitorFactory get typeResolverVisitorFactory =>
       baseContext.typeResolverVisitorFactory;
 
diff --git a/pkg/analyzer/test/src/task/general_test.dart b/pkg/analyzer/test/src/task/general_test.dart
new file mode 100644
index 0000000..664a2d6
--- /dev/null
+++ b/pkg/analyzer/test/src/task/general_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.src.task.general_test;
+
+import 'package:analyzer/src/generated/engine.dart'
+    hide AnalysisTask, GetContentTask;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/general.dart';
+import 'package:analyzer/task/general.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:typed_mock/typed_mock.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../generated/test_support.dart';
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(GetContentTaskTest);
+}
+
+@reflectiveTest
+class GetContentTaskTest extends EngineTestCase {
+  test_buildInputs() {
+    AnalysisTarget target = new TestSource();
+    Map<String, TaskInput> inputs = GetContentTask.buildInputs(target);
+    expect(inputs, isEmpty);
+  }
+
+  test_constructor() {
+    AnalysisContext context = new _MockContext();
+    AnalysisTarget target = new TestSource();
+    GetContentTask task = new GetContentTask(context, target);
+    expect(task, isNotNull);
+    expect(task.context, context);
+    expect(task.target, target);
+  }
+
+  test_createTask() {
+    AnalysisContext context = new _MockContext();
+    AnalysisTarget target = new TestSource();
+    GetContentTask task = GetContentTask.createTask(context, target);
+    expect(task, isNotNull);
+    expect(task.context, context);
+    expect(task.target, target);
+  }
+
+  test_descriptor() {
+    AnalysisContext context = new _MockContext();
+    AnalysisTarget target = new TestSource();
+    GetContentTask task = new GetContentTask(context, target);
+    expect(task.descriptor, GetContentTask.DESCRIPTOR);
+  }
+
+  test_perform() {
+    AnalysisContext context = new _MockContext();
+    Source target = new TestSource();
+    GetContentTask task = new GetContentTask(context, target);
+    when(context.getContents(target))
+        .thenReturn(new TimestampedData<String>(42, 'foo'));
+    task.perform();
+    expect(task.caughtException, isNull);
+    expect(task.outputs, hasLength(2));
+    expect(task.outputs[CONTENT], 'foo');
+    expect(task.outputs[MODIFICATION_TIME], 42);
+  }
+}
+
+class _MockContext extends TypedMock implements AnalysisContext {
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/analyzer/test/src/task/inputs_test.dart b/pkg/analyzer/test/src/task/inputs_test.dart
index 04305bc..f894d11 100644
--- a/pkg/analyzer/test/src/task/inputs_test.dart
+++ b/pkg/analyzer/test/src/task/inputs_test.dart
@@ -14,31 +14,81 @@
 
 main() {
   groupSep = ' | ';
-  runReflectiveTests(ListBasedTaskInputTest);
-  runReflectiveTests(ListBasedTaskInputBuilderTest);
+  runReflectiveTests(ListTaskInputImplTest);
+  runReflectiveTests(ListToListTaskInputTest);
+  runReflectiveTests(ListToListTaskInputBuilderTest);
+  runReflectiveTests(ListToMapTaskInputBuilderTest);
+  runReflectiveTests(ListToMapTaskInputTest);
   runReflectiveTests(SimpleTaskInputTest);
   runReflectiveTests(SimpleTaskInputBuilderTest);
   runReflectiveTests(TopLevelTaskInputBuilderTest);
 }
 
 @reflectiveTest
-class ListBasedTaskInputBuilderTest extends EngineTestCase {
+class ListTaskInputImplTest extends EngineTestCase {
+  static final AnalysisTarget target = new TestSource();
+  static final result1 =
+      new ResultDescriptorImpl<List<AnalysisTarget>>('result1', null);
+  static final result2 = new ResultDescriptorImpl<int>('result2', null);
+
+  test_create() {
+    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
+    expect(input, isNotNull);
+    expect(input.target, target);
+    expect(input.result, result1);
+  }
+
+  test_createBuilder() {
+    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
+    expect(input.createBuilder(), new isInstanceOf<SimpleTaskInputBuilder>());
+  }
+
+  test_toList() {
+    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
+    TaskInput<List> input2 = input.toList((target) => 'name');
+    expect(input2,
+        new isInstanceOf<ListToListTaskInput<AnalysisTarget, String>>());
+  }
+
+  test_toListOf() {
+    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
+    TaskInput<List> input2 = input.toListOf(result2);
+    expect(
+        input2, new isInstanceOf<ListToListTaskInput<AnalysisTarget, int>>());
+  }
+
+  test_toMap() {
+    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
+    TaskInput<Map> input2 = input.toMap((target) => 'name');
+    expect(
+        input2, new isInstanceOf<ListToMapTaskInput<AnalysisTarget, String>>());
+  }
+
+  test_toMapOf() {
+    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
+    TaskInput<Map> input2 = input.toMapOf(result2);
+    expect(input2, new isInstanceOf<ListToMapTaskInput<AnalysisTarget, int>>());
+  }
+}
+
+@reflectiveTest
+class ListToListTaskInputBuilderTest extends EngineTestCase {
   static final AnalysisTarget target1 = new TestSource();
   static final ResultDescriptorImpl result1 =
       new ResultDescriptorImpl('result1', null);
   static final ResultDescriptorImpl result2 =
       new ResultDescriptorImpl('result2', null);
-  static final ListBasedTaskInput input = new ListBasedTaskInput(
-      result1.inputFor(target1), (element) => result2.inputFor(element));
+  static final ListToListTaskInput input = new ListToListTaskInput(
+      result1.of(target1), (element) => result2.of(element));
 
   test_create() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     expect(builder, isNotNull);
     expect(builder.input, input);
   }
 
   test_currentResult_afterComplete() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     builder.moveNext();
     builder.currentValue = [];
     builder.moveNext();
@@ -46,18 +96,18 @@
   }
 
   test_currentResult_afterOneMoveNext() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     builder.moveNext();
     expect(builder.currentResult, result1);
   }
 
   test_currentResult_beforeMoveNext() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     expect(builder.currentResult, null);
   }
 
   test_currentTarget_afterComplete() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     builder.moveNext();
     builder.currentValue = [];
     builder.moveNext();
@@ -65,24 +115,24 @@
   }
 
   test_currentTarget_afterOneMoveNext() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     builder.moveNext();
     expect(builder.currentTarget, target1);
   }
 
   test_currentTarget_beforeMoveNext() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     expect(builder.currentTarget, null);
   }
 
   test_currentValue_afterOneMoveNext() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     builder.moveNext();
     builder.currentValue = [];
   }
 
   test_currentValue_beforeMoveNext() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     expect(() {
       builder.currentValue = [];
     }, throwsStateError);
@@ -93,7 +143,7 @@
     AnalysisTarget target3 = new TestSource();
     String value2 = 'value2';
     String value3 = 'value3';
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     builder.moveNext(); // Advance to requesting the list
     builder.currentValue = [target2, target3];
     builder.moveNext(); // Advance to requesting result2 for target2
@@ -110,24 +160,24 @@
   }
 
   test_inputValue_afterOneMoveNext() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     builder.moveNext();
     expect(() => builder.inputValue, throwsStateError);
   }
 
   test_inputValue_beforeMoveNext() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     expect(() => builder.inputValue, throwsStateError);
   }
 
   test_moveNext_withoutSet() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     expect(builder.moveNext(), true);
     expect(() => builder.moveNext(), throwsStateError);
   }
 
   test_moveNext_withSet() {
-    ListBasedTaskInputBuilder builder = new ListBasedTaskInputBuilder(input);
+    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
     expect(builder.moveNext(), true);
     builder.currentValue = [];
     expect(builder.moveNext(), false);
@@ -136,24 +186,160 @@
 }
 
 @reflectiveTest
-class ListBasedTaskInputTest extends EngineTestCase {
+class ListToListTaskInputTest extends EngineTestCase {
   static final AnalysisTarget target = new TestSource();
   static final ResultDescriptorImpl result =
       new ResultDescriptorImpl('result', null);
 
   test_create() {
-    SimpleTaskInput baseAccessor = result.inputFor(target);
+    SimpleTaskInput baseAccessor = result.of(target);
     GenerateTaskInputs generate = (object) {};
-    ListBasedTaskInput input = new ListBasedTaskInput(baseAccessor, generate);
+    ListToListTaskInput input = new ListToListTaskInput(baseAccessor, generate);
     expect(input, isNotNull);
     expect(input.baseAccessor, baseAccessor);
     expect(input.generateTaskInputs, equals(generate));
   }
 
   test_createBuilder() {
-    SimpleTaskInput baseAccessor = result.inputFor(target);
+    SimpleTaskInput baseAccessor = result.of(target);
     GenerateTaskInputs generate = (object) {};
-    ListBasedTaskInput input = new ListBasedTaskInput(baseAccessor, generate);
+    ListToListTaskInput input = new ListToListTaskInput(baseAccessor, generate);
+    expect(input.createBuilder(), isNotNull);
+  }
+}
+
+@reflectiveTest
+class ListToMapTaskInputBuilderTest extends EngineTestCase {
+  static final AnalysisTarget target1 = new TestSource('target1');
+  static final ResultDescriptorImpl result1 =
+      new ResultDescriptorImpl('result1', null);
+  static final ResultDescriptorImpl result2 =
+      new ResultDescriptorImpl('result2', null);
+  static final ListToMapTaskInput input = new ListToMapTaskInput(
+      result1.of(target1), (element) => result2.of(element));
+
+  test_create() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    expect(builder, isNotNull);
+    expect(builder.input, input);
+  }
+
+  test_currentResult_afterComplete() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValue = [];
+    builder.moveNext();
+    expect(builder.currentResult, null);
+  }
+
+  test_currentResult_afterOneMoveNext() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext();
+    expect(builder.currentResult, result1);
+  }
+
+  test_currentResult_beforeMoveNext() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    expect(builder.currentResult, null);
+  }
+
+  test_currentTarget_afterComplete() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValue = [];
+    builder.moveNext();
+    expect(builder.currentTarget, null);
+  }
+
+  test_currentTarget_afterOneMoveNext() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext();
+    expect(builder.currentTarget, target1);
+  }
+
+  test_currentTarget_beforeMoveNext() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    expect(builder.currentTarget, null);
+  }
+
+  test_currentValue_afterOneMoveNext() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext();
+    builder.currentValue = [];
+  }
+
+  test_currentValue_beforeMoveNext() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    expect(() {
+      builder.currentValue = [];
+    }, throwsStateError);
+  }
+
+  test_inputValue_afterComplete() {
+    AnalysisTarget target2 = new TestSource('target2');
+    AnalysisTarget target3 = new TestSource('target3');
+    String value2 = 'value2';
+    String value3 = 'value3';
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext(); // Advance to requesting the list
+    builder.currentValue = [target2, target3];
+    builder.moveNext(); // Advance to requesting result2 for target2
+    builder.currentValue = value2;
+    builder.moveNext(); // Advance to requesting result2 for target3
+    builder.currentValue = value3;
+    builder.moveNext(); // Advance to the end
+    var inputValue = builder.inputValue;
+    expect(inputValue, new isInstanceOf<Map>());
+    expect(inputValue.length, 2);
+    expect(inputValue, containsPair(target2, value2));
+    expect(inputValue, containsPair(target3, value3));
+  }
+
+  test_inputValue_afterOneMoveNext() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    builder.moveNext();
+    expect(() => builder.inputValue, throwsStateError);
+  }
+
+  test_inputValue_beforeMoveNext() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    expect(() => builder.inputValue, throwsStateError);
+  }
+
+  test_moveNext_withoutSet() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    expect(builder.moveNext(), true);
+    expect(() => builder.moveNext(), throwsStateError);
+  }
+
+  test_moveNext_withSet() {
+    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
+    expect(builder.moveNext(), true);
+    builder.currentValue = [];
+    expect(builder.moveNext(), false);
+    expect(builder.moveNext(), false);
+  }
+}
+
+@reflectiveTest
+class ListToMapTaskInputTest extends EngineTestCase {
+  static final AnalysisTarget target = new TestSource();
+  static final ResultDescriptorImpl result =
+      new ResultDescriptorImpl('result', null);
+
+  test_create() {
+    SimpleTaskInput baseAccessor = result.of(target);
+    GenerateTaskInputs generate = (object) {};
+    ListToMapTaskInput input = new ListToMapTaskInput(baseAccessor, generate);
+    expect(input, isNotNull);
+    expect(input.baseAccessor, baseAccessor);
+    expect(input.generateTaskInputs, equals(generate));
+  }
+
+  test_createBuilder() {
+    SimpleTaskInput baseAccessor = result.of(target);
+    GenerateTaskInputs generate = (object) {};
+    ListToMapTaskInput input = new ListToMapTaskInput(baseAccessor, generate);
     expect(input.createBuilder(), isNotNull);
   }
 }
diff --git a/pkg/analyzer/test/src/task/model_test.dart b/pkg/analyzer/test/src/task/model_test.dart
index 8bf9625..fcc7f2b 100644
--- a/pkg/analyzer/test/src/task/model_test.dart
+++ b/pkg/analyzer/test/src/task/model_test.dart
@@ -58,7 +58,7 @@
 @reflectiveTest
 class ContributionPointImplTest extends EngineTestCase {
   test_contributors_empty() {
-    ContributionPointImpl point = new ContributionPointImpl('point');
+    CompositeResultDescriptorImpl point = new CompositeResultDescriptorImpl('point');
     List<ResultDescriptor> contributors = point.contributors;
     expect(contributors, isEmpty);
   }
@@ -66,7 +66,7 @@
   test_contributors_nonEmpty() {
     ResultDescriptorImpl result1 = new ResultDescriptorImpl('result1', null);
     ResultDescriptorImpl result2 = new ResultDescriptorImpl('result2', null);
-    ContributionPointImpl point = new ContributionPointImpl('point');
+    CompositeResultDescriptorImpl point = new CompositeResultDescriptorImpl('point');
     point.recordContributor(result1);
     point.recordContributor(result2);
     List<ResultDescriptor> contributors = point.contributors;
@@ -79,12 +79,12 @@
   }
 
   test_create() {
-    expect(new ContributionPointImpl('name'), isNotNull);
+    expect(new CompositeResultDescriptorImpl('name'), isNotNull);
   }
 
   test_name() {
     String name = 'point';
-    ContributionPointImpl point = new ContributionPointImpl(name);
+    CompositeResultDescriptorImpl point = new CompositeResultDescriptorImpl(name);
     expect(point.name, name);
   }
 }
@@ -92,7 +92,7 @@
 @reflectiveTest
 class ResultDescriptorImplTest extends EngineTestCase {
   test_create_withContribution() {
-    ContributionPointImpl point = new ContributionPointImpl('point');
+    CompositeResultDescriptorImpl point = new CompositeResultDescriptorImpl('point');
     ResultDescriptorImpl result =
         new ResultDescriptorImpl('result', null, contributesTo: point);
     expect(result, isNotNull);
@@ -107,7 +107,7 @@
   test_inputFor() {
     AnalysisTarget target = new TestSource();
     ResultDescriptorImpl result = new ResultDescriptorImpl('result', null);
-    TaskInput input = result.inputFor(target);
+    TaskInput input = result.of(target);
     expect(input, isNotNull);
   }
 
diff --git a/pkg/analyzer/test/src/task/test_all.dart b/pkg/analyzer/test/src/task/test_all.dart
index 39216fe..bee52dc 100644
--- a/pkg/analyzer/test/src/task/test_all.dart
+++ b/pkg/analyzer/test/src/task/test_all.dart
@@ -8,6 +8,7 @@
 
 import 'dart_test.dart' as dart_test;
 import 'driver_test.dart' as driver_test;
+import 'general_test.dart' as general_test;
 import 'inputs_test.dart' as inputs_test;
 import 'manager_test.dart' as manager_test;
 import 'model_test.dart' as model_test;
@@ -18,6 +19,7 @@
   group('task tests', () {
     dart_test.main();
     driver_test.main();
+    general_test.main();
     inputs_test.main();
     manager_test.main();
     model_test.main();
diff --git a/pkg/analyzer/test/src/task/test_support.dart b/pkg/analyzer/test/src/task/test_support.dart
index cafd4b9..80cd7c3 100644
--- a/pkg/analyzer/test/src/task/test_support.dart
+++ b/pkg/analyzer/test/src/task/test_support.dart
@@ -30,10 +30,10 @@
   /**
    * The next value that is to be used for a result.
    */
-  int value = 1;
+  int value;
 
   TestAnalysisTask(AnalysisContext context, AnalysisTarget target,
-      {this.descriptor, this.exception, this.results})
+      {this.descriptor, this.exception, this.results, this.value: 1})
       : super(context, target);
 
   @override
diff --git a/pkg/analyzer/test/test_all.dart b/pkg/analyzer/test/test_all.dart
index 7392070..acf1154 100644
--- a/pkg/analyzer/test/test_all.dart
+++ b/pkg/analyzer/test/test_all.dart
@@ -6,6 +6,7 @@
 
 import 'package:unittest/unittest.dart';
 
+import 'cancelable_future_test.dart' as cancelable_future_test;
 import 'enum_test.dart' as enum_test;
 import 'error_test.dart' as error;
 import 'file_system/test_all.dart' as file_system;
@@ -13,10 +14,10 @@
 import 'instrumentation/test_all.dart' as instrumentation;
 import 'options_test.dart' as options;
 import 'parse_compilation_unit_test.dart' as parse_compilation_unit;
+import 'plugin/test_all.dart' as plugin_test_all;
 import 'source/test_all.dart' as source;
 import 'src/test_all.dart' as src;
 import 'task/test_all.dart' as task;
-import 'cancelable_future_test.dart' as cancelable_future_test;
 
 /// Utility for manually running all tests.
 main() {
@@ -30,6 +31,7 @@
     instrumentation.main();
     options.main();
     parse_compilation_unit.main();
+    plugin_test_all.main();
     source.main();
     src.main();
     task.main();
diff --git a/pkg/analyzer2dart/lib/src/cps_generator.dart b/pkg/analyzer2dart/lib/src/cps_generator.dart
index e932e99..fbb0ee0 100644
--- a/pkg/analyzer2dart/lib/src/cps_generator.dart
+++ b/pkg/analyzer2dart/lib/src/cps_generator.dart
@@ -15,6 +15,7 @@
     show DART_CONSTANT_SYSTEM;

 import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;

 import 'package:compiler/src/cps_ir/cps_ir_builder.dart';

+import 'package:compiler/src/cps_ir/cps_ir_builder_task.dart';

 import 'package:compiler/src/universe/universe.dart';

 

 import 'semantic_visitor.dart';

@@ -390,10 +391,7 @@
     // [TreeShaker] and shared with the [CpsGeneratingVisitor].

     assert(invariant(node, target.isTopLevel || target.isStatic,

                      '$target expected to be top-level or static.'));

-    return irBuilder.buildStaticSet(

-        target,

-        new Selector.setter(target.name, target.library),

-        build(node.rightHandSide));

+    return irBuilder.buildStaticSet(target, build(node.rightHandSide));

   }

 

   @override

@@ -413,8 +411,7 @@
     // [TreeShaker] and shared with the [CpsGeneratingVisitor].

     assert(invariant(node, target.isTopLevel || target.isStatic,

                      '$target expected to be top-level or static.'));

-    return irBuilder.buildStaticGet(target,

-        new Selector.getter(target.name, target.library));

+    return irBuilder.buildStaticGet(target);

   }

 

   ir.Primitive handleBinaryExpression(BinaryExpression node,

@@ -572,6 +569,22 @@
         converter.convertType(node.type.type),

         isTypeTest: false);

   }

+

+  @override

+  visitTryStatement(TryStatement node) {

+    List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];

+    for (CatchClause catchClause in node.catchClauses) {

+      catchClauseInfos.add(new CatchClauseInfo(

+          exceptionVariable: converter.convertElement(

+              catchClause.exceptionParameter.staticElement),

+          buildCatchBlock: subbuild(catchClause.body)));

+

+    }

+    irBuilder.buildTry(

+        tryStatementInfo: new TryStatementInfo(),

+        buildTryBlock: subbuild(node.body),

+        catchClauseInfos: catchClauseInfos);

+  }

 }

 

 class NullCapturedVariables extends DartCapturedVariables {

diff --git a/pkg/analyzer2dart/lib/src/modely.dart b/pkg/analyzer2dart/lib/src/modely.dart
index 4df5cdc..493b58d 100644
--- a/pkg/analyzer2dart/lib/src/modely.dart
+++ b/pkg/analyzer2dart/lib/src/modely.dart
@@ -753,9 +753,15 @@
   bool get isLocal => true;
 
   @override
+  bool get isInstanceMember => false;
+
+  @override
   bool get isStatic => false;
 
   @override
+  bool get isTopLevel => false;
+
+  @override
   get executableContext => unsupported('executableContext');
 
   // TODO(johnniwinther): Ensure the correct semantics of this.
@@ -880,4 +886,4 @@
 
   @override
   get nestedClosures => unsupported('nestedClosures');
-}
\ No newline at end of file
+}
diff --git a/pkg/analyzer2dart/lib/src/util.dart b/pkg/analyzer2dart/lib/src/util.dart
index 34bc33d..e4b0d33 100644
--- a/pkg/analyzer2dart/lib/src/util.dart
+++ b/pkg/analyzer2dart/lib/src/util.dart
@@ -29,7 +29,7 @@
 /// [source].

 void reportSourceMessage(Source source, AstNode node, String message) {

   SourceFile sourceFile =

-      new StringSourceFile(source.fullName, source.contents.data);

+      new StringSourceFile.fromName(source.fullName, source.contents.data);

 

   print(sourceFile.getLocationMessage(message, node.offset, node.end));

 }

diff --git a/pkg/analyzer2dart/test/end2end_data.dart b/pkg/analyzer2dart/test/end2end_data.dart
index d439638..b1cb1db 100644
--- a/pkg/analyzer2dart/test/end2end_data.dart
+++ b/pkg/analyzer2dart/test/end2end_data.dart
@@ -866,5 +866,38 @@
   return new C().foo();
 }
 '''),
-]),
+  ]),
+
+  const Group('Try-catch', const <TestSpec>[
+    const TestSpec('''
+main() {
+  try {} catch (e) {}
+}
+''',
+// TODO(kmillikin): Remove the unused stack trace parameter.
+'''
+main() {
+  try {} catch (e, v0) {}
+}
+'''),
+
+    const TestSpec('''
+main() {
+  try {
+    return;
+  } catch (e) {}
+}
+''',
+// TODO(kmillikin): Remove the unused stack trace parameter and unneeded return
+// statement(s).
+'''
+main() {
+  try {
+    return null;
+  } catch (e, v0) {
+    return null;
+  }
+}
+'''),
+  ]),
 ];
diff --git a/pkg/analyzer2dart/test/sexpr_data.dart b/pkg/analyzer2dart/test/sexpr_data.dart
index d380c6d..b9fcea3 100644
--- a/pkg/analyzer2dart/test/sexpr_data.dart
+++ b/pkg/analyzer2dart/test/sexpr_data.dart
@@ -23,7 +23,7 @@
     const TestSpec('''
 main() {}
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Null)))
     (InvokeContinuation return (v0))))
 '''),
@@ -34,7 +34,7 @@
   foo();
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetCont ((k0 (v0)
       (LetPrim (v1 (Constant (Null)))
         (InvokeContinuation return (v1)))))
@@ -48,7 +48,7 @@
   return 0;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (InvokeContinuation return (v0))))
 '''),
@@ -58,7 +58,7 @@
   return 1.5;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Double 1.5)))
     (InvokeContinuation return (v0))))
 '''),
@@ -68,7 +68,7 @@
   return true;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Bool true)))
     (InvokeContinuation return (v0))))
 '''),
@@ -78,7 +78,7 @@
   return false;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Bool false)))
     (InvokeContinuation return (v0))))
 '''),
@@ -88,7 +88,7 @@
   return "a";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (String "a")))
     (InvokeContinuation return (v0))))
 '''),
@@ -98,7 +98,7 @@
     const TestSpec('''
 main(args) {}
 ''', '''
-(FunctionDefinition main (args) return
+(FunctionDefinition main () (args) return
   (LetPrim (v0 (Constant (Null)))
     (InvokeContinuation return (v0))))
 '''),
@@ -106,7 +106,7 @@
     const TestSpec('''
 main(a, b) {}
 ''', '''
-(FunctionDefinition main (a b) return
+(FunctionDefinition main () (a b) return
   (LetPrim (v0 (Constant (Null)))
     (InvokeContinuation return (v0))))
 '''),
@@ -119,7 +119,7 @@
   foo(null);
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Null)))
     (LetCont ((k0 (v1)
         (LetPrim (v2 (Constant (Null)))
@@ -135,7 +135,7 @@
   bar(0, "");
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Null)))
     (LetCont ((k0 (v1)
         (LetPrim (v2 (Constant (Int 0)))
@@ -153,7 +153,7 @@
   return foo(null);
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Null)))
     (LetCont ((k0 (v1)
         (InvokeContinuation return (v1))))
@@ -168,7 +168,7 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Null)))
     (InvokeContinuation return (v0))))
 '''),
@@ -179,7 +179,7 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (InvokeContinuation return (v0))))
 '''),
@@ -189,7 +189,7 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (InvokeContinuation return (a)))
 '''),
     ]),
@@ -202,7 +202,7 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Null)))
     (LetPrim (v1 (Constant (Int 10)))
       (InvokeContinuation return (v1)))))
@@ -215,7 +215,7 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (Int 10)))
       (InvokeContinuation return (v1)))))
@@ -230,7 +230,7 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((k0 (v1)
         (LetPrim (v2 (Constant (String "")))
@@ -248,7 +248,7 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (LetPrim (v1 (Constant (String "")))
         (LetCont ((k1 (v2)
@@ -266,7 +266,7 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (LetCont ((k1 (v1)
           (InvokeContinuation return (v0))))
@@ -286,7 +286,7 @@
   return a.foo;
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (InvokeMethod a foo () k0)))
@@ -298,7 +298,7 @@
   return a.foo;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (String "")))
     (LetCont ((k0 (v1)
         (InvokeContinuation return (v1))))
@@ -312,7 +312,7 @@
   return a.foo(0);
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((k0 (v1)
         (InvokeContinuation return (v1))))
@@ -325,7 +325,7 @@
   return a.foo(0, 1);
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (String "")))
     (LetPrim (v1 (Constant (Int 0)))
       (LetPrim (v2 (Constant (Int 1)))
@@ -341,7 +341,7 @@
   return 0 + "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -354,7 +354,7 @@
   return 0 - "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -367,7 +367,7 @@
   return 0 * "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -380,7 +380,7 @@
   return 0 / "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -393,7 +393,7 @@
   return 0 ~/ "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -406,7 +406,7 @@
   return 0 < "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -419,7 +419,7 @@
   return 0 <= "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -432,7 +432,7 @@
   return 0 > "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -445,7 +445,7 @@
   return 0 >= "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -458,7 +458,7 @@
   return 0 << "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -471,7 +471,7 @@
   return 0 >> "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -484,7 +484,7 @@
   return 0 & "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -497,7 +497,7 @@
   return 0 | "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -510,7 +510,7 @@
   return 0 ^ "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -523,7 +523,7 @@
   return 0 == "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -536,7 +536,7 @@
   return 0 != "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -557,7 +557,7 @@
   return 0 && "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((k0 (v1)
         (InvokeContinuation return (v1))))
@@ -581,7 +581,7 @@
   return 0 || "";
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((k0 (v1)
         (InvokeContinuation return (v1))))
@@ -605,7 +605,7 @@
   return 0 + "" * 2;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetPrim (v2 (Constant (Int 2)))
@@ -621,7 +621,7 @@
   return 0 * "" + 2;
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "")))
       (LetCont ((k0 (v2)
@@ -641,7 +641,7 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 ()
       (LetPrim (v0 (Constant (Null)))
         (InvokeContinuation return (v0)))))
@@ -664,7 +664,7 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 ()
       (LetPrim (v0 (Constant (Null)))
         (InvokeContinuation return (v0)))))
@@ -691,7 +691,7 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 ()
       (LetPrim (v0 (Constant (Null)))
         (InvokeContinuation return (v0)))))
@@ -718,7 +718,7 @@
   return a ? print(0) : print(1);
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (LetCont ((k1 ()
@@ -744,7 +744,7 @@
   return 1;
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetPrim (v0 (Constant (Int 0)))
     (InvokeContinuation return (v0))))
 '''),
@@ -760,7 +760,7 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 ()
       (LetPrim (v0 (Constant (Int 0)))
         (InvokeContinuation return (v0))))
@@ -783,7 +783,7 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 ()
       (LetPrim (v0 (Constant (Int 0)))
         (LetCont ((k1 (v1)
@@ -806,7 +806,7 @@
   new Object();
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (LetPrim (v1 (Constant (Null)))
         (InvokeContinuation return (v1)))))
@@ -818,7 +818,7 @@
   new Deprecated("");
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetPrim (v0 (Constant (String "")))
     (LetCont ((k0 (v1)
         (LetPrim (v2 (Constant (Null)))
@@ -833,7 +833,7 @@
   return [];
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (LiteralList ()))
     (InvokeContinuation return (v0))))
 '''),
@@ -843,7 +843,7 @@
   return [0];
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (LiteralList (v0)))
       (InvokeContinuation return (v1)))))
@@ -854,7 +854,7 @@
   return [0, 1, a];
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (Int 1)))
       (LetPrim (v2 (LiteralList (v0 v1 a)))
@@ -866,7 +866,7 @@
   return [0, [1], [a, [3]]];
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (Int 1)))
       (LetPrim (v2 (LiteralList (v1)))
@@ -884,7 +884,7 @@
   return {};
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (LiteralMap () ()))
     (InvokeContinuation return (v0))))
 '''),
@@ -894,7 +894,7 @@
   return {"a": 0};
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (String "a")))
     (LetPrim (v1 (Constant (Int 0)))
       (LetPrim (v2 (LiteralMap (v0) (v1)))
@@ -906,7 +906,7 @@
   return {"a": 0, "b": 1, "c": a};
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetPrim (v0 (Constant (String "a")))
     (LetPrim (v1 (Constant (Int 0)))
       (LetPrim (v2 (Constant (String "b")))
@@ -921,7 +921,7 @@
   return {0: "a", 1: {2: "b"}, a: {3: "c"}};
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetPrim (v0 (Constant (Int 0)))
     (LetPrim (v1 (Constant (String "a")))
       (LetPrim (v2 (Constant (Int 1)))
@@ -942,7 +942,7 @@
   for (;;) {}
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetCont ((rec k0 ()
       (LetPrim (v0 (Constant (Bool true)))
         (LetCont ((k1 ()
@@ -961,7 +961,7 @@
   }
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((rec k0 (v1)
         (LetPrim (v2 (Constant (Int 10)))
@@ -988,7 +988,7 @@
   }
 }
 ''', '''
-(FunctionDefinition main (i) return
+(FunctionDefinition main () (i) return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((rec k0 (v1)
         (LetPrim (v2 (Constant (Int 10)))
@@ -1015,7 +1015,7 @@
   while (true) {}
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetCont ((rec k0 ()
       (LetPrim (v0 (Constant (Bool true)))
         (LetCont ((k1 ()
@@ -1036,7 +1036,7 @@
   }
 }
 ''', '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((rec k0 (v1)
         (LetPrim (v2 (Constant (Int 10)))
@@ -1063,7 +1063,7 @@
   return a is String;
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (TypeOperator is a String k0)))
@@ -1074,7 +1074,7 @@
   return a is List<String>;
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (TypeOperator is a List<String> k0)))
@@ -1085,7 +1085,7 @@
   return a is Comparator<String>;
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (TypeOperator is a Comparator<String> k0)))
@@ -1096,7 +1096,7 @@
   return a is! String;
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (LetCont ((k1 (v1)
           (InvokeContinuation return (v1))))
@@ -1115,7 +1115,7 @@
   return a as String;
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (TypeOperator as a String k0)))
@@ -1132,7 +1132,7 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (LetCont ((rec k1 (v1)
           (LetCont ((k2 (v2)
@@ -1161,7 +1161,7 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (LetCont ((rec k1 (v1)
           (LetCont ((k2 (v2)
@@ -1192,7 +1192,7 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetPrim (v0 (Constant (Null)))
     (LetCont ((k0 (v1)
         (LetCont ((rec k1 (v2 v3)
@@ -1220,9 +1220,9 @@
   return local();
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetPrim (v0 (CreateFunction
-      (FunctionDefinition local () return
+      (FunctionDefinition local () () return
         (LetPrim (v1 (Constant (Null)))
           (InvokeContinuation return (v1))))))
     (LetCont ((k0 (v2)
@@ -1237,9 +1237,9 @@
   return l();
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetPrim (v0 (CreateFunction
-      (FunctionDefinition local () return
+      (FunctionDefinition local () () return
         (LetPrim (v1 (Constant (Null)))
           (InvokeContinuation return (v1))))))
     (LetCont ((k0 (v2)
@@ -1252,9 +1252,9 @@
   return () {}();
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetPrim (v0 (CreateFunction
-      (FunctionDefinition  () return
+      (FunctionDefinition  () () return
         (LetPrim (v1 (Constant (Null)))
           (InvokeContinuation return (v1))))))
     (LetCont ((k0 (v2)
@@ -1268,20 +1268,20 @@
   return c();
 }
 ''', '''
-(FunctionDefinition main (a) return
+(FunctionDefinition main () (a) return
   (LetCont ((k0 (v0)
       (LetCont ((k1 (v1)
           (InvokeContinuation return (v1))))
         (InvokeMethod v0 call () k1))))
     (LetCont ((k2 ()
         (LetPrim (v2 (CreateFunction
-            (FunctionDefinition  () return
+            (FunctionDefinition  () () return
               (LetPrim (v3 (Constant (Int 0)))
                 (InvokeContinuation return (v3))))))
           (InvokeContinuation k0 (v2))))
               (k3 ()
         (LetPrim (v4 (CreateFunction
-            (FunctionDefinition  () return
+            (FunctionDefinition  () () return
               (LetPrim (v5 (Constant (Int 1)))
                 (InvokeContinuation return (v5))))))
           (InvokeContinuation k0 (v4)))))
@@ -1297,7 +1297,7 @@
 }
 ''', const {
       'main': '''
-(FunctionDefinition main (args) return
+(FunctionDefinition main () (args) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (InvokeStatic field () k0)))
@@ -1313,7 +1313,7 @@
 }
 ''', const {
       'main': '''
-(FunctionDefinition main (args) return
+(FunctionDefinition main () (args) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (InvokeStatic field () k0)))
@@ -1331,7 +1331,7 @@
 }
 ''', const {
       'main': '''
-(FunctionDefinition main (args) return
+(FunctionDefinition main () (args) return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (InvokeStatic field () k0)))
@@ -1349,7 +1349,7 @@
   return field;
 }
 ''', '''
-(FunctionDefinition main (args) return
+(FunctionDefinition main () (args) return
   (LetCont ((k0 (v0)
       (LetCont ((k1 (v1)
           (LetCont ((k2 (v2)
@@ -1368,10 +1368,10 @@
   print(getFoo());
 }
 ''', '''
-(FunctionDefinition main (x foo) return
+(FunctionDefinition main () (x foo) return
   (LetCont ((k0 (v0)
       (LetPrim (v1 (CreateFunction
-          (FunctionDefinition getFoo () return
+          (FunctionDefinition getFoo () () return
             (LetPrim (v2 (GetMutableVariable foo))
               (InvokeContinuation return (v2))))))
         (LetCont ((k1 (v3)
@@ -1393,13 +1393,14 @@
 ''',
     const {
 'main': '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (InvokeConstructor C () k0)))
 ''',
 'C.':  '''
-(FunctionDefinition  () return
+(ConstructorDefinition (this) () return (
+    )
   (LetPrim (v0 (Constant (Null)))
     (InvokeContinuation return (v0))))
 '''}),
@@ -1414,13 +1415,14 @@
 ''',
     const {
 'main': '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (InvokeConstructor C () k0)))
 ''',
 'C.': '''
-(FunctionDefinition  () return
+(ConstructorDefinition (this) () return (
+    )
   (LetPrim (v0 (Constant (Null)))
     (InvokeContinuation return (v0))))
 '''}),
@@ -1436,18 +1438,20 @@
 ''',
     const {
 'main': '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (InvokeConstructor C () k0)))
 ''',
 'B.':  '''
-(FunctionDefinition  () return
+(ConstructorDefinition (this) () return (
+    )
   (LetPrim (v0 (Constant (Null)))
     (InvokeContinuation return (v0))))
 ''',
 'C.': '''
-(FunctionDefinition  () return
+(ConstructorDefinition (this) () return (
+    )
   (LetPrim (v0 (Constant (Null)))
     (InvokeContinuation return (v0))))
 '''}),
@@ -1463,18 +1467,20 @@
 ''',
     const {
 'main': '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetCont ((k0 (v0)
       (InvokeContinuation return (v0))))
     (InvokeConstructor C () k0)))
 ''',
 'B.': '''
-(FunctionDefinition  () return
+(ConstructorDefinition (this) () return (
+    )
   (LetPrim (v0 (Constant (Null)))
     (InvokeContinuation return (v0))))
 ''',
 'C.':  '''
-(FunctionDefinition  () return
+(ConstructorDefinition (this) () return (
+    )
   (LetPrim (v0 (Constant (Null)))
     (InvokeContinuation return (v0))))
 '''}),
@@ -1492,7 +1498,7 @@
 ''',
     const {
 'main': '''
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetCont ((k0 (v0)
       (LetCont ((k1 (v1)
           (InvokeContinuation return (v1))))
@@ -1500,9 +1506,45 @@
     (InvokeConstructor C () k0)))
 ''',
 'C.foo': '''
-(FunctionDefinition foo () return
+(FunctionDefinition foo (this) () return
   (LetPrim (v0 (Constant (Null)))
     (InvokeContinuation return (v0))))
 '''}),
   ]),
+
+
+  const Group('Try-catch', const <TestSpec>[
+    const TestSpec('''
+main() {
+  try {} catch (e) {}
+}
+''',
+'''
+(FunctionDefinition main () () return
+  (LetCont ((k0 ()
+      (LetPrim (v0 (Constant (Null)))
+        (InvokeContinuation return (v0)))))
+    (LetHandler ((v1 v2)
+        (InvokeContinuation k0 ()))
+      (InvokeContinuation k0 ()))))
+'''),
+
+    const TestSpec('''
+main() {
+  try {
+    return;
+  } catch (e) {}
+}
+''',
+'''
+(FunctionDefinition main () () return
+  (LetCont ((k0 ()
+      (LetPrim (v0 (Constant (Null)))
+        (InvokeContinuation return (v0)))))
+    (LetHandler ((v1 v2)
+        (InvokeContinuation k0 ()))
+      (LetPrim (v3 (Constant (Null)))
+        (InvokeContinuation return (v3))))))
+'''),
+  ]),
 ];
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index beeadde..175ca25 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -21,18 +21,9 @@
 import 'universe/universe.dart' show
     Universe;
 
-class ClosureNamer {
-  String getClosureVariableName(String name, int id) {
-    return "${name}_$id";
-  }
-
-  void forgetElement(Element element) {}
-}
-
 class ClosureTask extends CompilerTask {
   Map<Node, ClosureClassMap> closureMappingCache;
-  ClosureNamer namer;
-  ClosureTask(Compiler compiler, this.namer)
+  ClosureTask(Compiler compiler)
       : closureMappingCache = new Map<Node, ClosureClassMap>(),
         super(compiler);
 
@@ -46,7 +37,7 @@
       if (cached != null) return cached;
 
       ClosureTranslator translator =
-          new ClosureTranslator(compiler, elements, closureMappingCache, namer);
+          new ClosureTranslator(compiler, elements, closureMappingCache);
 
       // The translator will store the computed closure-mappings inside the
       // cache. One for given node and one for each nested closure.
@@ -91,7 +82,6 @@
       throw new SpannableAssertionFailure(
           closure, 'Not a closure: $closure (${closure.runtimeType}).');
     }
-    namer.forgetElement(cls);
     compiler.enqueuer.codegen.forgetElement(cls);
   }
 }
@@ -459,14 +449,37 @@
   // The closureData of the currentFunctionElement.
   ClosureClassMap closureData;
 
-  ClosureNamer namer;
-
   bool insideClosure = false;
 
   ClosureTranslator(this.compiler,
                     this.elements,
-                    this.closureMappingCache,
-                    this.namer);
+                    this.closureMappingCache);
+
+  /// Generate a unique name for the [id]th closure field, with proposed name
+  /// [name].
+  ///
+  /// The result is used as the name of [ClosureFieldElement]s, and must
+  /// therefore be unique to avoid breaking an invariant in the element model
+  /// (classes cannot declare multiple fields with the same name).
+  ///
+  /// Also, the names should be distinct from real field names to prevent
+  /// clashes with selectors for those fields.
+  String getClosureVariableName(String name, int id) {
+    return "_captured_${name}_$id";
+  }
+
+  /// Generate a unique name for the [id]th box field, with proposed name
+  /// [name].
+  ///
+  /// The result is used as the name of [BoxFieldElement]s, and must
+  /// therefore be unique to avoid breaking an invariant in the element model
+  /// (classes cannot declare multiple fields with the same name).
+  ///
+  /// Also, the names should be distinct from real field names to prevent
+  /// clashes with selectors for those fields.
+  String getBoxFieldName(int id) {
+    return "_box_$id";
+  }
 
   bool isCapturedVariable(Local element) {
     return _capturedVariableMapping.containsKey(element);
@@ -569,7 +582,7 @@
 
       for (Local capturedLocal in fieldCaptures.toList()..sort(compareLocals)) {
         int id = closureFieldCounter++;
-        String name = namer.getClosureVariableName(capturedLocal.name, id);
+        String name = getClosureVariableName(capturedLocal.name, id);
         addClosureField(capturedLocal, name);
       }
       closureClass.reverseBackendMembers();
@@ -797,18 +810,14 @@
       if (isCapturedVariable(variable)) {
         if (box == null) {
           // TODO(floitsch): construct better box names.
-          String boxName =
-              namer.getClosureVariableName('box', closureFieldCounter++);
+          String boxName = getBoxFieldName(closureFieldCounter++);
           box = new BoxLocal(boxName, executableContext);
         }
         String elementName = variable.name;
         String boxedName =
-            namer.getClosureVariableName(elementName, boxedFieldCounter++);
+            getClosureVariableName(elementName, boxedFieldCounter++);
         // TODO(kasperl): Should this be a FieldElement instead?
         BoxFieldElement boxed = new BoxFieldElement(boxedName, variable, box);
-        // No need to rename the fields of a box, so we give them a native name
-        // right now.
-        boxed.setFixedBackendName(boxedName);
         scopeMapping[variable] = boxed;
         setCapturedVariableBoxField(variable, boxed);
       }
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index bd636e4..dcaea59 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -361,13 +361,14 @@
    */
   void registerRuntimeType(Enqueuer enqueuer, Registry registry) {}
 
-  /**
-   * Call this method to enable [noSuchMethod] handling in the
-   * backend.
-   */
-  void enableNoSuchMethod(Element context, Enqueuer enqueuer) {
-    enqueuer.registerInvocation(compiler.noSuchMethodSelector);
-  }
+  /// Call this to register a `noSuchMethod` implementation.
+  void registerNoSuchMethod(Element noSuchMethodElement) {}
+
+  /// Call this method to enable support for `noSuchMethod`.
+  void enableNoSuchMethod(Enqueuer enqueuer) {}
+
+  /// Returns whether or not `noSuchMethod` support has been enabled.
+  bool get enabledNoSuchMethod => false;
 
   /// Call this method to enable support for isolates.
   void enableIsolateSupport(Enqueuer enqueuer) {}
@@ -402,12 +403,6 @@
 
   ClassElement defaultSuperclass(ClassElement element) => compiler.objectClass;
 
-  bool isDefaultNoSuchMethodImplementation(Element element) {
-    assert(element.name == Compiler.NO_SUCH_METHOD);
-    ClassElement classElement = element.enclosingClass;
-    return classElement == compiler.objectClass;
-  }
-
   bool isInterceptorClass(ClassElement element) => false;
 
   /// Returns `true` if [element] is a foreign element, that is, that the
@@ -949,7 +944,6 @@
   final Selector symbolValidatedConstructorSelector = new Selector.call(
       'validated', null, 1);
 
-  bool enabledNoSuchMethod = false;
   bool enabledRuntimeType = false;
   bool enabledFunctionApply = false;
   bool enabledInvokeOn = false;
@@ -1049,16 +1043,16 @@
     globalDependencies =
         new CodegenRegistry(this, new TreeElementMapping(null));
 
-    closureMapping.ClosureNamer closureNamer;
     if (emitJavaScript) {
       js_backend.JavaScriptBackend jsBackend =
           new js_backend.JavaScriptBackend(this, generateSourceMap);
-      closureNamer = jsBackend.namer;
       backend = jsBackend;
     } else {
-      closureNamer = new closureMapping.ClosureNamer();
       backend = new dart_backend.DartBackend(this, strips,
                                              multiFile: dart2dartMultiFile);
+      if (dumpInfo) {
+        throw new ArgumentError('--dump-info is not supported for dart2dart.');
+      }
     }
 
     tasks = [
@@ -1068,7 +1062,7 @@
       parser = new ParserTask(this),
       patchParser = new PatchParserTask(this),
       resolver = new ResolverTask(this, backend.constantCompilerTask),
-      closureToClassMapper = new closureMapping.ClosureTask(this, closureNamer),
+      closureToClassMapper = new closureMapping.ClosureTask(this),
       checker = new TypeCheckerTask(this),
       irBuilder = new IrBuilderTask(this),
       typesTask = new ti.TypesTask(this),
@@ -1623,9 +1617,6 @@
     if (hasIsolateSupport) {
       backend.enableIsolateSupport(enqueuer.codegen);
     }
-    if (enabledNoSuchMethod) {
-      backend.enableNoSuchMethod(null, enqueuer.codegen);
-    }
     if (compileAll) {
       libraryLoader.libraries.forEach((LibraryElement library) {
         fullyEnqueueLibrary(library, enqueuer.codegen);
diff --git a/pkg/compiler/lib/src/core_types.dart b/pkg/compiler/lib/src/core_types.dart
index ba71b3f..a1ec975 100644
--- a/pkg/compiler/lib/src/core_types.dart
+++ b/pkg/compiler/lib/src/core_types.dart
@@ -5,6 +5,7 @@
 library dart2js.type_system;
 
 import 'dart_types.dart';
+import 'elements/elements.dart' show ClassElement;
 
 /// The core types in Dart.
 abstract class CoreTypes {
@@ -45,6 +46,9 @@
   /// [elementType] as its type argument.
   InterfaceType iterableType([DartType elementType = const DynamicType()]);
 
+  /// The `Future` class declaration.
+  ClassElement get futureClass;
+
   /// Returns an instance of the `Future` type defined in 'dart:async' with
   /// [elementType] as its type argument.
   InterfaceType futureType([DartType elementType = const DynamicType()]);
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index b0bc57c..deffab4 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -9,19 +9,11 @@
 import '../dart_types.dart';
 import '../dart2jslib.dart';
 import '../elements/elements.dart';
-import '../io/source_file.dart';
 import '../io/source_information.dart';
 import '../tree/tree.dart' as ast;
-import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator;
-import '../universe/universe.dart' show SelectorKind;
-import 'cps_ir_nodes.dart' as ir;
-import '../elements/modelx.dart' show SynthesizedConstructorElementX,
-    ConstructorBodyElementX, FunctionSignatureX;
 import '../closure.dart' hide ClosureScope;
-import '../closure.dart' as closurelib;
-import '../js_backend/js_backend.dart' show JavaScriptBackend;
-
-part 'cps_ir_builder_visitor.dart';
+import 'cps_ir_nodes.dart' as ir;
+import 'cps_ir_builder_task.dart' show DartCapturedVariables;
 
 /// A mapping from variable elements to their compile-time values.
 ///
@@ -227,10 +219,25 @@
   final ExecutableElement currentElement;
 
   final ir.Continuation returnContinuation = new ir.Continuation.retrn();
+  ir.Parameter _thisParameter;
+  ir.Parameter enclosingMethodThisParameter;
 
   final List<ir.Definition> functionParameters = <ir.Definition>[];
 
   IrBuilderDelimitedState(this.constantSystem, this.currentElement);
+
+  ir.Parameter get thisParameter => _thisParameter;
+  void set thisParameter(ir.Parameter value) {
+    assert(_thisParameter == null);
+    _thisParameter = value;
+  }
+}
+
+class ThisParameterLocal implements Local {
+  final ExecutableElement executableContext;
+  ThisParameterLocal(this.executableContext);
+  String get name => 'this';
+  toString() => 'ThisParameterLocal($executableContext)';
 }
 
 /// A factory for building the cps IR.
@@ -240,6 +247,7 @@
 abstract class IrBuilder {
   IrBuilder _makeInstance();
 
+  // TODO(johnniwinther): Remove this from the [IrBuilder].
   /// A map from TryStatements in the AST to their analysis information.
   ///
   /// This includes which variables should be copied into [ir.MutableVariable]s
@@ -266,8 +274,6 @@
 
   void declareLocalVariable(LocalVariableElement element,
                             {ir.Primitive initialValue});
-  ir.Primitive buildLocalGet(LocalElement element);
-  ir.Primitive buildLocalSet(LocalElement element, ir.Primitive value);
 
   /// Called when entering a nested function with free variables.
   ///
@@ -303,6 +309,7 @@
   /// Add the given function parameter to the IR, and bind it in the environment
   /// or put it in its box, if necessary.
   void _createFunctionParameter(ParameterElement parameterElement);
+  void _createThisParameter();
 
   /// Creates an access to the receiver from the current (or enclosing) method.
   ///
@@ -368,6 +375,14 @@
         ..environment = new Environment.from(environment);
   }
 
+  /// Construct a builder for making constructor field initializers.
+  IrBuilder makeInitializerBuilder() {
+    return _makeInstance()
+        ..state = new IrBuilderDelimitedState(state.constantSystem,
+                                              state.currentElement)
+        ..environment = new Environment.from(environment);
+  }
+
   /// Construct a visitor for a recursive continuation.
   ///
   /// The recursive continuation builder has fresh parameters (i.e. SSA phis)
@@ -386,8 +401,11 @@
 
   /// Construct a builder for an inner function.
   IrBuilder makeInnerFunctionBuilder(ExecutableElement currentElement) {
+    IrBuilderDelimitedState innerState =
+        new IrBuilderDelimitedState(state.constantSystem, currentElement)
+          ..enclosingMethodThisParameter = state.enclosingMethodThisParameter;
     return _makeInstance()
-        ..state = new IrBuilderDelimitedState(state.constantSystem, currentElement)
+        ..state = innerState
         ..environment = new Environment.empty();
   }
 
@@ -401,6 +419,7 @@
   List<ir.Primitive> buildFunctionHeader(Iterable<ParameterElement> parameters,
                                         {ClosureScope closureScope,
                                          ClosureEnvironment env}) {
+    _createThisParameter();
     _enterClosureEnvironment(env);
     _enterScope(closureScope);
     parameters.forEach(_createFunctionParameter);
@@ -422,11 +441,11 @@
     state.localConstants.add(new ConstDeclaration(variableElement, value));
   }
 
-  // Plug an expression into the 'hole' in the context being accumulated.  The
-  // empty context (just a hole) is represented by root (and current) being
-  // null.  Since the hole in the current context is filled by this function,
-  // the new hole must be in the newly added expression---which becomes the
-  // new value of current.
+  /// Plug an expression into the 'hole' in the context being accumulated.  The
+  /// empty context (just a hole) is represented by root (and current) being
+  /// null.  Since the hole in the current context is filled by this function,
+  /// the new hole must be in the newly added expression---which becomes the
+  /// new value of current.
   void add(ir.Expression expr) {
     assert(isOpen);
     if (_root == null) {
@@ -436,6 +455,12 @@
     }
   }
 
+  /// Create and add a new [LetPrim] for [primitive].
+  ir.Primitive addPrimitive(ir.Primitive primitive) {
+    add(new ir.LetPrim(primitive));
+    return primitive;
+  }
+
   ir.Primitive _continueWithExpression(ir.Expression build(ir.Continuation k)) {
     ir.Parameter v = new ir.Parameter(null);
     ir.Continuation k = new ir.Continuation([v]);
@@ -448,6 +473,8 @@
                                   Selector selector,
                                   List<ir.Primitive> arguments,
                                   SourceInformation sourceInformation) {
+    assert(!element.isLocal);
+    assert(!element.isInstanceMember);
     assert(isOpen);
     return _continueWithExpression(
         (k) => new ir.InvokeStatic(element, selector, k, arguments,
@@ -457,6 +484,7 @@
   ir.Primitive _buildInvokeSuper(Element target,
                                  Selector selector,
                                  List<ir.Primitive> arguments) {
+    assert(target.isInstanceMember);
     assert(isOpen);
     return _continueWithExpression(
         (k) => new ir.InvokeMethodDirectly(
@@ -484,9 +512,7 @@
   /// Create a constant literal from [constant].
   ir.Constant buildConstantLiteral(ConstantExpression constant) {
     assert(isOpen);
-    ir.Constant prim = new ir.Constant(constant);
-    add(new ir.LetPrim(prim));
-    return prim;
+    return addPrimitive(new ir.Constant(constant));
   }
 
   // Helper for building primitive literals.
@@ -525,9 +551,7 @@
   ir.Primitive buildListLiteral(InterfaceType type,
                                 Iterable<ir.Primitive> values) {
     assert(isOpen);
-    ir.Primitive result = new ir.LiteralList(type, values);
-    add(new ir.LetPrim(result));
-    return result;
+    return addPrimitive(new ir.LiteralList(type, values));
   }
 
   /// Creates a non-constant map literal of the provided [type] and with the
@@ -545,9 +569,7 @@
           build(key.current), build(value.current)));
     }
     assert(!key.moveNext() && !value.moveNext());
-    ir.Primitive result = new ir.LiteralMap(type, entries);
-    add(new ir.LetPrim(result));
-    return result;
+    return addPrimitive(new ir.LiteralMap(type, entries));
   }
 
   /// Creates a conditional expression with the provided [condition] where the
@@ -657,30 +679,35 @@
           message: "Local constants for abstract method $element: "
                    "${state.localConstants}"));
       return new ir.FunctionDefinition.abstract(
-                element, state.functionParameters, defaults);
+          element, state.thisParameter, state.functionParameters, defaults);
     } else {
       ir.RunnableBody body = makeRunnableBody();
       return new ir.FunctionDefinition(
-          element, state.functionParameters, body,
+          element, state.thisParameter, state.functionParameters, body,
           state.localConstants, defaults);
     }
   }
 
+  /// Create a constructor definition without a body, for representing
+  /// external constructors declarations.
+  ir.ConstructorDefinition makeAbstractConstructorDefinition(
+      List<ConstantExpression> defaults) {
+    FunctionElement element = state.currentElement;
+    assert(invariant(element, _root == null,
+        message: "Non-empty body for external constructor $element: $_root"));
+    assert(invariant(element, state.localConstants.isEmpty,
+        message: "Local constants for external constructor $element: "
+                 "${state.localConstants}"));
+    return new ir.ConstructorDefinition.abstract(
+        element, state.functionParameters, defaults);
+  }
+
   ir.ConstructorDefinition makeConstructorDefinition(
       List<ConstantExpression> defaults, List<ir.Initializer> initializers) {
     FunctionElement element = state.currentElement;
-    if (element.isExternal) {
-      assert(invariant(element, _root == null,
-          message: "Non-empty body for external constructor $element: $_root"));
-      assert(invariant(element, state.localConstants.isEmpty,
-          message: "Local constants for external constructor $element: "
-                   "${state.localConstants}"));
-      return new ir.ConstructorDefinition.abstract(
-                element, state.functionParameters, defaults);
-    }
     ir.RunnableBody body = makeRunnableBody();
     return new ir.ConstructorDefinition(
-        element, state.functionParameters, body, initializers,
+        element, state.thisParameter, state.functionParameters, body, initializers,
         state.localConstants, defaults);
   }
 
@@ -691,10 +718,18 @@
                                     Selector selector,
                                     List<ir.Primitive> arguments);
 
-  /// Create a setter invocation on the super class where the setter name and
-  /// argument are defined by [selector] and [value], respectively.
-  void buildSuperSet(Element target, Selector selector, ir.Primitive value) {
+  /// Create a getter invocation of the [target] on the super class.
+  ir.Primitive buildSuperGet(Element target) {
+    Selector selector = new Selector.getter(target.name, target.library);
+    return buildSuperInvocation(target, selector, const <ir.Primitive>[]);
+  }
+
+  /// Create a setter invocation of the [target] on the super class of with
+  /// [value].
+  ir.Primitive buildSuperSet(Element target, ir.Primitive value) {
+    Selector selector = new Selector.setter(target.name, target.library);
     buildSuperInvocation(target, selector, [value]);
+    return value;
   }
 
   /// Create an index set invocation on the super class with the provided
@@ -743,6 +778,20 @@
     return value;
   }
 
+  /// Create a read access of [local].
+  ir.Primitive buildLocalGet(LocalElement element);
+
+  /// Create a write access to [local] with the provided [value].
+  ir.Primitive buildLocalSet(LocalElement element, ir.Primitive value);
+
+  /// Create an invocation of the local [element] where argument structure is
+  /// defined by [selector] and the argument values are defined by [arguments].
+  ir.Primitive buildLocalInvocation(LocalElement element,
+                                    Selector selector,
+                                    List<ir.Primitive> arguments) {
+    return buildCallInvocation(buildLocalGet(element), selector, arguments);
+  }
+
   /// Create a static invocation of [element] where argument structure is
   /// defined by [selector] and the argument values are defined by [arguments].
   ir.Primitive buildStaticInvocation(Element element,
@@ -755,9 +804,8 @@
   /// Create a static getter invocation of [element] where the getter name is
   /// defined by [selector].
   ir.Primitive buildStaticGet(Element element,
-                              Selector selector,
                               {SourceInformation sourceInformation}) {
-    assert(selector.isGetter);
+    Selector selector = new Selector.getter(element.name, element.library);
     // TODO(karlklose,sigurdm): build different nodes for getters.
     return _buildInvokeStatic(
         element, selector, const <ir.Primitive>[], sourceInformation);
@@ -766,10 +814,9 @@
   /// Create a static setter invocation of [element] where the setter name and
   /// argument are defined by [selector] and [value], respectively.
   ir.Primitive buildStaticSet(Element element,
-                              Selector selector,
                               ir.Primitive value,
                               {SourceInformation sourceInformation}) {
-    assert(selector.isSetter);
+    Selector selector = new Selector.setter(element.name, element.library);
     // TODO(karlklose,sigurdm): build different nodes for setters.
     _buildInvokeStatic(
         element, selector, <ir.Primitive>[value], sourceInformation);
@@ -943,14 +990,20 @@
     // The CPS translation of
     // [[for (initializer; condition; update) body; successor]] is:
     //
+    // _enterForLoopInitializer();
     // [[initializer]];
     // let cont loop(x, ...) =
     //     let prim cond = [[condition]] in
     //     let cont break() = [[successor]] in
     //     let cont exit() = break(v, ...) in
     //     let cont body() =
-    //       let cont continue(x, ...) = [[update]]; loop(v, ...) in
-    //       [[body]]; continue(v, ...) in
+    //         _enterForLoopBody();
+    //         let cont continue(x, ...) =
+    //             _enterForLoopUpdate();
+    //             [[update]];
+    //             loop(v, ...) in
+    //         [[body]];
+    //         continue(v, ...) in
     //     branch cond (body, exit) in
     // loop(v, ...)
     //
@@ -976,11 +1029,12 @@
     state.breakCollectors.add(breakCollector);
     state.continueCollectors.add(continueCollector);
 
-    IrBuilder bodyBuilder = condBuilder.makeDelimitedBuilder();
+    IrBuilder outerBodyBuilder = condBuilder.makeDelimitedBuilder();
+    outerBodyBuilder._enterForLoopBody(closureScope, loopVariables);
 
-    bodyBuilder._enterForLoopBody(closureScope, loopVariables);
+    IrBuilder innerBodyBuilder = outerBodyBuilder.makeDelimitedBuilder();
 
-    buildBody(bodyBuilder);
+    buildBody(innerBodyBuilder);
     assert(state.breakCollectors.last == breakCollector);
     assert(state.continueCollectors.last == continueCollector);
     state.breakCollectors.removeLast();
@@ -992,8 +1046,8 @@
     // is instead placed just outside the body of the body continuation.
     bool hasContinues = !continueCollector.isEmpty;
     IrBuilder updateBuilder = hasContinues
-        ? condBuilder.makeRecursiveBuilder()
-        : bodyBuilder;
+        ? outerBodyBuilder.makeRecursiveBuilder()
+        : innerBodyBuilder;
     updateBuilder._enterForLoopUpdate(closureScope, loopVariables);
     buildUpdate(updateBuilder);
 
@@ -1024,7 +1078,7 @@
       // If there are continues in the body, we need a named continue
       // continuation as a join point.
       continueContinuation = new ir.Continuation(updateBuilder._parameters);
-      if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder);
+      if (innerBodyBuilder.isOpen) continueCollector.addJump(innerBodyBuilder);
       invokeFullJoin(continueContinuation, continueCollector);
     }
     ir.Continuation loopContinuation =
@@ -1039,12 +1093,12 @@
     // only after it is guaranteed that they are not empty.
     if (hasContinues) {
       continueContinuation.body = updateBuilder._root;
-      bodyContinuation.body =
-          new ir.LetCont(continueContinuation,
-              bodyBuilder._root);
+      outerBodyBuilder.add(new ir.LetCont(continueContinuation,
+                                          innerBodyBuilder._root));
     } else {
-      bodyContinuation.body = bodyBuilder._root;
+      outerBodyBuilder.add(innerBodyBuilder._root);
     }
+    bodyContinuation.body = outerBodyBuilder._root;
 
     loopContinuation.body = condBuilder._root;
     add(new ir.LetCont(loopContinuation,
@@ -1134,13 +1188,16 @@
     bodyBuilder.add(new ir.LetCont(currentInvoked,
         new ir.InvokeMethod(iterator, new Selector.getter("current", null),
             currentInvoked, emptyArguments)));
+    // TODO(sra): Does this cover all cases? The general setter case include
+    // super.
     if (Elements.isLocal(variableElement)) {
       bodyBuilder.buildLocalSet(variableElement, currentValue);
-    } else if (Elements.isStaticOrTopLevel(variableElement)) {
-      bodyBuilder.buildStaticSet(
-          variableElement, variableSelector, currentValue);
+    } else if (Elements.isStaticOrTopLevel(variableElement) ||
+               Elements.isErroneous(variableElement)) {
+      bodyBuilder.buildStaticSet(variableElement, currentValue);
     } else {
       ir.Primitive receiver = bodyBuilder.buildThis();
+      assert(receiver != null);
       bodyBuilder.buildDynamicSet(receiver, variableSelector, currentValue);
     }
 
@@ -1212,11 +1269,11 @@
     //
     // let cont continue(x, ...) =
     //     let prim cond = [[condition]] in
-    //     let cont break() = [[successor]] in
-    //     let cont exit() = break(v, ...) in
-    //     let cont body() = [[body]]; continue(v, ...) in
-    //     branch cond (body, exit) in
-    // continue(v, ...)
+    //     let cont break(x, ...) = [[successor]] in
+    //     let cont exit() = break(v, ...)
+    //          and body() = [[body]]; continue(v, ...)
+    //     in branch cond (body, exit)
+    // in continue(v, ...)
     //
     // If there are no breaks in the body, the break continuation is inlined
     // in the exit continuation (i.e., the translation of the successor
@@ -1284,6 +1341,264 @@
     }
   }
 
+
+  /// Creates a do-while loop.
+  ///
+  /// The body and condition are created by [buildBody] and [buildCondition].
+  /// The jump target [target] is the target of `break` and `continue`
+  /// statements in the body that have the loop as their target.
+  /// [closureScope] contains all the variables declared in the loop (but not
+  /// declared in some inner closure scope).
+  void buildDoWhile({SubbuildFunction buildBody,
+                     SubbuildFunction buildCondition,
+                     JumpTarget target,
+                     ClosureScope closureScope}) {
+    assert(isOpen);
+    // The CPS translation of [[do body; while (condition); successor]] is:
+    //
+    // let cont break(x, ...) = [[successor]] in
+    // let cont rec loop(x, ...) =
+    //   let cont continue(x, ...) =
+    //     let prim cond = [[condition]] in
+    //       let cont exit() = break(v, ...)
+    //            and repeat() = loop(v, ...)
+    //       in branch cond (repeat, exit)
+    //   in [[body]]; continue(v, ...)
+    // in loop(v, ...)
+    IrBuilder bodyBuilder = makeRecursiveBuilder();
+    IrBuilder continueBuilder = bodyBuilder.makeRecursiveBuilder();
+
+    // Construct the continue continuation (i.e., the condition).
+    // <Continue> =
+    // let prim cond = [[condition]] in
+    //   let cont exit() = break(v, ...)
+    //        and repeat() = loop(v, ...)
+    //   in branch cond (repeat, exit)
+    ir.Primitive condition = buildCondition(continueBuilder);
+    // Use a delimited IrBuilder for the exit continuation's body so that
+    // we can capture the break with the body's break collector.
+    ir.Continuation exitContinuation = new ir.Continuation([]);
+    IrBuilder exitBuilder = continueBuilder.makeDelimitedBuilder();
+    ir.Continuation repeatContinuation = new ir.Continuation([]);
+    ir.InvokeContinuation invokeLoop =
+        new ir.InvokeContinuation.uninitialized(recursive: true);
+    invokeLoop.arguments =
+        continueBuilder.environment.index2value.map(
+            (ir.Primitive value) => new ir.Reference(value)).toList();
+    repeatContinuation.body = invokeLoop;
+    continueBuilder.add(
+        new ir.LetCont.many(<ir.Continuation>[exitContinuation,
+                                              repeatContinuation],
+            new ir.Branch(new ir.IsTrue(condition),
+                          repeatContinuation,
+                          exitContinuation)));
+    ir.Continuation continueContinuation =
+        new ir.Continuation(continueBuilder._parameters);
+    continueContinuation.body = continueBuilder._root;
+
+    // Construct the loop continuation (i.e., the body and condition).
+    // <Loop> =
+    // let cont continue(x, ...) =
+    //   <Continue>
+    // in [[body]]; continue(v, ...)
+    JumpCollector breakCollector = new JumpCollector(target);
+    JumpCollector continueCollector = new JumpCollector(target);
+    state.breakCollectors.add(breakCollector);
+    state.continueCollectors.add(continueCollector);
+    bodyBuilder._enterScope(closureScope);
+    buildBody(bodyBuilder);
+    assert(state.breakCollectors.last == breakCollector);
+    assert(state.continueCollectors.last == continueCollector);
+    state.breakCollectors.removeLast();
+    state.continueCollectors.removeLast();
+    // Add the jump from the loop's exit to the break condition.  It is only
+    // here where the exitBuilder's root is non-null and we can set the
+    // exitContinuation's body.
+    breakCollector.addJump(exitBuilder);
+    exitContinuation.body = exitBuilder._root;
+    if (bodyBuilder.isOpen) {
+      continueCollector.addJump(bodyBuilder);
+    }
+    invokeFullJoin(continueContinuation, continueCollector, recursive: false);
+    ir.Continuation loopContinuation =
+        new ir.Continuation(bodyBuilder._parameters);
+    loopContinuation.isRecursive = true;
+    loopContinuation.body =
+        new ir.LetCont(continueContinuation, bodyBuilder._root);
+    invokeLoop.continuation =
+        new ir.Reference<ir.Continuation>(loopContinuation);
+    ir.LetCont letLoop =
+        new ir.LetCont(loopContinuation,
+            new ir.InvokeContinuation(loopContinuation,
+                                      environment.index2value));
+
+    // Add the break condition.
+    ir.Continuation breakContinuation;
+    if (breakCollector.length == 1) {
+      // createJoin only works when there is more than one jump to a join-point
+      // continuation.  This is to potentially catch errors in the case that
+      // a join was intended and at least one jump is missing.  Unfortunately
+      // we have the explicit code below for the (common?) case that the
+      // only break from the do-while is the implicit one when the condition
+      // is false.
+      List<ir.Parameter> parameters = <ir.Parameter>[];
+      List<ir.Reference> arguments = <ir.Reference>[];
+      for (int i = 0; i < environment.length; ++i) {
+        ir.Parameter parameter =
+            new ir.Parameter(environment.index2variable[i]);
+        parameters.add(parameter);
+        environment.index2value[i] = parameter;
+        arguments.add(new ir.Reference(breakCollector.environments.first[i]));
+      }
+      breakContinuation = new ir.Continuation(parameters);
+      breakCollector.invocations.first.arguments = arguments;
+      breakCollector.invocations.first.continuation =
+          new ir.Reference(breakContinuation);
+    } else {
+      breakContinuation = createJoin(environment.length, breakCollector);
+    }
+    add(new ir.LetCont(breakContinuation, letLoop));
+  }
+
+  /// Creates a try-statement.
+  ///
+  /// [tryInfo] provides information on local variables declared and boxed
+  /// within this try statement.
+  /// [buildTryBlock] builds the try block.
+  /// [catchClauseInfos] provides access to the catch type, exception variable,
+  /// and stack trace variable, and a function for building the catch block.
+  void buildTry(
+      {TryStatementInfo tryStatementInfo,
+       SubbuildFunction buildTryBlock,
+       List<CatchClauseInfo> catchClauseInfos: const <CatchClauseInfo>[]}) {
+    assert(isOpen);
+
+    // Catch handlers are in scope for their body.  The CPS translation of
+    // [[try tryBlock catch (e) catchBlock; successor]] is:
+    //
+    // let cont join(v0, v1, ...) = [[successor]] in
+    //   let mutable m0 = x0 in
+    //     let mutable m1 = x1 in
+    //       ...
+    //       let handler catch_(e) =
+    //         let prim p0 = GetMutable(m0) in
+    //           let prim p1 = GetMutable(m1) in
+    //             ...
+    //             [[catchBlock]]
+    //             join(p0, p1, ...)
+    //       in
+    //         [[tryBlock]]
+    //         let prim p0' = GetMutable(m0) in
+    //           let prim p1' = GetMutable(m1) in
+    //             ...
+    //             join(p0', p1', ...)
+    //
+    // In other words, both the try and catch block are in the scope of the
+    // join-point continuation, and they are both in the scope of a sequence
+    // of mutable bindings for the variables assigned in the try.  The join-
+    // point continuation is not in the scope of these mutable bindings.
+    // The tryBlock is in the scope of a binding for the catch handler.  Each
+    // instruction (specifically, each call) in the tryBlock is in the dynamic
+    // scope of the handler.  The mutable bindings are dereferenced at the end
+    // of the try block and at the beginning of the catch block, so the
+    // variables are unboxed in the catch block and at the join point.
+
+    IrBuilder tryCatchBuilder = makeDelimitedBuilder();
+    // Variables that are boxed due to being captured in a closure are boxed
+    // for their entire lifetime, and so they do not need to be boxed on
+    // entry to any try block.  We check for them here because we can not
+    // identify all of them in the same pass where we identify the variables
+    // assigned in the try (the may be captured by a closure after the try
+    // statement).
+    Iterable<LocalVariableElement> boxedOnEntry =
+        tryStatementInfo.boxedOnEntry.where((LocalVariableElement variable) {
+      return !tryCatchBuilder.mutableCapturedVariables.contains(variable);
+    });
+    for (LocalVariableElement variable in boxedOnEntry) {
+      assert(!tryCatchBuilder.isInMutableVariable(variable));
+      ir.Primitive value = tryCatchBuilder.buildLocalGet(variable);
+      tryCatchBuilder.makeMutableVariable(variable);
+      tryCatchBuilder.declareLocalVariable(variable, initialValue: value);
+    }
+
+    IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder();
+    IrBuilder tryBuilder = tryCatchBuilder.makeDelimitedBuilder();
+    List<ir.Parameter> joinParameters =
+        new List<ir.Parameter>.generate(environment.length, (i) {
+      return new ir.Parameter(environment.index2variable[i]);
+    });
+    ir.Continuation joinContinuation = new ir.Continuation(joinParameters);
+
+    void interceptJumps(JumpCollector collector) {
+      collector.enterTry(boxedOnEntry);
+    }
+    void restoreJumps(JumpCollector collector) {
+      collector.leaveTry();
+    }
+    tryBuilder.state.breakCollectors.forEach(interceptJumps);
+    tryBuilder.state.continueCollectors.forEach(interceptJumps);
+    buildTryBlock(tryBuilder);
+    tryBuilder.state.breakCollectors.forEach(restoreJumps);
+    tryBuilder.state.continueCollectors.forEach(restoreJumps);
+    if (tryBuilder.isOpen) {
+      for (LocalVariableElement variable in boxedOnEntry) {
+        assert(tryBuilder.isInMutableVariable(variable));
+        ir.Primitive value = tryBuilder.buildLocalGet(variable);
+        tryBuilder.environment.update(variable, value);
+      }
+      tryBuilder.jumpTo(joinContinuation);
+    }
+
+    for (LocalVariableElement variable in boxedOnEntry) {
+      assert(catchBuilder.isInMutableVariable(variable));
+      ir.Primitive value = catchBuilder.buildLocalGet(variable);
+      // Note that we remove the variable from the set of mutable variables
+      // here (and not above for the try body).  This is because the set of
+      // mutable variables is global for the whole function and not local to
+      // a delimited builder.
+      catchBuilder.removeMutableVariable(variable);
+      catchBuilder.environment.update(variable, value);
+    }
+
+    // TODO(kmillikin): Handle multiple catch clauses.
+    assert(catchClauseInfos.length == 1);
+    for (CatchClauseInfo catchClauseInfo in catchClauseInfos) {
+      LocalVariableElement exceptionVariable =
+          catchClauseInfo.exceptionVariable;
+      ir.Parameter exceptionParameter = new ir.Parameter(exceptionVariable);
+      catchBuilder.environment.extend(exceptionVariable, exceptionParameter);
+      ir.Parameter traceParameter;
+      LocalVariableElement stackTraceVariable =
+          catchClauseInfo.stackTraceVariable;
+      if (stackTraceVariable != null) {
+        traceParameter = new ir.Parameter(stackTraceVariable);
+        catchBuilder.environment.extend(stackTraceVariable, traceParameter);
+      } else {
+        // Use a dummy continuation parameter for the stack trace parameter.
+        // This will ensure that all handlers have two parameters and so they
+        // can be treated uniformly.
+        traceParameter = new ir.Parameter(null);
+      }
+      catchClauseInfo.buildCatchBlock(catchBuilder);
+      if (catchBuilder.isOpen) {
+        catchBuilder.jumpTo(joinContinuation);
+      }
+      List<ir.Parameter> catchParameters =
+          <ir.Parameter>[exceptionParameter, traceParameter];
+      ir.Continuation catchContinuation = new ir.Continuation(catchParameters);
+      catchContinuation.body = catchBuilder._root;
+
+      tryCatchBuilder.add(
+          new ir.LetHandler(catchContinuation, tryBuilder._root));
+      tryCatchBuilder._current = null;
+    }
+
+    add(new ir.LetCont(joinContinuation, tryCatchBuilder._root));
+    for (int i = 0; i < environment.length; ++i) {
+      environment.index2value[i] = joinParameters[i];
+    }
+  }
+
   /// Create a return statement `return value;` or `return;` if [value] is
   /// null.
   void buildReturn([ir.Primitive value]) {
@@ -1323,6 +1638,47 @@
   }
 
 
+  /// Creates a labeled statement
+  void buildLabeledStatement({SubbuildFunction buildBody,
+                              JumpTarget target}) {
+    JumpCollector jumps = new JumpCollector(target);
+    state.breakCollectors.add(jumps);
+    IrBuilder innerBuilder = makeDelimitedBuilder();
+    buildBody(innerBuilder);
+    state.breakCollectors.removeLast();
+    bool hasBreaks = !jumps.isEmpty;
+    ir.Continuation joinContinuation;
+    if (hasBreaks) {
+      if (innerBuilder.isOpen) {
+        jumps.addJump(innerBuilder);
+      }
+
+      // All jumps to the break continuation must be in the scope of the
+      // continuation's binding.  The continuation is bound just outside the
+      // body to satisfy this property without extra analysis.
+      // As a consequence, the break continuation needs parameters for all
+      // local variables in scope at the exit from the body.
+      List<ir.Parameter> parameters =
+          new List<ir.Parameter>.generate(environment.length, (i) {
+        return new ir.Parameter(environment.index2variable[i]);
+      });
+      joinContinuation = new ir.Continuation(parameters);
+      invokeFullJoin(joinContinuation, jumps, recursive: false);
+      add(new ir.LetCont(joinContinuation, innerBuilder._root));
+      for (int i = 0; i < environment.length; ++i) {
+        environment.index2value[i] = parameters[i];
+      }
+    } else {
+      if (innerBuilder._root != null) {
+        add(innerBuilder._root);
+        _current = innerBuilder._current;
+        environment = innerBuilder.environment;
+      }
+    }
+    return null;
+  }
+
+
   // Build(BreakStatement L, C) = C[InvokeContinuation(...)]
   //
   // The continuation and arguments are filled in later after translating
@@ -1598,6 +1954,7 @@
   final Map<Local, ir.MutableVariable> local2mutable =
       <Local, ir.MutableVariable>{};
 
+  // Move this to the IrBuilderVisitor.
   final DartCapturedVariables capturedVariables;
 
   /// Creates a [MutableVariable] for the given local.
@@ -1705,9 +2062,9 @@
     for (LocalElement loopVariable in loopVariables) {
       if (isInMutableVariable(loopVariable)) {
         ir.MutableVariable mutableVariable = getMutableVariable(loopVariable);
-        ir.Primitive get = new ir.GetMutableVariable(mutableVariable);
-        add(new ir.LetPrim(get));
-        environment.update(loopVariable, get);
+        ir.Primitive value =
+            addPrimitive(new ir.GetMutableVariable(mutableVariable));
+        environment.update(loopVariable, value);
         dartState.registerizedMutableVariables.add(loopVariable);
       }
     }
@@ -1724,6 +2081,26 @@
     }
   }
 
+  void _createThisParameter() {
+    void create() {
+      ir.Parameter thisParameter =
+          new ir.Parameter(new ThisParameterLocal(state.currentElement));
+      state.thisParameter = thisParameter;
+      state.enclosingMethodThisParameter = thisParameter;
+    }
+    if (state.currentElement.isLocal) return;
+    if (state.currentElement.isStatic) return;
+    if (state.currentElement.isGenerativeConstructor) {
+      create();
+      return;
+    }
+    if (state.currentElement.isStatic) return;
+    if (state.currentElement.isInstanceMember) {
+      create();
+      return;
+    }
+  }
+
   void declareLocalVariable(LocalVariableElement variableElement,
                             {ir.Primitive initialValue}) {
     assert(isOpen);
@@ -1747,8 +2124,7 @@
       ir.MutableVariable variable = getMutableVariable(functionElement);
       add(new ir.DeclareFunction(variable, definition));
     } else {
-      ir.CreateFunction prim = new ir.CreateFunction(definition);
-      add(new ir.LetPrim(prim));
+      ir.CreateFunction prim = addPrimitive(new ir.CreateFunction(definition));
       environment.extend(functionElement, prim);
       prim.useElementAsHint(functionElement);
     }
@@ -1756,9 +2132,7 @@
 
   /// Create a function expression from [definition].
   ir.Primitive buildFunctionExpression(ir.FunctionDefinition definition) {
-    ir.CreateFunction prim = new ir.CreateFunction(definition);
-    add(new ir.LetPrim(prim));
-    return prim;
+    return addPrimitive(new ir.CreateFunction(definition));
   }
 
   /// Create a read access of [local].
@@ -1767,10 +2141,7 @@
     if (isInMutableVariable(local)) {
       // Do not use [local] as a hint on [result]. The variable should always
       // be inlined, but the hint prevents it.
-      ir.Primitive result =
-          new ir.GetMutableVariable(getMutableVariable(local));
-      add(new ir.LetPrim(result));
-      return result;
+      return addPrimitive(new ir.GetMutableVariable(getMutableVariable(local)));
     } else {
       return environment.lookup(local);
     }
@@ -1789,9 +2160,7 @@
   }
 
   ir.Primitive buildThis() {
-    ir.Primitive thisPrim = new ir.This();
-    add(new ir.LetPrim(thisPrim));
-    return thisPrim;
+    return state.enclosingMethodThisParameter;
   }
 
   ir.Primitive buildSuperInvocation(Element target,
@@ -1839,8 +2208,7 @@
     if (env == null) return;
 
     // Obtain a reference to the function object (this).
-    ir.Primitive thisPrim = new ir.This();
-    add(new ir.LetPrim(thisPrim));
+    ir.Parameter thisPrim = state.thisParameter;
 
     // Obtain access to the free variables.
     env.freeVariables.forEach((Local local, ClosureLocation location) {
@@ -1850,9 +2218,8 @@
       } else {
         // Unboxed variables are loaded from the function object immediately.
         // This includes BoxLocals which are themselves unboxed variables.
-        ir.Primitive load = new ir.GetField(thisPrim, location.field);
-        add(new ir.LetPrim(load));
-        environment.extend(local, load);
+        environment.extend(local,
+            addPrimitive(new ir.GetField(thisPrim, location.field)));
       }
     });
 
@@ -1868,10 +2235,16 @@
     }
   }
 
+  /// Creates a box for [scope.box] and binds the captured variables to
+  /// that box.
+  ///
+  /// The captured variables can subsequently be manipulated with
+  /// [declareLocalVariable], [buildLocalGet], and [buildLocalSet].
+  void enterScope(ClosureScope scope) => _enterScope(scope);
+
   void _enterScope(ClosureScope scope) {
     if (scope == null) return;
-    ir.CreateBox boxPrim = new ir.CreateBox();
-    add(new ir.LetPrim(boxPrim));
+    ir.CreateBox boxPrim = addPrimitive(new ir.CreateBox());
     environment.extend(scope.box, boxPrim);
     boxPrim.useElementAsHint(scope.box);
     scope.capturedVariables.forEach((Local local, ClosureLocation location) {
@@ -1896,6 +2269,13 @@
     }
   }
 
+  void _createThisParameter() {
+    if (Elements.isStaticOrTopLevel(state.currentElement)) return;
+    if (state.currentElement.isLocal) return;
+    state.thisParameter =
+        new ir.Parameter(new ThisParameterLocal(state.currentElement));
+  }
+
   void declareLocalVariable(LocalElement variableElement,
                             {ir.Primitive initialValue}) {
     assert(isOpen);
@@ -1930,9 +2310,7 @@
           : environment.lookup(field.local);
       arguments.add(value);
     }
-    ir.Primitive closure = new ir.CreateInstance(classElement, arguments);
-    add(new ir.LetPrim(closure));
-    return closure;
+    return addPrimitive(new ir.CreateInstance(classElement, arguments));
   }
 
   /// Create a read access of [local].
@@ -1943,8 +2321,7 @@
       ir.Primitive result = new ir.GetField(environment.lookup(location.box),
                                             location.field);
       result.useElementAsHint(local);
-      add(new ir.LetPrim(result));
-      return result;
+      return addPrimitive(result);
     } else {
       return environment.lookup(local);
     }
@@ -1990,23 +2367,19 @@
     // body, so there is no need to explicitly renew it.
     if (scope.boxedLoopVariables.isEmpty) return;
     ir.Primitive box = environment.lookup(scope.box);
-    ir.Primitive newBox = new ir.CreateBox();
+    ir.Primitive newBox = addPrimitive(new ir.CreateBox());
     newBox.useElementAsHint(scope.box);
-    add(new ir.LetPrim(newBox));
     for (VariableElement loopVar in scope.boxedLoopVariables) {
       ClosureLocation location = scope.capturedVariables[loopVar];
-      ir.Primitive get = new ir.GetField(box, location.field);
-      add(new ir.LetPrim(get));
-      add(new ir.SetField(newBox, location.field, get));
+      ir.Primitive value = addPrimitive(new ir.GetField(box, location.field));
+      add(new ir.SetField(newBox, location.field, value));
     }
     environment.update(scope.box, newBox);
   }
 
   ir.Primitive buildThis() {
     if (jsState.receiver != null) return jsState.receiver;
-    ir.Primitive thisPrim = new ir.This();
-    add(new ir.LetPrim(thisPrim));
-    return thisPrim;
+    return state.thisParameter;
   }
 
   ir.Primitive buildSuperInvocation(Element target,
@@ -2019,9 +2392,7 @@
     // this should be the result of inlining the field's getter.
     if (target is FieldElement) {
       if (selector.isGetter) {
-        ir.Primitive get = new ir.GetField(buildThis(), target);
-        add(new ir.LetPrim(get));
-        return get;
+        return addPrimitive(new ir.GetField(buildThis(), target));
       } else {
         assert(selector.isSetter);
         add(new ir.SetField(buildThis(), target, arguments.single));
@@ -2050,6 +2421,7 @@
   /// instead of being created in the header.
   void buildConstructorBodyHeader(Iterable<Local> parameters,
                                   ClosureScope closureScope) {
+    _createThisParameter();
     for (Local param in parameters) {
       ir.Parameter parameter = createLocalParameter(param);
       state.functionParameters.add(parameter);
@@ -2118,3 +2490,14 @@
   final Set<LocalVariableElement> boxedOnEntry =
       new Set<LocalVariableElement>();
 }
+
+// TODO(johnniwinther): Support passing of [DartType] for the exception.
+class CatchClauseInfo {
+  final LocalVariableElement exceptionVariable;
+  final LocalVariableElement stackTraceVariable;
+  final SubbuildFunction buildCatchBlock;
+
+  CatchClauseInfo({this.exceptionVariable,
+                   this.stackTraceVariable,
+                   this.buildCatchBlock});
+}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
similarity index 60%
rename from pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
rename to pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index 5c8313b..f375244 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -2,7 +2,26 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of dart2js.ir_builder;
+library dart2js.ir_builder_task;
+
+import '../closure.dart' as closurelib;
+import '../closure.dart' hide ClosureScope;
+import '../constants/expressions.dart';
+import '../dart_types.dart';
+import '../dart2jslib.dart';
+import '../elements/elements.dart';
+import '../elements/modelx.dart' show SynthesizedConstructorElementX,
+    ConstructorBodyElementX, FunctionSignatureX;
+import '../io/source_file.dart';
+import '../io/source_information.dart';
+import '../js_backend/js_backend.dart' show JavaScriptBackend;
+import '../resolution/semantic_visitor.dart';
+import '../resolution/operators.dart' as op;
+import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator;
+import '../tree/tree.dart' as ast;
+import '../universe/universe.dart' show SelectorKind;
+import 'cps_ir_nodes.dart' as ir;
+import 'cps_ir_builder.dart';
 
 /**
  * This task iterates through all resolved elements and builds [ir.Node]s. The
@@ -99,21 +118,20 @@
 
 }
 
-class _GetterElements {
-  ir.Primitive result;
-  ir.Primitive index;
-  ir.Primitive receiver;
-
-  _GetterElements({this.result, this.index, this.receiver}) ;
-}
-
 /**
  * A tree visitor that builds [IrNodes]. The visit methods add statements using
  * to the [builder] and return the last added statement for trees that represent
  * an expression.
  */
-abstract class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive>
-    with IrBuilderMixin<ast.Node> {
+abstract class IrBuilderVisitor extends SemanticVisitor<ir.Primitive, dynamic>
+    with IrBuilderMixin<ast.Node>,
+         BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>,
+         BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>,
+         BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>,
+         BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>,
+         BaseImplementationOfSuperIncDecsMixin<ir.Primitive, dynamic>,
+         ErrorBulkMixin<ir.Primitive, dynamic>
+    implements SemanticSendVisitor<ir.Primitive, dynamic> {
   final Compiler compiler;
   final SourceInformationBuilder sourceInformationBuilder;
 
@@ -141,6 +159,15 @@
                    this.sourceInformationBuilder)
       : super(elements);
 
+  @override
+  bulkHandleNode(ast.Node node, String message) => giveup(node, message);
+
+  @override
+  ir.Primitive apply(ast.Node node, _) => node.accept(this);
+
+  @override
+  SemanticSendVisitor get sendVisitor => this;
+
   /**
    * Builds the [ir.ExecutableDefinition] for an executable element. In case the
    * function uses features that cannot be expressed in the IR, this element
@@ -194,9 +221,13 @@
       return irBuilder.makeConstructorDefinition(const <ConstantExpression>[],
           const <ir.Initializer>[]);
     } else if (element.isGenerativeConstructor) {
-      initializers = buildConstructorInitializers(node, element);
-      visit(node.body);
-      return irBuilder.makeConstructorDefinition(defaults, initializers);
+      if (element.isExternal) {
+        return irBuilder.makeAbstractConstructorDefinition(defaults);
+      } else {
+        initializers = buildConstructorInitializers(node, element);
+        visit(node.body);
+        return irBuilder.makeConstructorDefinition(defaults, initializers);
+      }
     } else {
       visit(node.body);
       return irBuilder.makeFunctionDefinition(defaults);
@@ -211,7 +242,7 @@
     void tryAddInitializingFormal(ParameterElement parameterElement) {
       if (parameterElement.isInitializingFormal) {
         InitializingFormalElement initializingFormal = parameterElement;
-        withBuilder(irBuilder.makeDelimitedBuilder(), () {
+        withBuilder(irBuilder.makeInitializerBuilder(), () {
           ir.Primitive value = irBuilder.buildLocalGet(parameterElement);
           result.add(irBuilder.makeFieldInitializer(
               initializingFormal.fieldElement,
@@ -229,7 +260,7 @@
       if (initializer is ast.SendSet) {
         // Field initializer.
         FieldElement field = elements[initializer];
-        withBuilder(irBuilder.makeDelimitedBuilder(), () {
+        withBuilder(irBuilder.makeInitializerBuilder(), () {
           ir.Primitive value = visit(initializer.arguments.head);
           ir.RunnableBody body = irBuilder.makeRunnableBody(value);
           result.add(irBuilder.makeFieldInitializer(field, body));
@@ -243,7 +274,7 @@
         Selector selector = elements.getSelector(initializer);
         List<ir.RunnableBody> arguments =
             initializer.arguments.mapToList((ast.Node argument) {
-          return withBuilder(irBuilder.makeDelimitedBuilder(), () {
+          return withBuilder(irBuilder.makeInitializerBuilder(), () {
             ir.Primitive value = visit(argument);
             return irBuilder.makeRunnableBody(value);
           });
@@ -280,7 +311,7 @@
 
   ir.Primitive visit(ast.Node node) => node.accept(this);
 
-  // ==== Statements ====
+  // ## Statements ##
   visitBlock(ast.Block node) {
     irBuilder.buildBlock(node.statements.nodes, build);
   }
@@ -341,48 +372,24 @@
         subbuild(node.elsePart));
   }
 
-  ir.Primitive visitLabeledStatement(ast.LabeledStatement node) {
+  visitLabeledStatement(ast.LabeledStatement node) {
     ast.Statement body = node.statement;
-    if (body is ast.Loop) return visit(body);
-    JumpTarget target = elements.getTargetDefinition(body);
-    JumpCollector jumps = new JumpCollector(target);
-    irBuilder.state.breakCollectors.add(jumps);
-    IrBuilder innerBuilder = irBuilder.makeDelimitedBuilder();
-    withBuilder(innerBuilder, () {
+    if (body is ast.Loop) {
       visit(body);
-    });
-    irBuilder.state.breakCollectors.removeLast();
-    bool hasBreaks = !jumps.isEmpty;
-    ir.Continuation joinContinuation;
-    if (hasBreaks) {
-      if (innerBuilder.isOpen) {
-        jumps.addJump(innerBuilder);
-      }
-
-      // All jumps to the break continuation must be in the scope of the
-      // continuation's binding.  The continuation is bound just outside the
-      // body to satisfy this property without extra analysis.
-      // As a consequence, the break continuation needs parameters for all
-      // local variables in scope at the exit from the body.
-      List<ir.Parameter> parameters =
-          new List<ir.Parameter>.generate(irBuilder.environment.length, (i) {
-        return new ir.Parameter(irBuilder.environment.index2variable[i]);
-      });
-      joinContinuation = new ir.Continuation(parameters);
-      irBuilder.invokeFullJoin(joinContinuation, jumps, recursive: false);
-      irBuilder.add(new ir.LetCont(joinContinuation,
-          innerBuilder._root));
-      for (int i = 0; i < irBuilder.environment.length; ++i) {
-        irBuilder.environment.index2value[i] = parameters[i];
-      }
     } else {
-      if (innerBuilder._root != null) {
-        irBuilder.add(innerBuilder._root);
-        irBuilder._current = innerBuilder._current;
-        irBuilder.environment = innerBuilder.environment;
-      }
+      JumpTarget target = elements.getTargetDefinition(body);
+      irBuilder.buildLabeledStatement(
+          buildBody: subbuild(body),
+          target: target);
     }
-    return null;
+  }
+
+  visitDoWhile(ast.DoWhile node) {
+    irBuilder.buildDoWhile(
+        buildBody: subbuild(node.body),
+        buildCondition: subbuild(node.condition),
+        target: elements.getTargetDefinition(node),
+        closureScope: getClosureScopeForNode(node));
   }
 
   visitWhile(ast.While node) {
@@ -453,8 +460,7 @@
     return null;
   }
 
-  ir.Primitive visitTryStatement(ast.TryStatement node) {
-    assert(this.irBuilder.isOpen);
+  visitTryStatement(ast.TryStatement node) {
     // Try/catch is not yet implemented in the JS backend.
     if (this.irBuilder.tryStatements == null) {
       return giveup(node, 'try/catch in the JS backend');
@@ -473,133 +479,27 @@
       return giveup(node, 'try/finally');
     }
 
-    // Catch handlers are in scope for their body.  The CPS translation of
-    // [[try tryBlock catch (e) catchBlock; successor]] is:
-    //
-    // let cont join(v0, v1, ...) = [[successor]] in
-    //   let mutable m0 = x0 in
-    //     let mutable m1 = x1 in
-    //       ...
-    //       let handler catch_(e) =
-    //         let prim p0 = GetMutable(m0) in
-    //           let prim p1 = GetMutable(m1) in
-    //             ...
-    //             [[catchBlock]]
-    //             join(p0, p1, ...)
-    //       in
-    //         [[tryBlock]]
-    //         let prim p0' = GetMutable(m0) in
-    //           let prim p1' = GetMutable(m1) in
-    //             ...
-    //             join(p0', p1', ...)
-    //
-    // In other words, both the try and catch block are in the scope of the
-    // join-point continuation, and they are both in the scope of a sequence
-    // of mutable bindings for the variables assigned in the try.  The join-
-    // point continuation is not in the scope of these mutable bindings.
-    // The tryBlock is in the scope of a binding for the catch handler.  Each
-    // instruction (specifically, each call) in the tryBlock is in the dynamic
-    // scope of the handler.  The mutable bindings are dereferenced at the end
-    // of the try block and at the beginning of the catch block, so the
-    // variables are unboxed in the catch block and at the join point.
-
-    IrBuilder tryCatchBuilder = irBuilder.makeDelimitedBuilder();
-    TryStatementInfo tryInfo = tryCatchBuilder.tryStatements[node];
-    // Variables that are boxed due to being captured in a closure are boxed
-    // for their entire lifetime, and so they do not need to be boxed on
-    // entry to any try block.  We check for them here because we can not
-    // identify all of them in the same pass where we identify the variables
-    // assigned in the try (the may be captured by a closure after the try
-    // statement).
-    Iterable<LocalVariableElement> boxedOnEntry =
-        tryInfo.boxedOnEntry.where((LocalVariableElement variable) {
-      return !tryCatchBuilder.mutableCapturedVariables.contains(variable);
-    });
-    for (LocalVariableElement variable in boxedOnEntry) {
-      assert(!tryCatchBuilder.isInMutableVariable(variable));
-      ir.Primitive value = tryCatchBuilder.buildLocalGet(variable);
-      tryCatchBuilder.makeMutableVariable(variable);
-      tryCatchBuilder.declareLocalVariable(variable, initialValue: value);
-    }
-
-    IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder();
-    IrBuilder tryBuilder = tryCatchBuilder.makeDelimitedBuilder();
-    List<ir.Parameter> joinParameters =
-        new List<ir.Parameter>.generate(irBuilder.environment.length, (i) {
-      return new ir.Parameter(irBuilder.environment.index2variable[i]);
-    });
-    ir.Continuation joinContinuation = new ir.Continuation(joinParameters);
-
-    void interceptJumps(JumpCollector collector) {
-      collector.enterTry(boxedOnEntry);
-    }
-    void restoreJumps(JumpCollector collector) {
-      collector.leaveTry();
-    }
-    tryBuilder.state.breakCollectors.forEach(interceptJumps);
-    tryBuilder.state.continueCollectors.forEach(interceptJumps);
-    withBuilder(tryBuilder, () {
-      visit(node.tryBlock);
-    });
-    tryBuilder.state.breakCollectors.forEach(restoreJumps);
-    tryBuilder.state.continueCollectors.forEach(restoreJumps);
-    if (tryBuilder.isOpen) {
-      for (LocalVariableElement variable in boxedOnEntry) {
-        assert(tryBuilder.isInMutableVariable(variable));
-        ir.Primitive value = tryBuilder.buildLocalGet(variable);
-        tryBuilder.environment.update(variable, value);
+    List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
+    for (ast.CatchBlock catchClause in node.catchBlocks.nodes) {
+      assert(catchClause.exception != null);
+      LocalVariableElement exceptionVariable = elements[catchClause.exception];
+      LocalVariableElement stackTraceVariable;
+      if (catchClause.trace != null) {
+        stackTraceVariable = elements[catchClause.trace];
       }
-      tryBuilder.jumpTo(joinContinuation);
+      catchClauseInfos.add(new CatchClauseInfo(
+          exceptionVariable: exceptionVariable,
+          stackTraceVariable: stackTraceVariable,
+          buildCatchBlock: subbuild(catchClause.block)));
     }
 
-    for (LocalVariableElement variable in boxedOnEntry) {
-      assert(catchBuilder.isInMutableVariable(variable));
-      ir.Primitive value = catchBuilder.buildLocalGet(variable);
-      // Note that we remove the variable from the set of mutable variables
-      // here (and not above for the try body).  This is because the set of
-      // mutable variables is global for the whole function and not local to
-      // a delimited builder.
-      catchBuilder.removeMutableVariable(variable);
-      catchBuilder.environment.update(variable, value);
-    }
-    ast.CatchBlock catchClause = node.catchBlocks.nodes.head;
-    assert(catchClause.exception != null);
-    LocalVariableElement exceptionElement = elements[catchClause.exception];
-    ir.Parameter exceptionParameter = new ir.Parameter(exceptionElement);
-    catchBuilder.environment.extend(exceptionElement, exceptionParameter);
-    ir.Parameter traceParameter;
-    if (catchClause.trace != null) {
-      LocalVariableElement traceElement = elements[catchClause.trace];
-      traceParameter = new ir.Parameter(traceElement);
-      catchBuilder.environment.extend(traceElement, traceParameter);
-    } else {
-      // Use a dummy continuation parameter for the stack trace parameter.
-      // This will ensure that all handlers have two parameters and so they
-      // can be treated uniformly.
-      traceParameter = new ir.Parameter(null);
-    }
-    withBuilder(catchBuilder, () {
-      visit(catchClause.block);
-    });
-    if (catchBuilder.isOpen) {
-      catchBuilder.jumpTo(joinContinuation);
-    }
-    List<ir.Parameter> catchParameters =
-        <ir.Parameter>[exceptionParameter, traceParameter];
-    ir.Continuation catchContinuation = new ir.Continuation(catchParameters);
-    catchContinuation.body = catchBuilder._root;
-
-    tryCatchBuilder.add(new ir.LetHandler(catchContinuation, tryBuilder._root));
-    tryCatchBuilder._current = null;
-
-    irBuilder.add(new ir.LetCont(joinContinuation, tryCatchBuilder._root));
-    for (int i = 0; i < irBuilder.environment.length; ++i) {
-      irBuilder.environment.index2value[i] = joinParameters[i];
-    }
-    return null;
+    irBuilder.buildTry(
+        tryStatementInfo: irBuilder.tryStatements[node],
+        buildTryBlock: subbuild(node.tryBlock),
+        catchClauseInfos: catchClauseInfos);
   }
 
-  // ==== Expressions ====
+  // ## Expressions ##
   ir.Primitive visitConditional(ast.Conditional node) {
     return irBuilder.buildConditional(
         build(node.condition),
@@ -708,8 +608,12 @@
     return receiver;
   }
 
-  // ==== Sends ====
-  ir.Primitive visitAssert(ast.Send node) {
+  // ## Sends ##
+  @override
+  ir.Primitive visitAssert(
+      ast.Send node,
+      ast.Node condition,
+      _) {
     assert(irBuilder.isOpen);
     return giveup(node, 'Assert');
   }
@@ -719,109 +623,140 @@
     return visit(node.expression);
   }
 
-  ir.Primitive visitClosureSend(ast.Send node) {
-    assert(irBuilder.isOpen);
-    Element element = elements[node];
-    Selector selector = elements.getSelector(node);
-    ir.Primitive receiver = (element == null)
-        ? visit(node.selector)
-        : irBuilder.buildLocalGet(element);
+  @override
+  ir.Primitive visitExpressionInvoke(ast.Send node,
+                                     ast.Node expression,
+                                     ast.NodeList arguments,
+                                     Selector selector, _) {
+    ir.Primitive receiver = visit(expression);
     List<ir.Primitive> arguments = node.arguments.mapToList(visit);
     arguments = normalizeDynamicArguments(selector, arguments);
     return irBuilder.buildCallInvocation(receiver, selector, arguments);
   }
 
-  /// If [node] is null, returns this.
-  /// If [node] is super, returns null (for special handling)
-  /// Otherwise visits [node] and returns the result.
-  ir.Primitive visitReceiver(ast.Expression node) {
-    if (node == null) return irBuilder.buildThis();
-    if (node.isSuper()) return null;
-    return visit(node);
-  }
-
   /// Returns `true` if [node] is a super call.
   // TODO(johnniwinther): Remove the need for this.
   bool isSuperCall(ast.Send node) {
     return node != null && node.receiver != null && node.receiver.isSuper();
   }
 
-  ir.Primitive visitDynamicSend(ast.Send node) {
-    assert(irBuilder.isOpen);
-    Selector selector = elements.getSelector(node);
-    ir.Primitive receiver = visitReceiver(node.receiver);
-    List<ir.Primitive> arguments = node.arguments.mapToList(visit);
-    arguments = normalizeDynamicArguments(selector, arguments);
-    return irBuilder.buildDynamicInvocation(receiver, selector, arguments);
+  @override
+  ir.Primitive handleConstantGet(ast.Send node,
+                                 ConstantExpression constant, _) {
+    return irBuilder.buildConstantLiteral(constant);
   }
 
-  _GetterElements translateGetter(ast.Send node, Selector selector) {
-    Element element = elements[node];
-    ir.Primitive result;
-    ir.Primitive receiver;
-    ir.Primitive index;
+  /// If [node] is null, returns this.
+  /// Otherwise visits [node] and returns the result.
+  ir.Primitive translateReceiver(ast.Expression node) {
+    return node != null ? visit(node) : irBuilder.buildThis();
+  }
 
-    if (element != null && element.isConst) {
-      // Reference to constant local, top-level or static field
-      result = translateConstant(node);
-    } else if (Elements.isLocal(element)) {
-      // Reference to local variable
-      result = irBuilder.buildLocalGet(element);
-    } else if (element == null ||
-               Elements.isInstanceField(element) ||
-               Elements.isInstanceMethod(element) ||
-               selector.isIndex ||
-               // TODO(johnniwinther): clean up semantics of resolution.
-               node.isSuperCall) {
-      // Dynamic dispatch to a getter. Sometimes resolution will suggest a
-      // target element, but in these cases we must still emit a dynamic
-      // dispatch. The target element may be an instance method in case we are
-      // converting a method to a function object.
+  @override
+  ir.Primitive handleDynamicGet(
+      ast.Send node,
+      ast.Node receiver,
+      Selector selector,
+      _) {
+    return irBuilder.buildDynamicGet(
+        translateReceiver(receiver),
+        selector);
+  }
 
-      receiver = visitReceiver(node.receiver);
-      List<ir.Primitive> arguments = new List<ir.Primitive>();
-      if (selector.isIndex) {
-        index = visit(node.arguments.head);
-        arguments.add(index);
-      }
+  @override
+  ir.Primitive visitDynamicTypeLiteralGet(
+      ast.Send node,
+      ConstantExpression constant,
+      _) {
+    return irBuilder.buildConstantLiteral(constant);
+  }
 
-      assert(selector.kind == SelectorKind.GETTER ||
-             selector.kind == SelectorKind.INDEX);
-      if (isSuperCall(node)) {
-        result = irBuilder.buildSuperInvocation(element, selector, arguments);
-      } else {
-        result =
-            irBuilder.buildDynamicInvocation(receiver, selector, arguments);
-      }
-    } else if (element.isField || element.isGetter || element.isErroneous ||
-               element.isSetter) {
-      // TODO(johnniwinther): Change handling of setter selectors.
-      // Access to a static field or getter (non-static case handled above).
-      // Even if there is only a setter, we compile as if it was a getter,
-      // so the vm can fail at runtime.
-      assert(selector.kind == SelectorKind.GETTER ||
-             selector.kind == SelectorKind.SETTER);
-      result = irBuilder.buildStaticGet(element, selector,
-          sourceInformation: sourceInformationBuilder.buildGet(node));
-    } else if (Elements.isStaticOrTopLevelFunction(element)) {
-      // Convert a top-level or static function to a function object.
-      result = translateConstant(node);
-    } else {
-      throw "Unexpected SendSet getter: $node, $element";
+  @override
+  ir.Primitive handleLocalGet(
+      ast.Send node,
+      LocalElement element,
+      _) {
+    if (element.isConst) {
+      return translateConstant(node);
     }
-    return new _GetterElements(
-        result: result,index: index, receiver: receiver);
+    return irBuilder.buildLocalGet(element);
   }
 
-  ir.Primitive visitGetterSend(ast.Send node) {
-    assert(irBuilder.isOpen);
-    return translateGetter(node, elements.getSelector(node)).result;
-
+  @override
+  ir.Primitive handleStaticFieldGet(
+      ast.Send node,
+      FieldElement field,
+      _) {
+    if (field.isConst) {
+      return translateConstant(node);
+    }
+    return irBuilder.buildStaticGet(field,
+        sourceInformation: sourceInformationBuilder.buildGet(node));
   }
 
-  ir.Primitive translateLogicalOperator(ast.Operator op,
-                                        ast.Expression left,
-                                        ast.Expression right) {
+  @override
+  ir.Primitive handleStaticFunctionGet(
+      ast.Send node,
+      MethodElement function,
+      _) {
+    // TODO(karlklose): support foreign functions.
+    if (function.isForeign(compiler.backend)) {
+      return giveup(node, 'handleStaticFunctionGet: foreign: $function');
+    }
+    return translateConstant(node);
+  }
+
+  @override
+  ir.Primitive handleStaticGetterGet(
+      ast.Send node,
+      FunctionElement getter,
+      _) {
+    return irBuilder.buildStaticInvocation(getter,
+        new Selector.getter(getter.name, getter.library), const []);
+  }
+
+  @override
+  ir.Primitive visitSuperFieldGet(
+      ast.Send node,
+      FieldElement field,
+      _) {
+    return irBuilder.buildSuperGet(field);
+  }
+
+  @override
+  ir.Primitive visitSuperGetterGet(
+      ast.Send node,
+      FunctionElement getter,
+      _) {
+    return irBuilder.buildSuperGet(getter);
+  }
+
+  @override
+  ir.Primitive visitSuperMethodGet(
+      ast.Send node,
+      MethodElement method,
+      _) {
+    return irBuilder.buildSuperGet(method);
+  }
+
+  @override
+  ir.Primitive visitThisGet(ast.Identifier node, _) {
+    return irBuilder.buildThis();
+  }
+
+  ir.Primitive translateTypeVariableTypeLiteral(TypeVariableElement element) {
+    return buildReifyTypeVariable(irBuilder.buildThis(), element.type);
+  }
+
+  @override
+  ir.Primitive visitTypeVariableTypeLiteralGet(ast.Send node,
+                                               TypeVariableElement element, _) {
+    return translateTypeVariableTypeLiteral(element);
+  }
+
+  ir.Primitive translateLogicalOperator(ast.Expression left,
+                                        ast.Expression right,
+                                        {bool isLazyOr}) {
     ir.Primitive leftValue = visit(left);
 
     ir.Primitive buildRightValue(IrBuilder rightBuilder) {
@@ -829,240 +764,943 @@
     }
 
     return irBuilder.buildLogicalOperator(
-        leftValue, buildRightValue, isLazyOr: op.source == '||');
+        leftValue, buildRightValue, isLazyOr: isLazyOr);
   }
 
-  ir.Primitive visitOperatorSend(ast.Send node) {
-    assert(irBuilder.isOpen);
-    ast.Operator op = node.selector;
-    if (isUserDefinableOperator(op.source)) {
-      return visitDynamicSend(node);
-    }
-    if (op.source == '&&' || op.source == '||') {
-      assert(node.receiver != null);
-      assert(!node.arguments.isEmpty);
-      assert(node.arguments.tail.isEmpty);
-      return translateLogicalOperator(op, node.receiver, node.arguments.head);
-    }
-    if (op.source == "!") {
-      assert(node.receiver != null);
-      assert(node.arguments.isEmpty);
-      return irBuilder.buildNegation(visit(node.receiver));
-    }
-    if (op.source == "!=") {
-      assert(node.receiver != null);
-      assert(!node.arguments.isEmpty);
-      assert(node.arguments.tail.isEmpty);
-      return irBuilder.buildNegation(visitDynamicSend(node));
-    }
-    assert(invariant(node, op.source == "is" || op.source == "as",
-           message: "unexpected operator $op"));
-    DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
-    ir.Primitive receiver = visit(node.receiver);
+  @override
+  ir.Primitive visitLogicalAnd(
+      ast.Send node, ast.Node left, ast.Node right, _) {
+    return translateLogicalOperator(left, right, isLazyOr: false);
+  }
+
+  @override
+  ir.Primitive visitLogicalOr(
+      ast.Send node, ast.Node left, ast.Node right, _) {
+    return translateLogicalOperator(left, right, isLazyOr: true);
+  }
+
+  @override
+  ir.Primitive visitAs(
+      ast.Send node,
+      ast.Node expression,
+      DartType type,
+      _) {
+    ir.Primitive receiver = visit(expression);
+    return irBuilder.buildTypeOperator(receiver, type, isTypeTest: false);
+  }
+
+  @override
+  ir.Primitive visitIs(
+      ast.Send node,
+      ast.Node expression,
+      DartType type,
+      _) {
+    ir.Primitive receiver = visit(expression);
     return irBuilder.buildTypeOperator(
         receiver, type,
-        isTypeTest: op.source == "is",
-        isNotCheck: node.isIsNotCheck);
+        isTypeTest: true,
+        isNotCheck: false);
   }
 
-  // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]]
-  //   where (C', xs) = arguments.fold(Build, C)
-  ir.Primitive visitStaticSend(ast.Send node) {
-    assert(irBuilder.isOpen);
-    Element element = elements[node];
-    assert(!element.isConstructor);
-    // TODO(lry): support foreign functions.
-    if (element.isForeign(compiler.backend)) {
-      return giveup(node, 'StaticSend: foreign');
-    }
-
-    Selector selector = elements.getSelector(node);
-
-    if (selector.isCall && (element.isGetter || element.isField)) {
-      // We are invoking a static field or getter as if it was a method, e.g:
-      //
-      //     get foo => {..}
-      //     main() {  foo(1, 2, 3);  }
-      //
-      // We invoke the getter of 'foo' and then invoke the 'call' method
-      // on the result, using the given arguments.
-      Selector getter = new Selector.getterFrom(selector);
-      Selector call = new Selector.callClosureFrom(selector);
-      ir.Primitive receiver = irBuilder.buildStaticGet(element, getter);
-      List<ir.Primitive> arguments = node.arguments.mapToList(visit);
-      arguments = normalizeDynamicArguments(selector, arguments);
-      return irBuilder.buildCallInvocation(receiver, call, arguments);
-    } else if (selector.isGetter) {
-      // We are reading a static field or invoking a static getter.
-      return irBuilder.buildStaticGet(element, selector);
-    } else {
-      // We are invoking a static method.
-      assert(selector.isCall);
-      assert(element is FunctionElement);
-      List<ir.Primitive> arguments = node.arguments.mapToList(visit);
-      arguments = normalizeStaticArguments(selector, element, arguments);
-      return irBuilder.buildStaticInvocation(element, selector, arguments,
-          sourceInformation: sourceInformationBuilder.buildCall(node));
-    }
+  @override
+  ir.Primitive visitIsNot(ast.Send node,
+                          ast.Node expression, DartType type, _) {
+    ir.Primitive receiver = visit(expression);
+    return irBuilder.buildTypeOperator(
+        receiver, type,
+        isTypeTest: true,
+        isNotCheck: true);
   }
 
-  ir.Primitive visitSuperSend(ast.Send node) {
-    assert(irBuilder.isOpen);
-    Selector selector = elements.getSelector(node);
-    Element target = elements[node];
-
-    if (selector.isCall && (target.isGetter || target.isField)) {
-      // We are invoking a field or getter as if it was a method, e.g:
-      //
-      //     class A { get foo => {..} }
-      //     class B extends A {
-      //         m() {
-      //           super.foo(1, 2, 3);  }
-      //         }
-      //     }
-      //
-      // We invoke the getter of 'foo' and then invoke the 'call' method on
-      // the result, using the given arguments.
-      Selector getter = new Selector.getterFrom(selector);
-      Selector call = new Selector.callClosureFrom(selector);
-      ir.Primitive receiver =
-          irBuilder.buildSuperInvocation(target, getter, []);
-      List<ir.Primitive> arguments = node.arguments.mapToList(visit);
-      arguments = normalizeDynamicArguments(selector, arguments);
-      return irBuilder.buildCallInvocation(receiver, call, arguments);
-    } else if (selector.isCall) {
-      // We are invoking a method.
-      assert(target is FunctionElement);
-      List<ir.Primitive> arguments = node.arguments.mapToList(visit);
-      arguments = normalizeStaticArguments(selector, target, arguments);
-      return irBuilder.buildSuperInvocation(target, selector, arguments);
-    } else {
-      // We are invoking a getter, operator, indexer, etc.
-      List<ir.Primitive> arguments = node.argumentsNode == null
-          ? <ir.Primitive>[]
-          : node.arguments.mapToList(visit);
-      return irBuilder.buildSuperInvocation(target, selector, arguments);
-    }
+  ir.Primitive translateBinary(ast.Node left,
+                               op.BinaryOperator operator,
+                               ast.Node right) {
+    Selector selector = new Selector.binaryOperator(operator.selectorName);
+    ir.Primitive receiver = visit(left);
+    List<ir.Primitive> arguments = <ir.Primitive>[visit(right)];
+    arguments = normalizeDynamicArguments(selector, arguments);
+    return irBuilder.buildDynamicInvocation(receiver, selector, arguments);
   }
 
-  visitTypePrefixSend(ast.Send node) {
-    compiler.internalError(node, "visitTypePrefixSend should not be called.");
+  @override
+  ir.Primitive visitBinary(ast.Send node,
+                           ast.Node left,
+                           op.BinaryOperator operator,
+                           ast.Node right, _) {
+    return translateBinary(left, operator, right);
   }
 
-  ir.Primitive visitTypeLiteralSend(ast.Send node) {
-    assert(irBuilder.isOpen);
-    // If the user is trying to invoke the type literal or variable,
-    // it must be treated as a function call.
-    if (node.argumentsNode != null) {
-      // TODO(sigurdm): Handle this to match proposed semantics of issue #19725.
-      return giveup(node, 'Type literal invoked as function');
-    }
-
-    DartType type = elements.getTypeLiteralType(node);
-    if (type is TypeVariableType) {
-      ir.Primitive prim = new ir.ReifyTypeVar(type.element);
-      irBuilder.add(new ir.LetPrim(prim));
-      return prim;
-    } else {
-      return translateConstant(node);
-    }
+  @override
+  ir.Primitive visitIndex(ast.Send node,
+                          ast.Node receiver,
+                          ast.Node index, _) {
+    Selector selector = new Selector.index();
+    ir.Primitive target = visit(receiver);
+    List<ir.Primitive> arguments = <ir.Primitive>[visit(index)];
+    arguments = normalizeDynamicArguments(selector, arguments);
+    return irBuilder.buildDynamicInvocation(target, selector, arguments);
   }
 
-  ir.Primitive visitSendSet(ast.SendSet node) {
-    assert(irBuilder.isOpen);
-    Element element = elements[node];
-    ast.Operator op = node.assignmentOperator;
-    // For complex operators, this is the result of getting (before assigning)
-    ir.Primitive originalValue;
-    // For []+= style operators, this saves the index.
-    ir.Primitive index;
-    ir.Primitive receiver;
-    // This is what gets assigned.
-    ir.Primitive valueToStore;
-    Selector selector = elements.getSelector(node);
+  ir.Primitive translateSuperBinary(FunctionElement function,
+                                    op.BinaryOperator operator,
+                                    ast.Node argument) {
+    Selector selector = new Selector.binaryOperator(operator.selectorName);
+    List<ir.Primitive> arguments = <ir.Primitive>[visit(argument)];
+    arguments = normalizeDynamicArguments(selector, arguments);
+    return irBuilder.buildSuperInvocation(function, selector, arguments);
+  }
+
+  @override
+  ir.Primitive visitSuperBinary(
+      ast.Send node,
+      FunctionElement function,
+      op.BinaryOperator operator,
+      ast.Node argument,
+      _) {
+    return translateSuperBinary(function, operator, argument);
+  }
+
+  @override
+  ir.Primitive visitSuperIndex(
+      ast.Send node,
+      FunctionElement function,
+      ast.Node index,
+      _) {
+    Selector selector = new Selector.index();
+    List<ir.Primitive> arguments = <ir.Primitive>[visit(index)];
+    arguments = normalizeDynamicArguments(selector, arguments);
+    return irBuilder.buildSuperInvocation(function, selector, arguments);
+  }
+
+  @override
+  ir.Primitive visitEquals(
+      ast.Send node,
+      ast.Node left,
+      ast.Node right,
+      _) {
+    return translateBinary(left, op.BinaryOperator.EQ, right);
+  }
+
+  @override
+  ir.Primitive visitSuperEquals(
+      ast.Send node,
+      FunctionElement function,
+      ast.Node argument,
+      _) {
+    return translateSuperBinary(function, op.BinaryOperator.EQ, argument);
+  }
+
+  @override
+  ir.Primitive visitNot(
+      ast.Send node,
+      ast.Node expression,
+      _) {
+    return irBuilder.buildNegation(visit(expression));
+  }
+
+  @override
+  ir.Primitive visitNotEquals(
+      ast.Send node,
+      ast.Node left,
+      ast.Node right,
+      _) {
+    return irBuilder.buildNegation(
+        translateBinary(left, op.BinaryOperator.NOT_EQ, right));
+  }
+
+  @override
+  ir.Primitive visitSuperNotEquals(
+      ast.Send node,
+      FunctionElement function,
+      ast.Node argument,
+      _) {
+    return irBuilder.buildNegation(
+        translateSuperBinary(function, op.BinaryOperator.NOT_EQ, argument));
+  }
+
+  @override
+  ir.Primitive visitUnary(ast.Send node,
+                          op.UnaryOperator operator, ast.Node expression, _) {
+    // TODO(johnniwinther): Clean up the creation of selectors.
+    Selector selector =
+        new Selector(SelectorKind.OPERATOR, operator.selectorName, null, 0);
+    ir.Primitive receiver = translateReceiver(expression);
+    return irBuilder.buildDynamicInvocation(receiver, selector, const []);
+  }
+
+  @override
+  ir.Primitive visitSuperUnary(
+      ast.Send node,
+      op.UnaryOperator operator,
+      FunctionElement function,
+      _) {
+    // TODO(johnniwinther): Clean up the creation of selectors.
+    Selector selector =
+        new Selector(SelectorKind.OPERATOR, operator.selectorName, null, 0);
+    return irBuilder.buildSuperInvocation(function, selector, const []);
+  }
+
+  // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
+  // semantic correlation between arguments and invocation.
+  List<ir.Primitive> translateDynamicArguments(ast.NodeList nodeList,
+                                               Selector selector) {
+    List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
+    return normalizeDynamicArguments(selector, arguments);
+  }
+
+  // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
+  // semantic correlation between arguments and invocation.
+  List<ir.Primitive> translateStaticArguments(ast.NodeList nodeList,
+                                              Element element,
+                                              Selector selector) {
+    List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
+    return normalizeStaticArguments(selector, element, arguments);
+  }
+
+  ir.Primitive translateCallInvoke(ir.Primitive target,
+                                   ast.NodeList arguments,
+                                   Selector selector) {
+
+    return irBuilder.buildCallInvocation(target, selector,
+        translateDynamicArguments(arguments, selector));
+  }
+
+  ir.Primitive translateConstantInvoke(ConstantExpression constant,
+                                       ast.NodeList arguments,
+                                       Selector selector) {
+    return translateCallInvoke(
+        irBuilder.buildConstantLiteral(constant),
+        arguments,
+        selector);
+  }
+
+  @override
+  ir.Primitive handleConstantInvoke(
+      ast.Send node,
+      ConstantExpression constant,
+      ast.NodeList arguments,
+      Selector selector,
+      _) {
+    return translateConstantInvoke(constant, arguments, selector);
+  }
+
+  @override
+  ir.Primitive handleDynamicInvoke(
+      ast.Send node,
+      ast.Node receiver,
+      ast.NodeList arguments,
+      Selector selector,
+      _) {
+    return irBuilder.buildDynamicInvocation(
+        translateReceiver(receiver), selector,
+        translateDynamicArguments(arguments, selector));
+  }
+
+  ir.Primitive handleLocalInvoke(
+      ast.Send node,
+      LocalElement element,
+      ast.NodeList arguments,
+      Selector selector,
+      _) {
+    return irBuilder.buildLocalInvocation(element, selector,
+        translateDynamicArguments(arguments, selector));
+  }
+
+  @override
+  ir.Primitive handleStaticFieldInvoke(
+      ast.Send node,
+      FieldElement field,
+      ast.NodeList arguments,
+      Selector selector,
+      _) {
+    return translateCallInvoke(
+        irBuilder.buildStaticGet(field),
+        arguments, selector);
+  }
+
+  @override
+  ir.Primitive handleStaticFunctionInvoke(
+      ast.Send node,
+      MethodElement function,
+      ast.NodeList arguments,
+      Selector selector,
+      _) {
+    // TODO(karlklose): support foreign functions.
+    if (function.isForeign(compiler.backend)) {
+      return giveup(node, 'handleStaticFunctionInvoke: foreign: $function');
+    }
+    return irBuilder.buildStaticInvocation(function, selector,
+        translateStaticArguments(arguments, function, selector),
+        sourceInformation: sourceInformationBuilder.buildCall(node));
+  }
+
+  @override
+  ir.Primitive handleStaticGetterInvoke(
+      ast.Send node,
+      FunctionElement getter,
+      ast.NodeList arguments,
+      Selector selector,
+      _) {
+    return translateCallInvoke(
+        irBuilder.buildStaticGet(getter),
+        arguments, selector);
+  }
+
+  @override
+  ir.Primitive visitSuperFieldInvoke(
+      ast.Send node,
+      FieldElement field,
+      ast.NodeList arguments,
+      Selector selector,
+      _) {
+    return translateCallInvoke(
+        irBuilder.buildSuperGet(field),
+        arguments, selector);
+  }
+
+  @override
+  ir.Primitive visitSuperGetterInvoke(
+      ast.Send node,
+      FunctionElement getter,
+      ast.NodeList arguments,
+      Selector selector,
+      _) {
+    return translateCallInvoke(
+        irBuilder.buildSuperGet(getter),
+        arguments, selector);
+  }
+
+  @override
+  ir.Primitive visitSuperMethodInvoke(
+      ast.Send node,
+      MethodElement method,
+      ast.NodeList arguments,
+      Selector selector,
+      _) {
+    return irBuilder.buildSuperInvocation(method, selector,
+        translateDynamicArguments(arguments, selector));
+  }
+
+  @override
+  ir.Primitive visitThisInvoke(
+      ast.Send node,
+      ast.NodeList arguments,
+      Selector selector,
+      _) {
+    return translateCallInvoke(irBuilder.buildThis(), arguments, selector);
+  }
+
+  @override
+  ir.Primitive visitTypeVariableTypeLiteralInvoke(
+      ast.Send node,
+      TypeVariableElement element,
+      ast.NodeList arguments,
+      Selector selector,
+      _) {
+    return translateCallInvoke(
+        translateTypeVariableTypeLiteral(element),
+        arguments,
+        selector);
+  }
+
+  @override
+  ir.Primitive visitTypedefTypeLiteralInvoke(
+      ast.Send node,
+      TypeConstantExpression constant,
+      ast.NodeList arguments,
+      Selector selector, _) {
+    return translateConstantInvoke(constant, arguments, selector);
+  }
+
+  // TODO(johnniwinther): This should be a method on [IrBuilder].
+  ir.Primitive buildReifyTypeVariable(ir.Primitive target,
+                                      TypeVariableType variable);
+
+  @override
+  ir.Primitive visitIndexSet(
+       ast.SendSet node,
+       ast.Node receiver,
+       ast.Node index,
+       ast.Node rhs,
+       _) {
+    return irBuilder.buildDynamicIndexSet(
+        visit(receiver), visit(index), visit(rhs));
+  }
+
+  @override
+  ir.Primitive visitSuperIndexSet(
+      ast.SendSet node,
+      FunctionElement function,
+      ast.Node index,
+      ast.Node rhs,
+      _) {
+    return irBuilder.buildSuperIndexSet(function, visit(index), visit(rhs));
+  }
+
+  @override
+  ir.Primitive visitCompoundIndexSet(
+      ast.SendSet node,
+      ast.Node receiver,
+      ast.Node index,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    ir.Primitive target = visit(receiver);
+    ir.Primitive indexValue = visit(index);
+    return translateCompound(
+        getValue: () {
+          Selector selector = new Selector.index();
+          List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
+          arguments = normalizeDynamicArguments(selector, arguments);
+          return irBuilder.buildDynamicInvocation(target, selector, arguments);
+        },
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildDynamicIndexSet(target, indexValue, result);
+        });
+  }
+
+  @override
+  ir.Primitive visitSuperCompoundIndexSet(
+      ast.SendSet node,
+      FunctionElement getter,
+      FunctionElement setter,
+      ast.Node index,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    ir.Primitive indexValue = visit(index);
+    return translateCompound(
+        getValue: () {
+          Selector selector = new Selector.index();
+          List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
+          arguments = normalizeDynamicArguments(selector, arguments);
+          return irBuilder.buildSuperInvocation(getter, selector, arguments);
+        },
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperIndexSet(setter, indexValue, result);
+        });
+  }
+
+  ir.Primitive translatePrefixPostfix(
+      {ir.Primitive getValue(),
+       op.IncDecOperator operator,
+       void setValue(ir.Primitive value),
+       bool isPrefix}) {
+    ir.Primitive value = getValue();
     Selector operatorSelector =
-        elements.getOperatorSelectorInComplexSendSet(node);
-    Selector getterSelector =
-        elements.getGetterSelectorInComplexSendSet(node);
-    assert(
-        // Indexing send-sets have an argument for the index.
-        (selector.isIndexSet ? 1 : 0) +
-        // Non-increment send-sets have one more argument.
-        (ast.Operator.INCREMENT_OPERATORS.contains(op.source) ? 0 : 1)
-            == node.argumentCount());
+        new Selector.binaryOperator(operator.selectorName);
+    List<ir.Primitive> arguments =
+        <ir.Primitive>[irBuilder.buildIntegerLiteral(1)];
+    arguments = normalizeDynamicArguments(operatorSelector, arguments);
+    ir.Primitive result =
+        irBuilder.buildDynamicInvocation(value, operatorSelector, arguments);
+    setValue(result);
+    return isPrefix ? result : value;
+  }
 
-    ast.Node getAssignArgument() {
-      assert(invariant(node, !node.arguments.isEmpty,
-                       message: "argument expected"));
-      return selector.isIndexSet
-          ? node.arguments.tail.head
-          : node.arguments.head;
-    }
+  ir.Primitive translateCompound(
+      {ir.Primitive getValue(),
+       op.AssignmentOperator operator,
+       ast.Node rhs,
+       void setValue(ir.Primitive value)}) {
+    ir.Primitive value = getValue();
+    Selector operatorSelector =
+        new Selector.binaryOperator(operator.selectorName);
+    List<ir.Primitive> arguments = <ir.Primitive>[visit(rhs)];
+    arguments = normalizeDynamicArguments(operatorSelector, arguments);
+    ir.Primitive result =
+        irBuilder.buildDynamicInvocation(value, operatorSelector, arguments);
+    setValue(result);
+    return result;
+  }
 
-    // Get the value into valueToStore
-    if (op.source == "=") {
-      if (selector.isIndexSet) {
-        receiver = visitReceiver(node.receiver);
-        index = visit(node.arguments.head);
-      } else if (element == null || Elements.isInstanceField(element)) {
-        receiver = visitReceiver(node.receiver);
-      }
-      valueToStore = visit(getAssignArgument());
-    } else {
-      // Get the original value into getter
-      assert(ast.Operator.COMPLEX_OPERATORS.contains(op.source));
+  @override
+  ir.Primitive handleDynamicCompound(
+      ast.Send node,
+      ast.Node receiver,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      _) {
+    ir.Primitive target = translateReceiver(receiver);
+    return translateCompound(
+        getValue: () => irBuilder.buildDynamicGet(target, getterSelector),
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildDynamicSet(target, setterSelector, result);
+        });
+  }
 
-      _GetterElements getterResult = translateGetter(node, getterSelector);
-      index = getterResult.index;
-      receiver = getterResult.receiver;
-      originalValue = getterResult.result;
+  @override
+  ir.Primitive handleDynamicPostfixPrefix(
+      ast.Send node,
+      ast.Node receiver,
+      op.IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      arg,
+      {bool isPrefix}) {
+    ir.Primitive target = translateReceiver(receiver);
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildDynamicGet(target, getterSelector),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildDynamicSet(target, setterSelector, result);
+        },
+        isPrefix: isPrefix);
+  }
 
-      // Do the modification of the value in getter.
-      ir.Primitive arg;
-      if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) {
-        arg = irBuilder.buildIntegerLiteral(1);
-      } else {
-        arg = visit(getAssignArgument());
-      }
-      valueToStore = new ir.Parameter(null);
-      ir.Continuation k = new ir.Continuation([valueToStore]);
-      ir.Expression invoke =
-          new ir.InvokeMethod(originalValue, operatorSelector, k, [arg]);
-      irBuilder.add(new ir.LetCont(k, invoke));
-    }
+  @override
+  ir.Primitive handleDynamicSet(
+      ast.SendSet node,
+      ast.Node receiver,
+      Selector selector,
+      ast.Node rhs,
+      _) {
+    return irBuilder.buildDynamicSet(
+        translateReceiver(receiver),
+        selector,
+        visit(rhs));
+  }
 
-    if (Elements.isLocal(element)) {
-      irBuilder.buildLocalSet(element, valueToStore);
-    } else if ((!node.isSuperCall && Elements.isErroneous(element)) ||
-                Elements.isStaticOrTopLevel(element)) {
-      irBuilder.buildStaticSet(
-          element, elements.getSelector(node), valueToStore);
-    } else {
-      // Setter or index-setter invocation
-      Selector selector = elements.getSelector(node);
-      assert(selector.kind == SelectorKind.SETTER ||
-          selector.kind == SelectorKind.INDEX);
-      if (selector.isIndexSet) {
-        if (isSuperCall(node)) {
-          irBuilder.buildSuperIndexSet(element, index, valueToStore);
-        } else {
-          irBuilder.buildDynamicIndexSet(receiver, index, valueToStore);
-        }
-      } else {
-        if (isSuperCall(node)) {
-          irBuilder.buildSuperSet(element, selector, valueToStore);
-        } else {
-          irBuilder.buildDynamicSet(receiver, selector, valueToStore);
-        }
-      }
-    }
+  @override
+  ir.Primitive handleLocalCompound(
+      ast.Send node,
+      LocalElement element,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    return translateCompound(
+        getValue: () => irBuilder.buildLocalGet(element),
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildLocalSet(element, result);
+        });
+  }
 
-    if (node.isPostfix) {
-      assert(originalValue != null);
-      return originalValue;
-    } else {
-      return valueToStore;
-    }
+  @override
+  ir.Primitive handleLocalPostfixPrefix(
+      ast.Send node,
+      LocalElement element,
+      op.IncDecOperator operator,
+      arg,
+      {bool isPrefix}) {
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildLocalGet(element),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildLocalSet(element, result);
+        },
+        isPrefix: isPrefix);
+  }
+
+  @override
+  ir.Primitive handleLocalSet(
+      ast.SendSet node,
+      LocalElement element,
+      ast.Node rhs,
+      _) {
+    return irBuilder.buildLocalSet(element, visit(rhs));
+  }
+
+  @override
+  ir.Primitive handleStaticFieldCompound(
+      ast.Send node,
+      FieldElement field,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    return translateCompound(
+        getValue: () => irBuilder.buildStaticGet(field),
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildStaticSet(field, result);
+        });
+  }
+
+  @override
+  ir.Primitive handleStaticFieldPostfixPrefix(
+      ast.Send node,
+      FieldElement field,
+      op.IncDecOperator operator,
+      arg,
+      {bool isPrefix}) {
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildStaticGet(field),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildStaticSet(field, result);
+        },
+        isPrefix: isPrefix);
+  }
+
+  @override
+  ir.Primitive handleStaticFieldSet(
+      ast.SendSet node,
+      FieldElement field,
+      ast.Node rhs,
+      _) {
+    return irBuilder.buildStaticSet(field, visit(rhs));
+  }
+
+  @override
+  ir.Primitive visitSuperFieldSet(
+      ast.SendSet node,
+      FieldElement field,
+      ast.Node rhs,
+      _) {
+    return irBuilder.buildSuperSet(field, visit(rhs));
+  }
+
+  @override
+  ir.Primitive visitSuperSetterSet(
+      ast.SendSet node,
+      FunctionElement setter,
+      ast.Node rhs,
+      _) {
+    return irBuilder.buildSuperSet(setter, visit(rhs));
+  }
+
+  @override
+  ir.Primitive handleStaticGetterSetterCompound(
+      ast.Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    return translateCompound(
+        getValue: () => irBuilder.buildStaticGet(getter),
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildStaticSet(setter, result);
+        });
+  }
+
+  @override
+  ir.Primitive handleSuperFieldFieldPostfixPrefix(
+      ast.Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      op.IncDecOperator operator,
+      arg,
+      {bool isPrefix}) {
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildSuperGet(readField),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(writtenField, result);
+        },
+        isPrefix: isPrefix);
+  }
+
+  @override
+  ir.Primitive handleSuperFieldSetterPostfixPrefix(
+      ast.Send node,
+      FieldElement field,
+      FunctionElement setter,
+      op.IncDecOperator operator,
+      arg,
+      {bool isPrefix}) {
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildSuperGet(field),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(setter, result);
+        },
+        isPrefix: isPrefix);
+  }
+
+  @override
+  ir.Primitive handleSuperGetterFieldPostfixPrefix(
+      ast.Send node,
+      FunctionElement getter,
+      FieldElement field,
+      op.IncDecOperator operator,
+      arg,
+      {bool isPrefix}) {
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildSuperGet(getter),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(field, result);
+        },
+        isPrefix: isPrefix);
+  }
+
+  @override
+  ir.Primitive handleSuperGetterSetterPostfixPrefix(
+      ast.Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      op.IncDecOperator operator,
+      arg,
+      {bool isPrefix}) {
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildSuperGet(getter),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(setter, result);
+        },
+        isPrefix: isPrefix);
+  }
+
+  @override
+  ir.Primitive handleSuperMethodSetterPostfixPrefix(
+      ast.Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      op.IncDecOperator operator,
+      arg,
+      {bool isPrefix}) {
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildSuperGet(method),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(setter, result);
+        },
+        isPrefix: isPrefix);
+  }
+
+  @override
+  ir.Primitive handleStaticGetterSetterPostfixPrefix(
+      ast.Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      op.IncDecOperator operator,
+      arg,
+      {bool isPrefix}) {
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildStaticGet(getter),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildStaticSet(setter, result);
+        },
+        isPrefix: isPrefix);
+  }
+
+  @override
+  ir.Primitive handleStaticMethodSetterCompound(
+      ast.Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    return translateCompound(
+        getValue: () => irBuilder.buildStaticGet(method),
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildStaticSet(setter, result);
+        });
+  }
+
+  @override
+  ir.Primitive handleStaticMethodSetterPostfixPrefix(
+      ast.Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      op.IncDecOperator operator,
+      arg,
+      {bool isPrefix}) {
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildStaticGet(getter),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildStaticSet(setter, result);
+        },
+        isPrefix: isPrefix);
+  }
+
+  @override
+  ir.Primitive handleDynamicIndexPostfixPrefix(
+      ast.Send node,
+      ast.Node receiver,
+      ast.Node index,
+      op.IncDecOperator operator,
+      arg,
+      {bool isPrefix}) {
+    ir.Primitive target = visit(receiver);
+    ir.Primitive indexValue = visit(index);
+    return translatePrefixPostfix(
+        getValue: () {
+          Selector selector = new Selector.index();
+          List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
+          arguments = normalizeDynamicArguments(selector, arguments);
+          return irBuilder.buildDynamicInvocation(target, selector, arguments);
+        },
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          Selector selector = new Selector.indexSet();
+          List<ir.Primitive> arguments = <ir.Primitive>[indexValue, result];
+          arguments = normalizeDynamicArguments(selector, arguments);
+          irBuilder.buildDynamicInvocation(target, selector, arguments);
+        },
+        isPrefix: isPrefix);
+  }
+
+  @override
+  ir.Primitive handleSuperIndexPostfixPrefix(
+      ast.Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      ast.Node index,
+      op.IncDecOperator operator,
+      arg,
+      {bool isPrefix}) {
+    ir.Primitive indexValue = visit(index);
+    return translatePrefixPostfix(
+        getValue: () {
+          Selector selector = new Selector.index();
+          List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
+          arguments = normalizeDynamicArguments(selector, arguments);
+          return irBuilder.buildSuperInvocation(
+              indexFunction, selector, arguments);
+        },
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          Selector selector = new Selector.indexSet();
+          List<ir.Primitive> arguments = <ir.Primitive>[indexValue, result];
+          arguments = normalizeDynamicArguments(selector, arguments);
+          irBuilder.buildSuperInvocation(
+              indexSetFunction, selector, arguments);
+        },
+        isPrefix: isPrefix);
+  }
+
+  @override
+  ir.Primitive handleStaticSetterSet(
+      ast.SendSet node,
+      FunctionElement setter,
+      ast.Node rhs,
+      _) {
+    return irBuilder.buildStaticSet(setter, visit(rhs));
+  }
+
+  @override
+  ir.Primitive visitSuperFieldCompound(
+      ast.Send node,
+      FieldElement field,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    return translateCompound(
+        getValue: () => irBuilder.buildSuperGet(field),
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(field, result);
+        });
+  }
+
+  @override
+  ir.Primitive visitSuperFieldFieldPostfix(
+      ast.Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      op.IncDecOperator operator,
+      _) {
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildSuperGet(readField),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(writtenField, result);
+        },
+        isPrefix: false);
+  }
+
+  @override
+  ir.Primitive visitSuperFieldFieldPrefix(
+      ast.Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      op.IncDecOperator operator,
+      _) {
+    return translatePrefixPostfix(
+        getValue: () => irBuilder.buildSuperGet(readField),
+        operator: operator,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(writtenField, result);
+        },
+        isPrefix: true);
+  }
+
+  @override
+  ir.Primitive visitSuperFieldSetterCompound(
+      ast.Send node,
+      FieldElement field,
+      FunctionElement setter,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    return translateCompound(
+        getValue: () => irBuilder.buildSuperGet(field),
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(setter, result);
+        });
+  }
+
+  @override
+  ir.Primitive visitSuperGetterFieldCompound(
+      ast.Send node,
+      FunctionElement getter,
+      FieldElement field,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    return translateCompound(
+        getValue: () => irBuilder.buildSuperGet(getter),
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(field, result);
+        });
+  }
+
+  @override
+  ir.Primitive visitSuperGetterSetterCompound(
+      ast.Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    return translateCompound(
+        getValue: () => irBuilder.buildSuperGet(getter),
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(setter, result);
+        });
+  }
+
+  @override
+  ir.Primitive visitSuperMethodSetterCompound(
+      ast.Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      op.AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    return translateCompound(
+        getValue: () => irBuilder.buildSuperGet(method),
+        operator: operator,
+        rhs: rhs,
+        setValue: (ir.Primitive result) {
+          irBuilder.buildSuperSet(setter, result);
+        });
   }
 
   ir.Primitive visitNewExpression(ast.NewExpression node) {
@@ -1116,9 +1754,14 @@
     }
   }
 
-  void internalError(String reason, {ast.Node node}) {
+  void internalError(ast.Node node, String message) {
     giveup(node);
   }
+
+  @override
+  visitNode(ast.Node node) {
+    internalError(node, "Unhandled node");
+  }
 }
 
 final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
@@ -1381,6 +2024,15 @@
       List<ir.Primitive> arguments) {
     return arguments;
   }
+
+  @override
+  ir.Primitive buildReifyTypeVariable(ir.Primitive target,
+                                      TypeVariableType variable) {
+    assert(target == irBuilder.state.enclosingMethodThisParameter);
+    ir.Primitive prim = new ir.ReifyTypeVar(variable.element);
+    irBuilder.add(new ir.LetPrim(prim));
+    return prim;
+  }
 }
 
 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder].
@@ -1680,7 +2332,7 @@
 
     // Establish a scope in case parameters are captured.
     ClosureScope scope = getClosureScopeForFunction(target);
-    irBuilder._enterScope(scope);
+    irBuilder.enterScope(scope);
 
     // Load required parameters
     int index = 0;
@@ -1906,6 +2558,16 @@
     }
     return result;
   }
+
+  @override
+  ir.Primitive buildReifyTypeVariable(ir.Primitive target,
+                                      TypeVariableType variable) {
+    ir.Primitive typeArgument = new ir.ReadTypeVariable(variable, target);
+    irBuilder.add(new ir.LetPrim(typeArgument));
+    ir.Primitive type = new ir.ReifyRuntimeType(typeArgument);
+    irBuilder.add(new ir.LetPrim(type));
+    return type;
+  }
 }
 
 /// Interface for generating [SourceInformation] for the CPS.
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
new file mode 100644
index 0000000..0b115cb
--- /dev/null
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_integrity.dart
@@ -0,0 +1,221 @@
+library dart2js.cps_ir_integrity;
+
+import 'cps_ir_nodes.dart';
+import 'cps_ir_nodes_sexpr.dart';
+import '../tracer.dart' as tracer;
+
+/// Dump S-expressions on error if the tracer is enabled.
+///
+/// Technically this has nothing to do with the tracer, but if you want one
+/// enabled, you typically want the other as well, so we use the same flag.
+const bool ENABLE_DUMP = tracer.TRACE_FILTER_PATTERN != null;
+
+/// Performs integrity checks on the CPS IR.
+///
+/// To be run for debugging purposes, not for use in production.
+///
+/// The following integrity checks are performed:
+///
+/// - References are in scope of their definitions.
+/// - Recursive Continuations and InvokeContinuations are marked as recursive.
+/// - InvokeContinuations have the same arity as their target.
+/// - Reference chains are valid doubly-linked lists.
+/// - Reference chains contain exactly the references that are in the IR.
+/// - Each definition object occurs only once in the IR (no redeclaring).
+/// - Each reference object occurs only once in the IR (no sharing).
+///
+class CheckCpsIntegrity extends RecursiveVisitor {
+
+  ExecutableDefinition topLevelNode;
+
+  Set<Definition> seenDefinitions = new Set<Definition>();
+  Map<Definition, Set<Reference>> seenReferences =
+      <Definition, Set<Reference>>{};
+
+  Map<Definition, Node> bindings = <Definition, Node>{};
+  Set<Continuation> insideContinuations = new Set<Continuation>();
+
+  doInScope(Iterable<Definition> defs, Node binding, action()) {
+    for (Definition def in defs) {
+      bindings[def] = binding;
+    }
+    action();
+    for (Definition def in defs) {
+      bindings.remove(def);
+    }
+  }
+
+  void markAsSeen(Definition def) {
+    if (!seenDefinitions.add(def)) {
+      error('Redeclared $def', def);
+    }
+    seenReferences[def] = new Set<Reference>();
+  }
+
+  @override
+  visitLetCont(LetCont node) {
+    // Analyze each continuation separately without the others in scope.
+    for (Continuation continuation in node.continuations) {
+      // We always consider a continuation to be in scope of itself.
+      // The isRecursive flag is checked explicitly to give more useful
+      // error messages.
+      doInScope([continuation], node, () => visit(continuation));
+    }
+    // Analyze the body with all continuations in scope.
+    doInScope(node.continuations, node, () => visit(node.body));
+  }
+
+  @override
+  visitContinuation(Continuation node) {
+    markAsSeen(node);
+    if (node.isReturnContinuation) {
+      error('Non-return continuation missing body', node);
+    }
+    node.parameters.forEach(markAsSeen);
+    insideContinuations.add(node);
+    doInScope(node.parameters, node, () => visit(node.body));
+    insideContinuations.remove(node);
+  }
+
+  @override
+  visitRunnableBody(RunnableBody node) {
+    markAsSeen(node.returnContinuation);
+    if (!node.returnContinuation.isReturnContinuation) {
+      error('Return continuation with a body', node);
+    }
+    doInScope([node.returnContinuation], node, () => visit(node.body));
+  }
+
+  @override
+  visitLetPrim(LetPrim node) {
+    markAsSeen(node.primitive);
+    visit(node.primitive);
+    doInScope([node.primitive], node, () => visit(node.body));
+  }
+
+  @override
+  visitLetMutable(LetMutable node) {
+    markAsSeen(node.variable);
+    processReference(node.value);
+    doInScope([node.variable], node, () => visit(node.body));
+  }
+
+  @override
+  visitFunctionDefinition(FunctionDefinition node) {
+    if (node.thisParameter != null) {
+      markAsSeen(node.thisParameter);
+    }
+    node.parameters.forEach(markAsSeen);
+    if (node.body != null) {
+      doInOptionalScope(node.thisParameter, node,
+          () => doInScope(node.parameters, node, () => visit(node.body)));
+    }
+  }
+
+  @override
+  visitConstructorDefinition(ConstructorDefinition node) {
+    if (node.thisParameter != null) {
+      markAsSeen(node.thisParameter);
+    }
+    node.parameters.forEach(markAsSeen);
+    doInScope(node.parameters, node, () {
+      if (node.initializers != null) node.initializers.forEach(visit);
+      if (node.body != null) {
+        doInOptionalScope(node.thisParameter, node, () => visit(node.body));
+      }
+    });
+  }
+
+  doInOptionalScope(Parameter parameter, Node node, action) {
+    return (parameter == null)
+        ? action()
+        : doInScope([parameter], node, action);
+  }
+
+  @override
+  visitDeclareFunction(DeclareFunction node) {
+    markAsSeen(node.variable);
+    doInScope([node.variable], node, () {
+      visit(node.definition);
+      visit(node.body);
+    });
+  }
+
+  @override
+  processReference(Reference reference) {
+    if (!bindings.containsKey(reference.definition)) {
+      error('Referenced out of scope: ${reference.definition}', reference);
+    }
+    if (!seenReferences[reference.definition].add(reference)) {
+      error('Duplicate use of Reference to ${reference.definition}', reference);
+    }
+  }
+
+  @override
+  processInvokeContinuation(InvokeContinuation node) {
+    Continuation target = node.continuation.definition;
+    if (node.isRecursive && !insideContinuations.contains(target)) {
+      error('Non-recursive InvokeContinuation marked as recursive', node);
+    }
+    if (!node.isRecursive && insideContinuations.contains(target)) {
+      error('Recursive InvokeContinuation marked as non-recursive', node);
+    }
+    if (node.isRecursive && !target.isRecursive) {
+      error('Recursive Continuation was not marked as recursive', node);
+    }
+    if (node.arguments.length != target.parameters.length) {
+      error('Arity mismatch in InvokeContinuation', node);
+    }
+  }
+
+  void checkReferenceChain(Definition def) {
+    Set<Reference> chainedReferences = new Set<Reference>();
+    Reference prev = null;
+    for (Reference ref = def.firstRef; ref != null; ref = ref.next) {
+      if (ref.definition != def) {
+        error('Reference in chain for $def points to ${ref.definition}', def);
+      }
+      if (ref.previous != prev) {
+        error('Broken .previous link in reference to $def', def);
+      }
+      prev = ref;
+      if (!chainedReferences.add(ref)) {
+        error('Cyclic reference chain for $def', def);
+      }
+    }
+    if (!chainedReferences.containsAll(seenReferences[def])) {
+      error('Seen reference to $def not in reference chain', def);
+    }
+    if (!seenReferences[def].containsAll(chainedReferences)) {
+      error('Reference chain for $def contains orphaned references', def);
+    }
+  }
+
+  error(String message, node) {
+    String sexpr;
+    if (ENABLE_DUMP) {
+      try {
+        Decorator decorator = (n, String s) => n == node ? '**$s**' : s;
+        sexpr = new SExpressionStringifier(decorator).visit(topLevelNode);
+      } catch (e) {
+        sexpr = '(Exception thrown by SExpressionStringifier: $e)';
+      }
+    } else {
+      sexpr = '(Set DUMP_IR flag to enable)';
+    }
+    throw 'CPS integrity violation in ${topLevelNode.element}:\n'
+          '$message\n\n'
+          'SExpr dump (offending node marked with **):\n\n'
+          '$sexpr\n';
+  }
+
+  void check(ExecutableDefinition node) {
+    topLevelNode = node;
+    visit(node);
+
+    // Check this last, so out-of-scope references are not classified as
+    // a broken reference chain.
+    seenDefinitions.forEach(checkReferenceChain);
+  }
+
+}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index 3296adc..d16fd8c 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -9,8 +9,11 @@
 import '../constants/expressions.dart';
 import '../constants/values.dart' as values show ConstantValue;
 import '../cps_ir/optimizers.dart';
-import '../dart_types.dart' show DartType, GenericType;
-import '../dart2jslib.dart' as dart2js show invariant;
+import '../dart_types.dart' show DartType, GenericType, TypeVariableType;
+import '../dart2jslib.dart' as dart2js show
+    CURRENT_ELEMENT_SPANNABLE,
+    InternalErrorFunction,
+    invariant;
 import '../elements/elements.dart';
 import '../io/source_information.dart' show SourceInformation;
 import '../universe/universe.dart' show Selector, SelectorKind;
@@ -635,15 +638,9 @@
   accept(Visitor visitor) => visitor.visitConstant(this);
 }
 
-class This extends Primitive {
-  This();
-
-  accept(Visitor visitor) => visitor.visitThis(this);
-}
-
 /// Reify the given type variable as a [Type].
 /// This depends on the current binding of 'this'.
-class ReifyTypeVar extends Primitive {
+class ReifyTypeVar extends Primitive implements DartSpecificNode {
   final TypeVariableElement typeVariable;
 
   ReifyTypeVar(this.typeVariable);
@@ -703,6 +700,8 @@
   int parentIndex;
 
   accept(Visitor visitor) => visitor.visitParameter(this);
+
+  String toString() => 'Parameter(${hint == null ? null : hint.name})';
 }
 
 /// Continuations are normally bound by 'let cont'.  A continuation with one
@@ -731,6 +730,7 @@
 
 abstract class ExecutableDefinition implements Node {
   RunnableBody get body;
+  Element get element;
 
   applyPass(Pass pass);
 }
@@ -793,6 +793,7 @@
 class FunctionDefinition extends Node
     implements ExecutableDefinition {
   final FunctionElement element;
+  final Parameter thisParameter;
   /// Mixed list of [Parameter]s and [MutableVariable]s.
   final List<Definition> parameters;
   final RunnableBody body;
@@ -802,12 +803,14 @@
   final List<ConstantExpression> defaultParameterValues;
 
   FunctionDefinition(this.element,
+      this.thisParameter,
       this.parameters,
       this.body,
       this.localConstants,
       this.defaultParameterValues);
 
   FunctionDefinition.abstract(this.element,
+                              this.thisParameter,
                               this.parameters,
                               this.defaultParameterValues)
       : body = null,
@@ -844,13 +847,14 @@
   final List<Initializer> initializers;
 
   ConstructorDefinition(ConstructorElement element,
+                        Definition thisParameter, // only Dart
                         List<Definition> parameters,
                         RunnableBody body,
                         this.initializers,
                         List<ConstDeclaration> localConstants,
                         List<ConstantExpression> defaultParameterValues)
-      : super(element, parameters, body, localConstants,
-              defaultParameterValues);
+  : super(element, thisParameter, parameters, body, localConstants,
+          defaultParameterValues);
 
   // 'Abstract' here means "has no body" and is used to represent external
   // constructors.
@@ -859,12 +863,41 @@
       List<Definition> parameters,
       List<ConstantExpression> defaultParameterValues)
       : initializers = null,
-        super.abstract(element, parameters, defaultParameterValues);
+        super.abstract(element, null, parameters, defaultParameterValues);
 
   accept(Visitor visitor) => visitor.visitConstructorDefinition(this);
   applyPass(Pass pass) => pass.rewriteConstructorDefinition(this);
 }
 
+/// Converts the internal representation of a type to a Dart object of type
+/// [Type].
+class ReifyRuntimeType extends Primitive implements JsSpecificNode {
+  /// Reference to the internal representation of a type (as produced, for
+  /// example, by [ReadTypeVariable]).
+  final Reference<Primitive> value;
+  ReifyRuntimeType(Primitive value)
+    : this.value = new Reference<Primitive>(value);
+
+  @override
+  accept(Visitor visitor) => visitor.visitReifyRuntimeType(this);
+}
+
+/// Read the value the type variable [variable] from the target object.
+///
+/// The resulting value is an internal representation (and not neccessarily a
+/// Dart object), and must be reified by [ReifyRuntimeType], if it should be
+/// used as a Dart value.
+class ReadTypeVariable extends Primitive implements JsSpecificNode {
+  final TypeVariableType variable;
+  final Reference<Primitive> target;
+
+  ReadTypeVariable(this.variable, Primitive target)
+      : this.target = new Reference<Primitive>(target);
+
+  @override
+  accept(Visitor visitor) => visitor.visitReadTypeVariable(this);
+}
+
 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) {
   return definitions.map((e) => new Reference<Primitive>(e)).toList();
 }
@@ -872,79 +905,69 @@
 abstract class Visitor<T> {
   const Visitor();
 
-  T visit(Node node) => node.accept(this);
-  // Abstract classes.
-  T visitNode(Node node) => null;
-  T visitExpression(Expression node) => visitNode(node);
-  T visitDefinition(Definition node) => visitNode(node);
-  T visitPrimitive(Primitive node) => visitDefinition(node);
-  T visitCondition(Condition node) => visitNode(node);
-  T visitRunnableBody(RunnableBody node) => visitNode(node);
+  T visit(Node node);
 
   // Concrete classes.
-  T visitFieldDefinition(FieldDefinition node) => visitNode(node);
-  T visitFunctionDefinition(FunctionDefinition node) => visitNode(node);
-  T visitConstructorDefinition(ConstructorDefinition node) {
-    return visitFunctionDefinition(node);
-  }
+  T visitFieldDefinition(FieldDefinition node);
+  T visitFunctionDefinition(FunctionDefinition node);
+  T visitConstructorDefinition(ConstructorDefinition node);
+  T visitRunnableBody(RunnableBody node);
 
   // Initializers
-  T visitInitializer(Initializer node) => visitNode(node);
-  T visitFieldInitializer(FieldInitializer node) => visitInitializer(node);
-  T visitSuperInitializer(SuperInitializer node) => visitInitializer(node);
+  T visitFieldInitializer(FieldInitializer node);
+  T visitSuperInitializer(SuperInitializer node);
 
   // Expressions.
-  T visitLetPrim(LetPrim node) => visitExpression(node);
-  T visitLetCont(LetCont node) => visitExpression(node);
-  T visitLetHandler(LetHandler node) => visitExpression(node);
-  T visitLetMutable(LetMutable node) => visitExpression(node);
-  T visitInvokeStatic(InvokeStatic node) => visitExpression(node);
-  T visitInvokeContinuation(InvokeContinuation node) => visitExpression(node);
-  T visitInvokeMethod(InvokeMethod node) => visitExpression(node);
-  T visitInvokeMethodDirectly(InvokeMethodDirectly node) => visitExpression(node);
-  T visitInvokeConstructor(InvokeConstructor node) => visitExpression(node);
-  T visitConcatenateStrings(ConcatenateStrings node) => visitExpression(node);
-  T visitBranch(Branch node) => visitExpression(node);
-  T visitTypeOperator(TypeOperator node) => visitExpression(node);
-  T visitSetMutableVariable(SetMutableVariable node) => visitExpression(node);
-  T visitDeclareFunction(DeclareFunction node) => visitExpression(node);
-  T visitSetField(SetField node) => visitExpression(node);
+  T visitLetPrim(LetPrim node);
+  T visitLetCont(LetCont node);
+  T visitLetHandler(LetHandler node);
+  T visitLetMutable(LetMutable node);
+  T visitInvokeContinuation(InvokeContinuation node);
+  T visitInvokeStatic(InvokeStatic node);
+  T visitInvokeMethod(InvokeMethod node);
+  T visitInvokeMethodDirectly(InvokeMethodDirectly node);
+  T visitInvokeConstructor(InvokeConstructor node);
+  T visitConcatenateStrings(ConcatenateStrings node);
+  T visitBranch(Branch node);
+  T visitTypeOperator(TypeOperator node);
+  T visitSetMutableVariable(SetMutableVariable node);
+  T visitDeclareFunction(DeclareFunction node);
 
   // Definitions.
-  T visitLiteralList(LiteralList node) => visitPrimitive(node);
-  T visitLiteralMap(LiteralMap node) => visitPrimitive(node);
-  T visitConstant(Constant node) => visitPrimitive(node);
-  T visitThis(This node) => visitPrimitive(node);
-  T visitReifyTypeVar(ReifyTypeVar node) => visitPrimitive(node);
-  T visitCreateFunction(CreateFunction node) => visitPrimitive(node);
-  T visitGetMutableVariable(GetMutableVariable node) => visitPrimitive(node);
-  T visitParameter(Parameter node) => visitPrimitive(node);
-  T visitContinuation(Continuation node) => visitDefinition(node);
-  T visitMutableVariable(MutableVariable node) => visitDefinition(node);
-  T visitGetField(GetField node) => visitDefinition(node);
-  T visitCreateBox(CreateBox node) => visitDefinition(node);
-  T visitCreateInstance(CreateInstance node) => visitDefinition(node);
-
-  // Conditions.
-  T visitIsTrue(IsTrue node) => visitCondition(node);
+  T visitLiteralList(LiteralList node);
+  T visitLiteralMap(LiteralMap node);
+  T visitConstant(Constant node);
+  T visitReifyTypeVar(ReifyTypeVar node);
+  T visitCreateFunction(CreateFunction node);
+  T visitGetMutableVariable(GetMutableVariable node);
+  T visitParameter(Parameter node);
+  T visitContinuation(Continuation node);
+  T visitMutableVariable(MutableVariable node);
 
   // JavaScript specific nodes.
-  T visitIdentical(Identical node) => visitPrimitive(node);
-  T visitInterceptor(Interceptor node) => visitPrimitive(node);
+
+  // Conditions.
+  T visitIsTrue(IsTrue node);
+
+  // Expressions.
+  T visitSetField(SetField node);
+
+  // Definitions.
+  T visitIdentical(Identical node);
+  T visitInterceptor(Interceptor node);
+  T visitCreateInstance(CreateInstance node);
+  T visitGetField(GetField node);
+  T visitCreateBox(CreateBox node);
+  T visitReifyRuntimeType(ReifyRuntimeType node);
+  T visitReadTypeVariable(ReadTypeVariable node);
 }
 
 /// Recursively visits the entire CPS term, and calls abstract `process*`
 /// (i.e. `processLetPrim`) functions in pre-order.
-abstract class RecursiveVisitor extends Visitor {
+class RecursiveVisitor implements Visitor {
   const RecursiveVisitor();
 
-  // Ensures that RecursiveVisitor contains overrides for all relevant nodes.
-  // As a rule of thumb, nodes with structure to traverse should be overridden
-  // with the appropriate visits in this class (for example, visitLetCont),
-  // while leaving other nodes for subclasses (i.e., visitLiteralList).
-  visitNode(Node node) {
-    throw "$this is stale, add missing visit override for $node";
-  }
+  visit(Node node) => node.accept(this);
 
   processReference(Reference ref) {}
 
@@ -966,6 +989,7 @@
   processFunctionDefinition(FunctionDefinition node) {}
   visitFunctionDefinition(FunctionDefinition node) {
     processFunctionDefinition(node);
+    if (node.thisParameter != null) visit(node.thisParameter);
     node.parameters.forEach(visit);
     if (!node.isAbstract) {
       visit(node.body);
@@ -975,6 +999,7 @@
   processConstructorDefinition(ConstructorDefinition node) {}
   visitConstructorDefinition(ConstructorDefinition node) {
     processConstructorDefinition(node);
+    if (node.thisParameter != null) visit(node.thisParameter);
     node.parameters.forEach(visit);
     node.initializers.forEach(visit);
     visit(node.body);
@@ -983,14 +1008,13 @@
   processFieldInitializer(FieldInitializer node) {}
   visitFieldInitializer(FieldInitializer node) {
     processFieldInitializer(node);
-    visit(node.body.body);
+    visit(node.body);
   }
 
   processSuperInitializer(SuperInitializer node) {}
   visitSuperInitializer(SuperInitializer node) {
     processSuperInitializer(node);
-    node.arguments.forEach(
-        (RunnableBody argument) => visit(argument.body));
+    node.arguments.forEach(visit);
   }
 
   // Expressions.
@@ -1119,9 +1143,6 @@
   processConstant(Constant node) {}
   visitConstant(Constant node) => processConstant(node);
 
-  processThis(This node) {}
-  visitThis(This node) => processThis(node);
-
   processReifyTypeVar(ReifyTypeVar node) {}
   visitReifyTypeVar(ReifyTypeVar node) => processReifyTypeVar(node);
 
@@ -1139,6 +1160,7 @@
   processGetMutableVariable(GetMutableVariable node) {}
   visitGetMutableVariable(GetMutableVariable node) {
     processGetMutableVariable(node);
+    processReference(node.variable);
   }
 
   processParameter(Parameter node) {}
@@ -1197,6 +1219,18 @@
   visitCreateBox(CreateBox node) {
     processCreateBox(node);
   }
+
+  processReifyRuntimeType(ReifyRuntimeType node) {}
+  visitReifyRuntimeType(ReifyRuntimeType node) {
+    processReifyRuntimeType(node);
+    processReference(node.value);
+  }
+
+  processReadTypeVariable(ReadTypeVariable node) {}
+  visitReadTypeVariable(ReadTypeVariable node) {
+    processReadTypeVariable(node);
+    processReference(node.target);
+  }
 }
 
 /// Keeps track of currently unused register indices.
@@ -1224,11 +1258,15 @@
 /// redundant variables.
 /// Currently, the liveness analysis is very simple and is often inadequate
 /// for removing all of the redundant variables.
-class RegisterAllocator extends Visitor {
+class RegisterAllocator implements Visitor {
+  final dart2js.InternalErrorFunction internalError;
+
   /// Separate register spaces for each source-level variable/parameter.
   /// Note that null is used as key for primitives without hints.
   final Map<Local, RegisterArray> elementRegisters = <Local, RegisterArray>{};
 
+  RegisterAllocator(this.internalError);
+
   RegisterArray getRegisterArray(Local local) {
     RegisterArray registers = elementRegisters[local];
     if (registers == null) {
@@ -1252,6 +1290,8 @@
     }
   }
 
+  void visit(Node node) => node.accept(this);
+
   void visitReference(Reference reference) {
     allocate(reference.definition);
   }
@@ -1379,14 +1419,11 @@
   void visitConstant(Constant node) {
   }
 
-  void visitThis(This node) {
-  }
-
   void visitReifyTypeVar(ReifyTypeVar node) {
   }
 
   void visitCreateFunction(CreateFunction node) {
-    new RegisterAllocator().visit(node.definition);
+    new RegisterAllocator(internalError).visit(node.definition);
   }
 
   void visitGetMutableVariable(GetMutableVariable node) {
@@ -1398,14 +1435,21 @@
   }
 
   void visitDeclareFunction(DeclareFunction node) {
-    new RegisterAllocator().visit(node.definition);
+    new RegisterAllocator(internalError).visit(node.definition);
     visit(node.body);
   }
 
   void visitParameter(Parameter node) {
-    throw "Parameters should not be visited by RegisterAllocator";
+    // Parameters are handled differently depending on whether they are
+    // function parameters, continuation parameters, exception handler
+    // parameters, etc.  Thus we do not call visitParameter directly and
+    // handle them explicitly in their parent IR node.
+    internalError(dart2js.CURRENT_ELEMENT_SPANNABLE,
+                  'tried to allocate a parameter');
   }
 
+  void visitMutableVariable(MutableVariable node) {}
+
   void visitContinuation(Continuation node) {
     visit(node.body);
 
@@ -1448,4 +1492,12 @@
   void visitInterceptor(Interceptor node) {
     visitReference(node.input);
   }
+
+  void visitReifyRuntimeType(ReifyRuntimeType node) {
+    visitReference(node.value);
+  }
+
+  void visitReadTypeVariable(ReadTypeVariable node) {
+    visitReference(node.target);
+  }
 }
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
index 5e8eff6..3b71d9a 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
@@ -9,11 +9,12 @@
 import 'cps_ir_nodes.dart';
 
 /// A [Decorator] is a function used by [SExpressionStringifier] to augment the
-/// output produced for a node.  It can be provided to the constructor.
-typedef String Decorator(Node node, String s);
+/// output produced for a node or reference.  It can be provided to the
+/// constructor.
+typedef String Decorator(node, String s);
 
 /// Generate a Lisp-like S-expression representation of an IR node as a string.
-class SExpressionStringifier extends Visitor<String> with Indentation {
+class SExpressionStringifier extends Indentation implements Visitor<String> {
   final _Namer namer = new _Namer();
 
   String newValueName(Primitive node) => namer.nameValue(node);
@@ -22,12 +23,12 @@
 
   SExpressionStringifier([this.decorator]) {
     if (this.decorator == null) {
-      this.decorator = (Node node, String s) => s;
+      this.decorator = (node, String s) => s;
     }
   }
 
   String access(Reference<Definition> r) {
-    return decorator(r.definition, namer.getName(r.definition));
+    return decorator(r, namer.getName(r.definition));
   }
 
   String visitParameter(Parameter node) {
@@ -41,24 +42,28 @@
   /// Main entry point for creating a [String] from a [Node].  All recursive
   /// calls must go through this method.
   String visit(Node node) {
-    String s = super.visit(node);
+    String s = node.accept(this);
     return decorator(node, s);
   }
 
+  String formatThisParameter(Parameter thisParameter) {
+    return thisParameter == null ? '()' : '(${visit(thisParameter)})';
+  }
+
   String visitFunctionDefinition(FunctionDefinition node) {
     String name = node.element.name;
-    namer.setReturnContinuation(node.body.returnContinuation);
+    String thisParameter = formatThisParameter(node.thisParameter);
     String parameters = node.parameters.map(visit).join(' ');
-    String body = indentBlock(() => visit(node.body.body));
-    return '$indentation(FunctionDefinition $name ($parameters) return\n'
+    String body = visit(node.body);
+    return '$indentation'
+        '(FunctionDefinition $name $thisParameter ($parameters) return\n'
         '$body)';
   }
 
   String visitFieldDefinition(FieldDefinition node) {
     String name = node.element.name;
     if (node.hasInitializer) {
-      namer.setReturnContinuation(node.body.returnContinuation);
-      String body = indentBlock(() => visit(node.body.body));
+      String body = visit(node.body);
       return '$indentation(FieldDefinition $name () return\n'
              '$body)';
     } else {
@@ -66,6 +71,51 @@
     }
   }
 
+  String visitConstructorDefinition(ConstructorDefinition node) {
+    String name = node.element.name;
+    if (name != '') name = '$name ';
+    String thisParameter = formatThisParameter(node.thisParameter);
+    String parameters = node.parameters.map(visit).join(' ');
+    if (node.body != null) {
+      String initializers = indentBlock(() {
+        return indentBlock(() {
+          if (node.initializers.isEmpty) {
+            return '$indentation';
+          } else {
+            return node.initializers.map(visit).join('\n');
+          }
+        });
+      });
+      String body = visit(node.body);
+      return '$indentation'
+          '(ConstructorDefinition $name$thisParameter ($parameters) return'
+          ' (\n$initializers)\n$body)';
+    } else {
+      return '$indentation'
+          '(ConstructorDefinition $name$thisParameter ($parameters) return)';
+    }
+  }
+
+  String visitFieldInitializer(FieldInitializer node) {
+    String name = node.element.name;
+    String body = visit(node.body);
+    return '$indentation(FieldInitializer $name\n$body)';
+  }
+
+  String visitSuperInitializer(SuperInitializer node) {
+    String target = node.target.name;
+    String selector = node.selector.name;
+    String arguments =
+        indentBlock(() =>
+          indentBlock(() => node.arguments.map(visit).join('\n')));
+    return '$indentation(SuperInitializer $target $selector (\n$arguments)';
+  }
+
+  String visitRunnableBody(RunnableBody node) {
+    namer.setReturnContinuation(node.returnContinuation);
+    return indentBlock(() => visit(node.body));
+  }
+
   String visitLetPrim(LetPrim node) {
     String name = newValueName(node.primitive);
     String value = visit(node.primitive);
@@ -194,10 +244,6 @@
     return '(Constant $value)';
   }
 
-  String visitThis(This node) {
-    return '(This)';
-  }
-
   String visitReifyTypeVar(ReifyTypeVar node) {
     return '$indentation(ReifyTypeVar ${node.typeVariable.name})';
   }
@@ -289,6 +335,14 @@
   String visitInterceptor(Interceptor node) {
     return '(Interceptor ${access(node.input)})';
   }
+
+  String visitReifyRuntimeType(ReifyRuntimeType node) {
+    return '(ReifyRuntimeType ${access(node.value)})';
+  }
+
+  String visitReadTypeVariable(ReadTypeVariable node) {
+    return '(ReadTypeVariable ${access(node.target)}.${node.variable})';
+  }
 }
 
 class ConstantStringifier extends ConstantValueVisitor<String, Null> {
@@ -368,6 +422,9 @@
   int _valueCounter = 0;
   int _continuationCounter = 0;
 
+  // TODO(sra): Make the methods not assert and print something indicating an
+  // error, so printer can be used to inspect broken terms.
+
   String nameParameter(Parameter parameter) {
     assert(!_names.containsKey(parameter));
     return _names[parameter] = parameter.hint.name;
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
index 1fcb5a7..74c4b1c 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
@@ -31,34 +31,51 @@
   // Temporary field used during tree walk
   Names names;
 
-  visitExecutableDefinition(cps_ir.ExecutableDefinition node) {
+  printDefinition(cps_ir.ExecutableDefinition node) {
     names = new Names();
     BlockCollector builder = new BlockCollector(names);
     builder.visit(node);
 
     for (Block block in builder.entries) {
-      printNode(block);
+      printBlock(block);
     }
     for (Block block in builder.cont2block.values) {
-      printNode(block);
+      printBlock(block);
     }
     names = null;
   }
 
   visitFieldDefinition(cps_ir.FieldDefinition node) {
     if (node.hasInitializer) {
-      visitExecutableDefinition(node);
+      printDefinition(node);
     }
   }
 
   visitFunctionDefinition(cps_ir.FunctionDefinition node) {
     if (node.isAbstract) return;
-    visitExecutableDefinition(node);
+    printDefinition(node);
   }
 
   visitConstructorDefinition(cps_ir.ConstructorDefinition node) {
     if (node.isAbstract) return;
-    visitExecutableDefinition(node);
+    printDefinition(node);
+  }
+
+  // Bodies and initializers are not visited.  They contain continuations which
+  // are found by a BlockCollector, then those continuations are processed by
+  // this visitor.
+  unexpectedNode(cps_ir.Node node) {
+    throw 'The IR tracer reached an unexpected IR instruction: $node';
+  }
+
+  visitRunnableBody(cps_ir.RunnableBody node) {
+    unexpectedNode(node);
+  }
+  visitFieldInitializer(cps_ir.FieldInitializer node) {
+    unexpectedNode(node);
+  }
+  visitSuperInitializer(cps_ir.SuperInitializer node) {
+    unexpectedNode(node);
   }
 
   int countUses(cps_ir.Definition definition) {
@@ -71,7 +88,7 @@
     return count;
   }
 
-  printNode(Block block) {
+  printBlock(Block block) {
     tag("block", () {
       printProperty("name", block.name);
       printProperty("from_bci", -1);
@@ -131,7 +148,7 @@
 
   visitLetMutable(cps_ir.LetMutable node) {
     String id = names.name(node.variable);
-    printStmt(id, "${node.runtimeType} $id = ${formatReference(node.value)}");
+    printStmt(id, "LetMutable $id = ${formatReference(node.value)}");
     visit(node.body);
   }
 
@@ -227,7 +244,7 @@
     String dummy = names.name(node);
     String variable = names.name(node.variable.definition);
     String value = formatReference(node.value);
-    printStmt(dummy, '${node.runtimeType} $variable := $value');
+    printStmt(dummy, 'SetMutableVariable $variable := $value');
     visit(node.body);
   }
 
@@ -258,7 +275,7 @@
   }
 
   visitMutableVariable(cps_ir.MutableVariable node) {
-    return "${node.runtimeType} ${names.name(node)}";
+    return "MutableVariable ${names.name(node)}";
   }
 
   visitContinuation(cps_ir.Continuation node) {
@@ -304,10 +321,6 @@
     return "Interceptor(${formatReference(node.input)})";
   }
 
-  visitThis(cps_ir.This node) {
-    return "This";
-  }
-
   visitReifyTypeVar(cps_ir.ReifyTypeVar node) {
     return "ReifyTypeVar ${node.typeVariable.name}";
   }
@@ -318,18 +331,19 @@
 
   visitGetMutableVariable(cps_ir.GetMutableVariable node) {
     String variable = names.name(node.variable.definition);
-    return '${node.runtimeType} $variable';
+    return 'GetMutableVariable $variable';
   }
 
-  visitRunnableBody(cps_ir.RunnableBody node) {}
-  visitFieldInitializer(cps_ir.FieldInitializer node) {}
-  visitSuperInitializer(cps_ir.SuperInitializer node) {}
-  visitCondition(cps_ir.Condition c) {}
-  visitExpression(cps_ir.Expression e) {}
-  visitPrimitive(cps_ir.Primitive p) {}
-  visitDefinition(cps_ir.Definition d) {}
-  visitInitializer(cps_ir.Initializer i) {}
-  visitNode(cps_ir.Node n) {}
+  @override
+  visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
+    return "ReadTypeVariable ${node.variable.element} "
+        "${formatReference(node.target)}";
+  }
+
+  @override
+  visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
+    return "ReifyRuntimeType ${formatReference(node.value)}";
+  }
 }
 
 /**
@@ -385,7 +399,7 @@
   }
 }
 
-class BlockCollector extends cps_ir.Visitor {
+class BlockCollector implements cps_ir.Visitor {
   final Map<cps_ir.Continuation, Block> cont2block =
       <cps_ir.Continuation, Block>{};
   final Set<Block> entries = new Set<Block>();
@@ -403,6 +417,22 @@
     return block;
   }
 
+  visit(cps_ir.Node node) => node.accept(this);
+
+  visitFieldDefinition(cps_ir.FieldDefinition node) {
+    if (node.hasInitializer) {
+      visit(node.body);
+    }
+  }
+
+  visitFunctionDefinition(cps_ir.FunctionDefinition node) {
+    visit(node.body);
+  }
+
+  visitConstructorDefinition(cps_ir.ConstructorDefinition node) {
+    visit(node.body);
+  }
+
   visitRunnableBody(cps_ir.RunnableBody node) {
     current_block = new Block(names.name(node), [], node.body);
     entries.add(current_block);
@@ -417,24 +447,6 @@
     node.arguments.forEach(visit);
   }
 
-  visitExecutableDefinition(cps_ir.ExecutableDefinition node) {
-    visit(node.body);
-  }
-
-  visitFieldDefinition(cps_ir.FieldDefinition node) {
-    if (node.hasInitializer) {
-      visitExecutableDefinition(node);
-    }
-  }
-
-  visitFunctionDefinition(cps_ir.FunctionDefinition node) {
-    visitExecutableDefinition(node);
-  }
-
-  visitConstructorDefinition(cps_ir.ConstructorDefinition node) {
-    visitExecutableDefinition(node);
-  }
-
   visitLetPrim(cps_ir.LetPrim exp) {
     visit(exp.body);
   }
@@ -460,6 +472,10 @@
     }
   }
 
+  visitInvokeContinuation(cps_ir.InvokeContinuation exp) {
+    addEdgeToContinuation(exp.continuation);
+  }
+
   visitInvokeStatic(cps_ir.InvokeStatic exp) {
     addEdgeToContinuation(exp.continuation);
   }
@@ -468,6 +484,10 @@
     addEdgeToContinuation(exp.continuation);
   }
 
+  visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly exp) {
+    addEdgeToContinuation(exp.continuation);
+  }
+
   visitInvokeConstructor(cps_ir.InvokeConstructor exp) {
     addEdgeToContinuation(exp.continuation);
   }
@@ -476,10 +496,6 @@
     addEdgeToContinuation(exp.continuation);
   }
 
-  visitInvokeContinuation(cps_ir.InvokeContinuation exp) {
-    addEdgeToContinuation(exp.continuation);
-  }
-
   visitSetMutableVariable(cps_ir.SetMutableVariable exp) {
     visit(exp.body);
   }
@@ -503,10 +519,73 @@
     }
   }
 
+  visitTypeOperator(cps_ir.TypeOperator exp) {
+    addEdgeToContinuation(exp.continuation);
+  }
+
   visitContinuation(cps_ir.Continuation c) {
     var old_node = current_block;
     current_block = getBlock(c);
     visit(c.body);
     current_block = old_node;
   }
+
+  // Primitives and conditions are not visited when searching for blocks.
+  unexpectedNode(cps_ir.Node node) {
+    throw "The IR tracer's block collector reached an unexpected IR "
+        "instruction: $node";
+  }
+
+  visitLiteralList(cps_ir.LiteralList node) {
+    unexpectedNode(node);
+  }
+  visitLiteralMap(cps_ir.LiteralMap node) {
+    unexpectedNode(node);
+  }
+  visitConstant(cps_ir.Constant node) {
+    unexpectedNode(node);
+  }
+  visitReifyTypeVar(cps_ir.ReifyTypeVar node) {
+    unexpectedNode(node);
+  }
+  visitCreateFunction(cps_ir.CreateFunction node) {
+    unexpectedNode(node);
+  }
+  visitGetMutableVariable(cps_ir.GetMutableVariable node) {
+    unexpectedNode(node);
+  }
+  visitParameter(cps_ir.Parameter node) {
+    unexpectedNode(node);
+  }
+  visitMutableVariable(cps_ir.MutableVariable node) {
+    unexpectedNode(node);
+  }
+  visitGetField(cps_ir.GetField node) {
+    unexpectedNode(node);
+  }
+  visitCreateBox(cps_ir.CreateBox node) {
+    unexpectedNode(node);
+  }
+  visitCreateInstance(cps_ir.CreateInstance node) {
+    unexpectedNode(node);
+  }
+  visitIsTrue(cps_ir.IsTrue node) {
+    unexpectedNode(node);
+  }
+  visitIdentical(cps_ir.Identical node) {
+    unexpectedNode(node);
+  }
+  visitInterceptor(cps_ir.Interceptor node) {
+    unexpectedNode(node);
+  }
+
+  @override
+  visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
+    unexpectedNode(node);
+  }
+
+  @override
+  visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
+    unexpectedNode(node);
+  }
 }
diff --git a/pkg/compiler/lib/src/cps_ir/optimizers.dart b/pkg/compiler/lib/src/cps_ir/optimizers.dart
index 335a92b..5fba01c 100644
--- a/pkg/compiler/lib/src/cps_ir/optimizers.dart
+++ b/pkg/compiler/lib/src/cps_ir/optimizers.dart
@@ -32,6 +32,8 @@
   void rewriteConstructorDefinition(ConstructorDefinition root);
   void rewriteFunctionDefinition(FunctionDefinition root);
   void rewriteFieldDefinition(FieldDefinition root);
+
+  String get passName;
 }
 
 abstract class PassMixin implements Pass {
diff --git a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart b/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
index c0c80bd..b61e785 100644
--- a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
+++ b/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
@@ -13,6 +13,8 @@
 /// continuation signature, all invocations, and replaced within the
 /// continuation body.
 class RedundantPhiEliminator extends RecursiveVisitor with PassMixin {
+  String get passName => 'Redundant phi elimination';
+
   final Set<Continuation> workSet = new Set<Continuation>();
 
   @override
diff --git a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
index 79234f8..c3823ec 100644
--- a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
+++ b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
@@ -9,6 +9,8 @@
  * in 'Compiling with Continuations, Continued' by Andrew Kennedy.
  */
 class ShrinkingReducer extends PassMixin {
+  String get passName => 'Shrinking reductions';
+
   Set<_ReductionTask> _worklist;
 
   static final _DeletedNode _DELETED = new _DeletedNode();
@@ -484,6 +486,7 @@
 class ParentVisitor extends RecursiveVisitor {
   processFunctionDefinition(FunctionDefinition node) {
     node.body.parent = node;
+    if (node.thisParameter != null) node.thisParameter.parent = node;
     int index = 0;
     node.parameters.forEach((Definition parameter) {
       parameter.parent = node;
@@ -509,12 +512,11 @@
   // Expressions.
 
   processFieldInitializer(FieldInitializer node) {
-    node.body.body.parent = node;
+    node.body.parent = node;
   }
 
   processSuperInitializer(SuperInitializer node) {
-    node.arguments.forEach(
-        (RunnableBody argument) => argument.body.parent = node);
+    node.arguments.forEach((RunnableBody argument) => argument.parent = node);
   }
 
   processLetPrim(LetPrim node) {
@@ -660,6 +662,14 @@
 
   processCreateBox(CreateBox node) {
   }
+
+  processReifyRuntimeType(ReifyRuntimeType node) {
+    node.value.parent = node;
+  }
+
+  processReadTypeVariable(ReadTypeVariable node) {
+    node.target.parent = node;
+  }
 }
 
 class _ReductionKind {
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index ceef60f..bd723fc 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -93,6 +93,8 @@
  * by Wegman, Zadeck.
  */
 class TypePropagator<T> extends PassMixin {
+  String get passName => 'Sparse constant propagation';
+
   final types.DartTypes _dartTypes;
 
   // The constant system is used for evaluation of expressions with constant
@@ -287,7 +289,7 @@
  * const-ness as well as reachability, both of which are used in the subsequent
  * transformation pass.
  */
-class _TypePropagationVisitor<T> extends Visitor {
+class _TypePropagationVisitor<T> implements Visitor {
   // The node worklist stores nodes that are both reachable and need to be
   // processed, but have not been processed yet. Using a worklist avoids deep
   // recursion.
@@ -411,26 +413,38 @@
   }
 
   // -------------------------- Visitor overrides ------------------------------
+  void visit(Node node) { node.accept(this); }
 
-  void visitNode(Node node) {
-    internalError(NO_LOCATION_SPANNABLE,
-        "_TypePropagationVisitor is stale,"
-        " add missing visit overrides ($node)");
+  void visitFieldDefinition(FieldDefinition node) {
+    if (node.hasInitializer) {
+      setReachable(node.body);
+    }
+  }
+
+  void visitFunctionDefinition(FunctionDefinition node) {
+    if (node.thisParameter != null) {
+      setValue(node.thisParameter, nonConst());
+    }
+    node.parameters.forEach(visit);
+    setReachable(node.body);
+  }
+
+  void visitConstructorDefinition(ConstructorDefinition node) {
+    node.parameters.forEach(visit);
+    node.initializers.forEach(visit);
+    setReachable(node.body);
   }
 
   void visitRunnableBody(RunnableBody node) {
     setReachable(node.body);
   }
 
-  void visitFunctionDefinition(FunctionDefinition node) {
-    node.parameters.forEach(visit);
+  void visitFieldInitializer(FieldInitializer node) {
     setReachable(node.body);
   }
 
-  void visitFieldDefinition(FieldDefinition node) {
-    if (node.hasInitializer) {
-      setReachable(node.body);
-    }
+  void visitSuperInitializer(SuperInitializer node) {
+    node.arguments.forEach(setReachable);
   }
 
   // Expressions.
@@ -714,11 +728,6 @@
     setValue(node, constantValue(value, typeSystem.typeOf(value)));
   }
 
-  void visitThis(This node) {
-    // TODO(karlklose): Add the type.
-    setValue(node, nonConst());
-  }
-
   void visitReifyTypeVar(ReifyTypeVar node) {
     setValue(node, nonConst(typeSystem.typeType));
   }
@@ -833,6 +842,16 @@
   void visitCreateInstance(CreateInstance node) {
     setValue(node, nonConst());
   }
+
+  void visitReifyRuntimeType(ReifyRuntimeType node) {
+    setValue(node, nonConst(typeSystem.typeType));
+  }
+
+  void visitReadTypeVariable(ReadTypeVariable node) {
+    // TODO(karlklose): come up with a type marker for JS entities or switch to
+    // real constants of type [Type].
+    setValue(node, nonConst());
+  }
 }
 
 /// Represents the abstract value of a primitive value at some point in the
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 2ea3faa..3350684 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -114,6 +114,7 @@
   bool stripArgumentSet = false;
   bool analyzeOnly = false;
   bool analyzeAll = false;
+  bool dumpInfo = false;
   bool allowNativeExtensions = false;
   bool trustTypeAnnotations = false;
   bool trustPrimitives = false;
@@ -206,6 +207,11 @@
     passThrough(argument);
   }
 
+  setDumpInfo(String argument) {
+    implyCompilation(argument);
+    dumpInfo = true;
+  }
+
   setTrustTypeAnnotations(String argument) {
     trustTypeAnnotations = true;
     implyCompilation(argument);
@@ -328,7 +334,7 @@
     new OptionHandler('--disable-type-inference', implyCompilation),
     new OptionHandler('--terse', passThrough),
     new OptionHandler('--deferred-map=.+', implyCompilation),
-    new OptionHandler('--dump-info', implyCompilation),
+    new OptionHandler('--dump-info', setDumpInfo),
     new OptionHandler('--disallow-unsafe-eval',
                       (_) => hasDisallowUnsafeEval = true),
     new OptionHandler('--show-package-warnings', passThrough),
@@ -414,6 +420,10 @@
                   "combination with the '--analyze-only' option.");
     }
   }
+  if (dumpInfo && outputLanguage == OUTPUT_LANGUAGE_DART) {
+    helpAndFail("Option '--dump-info' is not supported in "
+                "combination with the '--output-type=dart' option.");
+  }
 
   diagnosticHandler.info('Package root is $packageRoot');
 
@@ -605,7 +615,9 @@
   --dump-info
     Generates an out.info.json file with information about the generated code.
     You can inspect the generated file with the viewer at:
-    https://dart-lang.github.io/dump-info-visualizer/
+        https://dart-lang.github.io/dump-info-visualizer/
+    This feature is currently not supported in combination with the 
+    '--output-type=dart' option.
 
   --generate-code-with-compile-time-errors
     Generates output even if the program contains compile-time errors. Use the
diff --git a/pkg/compiler/lib/src/dart2jslib.dart b/pkg/compiler/lib/src/dart2jslib.dart
index 19700eb..d52396c 100644
--- a/pkg/compiler/lib/src/dart2jslib.dart
+++ b/pkg/compiler/lib/src/dart2jslib.dart
@@ -15,7 +15,7 @@
 import 'constants/expressions.dart';
 import 'constants/values.dart';
 import 'core_types.dart';
-import 'cps_ir/cps_ir_builder.dart' show IrBuilderTask;
+import 'cps_ir/cps_ir_builder_task.dart' show IrBuilderTask;
 import 'dart_backend/dart_backend.dart' as dart_backend;
 import 'dart_types.dart';
 import 'deferred_load.dart' show DeferredLoadTask, OutputUnit;
diff --git a/pkg/compiler/lib/src/dart_backend/backend.dart b/pkg/compiler/lib/src/dart_backend/backend.dart
index 90baf1b..f2c6c71 100644
--- a/pkg/compiler/lib/src/dart_backend/backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend.dart
@@ -131,47 +131,68 @@
 
   void codegen(CodegenWorkItem work) { }
 
+  static bool checkTreeIntegrity(tree_ir.ExecutableDefinition node) {
+    new CheckTreeIntegrity().check(node);
+    return true; // So this can be used from assert().
+  }
+
+  static bool checkCpsIntegrity(cps_ir.ExecutableDefinition node) {
+    new CheckCpsIntegrity().check(node);
+    return true; // So this can be used from assert().
+  }
+
   /// Create an [ElementAst] from the CPS IR.
   static ElementAst createElementAst(
        ElementAstCreationContext context,
        Element element,
        cps_ir.ExecutableDefinition cpsDefinition) {
-    // Transformations on the CPS IR.
     context.traceCompilation(element.name);
+    context.traceGraph('CPS builder', cpsDefinition);
+    assert(checkCpsIntegrity(cpsDefinition));
+
+    // Transformations on the CPS IR.
+    void applyCpsPass(cps_opt.Pass pass) {
+      pass.rewrite(cpsDefinition);
+      context.traceGraph(pass.passName, cpsDefinition);
+      assert(checkCpsIntegrity(cpsDefinition));
+    }
 
     // TODO(karlklose): enable type propagation for dart2dart when constant
     // types are correctly marked as instantiated (Issue 21880).
-    new TypePropagator(context.dartTypes,
-                       context.constantSystem,
-                       new UnitTypeSystem(),
-                       context.internalError)
-        .rewrite(cpsDefinition);
-    context.traceGraph("Sparse constant propagation", cpsDefinition);
-    new RedundantPhiEliminator().rewrite(cpsDefinition);
-    context.traceGraph("Redundant phi elimination", cpsDefinition);
-    new ShrinkingReducer().rewrite(cpsDefinition);
-    context.traceGraph("Shrinking reductions", cpsDefinition);
+    TypePropagator typePropagator = new TypePropagator(
+        context.dartTypes,
+        context.constantSystem,
+        new UnitTypeSystem(),
+        context.internalError);
+    applyCpsPass(typePropagator);
+    applyCpsPass(new RedundantPhiEliminator());
+    applyCpsPass(new ShrinkingReducer());
 
     // Do not rewrite the IR after variable allocation.  Allocation
     // makes decisions based on an approximation of IR variable live
     // ranges that can be invalidated by transforming the IR.
-    new cps_ir.RegisterAllocator().visit(cpsDefinition);
+    new cps_ir.RegisterAllocator(context.internalError).visit(cpsDefinition);
 
     tree_builder.Builder builder =
         new tree_builder.Builder(context.internalError);
     tree_ir.ExecutableDefinition treeDefinition = builder.build(cpsDefinition);
     assert(treeDefinition != null);
     context.traceGraph('Tree builder', treeDefinition);
+    assert(checkTreeIntegrity(treeDefinition));
 
     // Transformations on the Tree IR.
-    new StatementRewriter().rewrite(treeDefinition);
-    context.traceGraph('Statement rewriter', treeDefinition);
-    new CopyPropagator().rewrite(treeDefinition);
-    context.traceGraph('Copy propagation', treeDefinition);
-    new LoopRewriter().rewrite(treeDefinition);
-    context.traceGraph('Loop rewriter', treeDefinition);
-    new LogicalRewriter().rewrite(treeDefinition);
-    context.traceGraph('Logical rewriter', treeDefinition);
+    void applyTreePass(tree_opt.Pass pass) {
+      pass.rewrite(treeDefinition);
+      context.traceGraph(pass.passName, treeDefinition);
+      assert(checkTreeIntegrity(treeDefinition));
+    }
+
+    applyTreePass(new StatementRewriter());
+    applyTreePass(new CopyPropagator());
+    applyTreePass(new LoopRewriter());
+    applyTreePass(new LogicalRewriter());
+
+    // Backend-specific transformations.
     new backend_ast_emitter.UnshadowParameters().unshadow(treeDefinition);
     context.traceGraph('Unshadow parameters', treeDefinition);
 
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
index 787dd5f..1508259 100644
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
@@ -518,9 +518,9 @@
     // Try to emit a local function declaration. This is useful for functions
     // that may occur in expression context, but could not be inlined anywhere.
     if (stmt.variable.element is FunctionElement &&
-        stmt.definition is tree.FunctionExpression &&
+        stmt.value is tree.FunctionExpression &&
         !context.declaredVariables.contains(stmt.variable)) {
-      tree.FunctionExpression functionExp = stmt.definition;
+      tree.FunctionExpression functionExp = stmt.value;
       FunctionExpression function =
           makeSubFunction(functionExp.definition, context);
       FunctionDeclaration decl = new FunctionDeclaration(function);
@@ -534,7 +534,7 @@
     bool isFirstOccurrence = (context.variableNames[stmt.variable] == null);
     bool isDeclaredHere = stmt.variable.host == context.currentElement;
     String name = context.getVariableName(stmt.variable);
-    Expression definition = visitExpression(stmt.definition, context);
+    Expression definition = visitExpression(stmt.value, context);
 
     // Try to pull into initializer.
     if (context.firstStatement == stmt && isFirstOccurrence && isDeclaredHere) {
@@ -950,6 +950,16 @@
     return errorUnsupportedNode(node);
   }
 
+  @override
+  Expression visitReadTypeVariable(tree.ReadTypeVariable node, arg) {
+    return errorUnsupportedNode(node);
+  }
+
+  @override
+  Expression visitReifyRuntimeType(tree.ReifyRuntimeType node, arg) {
+    return errorUnsupportedNode(node);
+  }
+
   errorUnsupportedNode(tree.JsSpecificNode node) {
     throw '$node not supported by dart backend';
   }
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
index 8398cbb..9bf9121 100644
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
@@ -398,9 +398,9 @@
       }
     } else if (exp is CallMethod) {
       precedence = CALLEE;
-      tree.Node receiver = exp.object is This
-          ? null
-          : makeExp(exp.object, PRIMARY, beginStmt: beginStmt);
+      // TODO(sra): Elide receiver when This, but only if not in a scope that
+      // shadows the method (e.g. constructor body).
+      tree.Node receiver = makeExp(exp.object, PRIMARY, beginStmt: beginStmt);
       result = new tree.Send(
           receiver,
           makeIdentifier(exp.methodName),
@@ -445,9 +445,9 @@
           colon);
     } else if (exp is FieldExpression) {
       precedence = PRIMARY;
-      tree.Node receiver = exp.object is This
-          ? null
-          : makeExp(exp.object, PRIMARY, beginStmt: beginStmt);
+      // TODO(sra): Elide receiver when This, but only if not in a scope that
+      // shadows the method (e.g. constructor body).
+      tree.Node receiver = makeExp(exp.object, PRIMARY, beginStmt: beginStmt);
       result = new tree.Send(receiver, makeIdentifier(exp.fieldName));
     } else if (exp is ConstructorDefinition) {
       precedence = EXPRESSION;
@@ -976,17 +976,16 @@
         setElement(definition, param.element, param);
       }
       if (param.defaultValue != null) {
-        return new tree.SendSet(
+        definition = new tree.SendSet(
             null,
             definition,
             new tree.Operator(assignOperator),
             singleton(makeExpression(param.defaultValue)));
-      } else {
-        return new tree.VariableDefinitions(
-            null,
-            makeEmptyModifiers(),
-            singleton(definition));
       }
+      return new tree.VariableDefinitions(
+          null,
+          makeEmptyModifiers(),
+          singleton(definition));
     } else {
       tree.Node definition;
       if (param.defaultValue != null) {
diff --git a/pkg/compiler/lib/src/dart_backend/dart_backend.dart b/pkg/compiler/lib/src/dart_backend/dart_backend.dart
index e498d5a..2d73044 100644
--- a/pkg/compiler/lib/src/dart_backend/dart_backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/dart_backend.dart
@@ -12,14 +12,19 @@
 import '../dart_types.dart';
 import '../tree/tree.dart';
 import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
+import '../cps_ir/cps_ir_nodes_sexpr.dart';
 import '../constants/expressions.dart';
 import '../cps_ir/optimizers.dart';
+import '../cps_ir/optimizers.dart' as cps_opt;
 import '../tree_ir/tree_ir_builder.dart' as tree_builder;
 import '../tree_ir/tree_ir_nodes.dart' as tree_ir;
 import '../util/util.dart';
 import '../mirror_renamer/mirror_renamer.dart';
 import '../tree_ir/optimization/optimization.dart'
     show LogicalRewriter, LoopRewriter, CopyPropagator, StatementRewriter;
+import '../tree_ir/optimization/optimization.dart' as tree_opt;
+import '../tree_ir/tree_ir_integrity.dart';
+import '../cps_ir/cps_ir_integrity.dart';
 import 'backend_ast_emitter.dart' as backend_ast_emitter;
 import 'backend_ast_nodes.dart' as backend_ast;
 import 'backend_ast_to_frontend_ast.dart' as backend2frontend;
@@ -35,4 +40,4 @@
 part 'backend.dart';
 part 'renamer.dart';
 part 'placeholder_collector.dart';
-part 'outputter.dart';
\ No newline at end of file
+part 'outputter.dart';
diff --git a/pkg/compiler/lib/src/dart_types.dart b/pkg/compiler/lib/src/dart_types.dart
index fd27d88..b9c90fe 100644
--- a/pkg/compiler/lib/src/dart_types.dart
+++ b/pkg/compiler/lib/src/dart_types.dart
@@ -1222,6 +1222,37 @@
     return new Types(compiler);
   }
 
+  /// Flatten [type] by recursively removing enclosing `Future` annotations.
+  ///
+  /// Defined in the language specification as:
+  ///
+  ///   If T = Future<S> then flatten(T) = flatten(S).
+  ///   Otherwise if T <: Future then let S be a type such that T << Future<S>
+  ///   and for all R, if T << Future<R> then S << R. Then flatten(T) =  S.
+  ///   In any other circumstance, flatten(T) = T.
+  ///
+  /// For instance:
+  ///     flatten(T) = T
+  ///     flatten(Future<T>) = T
+  ///     flatten(Future<Future<T>>) = T
+  ///
+  /// This method is used in the static typing of await and type checking of
+  /// return.
+  DartType flatten(DartType type) {
+    if (type is InterfaceType) {
+      if (type.element == coreTypes.futureClass) {
+        // T = Future<S>
+        return flatten(type.typeArguments.first);
+      }
+      InterfaceType futureType = type.asInstanceOf(coreTypes.futureClass);
+      if (futureType != null) {
+        // T << Future<S>
+        return futureType.typeArguments.single;
+      }
+    }
+    return type;
+  }
+
   /** Returns true if [t] is more specific than [s]. */
   bool isMoreSpecific(DartType t, DartType s) {
     return moreSpecificVisitor.isMoreSpecific(t, s);
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index c92ea25..5792cac 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -654,7 +654,7 @@
       'compilationDuration': compiler.totalCompileTime.elapsed.toString(),
       'toJsonDuration': 0,
       'dumpInfoDuration': this.timing.toString(),
-      'noSuchMethodEnabled': compiler.enabledNoSuchMethod
+      'noSuchMethodEnabled': backend.enabledNoSuchMethod
     };
 
     outJson['program'] = generalProgramInfo;
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index 5560c4a..4a8af6e 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -413,7 +413,6 @@
 
   void addMetadata(MetadataAnnotation annotation);
   void setNative(String name);
-  void setFixedBackendName(String name);
 
   Scope buildScope();
 
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 19eee6a..68ee1a4 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -244,9 +244,6 @@
     _isNative = true;
     _fixedBackendName = name;
   }
-  void setFixedBackendName(String name) {
-    _fixedBackendName = name;
-  }
 
   FunctionElement asFunctionElement() => null;
 
@@ -2016,6 +2013,8 @@
 
   FunctionExpression get node => constructor.node;
 
+  Link<MetadataAnnotation> get metadata => constructor.metadata;
+
   bool get isInstanceMember => true;
 
   FunctionType computeType(Compiler compiler) {
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index e00b750..adc2363 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -162,7 +162,7 @@
       FunctionElement function = member;
       function.computeSignature(compiler);
       if (function.name == Compiler.NO_SUCH_METHOD) {
-        enableNoSuchMethod(function);
+        registerNoSuchMethod(function);
       }
       if (function.name == Compiler.CALL_OPERATOR_NAME &&
           !cls.typeVariables.isEmpty) {
@@ -212,7 +212,8 @@
         .add(member);
   }
 
-  void enableNoSuchMethod(Element element) {}
+  void registerNoSuchMethod(Element noSuchMethod);
+
   void enableIsolateSupport() {}
 
   void processInstantiatedClass(ClassElement cls) {
@@ -736,19 +737,15 @@
     return true;
   }
 
+  void registerNoSuchMethod(Element element) {
+    compiler.backend.registerNoSuchMethod(element);
+  }
+
   void enableIsolateSupport() {
     compiler.hasIsolateSupport = true;
     compiler.backend.enableIsolateSupport(this);
   }
 
-  void enableNoSuchMethod(Element element) {
-    if (compiler.enabledNoSuchMethod) return;
-    if (compiler.backend.isDefaultNoSuchMethodImplementation(element)) return;
-
-    compiler.enabledNoSuchMethod = true;
-    compiler.backend.enableNoSuchMethod(element, this);
-  }
-
   /**
    * Adds an action to the deferred task queue.
    *
@@ -806,6 +803,8 @@
 
   final Set<Selector> newlySeenSelectors;
 
+  bool enabledNoSuchMethod = false;
+
   CodegenEnqueuer(Compiler compiler,
                   ItemCompilationContext itemCompilationContextCreator())
       : queue = new Queue<CodegenWorkItem>(),
@@ -855,6 +854,13 @@
     return true;
   }
 
+  void registerNoSuchMethod(Element element) {
+    if (!enabledNoSuchMethod && compiler.backend.enabledNoSuchMethod) {
+      compiler.backend.enableNoSuchMethod(this);
+      enabledNoSuchMethod = true;
+    }
+  }
+
   void _logSpecificSummary(log(message)) {
     log('Compiled ${generatedCode.length} methods.');
   }
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index 5ce37d1..dd58fb3 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -305,7 +305,7 @@
       bailout('Used as key in Map');
     }
 
-    if (info.targetsIncludeNoSuchMethod &&
+    if (info.targetsIncludeComplexNoSuchMethod(inferrer) &&
         info.arguments != null &&
         info.arguments.contains(currentUser)) {
       bailout('Passed to noSuchMethod');
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 7b673d0..b87a892 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -760,11 +760,12 @@
     }
   }
 
-  bool get targetsIncludeNoSuchMethod {
+  bool targetsIncludeComplexNoSuchMethod(TypeGraphInferrerEngine inferrer) {
     return targets.any((Element e) {
       return e is FunctionElement &&
              e.isInstanceMember &&
-             e.name == Compiler.NO_SUCH_METHOD;
+             e.name == Compiler.NO_SUCH_METHOD &&
+             inferrer.backend.isComplexNoSuchMethod(e);
     });
   }
 
diff --git a/pkg/compiler/lib/src/io/source_file.dart b/pkg/compiler/lib/src/io/source_file.dart
index c8f79cd..8fd28ff 100644
--- a/pkg/compiler/lib/src/io/source_file.dart
+++ b/pkg/compiler/lib/src/io/source_file.dart
@@ -6,6 +6,7 @@
 
 import 'dart:math';
 import 'dart:convert' show UTF8;
+import 'dart:typed_data' show Uint8List;
 
 import 'line_column_provider.dart';
 
@@ -25,8 +26,11 @@
   /** The text content of the file represented as a String. */
   String slowText();
 
-  /** The content of the file represented as a UTF-8 encoded [List<int>]. */
-  List<int> slowUtf8Bytes();
+  /**
+   * The content of the file represented as a UTF-8 encoded [List<int>],
+   * terminated with a trailing 0 byte.
+   */
+  List<int> slowUtf8ZeroTerminatedBytes();
 
   /**
    * The length of the string representation of this source file, i.e.,
@@ -168,17 +172,36 @@
   }
 }
 
+List<int> _zeroTerminateIfNecessary(List<int> bytes) {
+  if (bytes.length > 0 && bytes.last == 0) return bytes;
+  List<int> result = new Uint8List(bytes.length + 1);
+  result.setRange(0, bytes.length, bytes);
+  result[result.length - 1] = 0;
+  return result;
+}
+
 class Utf8BytesSourceFile extends SourceFile {
   final Uri uri;
 
   /** The UTF-8 encoded content of the source file. */
-  final List<int> content;
+  final List<int> zeroTerminatedContent;
 
-  Utf8BytesSourceFile(this.uri, this.content);
+  /**
+   * Creates a Utf8BytesSourceFile.
+   *
+   * If possible, the given [content] should be zero-terminated. If it isn't,
+   * the constructor clones the content and adds a trailing 0.
+   */
+  Utf8BytesSourceFile(this.uri, List<int> content)
+    : this.zeroTerminatedContent = _zeroTerminateIfNecessary(content);
 
-  String slowText() => UTF8.decode(content);
+  String slowText() {
+    // Don't convert the trailing zero byte.
+    return UTF8.decoder.convert(
+        zeroTerminatedContent, 0, zeroTerminatedContent.length - 1);
+  }
 
-  List<int> slowUtf8Bytes() => content;
+  List<int> slowUtf8ZeroTerminatedBytes() => zeroTerminatedContent;
 
   String slowSubstring(int start, int end) {
     // TODO(lry): to make this faster, the scanner could record the UTF-8 slack
@@ -230,7 +253,9 @@
 
   String slowText() => text;
 
-  List<int> slowUtf8Bytes() => UTF8.encode(text);
+  List<int> slowUtf8ZeroTerminatedBytes() {
+    return _zeroTerminateIfNecessary(UTF8.encode(text));
+  }
 
   String slowSubstring(int start, int end) => text.substring(start, end);
 }
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index 83611e2..e23b1cf 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -117,6 +117,7 @@
   /// or error case.
   String errorCodeName;
 
+  final String suggestedBodyName;
   /// The inner function that is scheduled to do each await/yield,
   /// and called to do a new iteration for sync*.
   js.VariableUse get body => new js.VariableUse(bodyName);
@@ -179,7 +180,8 @@
 
   AsyncRewriterBase(this.diagnosticListener,
                     spannable,
-                    this.safeVariableName)
+                    this.safeVariableName,
+                    this.suggestedBodyName)
       : _spannable = spannable;
 
   /// Initialize names used by the subClass.
@@ -199,7 +201,7 @@
     // generated after the analysis.
     resultName = freshName("result");
     errorCodeName = freshName("errorCode");
-    bodyName = freshName("body");
+    bodyName = freshName(suggestedBodyName);
     gotoName = freshName("goto");
     handlerName = freshName("handler");
     nextName = freshName("next");
@@ -1674,10 +1676,12 @@
                 spannable,
                 {this.asyncHelper,
                  this.newCompleter,
-                 safeVariableName})
+                 String safeVariableName(String proposedName),
+                 String bodyName})
         : super(diagnosticListener,
                 spannable,
-                safeVariableName);
+                safeVariableName,
+                bodyName);
 
   @override
   void addYield(js.DartYield node, js.Expression expression) {
@@ -1804,10 +1808,12 @@
                  this.newIterable,
                  this.yieldStarExpression,
                  this.uncaughtErrorExpression,
-                 safeVariableName})
+                 String safeVariableName(String proposedName),
+                 String bodyName})
         : super(diagnosticListener,
                 spannable,
-                safeVariableName);
+                safeVariableName,
+                bodyName);
 
   /// Translates a yield/yield* in an sync*.
   ///
@@ -1972,10 +1978,12 @@
                  this.newController,
                  this.yieldExpression,
                  this.yieldStarExpression,
-                 String safeVariableName(String original)})
+                 String safeVariableName(String proposedName),
+                 String bodyName})
         : super(diagnosticListener,
                 spannable,
-                safeVariableName);
+                safeVariableName,
+                bodyName);
 
 
   /// Translates a yield/yield* in an async* function.
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 0723cd1..3559724 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -26,38 +26,191 @@
  *   !canInline(function, insideLoop: true) implies !canInline(function)
  */
 class FunctionInlineCache {
-  final Map<FunctionElement, bool> canBeInlined =
-      new Map<FunctionElement, bool>();
+  static const int _unknown = -1;
+  static const int _mustNotInline = 0;
+  // May-inline-in-loop means that the function may not be inlined outside loops
+  // but may be inlined in a loop.
+  static const int _mayInlineInLoopMustNotOutside = 1;
+  // The function can be inlined in a loop, but not outside.
+  static const int _canInlineInLoopMustNotOutside = 2;
+  // May-inline means that we know that it can be inlined inside a loop, but
+  // don't know about the general case yet.
+  static const int _canInlineInLoopMayInlineOutside = 3;
+  static const int _canInline = 4;
+  static const int _mustInline = 5;
 
-  final Map<FunctionElement, bool> canBeInlinedInsideLoop =
-      new Map<FunctionElement, bool>();
+  final Map<FunctionElement, int> _cachedDecisions =
+      new Map<FunctionElement, int>();
 
-  // Returns [:true:]/[:false:] if we have a cached decision.
-  // Returns [:null:] otherwise.
+  // Returns `true`/`false` if we have a cached decision.
+  // Returns `null` otherwise.
   bool canInline(FunctionElement element, {bool insideLoop}) {
-    return insideLoop ? canBeInlinedInsideLoop[element] : canBeInlined[element];
+    int decision = _cachedDecisions[element];
+
+    if (decision == null) {
+      // These synthetic elements are not yet present when we initially compute
+      // this cache from metadata annotations, so look for their parent.
+      if (element is ConstructorBodyElement) {
+        ConstructorBodyElement body = element;
+        decision = _cachedDecisions[body.constructor];
+      }
+      if (decision == null) {
+        decision = _unknown;
+      }
+    }
+
+    if (insideLoop) {
+      switch (decision) {
+        case _mustNotInline:
+          return false;
+
+        case _unknown:
+        case _mayInlineInLoopMustNotOutside:
+          // We know we can't inline outside a loop, but don't know for the
+          // loop case. Return `null` to indicate that we don't know yet.
+          return null;
+
+        case _canInlineInLoopMustNotOutside:
+        case _canInlineInLoopMayInlineOutside:
+        case _canInline:
+        case _mustInline:
+          return true;
+      }
+    } else {
+      switch (decision) {
+        case _mustNotInline:
+        case _mayInlineInLoopMustNotOutside:
+        case _canInlineInLoopMustNotOutside:
+          return false;
+
+        case _unknown:
+        case _canInlineInLoopMayInlineOutside:
+          // We know we can inline inside a loop, but don't know for the
+          // non-loop case. Return `null` to indicate that we don't know yet.
+          return null;
+
+        case _canInline:
+        case _mustInline:
+          return true;
+      }
+    }
+
+    // Quiet static checker.
+    return null;
   }
 
   void markAsInlinable(FunctionElement element, {bool insideLoop}) {
+    int oldDecision = _cachedDecisions[element];
+
+    if (oldDecision == null) {
+      oldDecision = _unknown;
+    }
+
     if (insideLoop) {
-      canBeInlinedInsideLoop[element] = true;
+      switch (oldDecision) {
+        case _mustNotInline:
+          throw new SpannableAssertionFailure(element,
+              "Can't mark a function as non-inlinable and inlinable at the "
+              "same time.");
+
+        case _unknown:
+          // We know that it can be inlined in a loop, but don't know about the
+          // non-loop case yet.
+          _cachedDecisions[element] = _canInlineInLoopMayInlineOutside;
+          break;
+
+        case _mayInlineInLoopMustNotOutside:
+          _cachedDecisions[element] = _canInlineInLoopMustNotOutside;
+          break;
+
+        case _canInlineInLoopMustNotOutside:
+        case _canInlineInLoopMayInlineOutside:
+        case _canInline:
+        case _mustInline:
+          // Do nothing.
+          break;
+      }
     } else {
-      // If we can inline a function outside a loop then we should do it inside
-      // a loop as well.
-      canBeInlined[element] = true;
-      canBeInlinedInsideLoop[element] = true;
+      switch (oldDecision) {
+        case _mustNotInline:
+        case _mayInlineInLoopMustNotOutside:
+        case _canInlineInLoopMustNotOutside:
+          throw new SpannableAssertionFailure(element,
+              "Can't mark a function as non-inlinable and inlinable at the "
+              "same time.");
+
+        case _unknown:
+        case _canInlineInLoopMayInlineOutside:
+          _cachedDecisions[element] = _canInline;
+          break;
+
+        case _canInline:
+        case _mustInline:
+          // Do nothing.
+          break;
+
+      }
     }
   }
 
-  void markAsNonInlinable(FunctionElement element, {bool insideLoop}) {
-    if (insideLoop == null || insideLoop) {
-      // If we can't inline a function inside a loop, then we should not inline
-      // it outside a loop either.
-      canBeInlined[element] = false;
-      canBeInlinedInsideLoop[element] = false;
-    } else {
-      canBeInlined[element] = false;
+  void markAsNonInlinable(FunctionElement element, {bool insideLoop: true}) {
+    int oldDecision = _cachedDecisions[element];
+
+    if (oldDecision == null) {
+      oldDecision = _unknown;
     }
+
+    if (insideLoop) {
+      switch (oldDecision) {
+        case _canInlineInLoopMustNotOutside:
+        case _canInlineInLoopMayInlineOutside:
+        case _canInline:
+        case _mustInline:
+          throw new SpannableAssertionFailure(element,
+              "Can't mark a function as non-inlinable and inlinable at the "
+              "same time.");
+
+        case _mayInlineInLoopMustNotOutside:
+        case _unknown:
+          _cachedDecisions[element] = _mustNotInline;
+          break;
+
+        case _mustNotInline:
+          // Do nothing.
+          break;
+      }
+    } else {
+      switch (oldDecision) {
+        case _canInline:
+        case _mustInline:
+          throw new SpannableAssertionFailure(element,
+              "Can't mark a function as non-inlinable and inlinable at the "
+              "same time.");
+
+        case _unknown:
+          // We can't inline outside a loop, but we might still be allowed to do
+          // so outside.
+          _cachedDecisions[element] = _mayInlineInLoopMustNotOutside;
+          break;
+
+        case _canInlineInLoopMayInlineOutside:
+          // We already knew that the function could be inlined inside a loop,
+          // but didn't have information about the non-loop case. Now we know
+          // that it can't be inlined outside a loop.
+          _cachedDecisions[element] = _canInlineInLoopMustNotOutside;
+          break;
+
+        case _mayInlineInLoopMustNotOutside:
+        case _canInlineInLoopMustNotOutside:
+        case _mustNotInline:
+          // Do nothing.
+          break;
+      }
+    }
+  }
+
+  void markAsMustInline(FunctionElement element) {
+    _cachedDecisions[element] = _mustInline;
   }
 }
 
@@ -84,22 +237,10 @@
   static const String START_ROOT_ISOLATE = 'startRootIsolate';
 
 
-  /// The list of functions for classes in the [internalLibrary] that we want
-  /// to inline always.  Any function in this list must be inlinable with
-  /// respect to the conditions used in [InlineWeeder.canInline], except for
-  /// size/complexity heuristics.
-  static const Map<String, List<String>> ALWAYS_INLINE =
-      const <String, List<String>> {
-  };
-
   String get patchVersion => USE_NEW_EMITTER ? 'new' : 'old';
 
   final Annotations annotations = new Annotations();
 
-  /// List of [FunctionElement]s that we want to inline always.  This list is
-  /// filled when resolution is complete by looking up in [internalLibrary].
-  List<FunctionElement> functionsToAlwaysInline;
-
   /// Reference to the internal library to lookup functions to always inline.
   LibraryElement internalLibrary;
 
@@ -174,6 +315,7 @@
   ClassElement noSideEffectsClass;
   ClassElement noThrowsClass;
   ClassElement noInlineClass;
+  ClassElement forceInlineClass;
   ClassElement irRepresentationClass;
 
   Element getInterceptorMethod;
@@ -443,6 +585,9 @@
   /// constructors for custom elements.
   CustomElementsAnalysis customElementsAnalysis;
 
+  /// Support for classifying `noSuchMethod` implementations.
+  NoSuchMethodRegistry noSuchMethodRegistry;
+
   JavaScriptConstantTask constantCompilerTask;
 
   JavaScriptResolutionCallbacks resolutionCallbacks;
@@ -451,6 +596,8 @@
 
   bool get canHandleCompilationFailed => true;
 
+  bool enabledNoSuchMethod = false;
+
   JavaScriptBackend(Compiler compiler, bool generateSourceMap)
       : namer = determineNamer(compiler),
         oneShotInterceptors = new Map<String, Selector>(),
@@ -461,6 +608,7 @@
     emitter = new CodeEmitterTask(compiler, namer, generateSourceMap);
     typeVariableHandler = new TypeVariableHandler(this);
     customElementsAnalysis = new CustomElementsAnalysis(this);
+    noSuchMethodRegistry = new NoSuchMethodRegistry(this);
     constantCompilerTask = new JavaScriptConstantTask(compiler);
     resolutionCallbacks = new JavaScriptResolutionCallbacks(this);
     patchResolverTask = new PatchResolverTask(compiler);
@@ -560,7 +708,7 @@
    * Record that [method] is called from a subclass via `super`.
    */
   bool maybeRegisterAliasedSuperMember(Element member, Selector selector) {
-    if (selector.isGetter || compiler.hasIncrementalSupport) {
+    if (!canUseAliasedSuperMember(member, selector)) {
       // Invoking a super getter isn't supported, this would require changes to
       // compact field descriptors in the emitter.
       // We also turn off this optimization in incremental compilation, to
@@ -572,6 +720,10 @@
     return true;
   }
 
+  bool canUseAliasedSuperMember(Element member, Selector selector) {
+    return !selector.isGetter && !compiler.hasIncrementalSupport;
+  }
+
   /**
    * Returns `true` if [member] is called from a subclass via `super`.
    */
@@ -961,26 +1113,6 @@
     super.onResolutionComplete();
     computeMembersNeededForReflection();
     rti.computeClassesNeedingRti();
-    computeFunctionsToAlwaysInline();
-  }
-
-  void computeFunctionsToAlwaysInline() {
-    functionsToAlwaysInline = <FunctionElement>[];
-    if (internalLibrary == null) return;
-
-    // Try to find all functions intended to always inline.  If their enclosing
-    // class is not resolved we skip the methods, but it is an error to mention
-    // a function or class that cannot be found.
-    for (String className in ALWAYS_INLINE.keys) {
-      ClassElement cls = find(internalLibrary, className);
-      if (cls.resolutionState != STATE_DONE) continue;
-      for (String functionName in ALWAYS_INLINE[className]) {
-        Element function = cls.lookupMember(functionName);
-        assert(invariant(cls, function is FunctionElement,
-            message: 'unable to find function $functionName in $className'));
-        functionsToAlwaysInline.add(function);
-      }
-    }
   }
 
   void registerGetRuntimeTypeArgument(Registry registry) {
@@ -1084,11 +1216,13 @@
     enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, registry);
   }
 
-  void enableNoSuchMethod(Element context, Enqueuer world) {
+  void registerNoSuchMethod(Element noSuchMethod) {
+    noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod);
+  }
+
+  void enableNoSuchMethod(Enqueuer world) {
     enqueue(world, getCreateInvocationMirror(), compiler.globalDependencies);
     world.registerInvocation(compiler.noSuchMethodSelector);
-    // TODO(tyoverby): Send the context element to DumpInfoTask to be
-    // blamed.
   }
 
   void enableIsolateSupport(Enqueuer enqueuer) {
@@ -1141,13 +1275,8 @@
         compiler.enabledRuntimeType;
   }
 
-  bool isDefaultNoSuchMethodImplementation(Element element) {
-    assert(element.name == Compiler.NO_SUCH_METHOD);
-    ClassElement classElement = element.enclosingClass;
-    return classElement == compiler.objectClass
-        || classElement == jsInterceptorClass
-        || classElement == jsNullClass;
-  }
+  bool isComplexNoSuchMethod(FunctionElement element) =>
+    noSuchMethodRegistry.isComplex(element);
 
   bool isDefaultEqualityImplementation(Element element) {
     assert(element.name == '==');
@@ -1869,6 +1998,7 @@
         noSideEffectsClass = findClass('NoSideEffects');
         noThrowsClass = findClass('NoThrows');
         noInlineClass = findClass('NoInline');
+        forceInlineClass = findClass('ForceInline');
         irRepresentationClass = findClass('IrRepresentation');
 
         getIsolateAffinityTagMarker = findMethod('getIsolateAffinityTag');
@@ -2276,6 +2406,14 @@
     customElementsAnalysis.onQueueEmpty(enqueuer);
     if (!enqueuer.queueIsEmpty) return false;
 
+    noSuchMethodRegistry.onQueueEmpty();
+    if (!enabledNoSuchMethod &&
+        (noSuchMethodRegistry.hasThrowingNoSuchMethod ||
+         noSuchMethodRegistry.hasComplexNoSuchMethod)) {
+      enableNoSuchMethod(enqueuer);
+      enabledNoSuchMethod = true;
+    }
+
     if (compiler.hasIncrementalSupport) {
       // Always enable tear-off closures during incremental compilation.
       Element e = findHelper('closureFromTearOff');
@@ -2318,13 +2456,15 @@
   }
 
   void onElementResolved(Element element, TreeElements elements) {
-    if (element.isFunction && annotations.noInline(element)) {
+    if ((element.isFunction || element.isGenerativeConstructor) &&
+        annotations.noInline(element)) {
       inlineCache.markAsNonInlinable(element);
     }
 
     LibraryElement library = element.library;
     if (!library.isPlatformLibrary && !library.canUseNative) return;
     bool hasNoInline = false;
+    bool hasForceInline = false;
     bool hasNoThrows = false;
     bool hasNoSideEffects = false;
     for (MetadataAnnotation metadata in element.metadata) {
@@ -2332,7 +2472,15 @@
       if (!metadata.constant.value.isConstructedObject) continue;
       ObjectConstantValue value = metadata.constant.value;
       ClassElement cls = value.type.element;
-      if (cls == noInlineClass) {
+      if (cls == forceInlineClass) {
+        hasForceInline = true;
+        if (VERBOSE_OPTIMIZER_HINTS) {
+          compiler.reportHint(element,
+              MessageKind.GENERIC,
+              {'text': "Must inline"});
+        }
+        inlineCache.markAsMustInline(element);
+      } else if (cls == noInlineClass) {
         hasNoInline = true;
         if (VERBOSE_OPTIMIZER_HINTS) {
           compiler.reportHint(element,
@@ -2363,6 +2511,10 @@
         compiler.world.registerSideEffectsFree(element);
       }
     }
+    if (hasForceInline && hasNoInline) {
+      compiler.internalError(element,
+          "@ForceInline() must not be used with @NoInline.");
+    }
     if (hasNoThrows && !hasNoInline) {
       compiler.internalError(element,
           "@NoThrows() should always be combined with @NoInline.");
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index 9449644..f6c7e21 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -257,15 +257,27 @@
   @override
   js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) {
     checkStaticTargetIsValid(node, node.target);
-
-    if (node.target is! FunctionElement) {
-      giveup(node, 'static getters and setters are not supported.');
-    }
     Selector selector = node.selector;
-    FunctionElement target = node.target;
-    List<js.Expression> arguments = visitArguments(node.arguments);
-    return buildStaticInvoke(selector, target, arguments,
-        sourceInformation: node.sourceInformation);
+    if (node.target is FunctionElement) {
+      assert(selector.isGetter || selector.isSetter || selector.isCall);
+      FunctionElement target = node.target;
+      List<js.Expression> arguments = visitArguments(node.arguments);
+      return buildStaticInvoke(selector, target, arguments,
+          sourceInformation: node.sourceInformation);
+    } else {
+      assert(selector.isGetter || selector.isSetter);
+      FieldElement target = node.target;
+      registry.registerStaticUse(target);
+      js.Expression field = glue.staticFieldAccess(target);
+      if (selector.isGetter) {
+        assert(node.arguments.isEmpty);
+        return field;
+      } else {
+        assert(node.arguments.length == 1);
+        js.Expression value = visitExpression(node.arguments.first);
+        return new js.Assignment(field, value);
+      }
+    }
   }
 
   @override
@@ -331,12 +343,6 @@
   }
 
   @override
-  js.Expression visitReifyTypeVar(tree_ir.ReifyTypeVar node) {
-    return giveup(node);
-    // TODO: implement visitReifyTypeVar
-  }
-
-  @override
   js.Expression visitThis(tree_ir.This node) {
     return new js.This();
   }
@@ -407,7 +413,7 @@
 
   @override
   void visitAssign(tree_ir.Assign node) {
-    tree_ir.Expression value = node.definition;
+    tree_ir.Expression value = node.value;
     js.Expression definition = visitExpression(value);
 
     accumulator.add(new js.ExpressionStatement(new js.Assignment(
@@ -517,9 +523,47 @@
     visitStatement(node.next);
   }
 
+  js.Expression buildStaticHelperInvocation(FunctionElement helper,
+                                            List<js.Expression> arguments) {
+    registry.registerStaticUse(helper);
+    return buildStaticInvoke(new Selector.fromElement(helper), helper,
+        arguments);
+  }
+
+  @override
+  js.Expression visitReifyRuntimeType(tree_ir.ReifyRuntimeType node) {
+    FunctionElement createType = glue.getCreateRuntimeType();
+    FunctionElement typeToString = glue.getRuntimeTypeToString();
+    return buildStaticHelperInvocation(createType,
+        [buildStaticHelperInvocation(typeToString,
+            [visitExpression(node.value)])]);
+  }
+
+  @override
+  js.Expression visitReadTypeVariable(tree_ir.ReadTypeVariable node) {
+    ClassElement context = node.variable.element.enclosingClass;
+    js.Expression index = js.number(glue.getTypeVariableIndex(node.variable));
+    if (glue.needsSubstitutionForTypeVariableAccess(context)) {
+      js.Expression substitution = glue.getSubstitutionName(context);
+      return buildStaticHelperInvocation(
+          glue.getTypeArgumentWithSubstitution(),
+          [visitExpression(node.target), substitution, index]);
+    } else {
+      return buildStaticHelperInvocation(
+          glue.getTypeArgumentByIndex(),
+          [visitExpression(node.target), index]);
+    }
+  }
+
+
   // Dart-specific IR nodes
 
   @override
+  visitReifyTypeVar(tree_ir.ReifyTypeVar node) {
+    return errorUnsupportedNode(node);
+  }
+
+  @override
   visitFunctionExpression(tree_ir.FunctionExpression node) {
     return errorUnsupportedNode(node);
   }
@@ -539,7 +583,7 @@
     return errorUnsupportedNode(node);
   }
 
-  dynamic errorUnsupportedNode(tree_ir.DartSpecificNode node) {
+  errorUnsupportedNode(tree_ir.DartSpecificNode node) {
     throw "Unsupported node in JS backend: $node";
   }
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/glue.dart b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
index ebe8923..5dfd8de 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
@@ -11,6 +11,7 @@
 import '../../constants/values.dart';
 import '../../elements/elements.dart';
 import '../../constants/expressions.dart';
+import '../../dart_types.dart' show TypeVariableType;
 
 /// Encapsulates the dependencies of the function-compiler to the compiler,
 /// backend and emitter.
@@ -42,10 +43,14 @@
     return _backend.constants.getConstantForVariable(variable);
   }
 
-  js.Expression staticFunctionAccess(Element element) {
+  js.Expression staticFunctionAccess(FunctionElement element) {
     return _backend.emitter.staticFunctionAccess(element);
   }
 
+  js.Expression staticFieldAccess(FieldElement element) {
+    return _backend.emitter.staticFieldAccess(element);
+  }
+
   String safeVariableName(String name) {
     return _namer.safeVariableName(name);
   }
@@ -115,4 +120,38 @@
     return new js.VariableUse(
         _backend.namer.globalObjectFor(_backend.interceptorsLibrary));
   }
+
+  FunctionElement getCreateRuntimeType() {
+    return _backend.getCreateRuntimeType();
+  }
+
+  FunctionElement getRuntimeTypeToString() {
+    return _backend.getRuntimeTypeToString();
+  }
+
+  FunctionElement getTypeArgumentWithSubstitution() {
+    return _backend.getGetRuntimeTypeArgument();
+  }
+
+  FunctionElement getTypeArgumentByIndex() {
+    return _backend.getGetTypeArgumentByIndex();
+  }
+
+  js.Expression getSubstitutionName(ClassElement cls) {
+    return js.string(_namer.substitutionName(cls));
+  }
+
+  int getTypeVariableIndex(TypeVariableType variable) {
+    return RuntimeTypes.getTypeVariableIndex(variable.element);
+  }
+
+  bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
+    ClassWorld classWorld = _compiler.world;
+    if (classWorld.isUsedAsMixin(cls)) return true;
+
+    Iterable<ClassElement> subclasses = _compiler.world.strictSubclassesOf(cls);
+    return subclasses.any((ClassElement subclass) {
+      return !_backend.rti.isTrivialSubstitution(subclass, cls);
+    });
+  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/task.dart b/pkg/compiler/lib/src/js_backend/codegen/task.dart
index 0eb0685..db85809 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/task.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/task.dart
@@ -13,6 +13,8 @@
 import '../../dart2jslib.dart';
 import '../../cps_ir/cps_ir_nodes.dart' as cps;
 import '../../cps_ir/cps_ir_builder.dart';
+import '../../cps_ir/cps_ir_integrity.dart';
+import '../../cps_ir/cps_ir_builder_task.dart';
 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir;
 import '../../types/types.dart' show TypeMask, UnionTypeMask, FlatTypeMask,
     ForwardingTypeMask;
@@ -22,10 +24,13 @@
 import '../../tree_ir/tree_ir_builder.dart' as tree_builder;
 import '../../dart_backend/backend_ast_emitter.dart' as backend_ast_emitter;
 import '../../cps_ir/optimizers.dart';
+import '../../cps_ir/optimizers.dart' as cps_opt;
 import '../../tracer.dart';
 import '../../js_backend/codegen/codegen.dart';
 import '../../ssa/ssa.dart' as ssa;
 import '../../tree_ir/optimization/optimization.dart';
+import '../../tree_ir/optimization/optimization.dart' as tree_opt;
+import '../../tree_ir/tree_ir_integrity.dart';
 import '../../cps_ir/cps_ir_nodes_sexpr.dart';
 import 'js_tree_builder.dart';
 
@@ -135,36 +140,49 @@
     throw 'unsupported: $type';
   }
 
-  cps.FunctionDefinition optimizeCpsIR(cps.FunctionDefinition cpsNode) {
-    // Transformations on the CPS IR.
-
-    TypePropagator typePropagator = new TypePropagator<TypeMask>(
-        compiler.types,
-        constantSystem,
-        new TypeMaskSystem(compiler),
-        compiler.internalError);
-    typePropagator.rewrite(cpsNode);
-    traceGraph("Sparse constant propagation", cpsNode);
-
+  void dumpTypedIR(cps.FunctionDefinition cpsNode,
+                   TypePropagator<TypeMask> typePropagator) {
     if (PRINT_TYPED_IR_FILTER != null &&
         PRINT_TYPED_IR_FILTER.matchAsPrefix(cpsNode.element.name) != null) {
-      String printType(cps.Node node, String s) {
+      String printType(nodeOrRef, String s) {
+        cps.Node node = nodeOrRef is cps.Reference
+            ? nodeOrRef.definition
+            : nodeOrRef;
         var type = typePropagator.getType(node);
         return type == null ? s : "$s:${formatTypeMask(type.type)}";
       }
       DEBUG_MODE = true;
       print(new SExpressionStringifier(printType).visit(cpsNode));
     }
+  }
 
-    new RedundantPhiEliminator().rewrite(cpsNode);
-    traceGraph("Redundant phi elimination", cpsNode);
-    new ShrinkingReducer().rewrite(cpsNode);
-    traceGraph("Shrinking reductions", cpsNode);
+  static bool checkCpsIntegrity(cps.ExecutableDefinition node) {
+    new CheckCpsIntegrity().check(node);
+    return true; // So this can be used from assert().
+  }
+
+  cps.FunctionDefinition optimizeCpsIR(cps.FunctionDefinition cpsNode) {
+    // Transformations on the CPS IR.
+    void applyCpsPass(cps_opt.Pass pass) {
+      pass.rewrite(cpsNode);
+      traceGraph(pass.passName, cpsNode);
+      assert(checkCpsIntegrity(cpsNode));
+    }
+
+    TypePropagator typePropagator = new TypePropagator<TypeMask>(
+        compiler.types,
+        constantSystem,
+        new TypeMaskSystem(compiler),
+        compiler.internalError);
+    applyCpsPass(typePropagator);
+    dumpTypedIR(cpsNode, typePropagator);
+    applyCpsPass(new RedundantPhiEliminator());
+    applyCpsPass(new ShrinkingReducer());
 
     // Do not rewrite the IR after variable allocation.  Allocation
     // makes decisions based on an approximation of IR variable live
     // ranges that can be invalidated by transforming the IR.
-    new cps.RegisterAllocator().visit(cpsNode);
+    new cps.RegisterAllocator(compiler.internalError).visit(cpsNode);
     return cpsNode;
   }
 
@@ -174,23 +192,28 @@
     tree_ir.FunctionDefinition treeNode = builder.buildFunction(cpsNode);
     assert(treeNode != null);
     traceGraph('Tree builder', treeNode);
+    assert(checkTreeIntegrity(treeNode));
     return treeNode;
   }
 
-  tree_ir.FunctionDefinition optimizeTreeIR(
-      tree_ir.FunctionDefinition treeNode) {
-    // Transformations on the Tree IR.
-    new StatementRewriter().rewrite(treeNode);
-    traceGraph('Statement rewriter', treeNode);
-    new CopyPropagator().rewrite(treeNode);
-    traceGraph('Copy propagation', treeNode);
-    new LoopRewriter().rewrite(treeNode);
-    traceGraph('Loop rewriter', treeNode);
-    new LogicalRewriter().rewrite(treeNode);
-    traceGraph('Logical rewriter', treeNode);
-    new backend_ast_emitter.UnshadowParameters().unshadow(treeNode);
-    traceGraph('Unshadow parameters', treeNode);
-    return treeNode;
+  static bool checkTreeIntegrity(tree_ir.ExecutableDefinition node) {
+    new CheckTreeIntegrity().check(node);
+    return true; // So this can be used from assert().
+  }
+
+  tree_ir.FunctionDefinition optimizeTreeIR(tree_ir.FunctionDefinition node) {
+    void applyTreePass(tree_opt.Pass pass) {
+      pass.rewrite(node);
+      traceGraph(pass.passName, node);
+      assert(checkTreeIntegrity(node));
+    }
+
+    applyTreePass(new StatementRewriter());
+    applyTreePass(new CopyPropagator());
+    applyTreePass(new LoopRewriter());
+    applyTreePass(new LogicalRewriter());
+
+    return node;
   }
 
   js.Fun compileToJavaScript(CodegenWorkItem work,
diff --git a/pkg/compiler/lib/src/js_backend/js_backend.dart b/pkg/compiler/lib/src/js_backend/js_backend.dart
index daf1a71..c07946b 100644
--- a/pkg/compiler/lib/src/js_backend/js_backend.dart
+++ b/pkg/compiler/lib/src/js_backend/js_backend.dart
@@ -51,5 +51,6 @@
 part 'custom_elements_analysis.dart';
 part 'minify_namer.dart';
 part 'namer.dart';
+part 'no_such_method_registry.dart';
 part 'runtime_types.dart';
 part 'type_variable_handler.dart';
diff --git a/pkg/compiler/lib/src/js_backend/minify_namer.dart b/pkg/compiler/lib/src/js_backend/minify_namer.dart
index 579429e..45a10eb 100644
--- a/pkg/compiler/lib/src/js_backend/minify_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/minify_namer.dart
@@ -48,15 +48,6 @@
     return freshName;
   }
 
-  String getClosureVariableName(String _, int id) {
-    if (id < ALPHABET_CHARACTERS) {
-      return new String.fromCharCodes([_letterNumber(id)]);
-    }
-    // Fall back to a slightly longer name.
-    String basename = _disambiguateMember(null, 'closure');
-    return '${basename}_$id';
-  }
-
   // From issue 7554.  These should not be used on objects (as instance
   // variables) because they clash with names from the DOM. However, it is
   // OK to use them as fields, as we only access fields directly if we know
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index edc0a20..1dd4fc1 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -101,7 +101,7 @@
  * For local variables, the [Namer] only provides *proposed names*. These names
  * must be disambiguated elsewhere.
  */
-class Namer implements ClosureNamer {
+class Namer {
 
   static const List<String> javaScriptKeywords = const <String>[
     // These are current keywords.
@@ -332,6 +332,7 @@
   final String defaultValuesField = r'$defaultValues';
   final String methodsWithOptionalArgumentsField =
       r'$methodsWithOptionalArguments';
+  final String deferredAction = r'$deferredAction';
 
   final String classDescriptorProperty = r'^';
   final String requiredParameterField = r'$requiredArgCount';
@@ -417,6 +418,10 @@
       case JsGetName.GETTER_PREFIX: return getterPrefix;
       case JsGetName.SETTER_PREFIX: return setterPrefix;
       case JsGetName.CALL_PREFIX: return callPrefix;
+      case JsGetName.CALL_PREFIX0: return '${callPrefix}\$0';
+      case JsGetName.CALL_PREFIX1: return '${callPrefix}\$1';
+      case JsGetName.CALL_PREFIX2: return '${callPrefix}\$2';
+      case JsGetName.CALL_PREFIX3: return '${callPrefix}\$3';
       case JsGetName.CALL_CATCH_ALL: return callCatchAllName;
       case JsGetName.REFLECTABLE: return reflectableField;
       case JsGetName.CLASS_DESCRIPTOR_PROPERTY:
@@ -425,6 +430,7 @@
         return requiredParameterField;
       case JsGetName.DEFAULT_VALUES_PROPERTY: return defaultValuesField;
       case JsGetName.CALL_NAME_PROPERTY: return callNameField;
+      case JsGetName.DEFERRED_ACTION_PROPERTY: return deferredAction;
       default:
         compiler.reportError(
           node, MessageKind.GENERIC,
@@ -661,14 +667,24 @@
     ClassElement enclosingClass = element.enclosingClass;
 
     if (element.hasFixedBackendName) {
-      // Box fields and certain native fields must be given a specific name.
-      // Native names must not contain '$'. We rely on this to avoid clashes.
-      assert(element is BoxFieldElement ||
-          enclosingClass.isNative && !element.fixedBackendName.contains(r'$'));
+      // Certain native fields must be given a specific name. Native names must
+      // not contain '$'. We rely on this to avoid clashes.
+      assert(enclosingClass.isNative &&
+             !element.fixedBackendName.contains(r'$'));
 
       return element.fixedBackendName;
     }
 
+    // Instances of BoxFieldElement are special. They are already created with
+    // a unique and safe name. However, as boxes are not really instances of
+    // classes, the usual naming scheme that tries to avoid name clashes with
+    // super classes does not apply. We still do not mark the name as a
+    // fixedBackendName, as we want to allow other namers to do something more
+    // clever with them.
+    if (element is BoxFieldElement) {
+      return element.name;
+    }
+
     // If the name of the field might clash with another field,
     // use a mangled field name to avoid potential clashes.
     // Note that if the class extends a native class, that native class might
@@ -970,20 +986,6 @@
     return name;
   }
 
-  /// Generate a unique name for the [id]th closure variable, with proposed name
-  /// [name].
-  ///
-  /// The result is used as the name of [BoxFieldElement]s and
-  /// [ClosureFieldElement]s, and must therefore be unique to avoid breaking an
-  /// invariant in the element model (classes cannot declare multiple fields
-  /// with the same name).
-  ///
-  /// Since the result is used as an element name, it will later show up as a
-  /// *proposed name* when the element is passed to [instanceFieldPropertyName].
-  String getClosureVariableName(String name, int id) {
-    return "${name}_$id";
-  }
-
   /**
    * Returns a proposed name for the given top-level or static element.
    * The returned id is guaranteed to be a valid JS-id.
@@ -1347,7 +1349,6 @@
   String get incrementalHelperName => r'$dart_unsafe_incremental_support';
 
   jsAst.Expression get accessIncrementalHelper {
-    assert(compiler.hasIncrementalSupport);
     return js('self.${incrementalHelperName}');
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
new file mode 100644
index 0000000..70a7936
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
@@ -0,0 +1,183 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of js_backend;
+
+/**
+ * Categorizes `noSuchMethod` implementations.
+ *
+ * If user code includes `noSuchMethod` implementations, type inference is
+ * hindered because (for instance) any selector where the type of the
+ * receiver is not known all implementations of `noSuchMethod` must be taken
+ * into account when inferring the return type.
+ *
+ * The situation can be ameliorated with some heuristics for disregarding some
+ * `noSuchMethod` implementations during type inference. We can partition
+ * `noSuchMethod` implementations into 3 categories.
+ *
+ * Implementations in category A are the default implementations
+ * `Object.noSuchMethod` and `Interceptor.noSuchMethod`.
+ *
+ * Implementations in category B syntactically immediately throw, for example:
+ *
+ *     noSuchMethod(x) => throw 'not implemented'
+ *
+ * Implementations that do not fall into category A or B are in category C. They
+ * are the only category of implementation that are considered during type
+ * inference.
+ *
+ * Implementations that syntactically just forward to the super implementation,
+ * for example:
+ *
+ *     noSuchMethod(x) => super.noSuchMethod(x);
+ *
+ * are in the same category as the superclass implementation. This covers a
+ * common case, where users implement `noSuchMethod` with these dummy
+ * implementations to avoid warnings.
+ */
+class NoSuchMethodRegistry {
+  /// The implementations that fall into category A, described above.
+  final Set<FunctionElement> defaultImpls = new Set<FunctionElement>();
+  /// The implementations that fall into category B, described above.
+  final Set<FunctionElement> throwingImpls = new Set<FunctionElement>();
+  /// The implementations that fall into category C, described above.
+  final Set<Element> otherImpls = new Set<Element>();
+
+  /// The implementations that have not yet been categorized.
+  final Set<Element> _uncategorizedImpls = new Set<Element>();
+
+  final JavaScriptBackend _backend;
+  final Compiler _compiler;
+
+  NoSuchMethodRegistry(JavaScriptBackend backend)
+      : this._backend = backend,
+        this._compiler = backend.compiler;
+
+  bool get hasThrowingNoSuchMethod => throwingImpls.isNotEmpty;
+  bool get hasComplexNoSuchMethod => otherImpls.isNotEmpty;
+
+  void registerNoSuchMethod(Element noSuchMethodElement) {
+    _uncategorizedImpls.add(noSuchMethodElement);
+  }
+
+  void onQueueEmpty() {
+    _uncategorizedImpls.forEach(_categorizeImpl);
+    _uncategorizedImpls.clear();
+  }
+
+  /// Returns [true] if the given element is a complex [noSuchMethod]
+  /// implementation. An implementation is complex if it falls into
+  /// category C, as described above.
+  bool isComplex(FunctionElement element) {
+    assert(element.name == Compiler.NO_SUCH_METHOD);
+    return otherImpls.contains(element);
+  }
+
+  NsmCategory _categorizeImpl(Element noSuchMethodElement) {
+    assert(noSuchMethodElement.name == Compiler.NO_SUCH_METHOD);
+    if (defaultImpls.contains(noSuchMethodElement)) {
+      return NsmCategory.DEFAULT;
+    }
+    if (throwingImpls.contains(noSuchMethodElement)) {
+      return NsmCategory.THROWING;
+    }
+    if (otherImpls.contains(noSuchMethodElement)) {
+      return NsmCategory.OTHER;
+    }
+    if (noSuchMethodElement is! FunctionElement ||
+        !_compiler.noSuchMethodSelector.signatureApplies(noSuchMethodElement)) {
+      otherImpls.add(noSuchMethodElement);
+      return NsmCategory.OTHER;
+    }
+    FunctionElement noSuchMethodFunc = noSuchMethodElement as FunctionElement;
+    if (_isDefaultNoSuchMethodImplementation(noSuchMethodFunc)) {
+      defaultImpls.add(noSuchMethodFunc);
+      return NsmCategory.DEFAULT;
+    } else if (_hasForwardingSyntax(noSuchMethodFunc)) {
+      // If the implementation is 'noSuchMethod(x) => super.noSuchMethod(x);'
+      // then it is in the same category as the super call.
+      Element superCall = noSuchMethodFunc.enclosingClass
+          .lookupSuperSelector(_compiler.noSuchMethodSelector);
+      NsmCategory category = _categorizeImpl(superCall);
+      switch(category) {
+        case NsmCategory.DEFAULT:
+          defaultImpls.add(noSuchMethodFunc);
+          break;
+        case NsmCategory.THROWING:
+          throwingImpls.add(noSuchMethodFunc);
+          break;
+        case NsmCategory.OTHER:
+          otherImpls.add(noSuchMethodFunc);
+          break;
+      }
+      return category;
+    } else if (_hasThrowingSyntax(noSuchMethodFunc)) {
+      throwingImpls.add(noSuchMethodFunc);
+      return NsmCategory.THROWING;
+    } else {
+      otherImpls.add(noSuchMethodFunc);
+      return NsmCategory.OTHER;
+    }
+  }
+
+  bool _isDefaultNoSuchMethodImplementation(Element element) {
+    ClassElement classElement = element.enclosingClass;
+    return classElement == _compiler.objectClass
+        || classElement == _backend.jsInterceptorClass
+        || classElement == _backend.jsNullClass;
+  }
+
+  bool _hasForwardingSyntax(FunctionElement element) {
+    // At this point we know that this is signature-compatible with
+    // Object.noSuchMethod, but it may have more than one argument as long as
+    // it only has one required argument.
+    String param = element.parameters.first.name;
+    Statement body = element.node.body;
+    Expression expr;
+    if (body is Return && body.isArrowBody) {
+      expr = body.expression;
+    } else if (body is Block &&
+        !body.statements.isEmpty &&
+        body.statements.nodes.tail.isEmpty) {
+      Statement stmt = body.statements.nodes.head;
+      if (stmt is Return && stmt.hasExpression) {
+        expr = stmt.expression;
+      }
+    }
+    if (expr is Send &&
+        expr.isSuperCall &&
+        expr.selector is Identifier &&
+        (expr.selector as Identifier).source == Compiler.NO_SUCH_METHOD) {
+      var arg = expr.arguments.head;
+      if (expr.arguments.tail.isEmpty &&
+          arg is Send &&
+          arg.argumentsNode == null &&
+          arg.receiver == null &&
+          arg.selector is Identifier &&
+          arg.selector.source == param) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  bool _hasThrowingSyntax(FunctionElement element) {
+    Statement body = element.node.body;
+    if (body is Return && body.isArrowBody) {
+      if (body.expression is Throw) {
+        return true;
+      }
+    } else if (body is Block &&
+        !body.statements.isEmpty &&
+        body.statements.nodes.tail.isEmpty) {
+      if (body.statements.nodes.head is ExpressionStatement) {
+        ExpressionStatement stmt = body.statements.nodes.head;
+        return stmt.expression is Throw;
+      }
+    }
+    return false;
+  }
+}
+
+enum NsmCategory { DEFAULT, THROWING, OTHER }
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 4e8e368..8aefed6 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -663,7 +663,12 @@
       index++;
     }
     for (DartType type in types) {
-      elements.add(visit(type));
+      jsAst.Expression element = visit(type);
+      if (element is jsAst.LiteralNull) {
+        elements.add(new jsAst.ArrayHole());
+      } else {
+        elements.add(element);
+      }
     }
     return new jsAst.ArrayInitializer(elements);
   }
@@ -675,8 +680,7 @@
       properties.add(new jsAst.Property(js.string(name), value));
     }
 
-    jsAst.LiteralString name = js.string(namer.getFunctionTypeName(type));
-    addProperty(namer.functionTypeTag, name);
+    addProperty(namer.functionTypeTag, js.string(''));
     if (type.returnType.isVoid) {
       addProperty(namer.functionTypeVoidReturnTag, js('true'));
     } else if (!type.returnType.treatAsDynamic) {
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index 2a5ded5..8ff364d 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -20,9 +20,10 @@
     //        [ constructorName, fields,
     //            fields.map(
     //                (name) => js('this.# = #', [name, name]))]));
-    return js('function(#) { #; }',
+    return js('function(#) { #; this.#();}',
         [fields,
-         fields.map((name) => js('this.# = #', [name, name]))]);
+         fields.map((name) => js('this.# = #', [name, name])),
+         namer.deferredAction]);
   }
 
   jsAst.Expression generateGetter(Element member, String fieldName) {
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
index d92af17..38c4cda 100644
--- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -108,4 +108,4 @@
 part 'old_emitter/emitter.dart';
 part 'old_emitter/interceptor_emitter.dart';
 part 'old_emitter/nsm_emitter.dart';
-part 'old_emitter/reflection_data_parser.dart';
+part 'old_emitter/setup_program_builder.dart';
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index 5319a87..9876dac 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -9,12 +9,19 @@
   final Emitter _emitter;
 
   /// A list of JS expressions that represent metadata, parameter names and
-  /// type, and return types.
-  final List<String> globalMetadata = [];
+  /// type variable types.
+  final List<String> globalMetadata = <String>[];
 
   /// A map used to canonicalize the entries of globalMetadata.
   final Map<String, int> _globalMetadataMap = <String, int>{};
 
+  /// A list of JS expression representing types including function types and
+  /// typedefs.
+  final List<String> types = <String>[];
+
+  /// A map used to canonicalize the entries of types.
+  final Map<String, int> _typesMap = <String, int>{};
+
   MetadataCollector(this._compiler, this._emitter);
 
   JavaScriptBackend get _backend => _compiler.backend;
@@ -96,7 +103,7 @@
               return _backend.isAccessibleByReflection(typedef.element);
             });
 
-    return addGlobalMetadata(
+    return addType(
         jsAst.prettyPrint(representation, _compiler).getText());
   }
 
@@ -111,6 +118,13 @@
     });
   }
 
+  int addType(String compiledType) {
+    return _typesMap.putIfAbsent(compiledType, () {
+      types.add(compiledType);
+      return types.length - 1;
+    });
+  }
+
   List<int> computeMetadata(FunctionElement element) {
     return _compiler.withCurrentElement(element, () {
       if (!_mustEmitMetadataFor(element)) return const <int>[];
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index 4e19d86..5a49cf1 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -55,6 +55,18 @@
   /// data.
   List<String> get metadata => _metadataCollector.globalMetadata;
 
+  /// A list of pretty-printed JavaScript expressions.
+  ///
+  /// This list must be emitted in the `TYPES` embedded global.
+  /// The list references constants and must hence be emitted after constants
+  /// have been initialized.
+  ///
+  /// Note: the metadata is derived from the task's `metadataCollector`. The
+  /// list must not be emitted before all operations on it are done. For
+  /// example, the old emitter generates metadata when emitting reflection
+  /// data.
+  List<String> get metadataTypes => _metadataCollector.types;
+
   bool get isSplit => fragments.length > 1;
   Iterable<Fragment> get deferredFragments => fragments.skip(1);
 }
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
index 9afa419..32c5a63 100644
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
@@ -29,7 +29,8 @@
     LEAF_TAGS,
     MANGLED_GLOBAL_NAMES,
     METADATA,
-    TYPE_TO_INTERCEPTOR_MAP;
+    TYPE_TO_INTERCEPTOR_MAP,
+    TYPES;
 
 import '../js_emitter.dart' show NativeGenerator, buildTearOffCode;
 import '../model.dart';
@@ -117,8 +118,8 @@
     if (isConstantInlinedOrAlreadyEmitted(value)) {
       return constantEmitter.generate(value);
     }
-    return js.js('#.#', [namer.globalObjectForConstant(value),
-                         namer.constantName(value)]);
+    return js.js('#.#()', [namer.globalObjectForConstant(value),
+                           namer.constantName(value)]);
   }
 
   int emitProgram(Program program) {
@@ -153,6 +154,11 @@
   js.LiteralString unparse(Compiler compiler, js.Node value) {
     String text = js.prettyPrint(value, compiler).getText();
     if (value is js.Fun) text = '($text)';
+    if (value is js.LiteralExpression &&
+        (value.template.startsWith("function ") ||
+         value.template.startsWith("{"))) {
+      text = '($text)';
+    }
     return js.js.escapedString(text);
   }
 
@@ -167,6 +173,8 @@
     List<js.Expression> elements = fragment.libraries.map(emitLibrary).toList();
     elements.add(
         emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
+    elements.add(emitConstants(fragment.constants));
+
 
     js.Expression code = new js.ArrayInitializer(elements);
 
@@ -184,7 +192,6 @@
            backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()),
        'outputContainsConstantList': program.outputContainsConstantList,
        'embeddedGlobals': emitEmbeddedGlobals(program),
-       'constants': emitConstants(fragment.constants),
        'staticNonFinals':
             emitStaticNonFinalFields(fragment.staticNonFinalFields),
        'operatorIsPrefix': js.string(namer.operatorIsPrefix),
@@ -290,7 +297,7 @@
 
     globals.add(emitGetTypeFromName());
 
-    globals.add(emitMetadata(program));
+    globals.addAll(emitMetadata(program));
 
     if (program.needsNativeSupport) {
       globals.add(new js.Property(js.string(INTERCEPTORS_BY_TAG),
@@ -401,12 +408,21 @@
     return new js.Property(js.string(GET_TYPE_FROM_NAME), function);
   }
 
-  js.Property emitMetadata(Program program) {
-    String metadataList = "[${program.metadata.join(",")}]";
-    js.Expression metadata =
-        js.js.uncachedExpressionTemplate(metadataList).instantiate([]);
+  List<js.Property> emitMetadata(Program program) {
 
-    return new js.Property(js.string(METADATA), metadata);
+    List<js.Property> metadataGlobals = <js.Property>[];
+
+    js.Property createGlobal(List<String> list, String global) {
+      String listAsString = "[${list.join(",")}]";
+      js.Expression metadata =
+                js.js.uncachedExpressionTemplate(listAsString).instantiate([]);
+      return new js.Property(js.string(global), metadata);
+    }
+
+    metadataGlobals.add(createGlobal(program.metadata, METADATA));
+    metadataGlobals.add(createGlobal(program.metadataTypes, TYPES));
+
+    return metadataGlobals;
   }
 
   js.Expression emitDeferredFragment(DeferredFragment fragment,
@@ -421,16 +437,14 @@
     deferredCode.add(
         emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
 
+    deferredCode.add(emitConstants(fragment.constants));
+
     js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode);
 
     // This is the code that must be evaluated after all deferred classes have
     // been setup.
-    js.Statement immediateCode = js.js.statement('''{
-          #constants;
-          #eagerClasses;
-        }''',
-        {'constants': emitConstants(fragment.constants),
-         'eagerClasses': emitEagerClassInitializations(fragment.libraries)});
+    js.Statement immediateCode =
+        emitEagerClassInitializations(fragment.libraries);
 
     js.LiteralString immediateString = unparse(compiler, immediateCode);
     js.ArrayInitializer hunk =
@@ -439,13 +453,25 @@
     return js.js("$deferredInitializersGlobal[$hash] = #", hunk);
   }
 
-  js.Block emitConstants(List<Constant> constants) {
-    Iterable<js.Statement> statements = constants.map((Constant constant) {
-      js.Expression code = constantEmitter.generate(constant.value);
-      return js.js.statement("#.# = #;",
-                             [constant.holder.name, constant.name, code]);
-    });
-    return new js.Block(statements.toList());
+  // This string should be referenced wherever JavaScript code makes assumptions
+  // on the constants format.
+  static final String constantsDescription =
+      "The constants are encoded as a follows:"
+      "   [constantsHolderIndex, name, code, name2, code2, ...]."
+      "The array is completely empty if there is no constant at all.";
+
+  js.ArrayInitializer emitConstants(List<Constant> constants) {
+    List<js.Expression> data = <js.Expression>[];
+    if (constants.isNotEmpty) {
+      int holderIndex = constants.first.holder.index;
+      data.add(js.number(holderIndex));
+      data.addAll(constants.expand((Constant constant) {
+        assert(constant.holder.index == holderIndex);
+        js.Expression code = constantEmitter.generate(constant.value);
+        return [js.string(constant.name), unparse(compiler, code)];
+      }));
+    }
+    return new js.ArrayInitializer(data);
   }
 
   js.Block emitStaticNonFinalFields(List<StaticField> fields) {
@@ -814,10 +840,11 @@
   var functionCounter = 0;
 
   function $setupProgramName(program) {
-    for (var i = 0; i < program.length - 1; i++) {
+    for (var i = 0; i < program.length - 2; i++) {
       setupLibrary(program[i]);
     }
     setupLazyStatics(program[i]);
+    setupConstants(program[i + 1]);
   }
 
   function setupLibrary(library) {
@@ -863,11 +890,29 @@
     }
   }
 
+  function setupConstants(constants) {
+    // $constantsDescription.
+    if (constants.length == 0) return;
+    // We assume that all constants are in the same holder.
+    var holder = holders[constants[0]];
+    for (var i = 1; i < constants.length; i += 2) {
+      var name = constants[i];
+      var initializer = constants[i + 1];
+      setupConstant(name, holder, initializer);
+    }
+  }
+
   function setupStatic(name, holder, descriptor) {
     if (typeof descriptor == 'string') {
       holder[name] = function() {
+        if (descriptor == null) {
+          // Already compiled. This happens when we have calls to the static as
+          // arguments to the static: `foo(foo(499))`;
+          return holder[name].apply(this, arguments);
+        }
         var method = compile(name, descriptor);
         holder[name] = method;
+        descriptor = null;  // GC the descriptor.
         return method.apply(this, arguments);
       };
     } else {
@@ -902,7 +947,13 @@
 
       function setupCompileAllAndDelegateStub(name) {
         holder[name] = function() {
-          compileAllStubs();
+          // The descriptor is null if we already compiled this function. This
+          // happens when we have calls to the static as arguments to the
+          // static: `foo(foo(499))`;
+          if (descriptor != null) {
+            compileAllStubs();
+            descriptor = null;  // GC the descriptor.
+          }
           return holder[name].apply(this, arguments);
         };
       }
@@ -935,18 +986,44 @@
           // initialization failed.
           holder[name] = null;
         }
+        // TODO(floitsch): the function should probably be unique for each
+        // static.
         holder[getterName] = function() { return this[name]; };
       }
       return result;
     };
   }
 
+  function setupConstant(name, holder, descriptor) {
+    var c;
+    holder[name] = function() {
+      if (descriptor !== null) {
+        c = compile(name, descriptor);
+        name = null;
+        descriptor = null;
+      }
+      return c;
+    };
+  }
+
   function setupClass(name, holder, descriptor) {
     var patch = function() {
-      var constructor = compileConstructor(name, descriptor);
-      holder[name] = constructor;
-      constructor.ensureResolved = function() { return this; };
-      if (this === patch) return constructor;  // Was used as "ensureResolved".
+      if (patch.ensureResolved == patch) {
+        // We have not yet been compiled.
+        var constructor = compileConstructor(name, descriptor);
+        holder[name] = constructor;
+        name = holder = descriptor = null;  // GC the captured arguments.
+        // Make sure we can invoke 'ensureResolved' multiple times on the patch
+        // function.
+        patch.ensureResolved = function() { return constructor; };
+        constructor.ensureResolved = function() { return this; };
+      } else {
+        // This can happen when arguments to the constructor are of the same
+        // class, like in `new A(new A(null))`.
+        constructor = patch.ensureResolved();
+      }
+      // If the patch has been called as "ensureResolved" return.
+      if (this === patch) return constructor;
       var object = new constructor();
       constructor.apply(object, arguments);
       return object;
@@ -1051,9 +1128,6 @@
 
   $setupProgramName(program);
 
-  // Initialize constants.
-  #constants;
-
   // Initialize globals.
   #embeddedGlobals;
 
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
index d56dbb4..41ddf84 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
@@ -243,7 +243,7 @@
     }
 
     if (identical(classElement, compiler.objectClass)
-        && compiler.enabledNoSuchMethod) {
+        && backend.enabledNoSuchMethod) {
       // Emit the noSuchMethod handlers on the Object prototype now,
       // so that the code in the dynamicFunction helper can find
       // them. Note that this helper is invoked before analyzing the
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
index 1ee6e57..0a8e2d1 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
@@ -273,311 +273,20 @@
     return nsmEmitter.buildTrivialNsmHandlers();
   }
 
-  jsAst.FunctionDeclaration get generateAccessorFunction {
-    const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1;
-    const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1;
-    const RANGE1_ADJUST = - (FIRST_FIELD_CODE - RANGE1_FIRST);
-    const RANGE2_ADJUST = - (FIRST_FIELD_CODE + RANGE1_SIZE - RANGE2_FIRST);
-    const RANGE3_ADJUST =
-        - (FIRST_FIELD_CODE + RANGE1_SIZE + RANGE2_SIZE - RANGE3_FIRST);
-
-    String receiverParamName = compiler.enableMinification ? "r" : "receiver";
-    String valueParamName = compiler.enableMinification ? "v" : "value";
-    String reflectableField = namer.reflectableField;
-
-    return js.statement('''
-      function generateAccessor(fieldDescriptor, accessors, cls) {
-        var fieldInformation = fieldDescriptor.split("-");
-        var field = fieldInformation[0];
-        var len = field.length;
-        var code = field.charCodeAt(len - 1);
-        var reflectable;
-        if (fieldInformation.length > 1) reflectable = true;
-             else reflectable = false;
-        code = ((code >= $RANGE1_FIRST) && (code <= $RANGE1_LAST))
-              ? code - $RANGE1_ADJUST
-              : ((code >= $RANGE2_FIRST) && (code <= $RANGE2_LAST))
-                ? code - $RANGE2_ADJUST
-                : ((code >= $RANGE3_FIRST) && (code <= $RANGE3_LAST))
-                  ? code - $RANGE3_ADJUST
-                  : $NO_FIELD_CODE;
-
-        if (code) {  // needsAccessor
-          var getterCode = code & 3;
-          var setterCode = code >> 2;
-          var accessorName = field = field.substring(0, len - 1);
-
-          var divider = field.indexOf(":");
-          if (divider > 0) { // Colon never in first position.
-            accessorName = field.substring(0, divider);
-            field = field.substring(divider + 1);
-          }
-
-          if (getterCode) {  // needsGetter
-            var args = (getterCode & 2) ? "$receiverParamName" : "";
-            var receiver = (getterCode & 1) ? "this" : "$receiverParamName";
-            var body = "return " + receiver + "." + field;
-            var property =
-                cls + ".prototype.${namer.getterPrefix}" + accessorName + "=";
-            var fn = "function(" + args + "){" + body + "}";
-            if (reflectable)
-              accessors.push(property + "\$reflectable(" + fn + ");\\n");
-            else
-              accessors.push(property + fn + ";\\n");
-          }
-
-          if (setterCode) {  // needsSetter
-            var args = (setterCode & 2)
-                ? "$receiverParamName,${_}$valueParamName"
-                : "$valueParamName";
-            var receiver = (setterCode & 1) ? "this" : "$receiverParamName";
-            var body = receiver + "." + field + "$_=$_$valueParamName";
-            var property =
-                cls + ".prototype.${namer.setterPrefix}" + accessorName + "=";
-            var fn = "function(" + args + "){" + body + "}";
-            if (reflectable)
-              accessors.push(property + "\$reflectable(" + fn + ");\\n");
-            else
-              accessors.push(property + fn + ";\\n");
-          }
-        }
-
-        return field;
-      }''');
+  jsAst.Statement buildNativeInfoHandler(
+      jsAst.Expression infoAccess,
+      jsAst.Expression constructorAccess,
+      jsAst.Expression subclassReadGenerator(jsAst.Expression subclass),
+      jsAst.Expression interceptorsByTagAccess,
+      jsAst.Expression leafTagsAccess) {
+    return nativeEmitter.buildNativeInfoHandler(infoAccess, constructorAccess,
+                                                subclassReadGenerator,
+                                                interceptorsByTagAccess,
+                                                leafTagsAccess);
   }
 
-  List<jsAst.Node> get defineClassFunction {
-    // First the class name, then the field names in an array and the members
-    // (inside an Object literal).
-    // The caller can also pass in the constructor as a function if needed.
-    //
-    // Example:
-    // defineClass("A", ["x", "y"], {
-    //  foo$1: function(y) {
-    //   print(this.x + y);
-    //  },
-    //  bar$2: function(t, v) {
-    //   this.x = t - v;
-    //  },
-    // });
-
-    bool hasIsolateSupport = compiler.hasIsolateSupport;
-    String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
-
-    jsAst.Expression defineClass = js(r'''
-        function(name, fields) {
-          var accessors = [];
-
-          var str = "function " + name + "(";
-          var body = "";
-          if (#hasIsolateSupport) { var fieldNames = ""; }
-
-          for (var i = 0; i < fields.length; i++) {
-            if(i != 0) str += ", ";
-
-            var field = generateAccessor(fields[i], accessors, name);
-            if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; }
-            var parameter = "parameter_" + field;
-            str += parameter;
-            body += ("this." + field + " = " + parameter + ";\n");
-          }
-          str += ") {\n" + body + "}\n";
-          str += name + ".builtin$cls=\"" + name + "\";\n";
-          str += "$desc=$collectedClasses." + name + ";\n";
-          str += "if($desc instanceof Array) $desc = \$desc[1];\n";
-          str += name + ".prototype = $desc;\n";
-          if (typeof defineClass.name != "string") {
-            str += name + ".name=\"" + name + "\";\n";
-          }
-          if (#hasIsolateSupport) {
-            str += name + "." + #fieldNamesProperty + "=[" + fieldNames
-                   + "];\n";
-          }
-          str += accessors.join("");
-
-          return str;
-        }''', { 'hasIsolateSupport': hasIsolateSupport,
-                'fieldNamesProperty': js.string(fieldNamesProperty)});
-
-    // Declare a function called "generateAccessor".  This is used in
-    // defineClassFunction.
-    List result = <jsAst.Node>[
-        generateAccessorFunction,
-        new jsAst.FunctionDeclaration(
-            new jsAst.VariableDeclaration('defineClass'), defineClass) ];
-
-    if (compiler.hasIncrementalSupport) {
-      result.add(
-          js(r'#.defineClass = defineClass', [namer.accessIncrementalHelper]));
-    }
-
-    if (hasIsolateSupport) {
-      jsAst.Expression createNewIsolateFunctionAccess =
-          generateEmbeddedGlobalAccess(embeddedNames.CREATE_NEW_ISOLATE);
-      var createIsolateAssignment =
-          js('# = function() { return new ${namer.isolateName}(); }',
-             createNewIsolateFunctionAccess);
-
-      jsAst.Expression classIdExtractorAccess =
-          generateEmbeddedGlobalAccess(embeddedNames.CLASS_ID_EXTRACTOR);
-      var classIdExtractorAssignment =
-          js('# = function(o) { return o.constructor.name; }',
-              classIdExtractorAccess);
-
-      jsAst.Expression classFieldsExtractorAccess =
-          generateEmbeddedGlobalAccess(embeddedNames.CLASS_FIELDS_EXTRACTOR);
-      var classFieldsExtractorAssignment = js('''
-      # = function(o) {
-        var fieldNames = o.constructor.$fieldNamesProperty;
-        if (!fieldNames) return [];  // TODO(floitsch): do something else here.
-        var result = [];
-        result.length = fieldNames.length;
-        for (var i = 0; i < fieldNames.length; i++) {
-          result[i] = o[fieldNames[i]];
-        }
-        return result;
-      }''', classFieldsExtractorAccess);
-
-      jsAst.Expression instanceFromClassIdAccess =
-          generateEmbeddedGlobalAccess(embeddedNames.INSTANCE_FROM_CLASS_ID);
-      jsAst.Expression allClassesAccess =
-          generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
-      var instanceFromClassIdAssignment =
-          js('# = function(name) { return new #[name](); }',
-             [instanceFromClassIdAccess, allClassesAccess]);
-
-      jsAst.Expression initializeEmptyInstanceAccess =
-          generateEmbeddedGlobalAccess(embeddedNames.INITIALIZE_EMPTY_INSTANCE);
-      var initializeEmptyInstanceAssignment = js('''
-      # = function(name, o, fields) {
-        #[name].apply(o, fields);
-        return o;
-      }''', [ initializeEmptyInstanceAccess, allClassesAccess ]);
-
-      result.addAll([createIsolateAssignment,
-                     classIdExtractorAssignment,
-                     classFieldsExtractorAssignment,
-                     instanceFromClassIdAssignment,
-                     initializeEmptyInstanceAssignment]);
-    }
-
-    return result;
-  }
-
-  /** Needs defineClass to be defined. */
-  jsAst.Expression buildInheritFrom() {
-    jsAst.Expression result = js(r"""
-        function() {
-          function tmp() {}
-          return function (constructor, superConstructor) {
-            if (superConstructor == null) {
-              // Fix up the the Dart Object class' prototype.
-              var prototype = constructor.prototype;
-              prototype.constructor = constructor;
-              prototype.#isObject = constructor;
-              return prototype;
-            }
-            tmp.prototype = superConstructor.prototype;
-            var object = new tmp();
-            var properties = constructor.prototype;
-            var members = Object.keys(properties);
-            for (var i = 0; i < members.length; i++) {
-              var member = members[i];
-              object[member] = properties[member];
-            }
-            // Use a function for `true` here, as functions are stored in the
-            // hidden class and not as properties in the object.
-            object[#operatorIsPrefix + constructor.name] = constructor;
-            object.constructor = constructor;
-            constructor.prototype = object;
-            return object;
-          };
-        }()
-      """, { 'operatorIsPrefix' : js.string(namer.operatorIsPrefix),
-             'isObject' : namer.operatorIs(compiler.objectClass) });
-    if (compiler.hasIncrementalSupport) {
-      result = js(
-          r'#.inheritFrom = #', [namer.accessIncrementalHelper, result]);
-    }
-    return js(r'var inheritFrom = #', [result]);
-  }
-
-  jsAst.Statement buildFinishClass(bool needsNativeSupport) {
-    String specProperty = '"${namer.nativeSpecProperty}"';  // "%"
-
-    jsAst.Expression finishedClassesAccess =
-        generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES);
-
-    jsAst.Expression nativeInfoAccess = js('prototype[$specProperty]', []);
-    jsAst.Expression constructorAccess = js('constructor', []);
-    Function subclassReadGenerator =
-        (jsAst.Expression subclass) => js('allClasses[#]', subclass);
-    jsAst.Expression interceptorsByTagAccess =
-        generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG);
-    jsAst.Expression leafTagsAccess =
-        generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS);
-    jsAst.Statement nativeInfoHandler = nativeEmitter.buildNativeInfoHandler(
-        nativeInfoAccess,
-        constructorAccess,
-        subclassReadGenerator,
-        interceptorsByTagAccess,
-        leafTagsAccess);
-
-    return js.statement('''
-    {
-      var finishedClasses = #finishedClassesAccess;
-
-      function finishClass(cls) {
-
-        if (finishedClasses[cls]) return;
-        finishedClasses[cls] = true;
-
-        var superclass = processedClasses.pending[cls];
-
-        if (#needsMixinSupport) {
-          if (superclass && superclass.indexOf("+") > 0) {
-            var s = superclass.split("+");
-            superclass = s[0];
-            var mixinClass = s[1];
-            finishClass(mixinClass);
-            var mixin = allClasses[mixinClass];
-            var mixinPrototype = mixin.prototype;
-            var clsPrototype = allClasses[cls].prototype;
-
-            var properties = Object.keys(mixinPrototype);
-            for (var i = 0; i < properties.length; i++) {
-              var d = properties[i];
-              if (!hasOwnProperty.call(clsPrototype, d))
-                clsPrototype[d] = mixinPrototype[d];
-            }
-          }
-        }
-
-        // The superclass is only false (empty string) for the Dart Object
-        // class.  The minifier together with noSuchMethod can put methods on
-        // the Object.prototype object, and they show through here, so we check
-        // that we have a string.
-        if (!superclass || typeof superclass != "string") {
-          inheritFrom(allClasses[cls], null);
-          return;
-        }
-        finishClass(superclass);
-        var superConstructor = allClasses[superclass];
-
-        if (!superConstructor)
-          superConstructor = existingIsolateProperties[superclass];
-
-        var constructor = allClasses[cls];
-        var prototype = inheritFrom(constructor, superConstructor);
-
-        if (#needsNativeSupport)
-          if (Object.prototype.hasOwnProperty.call(prototype, $specProperty))
-            #nativeInfoHandler
-      }
-    }''', {'finishedClassesAccess': finishedClassesAccess,
-           'needsMixinSupport': needsMixinSupport,
-           'needsNativeSupport': needsNativeSupport,
-           'nativeInfoHandler': nativeInfoHandler});
+  jsAst.ObjectInitializer generateInterceptedNamesSet() {
+    return interceptorEmitter.generateInterceptedNamesSet();
   }
 
   void emitFinishIsolateConstructorInvocation(CodeOutput output) {
@@ -851,21 +560,26 @@
             code]);
   }
 
-  void emitMetadata(List<String> globalMetadata, CodeOutput output) {
-    String metadataAccess =
-        generateEmbeddedGlobalAccessString(embeddedNames.METADATA);
-    output.add('$metadataAccess$_=$_[');
-    for (String metadata in globalMetadata) {
-      if (metadata is String) {
-        if (metadata != 'null') {
-          output.add(metadata);
-        }
-      } else {
-        throw 'Unexpected value in metadata: ${Error.safeToString(metadata)}';
-      }
-      output.add(',$n');
-    }
-    output.add('];$n');
+  void emitMetadata(Program program, CodeOutput output) {
+
+   addMetadataGlobal(List<String> list, String global) {
+     String globalAccess = generateEmbeddedGlobalAccessString(global);
+     output.add('$globalAccess$_=$_[');
+     for (String data in list) {
+       if (data is String) {
+         if (data != 'null') {
+           output.add(data);
+         }
+       } else {
+         throw 'Unexpected value in ${global}: ${Error.safeToString(data)}';
+       }
+       output.add(',$n');
+     }
+     output.add('];$n');
+   }
+
+   addMetadataGlobal(program.metadata, embeddedNames.METADATA);
+   addMetadataGlobal(program.metadataTypes, embeddedNames.TYPES);
   }
 
   void emitCompileTimeConstants(CodeOutput output,
@@ -1095,6 +809,20 @@
     }
   }
 
+  String get markerFun => 'markerFun';
+
+  void emitMarkerFun(CodeOutput output) {
+    jsAst.Statement markerFunStmt = js.statement('''
+      // This function is used to mark the end of the inheritance chain so that
+      // finishAddStubsHelper knows where to stop searching for deferred work.
+      // We have to put it at the top level so that we only get one instance of
+      // it even if we call parseReflectionData multiple times, e.g., due to 
+      // deferred loading.
+      function #() {}''', markerFun);
+    output.addBuffer(jsAst.prettyPrint(markerFunStmt, compiler));
+    output.add(N);
+  }
+
   void emitConvertToFastObjectFunction(CodeOutput output) {
     List<jsAst.Statement> debugCode = <jsAst.Statement>[];
     if (DEBUG_FAST_OBJECTS) {
@@ -1126,7 +854,44 @@
     output.add(N);
   }
 
-  void writeLibraryDescriptors(CodeOutput output, LibraryElement library) {
+  void emitConvertToSlowObjectFunction(CodeOutput output) {
+    jsAst.Statement convertToSlowObject = js.statement(r'''
+    function convertToSlowObject(properties) {
+      // Add and remove a property to make the object transition into hashmap
+      // mode.
+      properties.__MAGIC_SLOW_PROPERTY = 1;
+      delete properties.__MAGIC_SLOW_PROPERTY;
+      return properties;
+    }''');
+
+    output.addBuffer(jsAst.prettyPrint(convertToSlowObject, compiler));
+    output.add(N);
+  }
+
+  void emitSupportsDirectProtoAccess(CodeOutput output) {
+    jsAst.Statement supportsDirectProtoAccess;
+
+    if (compiler.hasIncrementalSupport) {
+      supportsDirectProtoAccess = js.statement(r'''
+        var supportsDirectProtoAccess = false;
+      ''');
+    } else {
+      supportsDirectProtoAccess = js.statement(r'''
+        var supportsDirectProtoAccess = (function () {
+          var cls = function () {};
+          cls.prototype = {'p': {}};
+          var object = new cls();
+          return object.__proto__ &&
+                 object.__proto__.p === cls.prototype.p;
+         })();
+      ''');
+    }
+
+    output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler));
+    output.add(N);
+  }
+
+  void writeLibraryDescriptor(CodeOutput output, LibraryElement library) {
     var uri = "";
     if (!compiler.enableMinification || backend.mustPreserveUris) {
       uri = library.canonicalUri;
@@ -1191,8 +956,7 @@
           #constructorName.builtin$cls = #constructorNameString;
           if (!"name" in #constructorName)
               #constructorName.name = #constructorNameString;
-          $desc = $collectedClasses.#constructorName;
-          if ($desc instanceof Array) $desc = $desc[1];
+          $desc = $collectedClasses.#constructorName[1];
           #constructorName.prototype = $desc;
           ''' /* next string is not a raw string */ '''
           if (#hasIsolateSupport) {
@@ -1355,6 +1119,7 @@
     // Using a named function here produces easier to read stack traces in
     // Chrome/V8.
     mainOutput.add('(function(${namer.currentIsolate})$_{\n');
+    emitSupportsDirectProtoAccess(mainOutput);
     if (compiler.hasIncrementalSupport) {
       mainOutput.addBuffer(jsAst.prettyPrint(js.statement(
           """
@@ -1365,7 +1130,7 @@
   #helper.addMethod = #addMethod;
   #helper.extractStubs = function(array, name, isStatic, originalDescriptor) {
     var descriptor = Object.create(null);
-    this.addStubs(descriptor, array, name, isStatic, originalDescriptor, []);
+    this.addStubs(descriptor, array, name, isStatic, []);
     return descriptor;
   };
 }""",
@@ -1411,8 +1176,8 @@
       mainOutput.add(
           '${globalsHolder}.${namer.isolateName}$_=$_${namer.isolateName}$N'
           '${globalsHolder}.$initName$_=${_}$initName$N'
-          '${globalsHolder}.$parseReflectionDataName$_=$_'
-            '$parseReflectionDataName$N');
+          '${globalsHolder}.$setupProgramName$_=$_'
+            '$setupProgramName$N');
     }
     mainOutput.add('init()$N$n');
     mainOutput.add('$isolateProperties$_=$_$isolatePropertiesName$N');
@@ -1430,17 +1195,32 @@
 
     CodeBuffer libraryBuffer = new CodeBuffer();
     for (LibraryElement library in Elements.sortedByPosition(libraries)) {
-      writeLibraryDescriptors(libraryBuffer, library);
+      writeLibraryDescriptor(libraryBuffer, library);
       elementDescriptors.remove(library);
     }
 
+    if (elementDescriptors.isNotEmpty) {
+      List<Element> remainingLibraries = elementDescriptors.keys
+          .where((Element e) => e is LibraryElement)
+          .toList();
+
+      // The remaining descriptors are only accessible through reflection.
+      // The program builder does not collect libraries that only
+      // contain typedefs that are used for reflection.
+      for (LibraryElement element in remainingLibraries) {
+        assert(element is LibraryElement || compiler.hasIncrementalSupport);
+        if (element is LibraryElement) {
+          writeLibraryDescriptor(libraryBuffer, element);
+          elementDescriptors.remove(element);
+        }
+      }
+    }
+
     bool needsNativeSupport = program.needsNativeSupport;
-    mainOutput
-        ..addBuffer(
-            jsAst.prettyPrint(
-                getReflectionDataParser(this, backend, needsNativeSupport),
-                compiler))
-        ..add(n);
+    mainOutput.addBuffer(
+        jsAst.prettyPrint(
+            buildSetupProgram(program, compiler, backend, namer, this),
+            compiler));
 
     // The argument to reflectionDataParser is assigned to a temporary 'dart'
     // so that 'dart.' will appear as the prefix to dart methods in stack
@@ -1457,9 +1237,10 @@
               compiler,
               monitor: compiler.dumpInfoTask,
               allowVariableMinification: false));
+      mainOutput.add(N);
     }
 
-    mainOutput.add('$parseReflectionDataName(dart)$N');
+    mainOutput.add('$setupProgramName(dart)$N');
 
     interceptorEmitter.emitGetInterceptorMethods(mainOutput);
     interceptorEmitter.emitOneShotInterceptors(mainOutput);
@@ -1489,7 +1270,7 @@
 
     mainOutput.add('\n');
 
-    emitMetadata(task.metadataCollector.globalMetadata, mainOutput);
+    emitMetadata(program, mainOutput);
 
     isolateProperties = isolatePropertiesName;
     // The following code should not use the short-hand for the
@@ -1501,6 +1282,9 @@
         '${namer.currentIsolate}$_=${_}new ${namer.isolateName}()$N');
 
     emitConvertToFastObjectFunction(mainOutput);
+    emitConvertToSlowObjectFunction(mainOutput);
+    emitMarkerFun(mainOutput);
+
     for (String globalObject in Namer.reservedGlobalObjectNames) {
       mainOutput.add('$globalObject = convertToFastObject($globalObject)$N');
     }
@@ -1703,7 +1487,7 @@
         CodeBuffer buffer = new CodeBuffer();
         outputBuffers[outputUnit] = buffer;
         for (LibraryElement library in Elements.sortedByPosition(libraries)) {
-          writeLibraryDescriptors(buffer, library);
+          writeLibraryDescriptor(buffer, library);
           elementDescriptors.remove(library);
         }
       }
@@ -1888,8 +1672,8 @@
       }
       output
           ..add('var init$_=$_${globalsHolder}.init$N')
-          ..add('var $parseReflectionDataName$_=$_'
-                    '$globalsHolder.$parseReflectionDataName$N')
+          ..add('var $setupProgramName$_=$_'
+                    '$globalsHolder.$setupProgramName$N')
           ..add('var ${namer.isolateName}$_=$_'
                     '${globalsHolder}.${namer.isolateName}$N');
       if (libraryDescriptorBuffer != null) {
@@ -1915,8 +1699,9 @@
                   precompiledFunctionAst, compiler,
                   monitor: compiler.dumpInfoTask,
                   allowVariableMinification: false));
+          output.add(N);
         }
-        output.add('$parseReflectionDataName(dart)$N');
+        output.add('$setupProgramName(dart)$N');
       }
 
       // Set the currentIsolate variable to the current isolate (which is
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart
deleted file mode 100644
index fc014bc..0000000
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/reflection_data_parser.dart
+++ /dev/null
@@ -1,495 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart2js.js_emitter;
-
-// TODO(ahe): Share these with js_helper.dart.
-const FUNCTION_INDEX = 0;
-const NAME_INDEX = 1;
-const CALL_NAME_INDEX = 2;
-const REQUIRED_PARAMETER_INDEX = 3;
-const OPTIONAL_PARAMETER_INDEX = 4;
-const DEFAULT_ARGUMENTS_INDEX = 5;
-
-const bool VALIDATE_DATA = false;
-
-// TODO(zarah): Rename this when renaming this file.
-String get parseReflectionDataName => 'parseReflectionData';
-
-jsAst.Expression getReflectionDataParser(OldEmitter oldEmitter,
-                                         JavaScriptBackend backend,
-                                         bool needsNativeSupport) {
-  Namer namer = backend.namer;
-  Compiler compiler = backend.compiler;
-  CodeEmitterTask emitter = backend.emitter;
-
-  String reflectableField = namer.reflectableField;
-  String reflectionInfoField = namer.reflectionInfoField;
-  String reflectionNameField = namer.reflectionNameField;
-  String metadataIndexField = namer.metadataIndexField;
-  String defaultValuesField = namer.defaultValuesField;
-  String methodsWithOptionalArgumentsField =
-      namer.methodsWithOptionalArgumentsField;
-
-  String unmangledNameIndex = backend.mustRetainMetadata
-      ? ' 3 * optionalParameterCount + 2 * requiredParameterCount + 3'
-      : ' 2 * optionalParameterCount + requiredParameterCount + 3';
-
-  jsAst.Expression typeInformationAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.TYPE_INFORMATION);
-  jsAst.Expression globalFunctionsAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS);
-  jsAst.Expression staticsAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.STATICS);
-  jsAst.Expression interceptedNamesAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTED_NAMES);
-  jsAst.Expression mangledGlobalNamesAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
-  jsAst.Expression mangledNamesAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
-  jsAst.Expression librariesAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.LIBRARIES);
-  jsAst.Expression metadataAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.METADATA);
-
-  jsAst.Statement processClassData = js.statement('''{
-  function processClassData(cls, descriptor, processedClasses) {
-    var newDesc = {};
-    var previousProperty;
-    var properties = Object.keys(descriptor);
-    for (var i = 0; i < properties.length; i++) {
-      var property = properties[i];
-      var firstChar = property.substring(0, 1);
-      if (property === "static") {
-        processStatics(#embeddedStatics[cls] = descriptor[property],
-                       processedClasses);
-      } else if (firstChar === "+") {
-        mangledNames[previousProperty] = property.substring(1);
-        var flag = descriptor[property];
-        if (flag > 0)
-          descriptor[previousProperty].$reflectableField = flag;
-      } else if (firstChar === "*") {
-        newDesc[previousProperty].$defaultValuesField = descriptor[property];
-        var optionalMethods = newDesc.$methodsWithOptionalArgumentsField;
-        if (!optionalMethods) {
-          newDesc.$methodsWithOptionalArgumentsField = optionalMethods={}
-        }
-        optionalMethods[property] = previousProperty;
-      } else {
-        var elem = descriptor[property];
-        if (property !== "${namer.classDescriptorProperty}" &&
-            elem != null &&
-            elem.constructor === Array &&
-            property !== "<>") {
-          addStubs(newDesc, elem, property, false, descriptor, []);
-        } else {
-          newDesc[previousProperty = property] = elem;
-        }
-      }
-    }
-
-    /* The 'fields' are either a constructor function or a
-     * string encoding fields, constructor and superclass. Gets the
-     * superclass and fields in the format
-     *   'Super;field1,field2'
-     * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor.
-     */
-    var classData = newDesc["${namer.classDescriptorProperty}"],
-        split, supr, fields = classData;
-
-    if (#hasRetainedMetadata)
-      if (typeof classData == "object" &&
-          classData instanceof Array) {
-        classData = fields = classData[0];
-      }
-    // ${ClassBuilder.fieldEncodingDescription}.
-    var s = fields.split(";");
-    fields = s[1] == "" ? [] : s[1].split(",");
-    supr = s[0];
-    // ${ClassBuilder.functionTypeEncodingDescription}.
-    split = supr.split(":");
-    if (split.length == 2) {
-      supr = split[0];
-      var functionSignature = split[1];
-      if (functionSignature)
-        newDesc.${namer.operatorSignature} = function(s) {
-          return function() {
-            return #metadata[s];
-          };
-        }(functionSignature);
-    }
-
-    if (supr) processedClasses.pending[cls] = supr;
-    if (#notInCspMode) {
-      processedClasses.combinedConstructorFunction += defineClass(cls, fields);
-      processedClasses.constructorsList.push(cls);
-    }
-    processedClasses.collected[cls] = [globalObject, newDesc];
-    classes.push(cls);
-  }
-}''', {'embeddedStatics': staticsAccess,
-       'hasRetainedMetadata': backend.hasRetainedMetadata,
-       'metadata': metadataAccess,
-       'notInCspMode': !compiler.useContentSecurityPolicy});
-
-  // TODO(zarah): Remove empty else branches in output when if(#hole) is false.
-  jsAst.Statement processStatics = js.statement('''
-    function processStatics(descriptor, processedClasses) {
-      var properties = Object.keys(descriptor);
-      for (var i = 0; i < properties.length; i++) {
-        var property = properties[i];
-        if (property === "${namer.classDescriptorProperty}") continue;
-        var element = descriptor[property];
-        var firstChar = property.substring(0, 1);
-        var previousProperty;
-        if (firstChar === "+") {
-          mangledGlobalNames[previousProperty] = property.substring(1);
-          var flag = descriptor[property];
-          if (flag > 0)
-            descriptor[previousProperty].$reflectableField = flag;
-          if (element && element.length)
-            #typeInformation[previousProperty] = element;
-        } else if (firstChar === "*") {
-          globalObject[previousProperty].$defaultValuesField = element;
-          var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
-          if (!optionalMethods) {
-            descriptor.$methodsWithOptionalArgumentsField = optionalMethods = {}
-          }
-          optionalMethods[property] = previousProperty;
-        } else if (typeof element === "function") {
-          globalObject[previousProperty = property] = element;
-          functions.push(property);
-          #globalFunctions[property] = element;
-        } else if (element.constructor === Array) {
-          if (#needsStructuredMemberInfo) {
-            addStubs(globalObject, element, property,
-                     true, descriptor, functions);
-          }
-        } else {
-          // We will not enter this case if no classes are defined.
-          if (#hasClasses) {
-            previousProperty = property;
-            processClassData(property, element, processedClasses);
-          }
-        }
-      }
-    }
-''', {'typeInformation': typeInformationAccess,
-      'globalFunctions': globalFunctionsAccess,
-      'hasClasses': oldEmitter.needsClassSupport,
-      'needsStructuredMemberInfo': oldEmitter.needsStructuredMemberInfo});
-
-
-  /**
-   * See [dart2js.js_emitter.ContainerBuilder.addMemberMethod] for format of
-   * [array].
-   */
-  jsAst.Statement addStubs = js.statement('''
-  function addStubs(descriptor, array, name, isStatic,
-                    originalDescriptor, functions) {
-    var index = $FUNCTION_INDEX, alias = array[index], f;
-    if (typeof alias == "string") {
-      f = array[++index];
-    } else {
-      f = alias;
-      alias = name;
-    }
-    var funcs = [originalDescriptor[name] = descriptor[name] =
-        descriptor[alias] = f];
-    f.\$stubName = name;
-    functions.push(name);
-    for (; index < array.length; index += 2) {
-      f = array[index + 1];
-      if (typeof f != "function") break;
-      f.\$stubName = ${readString("array", "index + 2")};
-      funcs.push(f);
-      if (f.\$stubName) {
-        originalDescriptor[f.\$stubName] = descriptor[f.\$stubName] = f;
-        functions.push(f.\$stubName);
-      }
-    }
-    for (var i = 0; i < funcs.length; index++, i++) {
-      funcs[i].\$callName = ${readString("array", "index + 1")};
-    }
-    var getterStubName = ${readString("array", "++index")};
-    array = array.slice(++index);
-    var requiredParameterInfo = ${readInt("array", "0")};
-    var requiredParameterCount = requiredParameterInfo >> 1;
-    var isAccessor = (requiredParameterInfo & 1) === 1;
-    var isSetter = requiredParameterInfo === 3;
-    var isGetter = requiredParameterInfo === 1;
-    var optionalParameterInfo = ${readInt("array", "1")};
-    var optionalParameterCount = optionalParameterInfo >> 1;
-    var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1;
-    var isIntercepted =
-           requiredParameterCount + optionalParameterCount != funcs[0].length;
-    var functionTypeIndex = ${readFunctionType("array", "2")};
-    var unmangledNameIndex = $unmangledNameIndex;
-
-    if (getterStubName) {
-      f = tearOff(funcs, array, isStatic, name, isIntercepted);
-      descriptor[name].\$getter = f;
-      f.\$getterStub = true;
-      // Used to create an isolate using spawnFunction.
-      if (isStatic) #globalFunctions[name] = f;
-      originalDescriptor[getterStubName] = descriptor[getterStubName] = f;
-      funcs.push(f);
-      if (getterStubName) functions.push(getterStubName);
-      f.\$stubName = getterStubName;
-      f.\$callName = null;
-      // Update the interceptedNames map (which only exists if `invokeOn` was
-      // enabled).
-      if (#enabledInvokeOn)
-        if (isIntercepted) #interceptedNames[getterStubName] = 1;
-    }
-
-    if (#usesMangledNames) {
-      var isReflectable = array.length > unmangledNameIndex;
-      if (isReflectable) {
-        for (var i = 0; i < funcs.length; i++) {
-          funcs[i].$reflectableField = 1;
-          funcs[i].$reflectionInfoField = array;
-        }
-        var mangledNames = isStatic ? #mangledGlobalNames : #mangledNames;
-        var unmangledName = ${readString("array", "unmangledNameIndex")};
-        // The function is either a getter, a setter, or a method.
-        // If it is a method, it might also have a tear-off closure.
-        // The unmangledName is the same as the getter-name.
-        var reflectionName = unmangledName;
-        if (getterStubName) mangledNames[getterStubName] = reflectionName;
-        if (isSetter) {
-          reflectionName += "=";
-        } else if (!isGetter) {
-          reflectionName += ":" + requiredParameterCount +
-            ":" + optionalParameterCount;
-        }
-        mangledNames[name] = reflectionName;
-        funcs[0].$reflectionNameField = reflectionName;
-        funcs[0].$metadataIndexField = unmangledNameIndex + 1;
-        if (optionalParameterCount) descriptor[unmangledName + "*"] = funcs[0];
-      }
-    }
-  }
-''', {'globalFunctions': globalFunctionsAccess,
-      'enabledInvokeOn': compiler.enabledInvokeOn,
-      'interceptedNames': interceptedNamesAccess,
-      'usesMangledNames':
-          compiler.mirrorsLibrary != null || compiler.enabledFunctionApply,
-      'mangledGlobalNames': mangledGlobalNamesAccess,
-      'mangledNames': mangledNamesAccess});
-
-  List<jsAst.Statement> tearOffCode = buildTearOffCode(backend);
-
-  jsAst.ObjectInitializer interceptedNamesSet =
-      oldEmitter.interceptorEmitter.generateInterceptedNamesSet();
-
-  jsAst.Statement init = js.statement('''{
-  var functionCounter = 0;
-  if (!#libraries) #libraries = [];
-  if (!#mangledNames) #mangledNames = map();
-  if (!#mangledGlobalNames) #mangledGlobalNames = map();
-  if (!#statics) #statics = map();
-  if (!#typeInformation) #typeInformation = map(); 
-  if (!#globalFunctions) #globalFunctions = map();
-  if (#enabledInvokeOn)
-    if (!#interceptedNames) #interceptedNames = #interceptedNamesSet;
-  var libraries = #libraries;
-  var mangledNames = #mangledNames;
-  var mangledGlobalNames = #mangledGlobalNames;
-  var hasOwnProperty = Object.prototype.hasOwnProperty;
-  var length = reflectionData.length;
-  var processedClasses = Object.create(null);
-  processedClasses.collected = Object.create(null);
-  processedClasses.pending = Object.create(null);
-  if (#notInCspMode) {
-    processedClasses.constructorsList = [];
-    // For every class processed [processedClasses.combinedConstructorFunction]
-    // will be updated with the corresponding constructor function. 
-    processedClasses.combinedConstructorFunction =
-        "function \$reflectable(fn){fn.$reflectableField=1;return fn};\\n"+
-        "var \$desc;\\n";
-  }
-  for (var i = 0; i < length; i++) {
-    var data = reflectionData[i];
-
-// [data] contains these elements:
-// 0. The library name (not unique).
-// 1. The library URI (unique).
-// 2. A function returning the metadata associated with this library.
-// 3. The global object to use for this library.
-// 4. An object literal listing the members of the library.
-// 5. This element is optional and if present it is true and signals that this
-// library is the root library (see dart:mirrors IsolateMirror.rootLibrary).
-//
-// The entries of [data] are built in [assembleProgram] above.
-
-    var name = data[0];
-    var uri = data[1];
-    var metadata = data[2];
-    var globalObject = data[3];
-    var descriptor = data[4];
-    var isRoot = !!data[5];
-    var fields = descriptor && descriptor["${namer.classDescriptorProperty}"];
-    if (fields instanceof Array) fields = fields[0];
-    var classes = [];
-    var functions = [];
-    processStatics(descriptor, processedClasses);
-    libraries.push([name, uri, classes, functions, metadata, fields, isRoot,
-                    globalObject]);
-  }
-    if (#needsClassSupport) finishClasses(processedClasses);
-}''', {'libraries': librariesAccess,
-       'mangledNames': mangledNamesAccess,
-       'mangledGlobalNames': mangledGlobalNamesAccess,
-       'statics': staticsAccess,
-       'typeInformation': typeInformationAccess,
-       'globalFunctions': globalFunctionsAccess,
-       'enabledInvokeOn': compiler.enabledInvokeOn,
-       'interceptedNames': interceptedNamesAccess,
-       'interceptedNamesSet': interceptedNamesSet,
-       'notInCspMode': !compiler.useContentSecurityPolicy,
-       'needsClassSupport': oldEmitter.needsClassSupport});
-
-  jsAst.Expression allClassesAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
-
-  // Class descriptions are collected in a JS object.
-  // 'finishClasses' takes all collected descriptions and sets up
-  // the prototype.
-  // Once set up, the constructors prototype field satisfy:
-  //  - it contains all (local) members.
-  //  - its internal prototype (__proto__) points to the superclass'
-  //    prototype field.
-  //  - the prototype's constructor field points to the JavaScript
-  //    constructor.
-  // For engines where we have access to the '__proto__' we can manipulate
-  // the object literal directly. For other engines we have to create a new
-  // object and copy over the members.
-  jsAst.Statement finishClasses = js.statement('''{
-  function finishClasses(processedClasses) {
-    if (#debugFastObjects)
-      print("Number of classes: " +
-            Object.getOwnPropertyNames(processedClasses.collected).length);
-
-    var allClasses = #allClasses;
-
-    if (#inCspMode) {
-      var constructors = #precompiled(processedClasses.collected);
-    }
-
-    if (#notInCspMode) {
-      processedClasses.combinedConstructorFunction +=
-        "return [\\n" + processedClasses.constructorsList.join(",\\n  ") + 
-        "\\n]";
-     var constructors =
-       new Function("\$collectedClasses", 
-           processedClasses.combinedConstructorFunction)
-               (processedClasses.collected);
-      processedClasses.combinedConstructorFunction = null;
-    }
-
-    for (var i = 0; i < constructors.length; i++) {
-      var constructor = constructors[i];
-      var cls = constructor.name;
-      var desc = processedClasses.collected[cls];
-      var globalObject = \$;
-      if (desc instanceof Array) {
-        globalObject = desc[0] || \$;
-        desc = desc[1];
-      }
-      if (#isTreeShakingDisabled)
-        constructor["${namer.metadataField}"] = desc;
-      allClasses[cls] = constructor;
-      globalObject[cls] = constructor;
-    }
-    constructors = null;
-
-    #finishClassFunction;
-
-    #trivialNsmHandlers;
-
-    var properties = Object.keys(processedClasses.pending);
-    for (var i = 0; i < properties.length; i++) finishClass(properties[i]);
-  }
-}''', {'allClasses': allClassesAccess,
-       'debugFastObjects': DEBUG_FAST_OBJECTS,
-       'isTreeShakingDisabled': backend.isTreeShakingDisabled,
-       'finishClassFunction': oldEmitter.buildFinishClass(needsNativeSupport),
-       'trivialNsmHandlers': oldEmitter.buildTrivialNsmHandlers(),
-       'inCspMode': compiler.useContentSecurityPolicy,
-       'notInCspMode': !compiler.useContentSecurityPolicy,
-       'precompiled': oldEmitter
-           .generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED)});
-
-  List<jsAst.Statement> incrementalSupport = <jsAst.Statement>[];
-  if (compiler.hasIncrementalSupport) {
-    incrementalSupport.add(
-        js.statement(
-            '#.addStubs = addStubs;', [namer.accessIncrementalHelper]));
-  }
-
-  return js('''
-function $parseReflectionDataName(reflectionData) {
-  "use strict";
-  if (#needsClassSupport) {
-    #defineClass;
-    #inheritFrom;
-    #finishClasses;
-    #processClassData;
-  }
-  #processStatics;
-  if (#needsStructuredMemberInfo) {
-    #addStubs;
-    #tearOffCode;
-  }
-  #incrementalSupport;
-  #init;
-}''', {
-      'defineClass': oldEmitter.defineClassFunction,
-      'inheritFrom': oldEmitter.buildInheritFrom(),
-      'processClassData': processClassData,
-      'processStatics': processStatics,
-      'incrementalSupport': incrementalSupport,
-      'addStubs': addStubs,
-      'tearOffCode': tearOffCode,
-      'init': init,
-      'finishClasses': finishClasses,
-      'needsClassSupport': oldEmitter.needsClassSupport,
-      'needsStructuredMemberInfo': oldEmitter.needsStructuredMemberInfo});
-}
-
-String readString(String array, String index) {
-  return readChecked(
-      array, index, 'result != null && typeof result != "string"', 'string');
-}
-
-String readInt(String array, String index) {
-  return readChecked(
-      array, index,
-      'result != null && (typeof result != "number" || (result|0) !== result)',
-      'int');
-}
-
-String readFunctionType(String array, String index) {
-  return readChecked(
-      array, index,
-      'result != null && '
-      '(typeof result != "number" || (result|0) !== result) && '
-      'typeof result != "function"',
-      'function or int');
-}
-
-String readChecked(String array, String index, String check, String type) {
-  if (!VALIDATE_DATA) return '$array[$index]';
-  return '''
-(function() {
-  var result = $array[$index];
-  if ($check) {
-    throw new Error(
-        name + ": expected value of type \'$type\' at index " + ($index) +
-        " but got " + (typeof result));
-  }
-  return result;
-})()''';
-}
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/setup_program_builder.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/setup_program_builder.dart
new file mode 100644
index 0000000..86fdcd8
--- /dev/null
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/setup_program_builder.dart
@@ -0,0 +1,811 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart2js.js_emitter;
+
+// TODO(ahe): Share these with js_helper.dart.
+const FUNCTION_INDEX = 0;
+const NAME_INDEX = 1;
+const CALL_NAME_INDEX = 2;
+const REQUIRED_PARAMETER_INDEX = 3;
+const OPTIONAL_PARAMETER_INDEX = 4;
+const DEFAULT_ARGUMENTS_INDEX = 5;
+
+const bool VALIDATE_DATA = false;
+
+const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1;
+const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1;
+const RANGE1_ADJUST = - (FIRST_FIELD_CODE - RANGE1_FIRST);
+const RANGE2_ADJUST = - (FIRST_FIELD_CODE + RANGE1_SIZE - RANGE2_FIRST);
+const RANGE3_ADJUST =
+    - (FIRST_FIELD_CODE + RANGE1_SIZE + RANGE2_SIZE - RANGE3_FIRST);
+
+String get setupProgramName => 'setupProgram';
+
+
+jsAst.Statement buildSetupProgram(Program program, Compiler compiler,
+                                JavaScriptBackend backend,
+                                Namer namer,
+                                OldEmitter emitter) {
+
+  jsAst.Expression typeInformationAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.TYPE_INFORMATION);
+  jsAst.Expression globalFunctionsAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS);
+  jsAst.Expression staticsAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.STATICS);
+  jsAst.Expression interceptedNamesAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTED_NAMES);
+  jsAst.Expression mangledGlobalNamesAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
+  jsAst.Expression mangledNamesAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
+  jsAst.Expression librariesAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.LIBRARIES);
+  jsAst.Expression typesAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.TYPES);
+  jsAst.Expression createNewIsolateFunctionAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.CREATE_NEW_ISOLATE);
+  jsAst.Expression classIdExtractorAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.CLASS_ID_EXTRACTOR);
+  jsAst.Expression allClassesAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
+  jsAst.Expression precompiledAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED);
+  jsAst.Expression finishedClassesAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES);
+  jsAst.Expression interceptorsByTagAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG);
+  jsAst.Expression leafTagsAccess =
+      emitter.generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS);
+  jsAst.Expression initializeEmptyInstanceAccess =
+      emitter.generateEmbeddedGlobalAccess(
+            embeddedNames.INITIALIZE_EMPTY_INSTANCE);
+  jsAst.Expression classFieldsExtractorAccess =
+      emitter.generateEmbeddedGlobalAccess(
+          embeddedNames.CLASS_FIELDS_EXTRACTOR);
+  jsAst.Expression instanceFromClassIdAccess =
+      emitter.generateEmbeddedGlobalAccess(
+          embeddedNames.INSTANCE_FROM_CLASS_ID);
+
+  String reflectableField = namer.reflectableField;
+  String reflectionInfoField = namer.reflectionInfoField;
+  String reflectionNameField = namer.reflectionNameField;
+  String metadataIndexField = namer.metadataIndexField;
+  String defaultValuesField = namer.defaultValuesField;
+  String methodsWithOptionalArgumentsField =
+      namer.methodsWithOptionalArgumentsField;
+  String unmangledNameIndex = backend.mustRetainMetadata
+      ? ' 3 * optionalParameterCount + 2 * requiredParameterCount + 3'
+      : ' 2 * optionalParameterCount + requiredParameterCount + 3';
+  String receiverParamName = compiler.enableMinification ? "r" : "receiver";
+  String valueParamName = compiler.enableMinification ? "v" : "value";
+  String space = compiler.enableMinification ? "" : " ";
+  String _ = space;
+
+  String specProperty = '"${namer.nativeSpecProperty}"';  // "%"
+  jsAst.Expression nativeInfoAccess = js('prototype[$specProperty]', []);
+  jsAst.Expression constructorAccess = js('constructor', []);
+  Function subclassReadGenerator =
+      (jsAst.Expression subclass) => js('allClasses[#]', subclass);
+  jsAst.Statement nativeInfoHandler = emitter.
+      buildNativeInfoHandler(nativeInfoAccess, constructorAccess,
+                             subclassReadGenerator, interceptorsByTagAccess,
+                             leafTagsAccess);
+
+  Map<String, dynamic> holes =
+    {'needsClassSupport': emitter.needsClassSupport,
+     'libraries': librariesAccess,
+     'mangledNames': mangledNamesAccess,
+     'mangledGlobalNames': mangledGlobalNamesAccess,
+     'statics': staticsAccess,
+     'typeInformation': typeInformationAccess,
+     'globalFunctions': globalFunctionsAccess,
+     'enabledInvokeOn': compiler.enabledInvokeOn,
+     'interceptedNames': interceptedNamesAccess,
+     'interceptedNamesSet': emitter.generateInterceptedNamesSet(),
+     'notInCspMode': !compiler.useContentSecurityPolicy,
+     'inCspMode': compiler.useContentSecurityPolicy,
+     'deferredAction': namer.deferredAction,
+     'hasIsolateSupport': program.hasIsolateSupport,
+     'fieldNamesProperty': js.string(OldEmitter.FIELD_NAMES_PROPERTY_NAME),
+     'hasIncrementalSupport': compiler.hasIncrementalSupport,
+     'incrementalHelper': namer.accessIncrementalHelper,
+     'createNewIsolateFunction': createNewIsolateFunctionAccess,
+     'isolateName': namer.isolateName,
+     'classIdExtractor': classIdExtractorAccess,
+     'classFieldsExtractor': classFieldsExtractorAccess,
+     'instanceFromClassId': instanceFromClassIdAccess,
+     'initializeEmptyInstance': initializeEmptyInstanceAccess,
+     'allClasses': allClassesAccess,
+     'debugFastObjects': DEBUG_FAST_OBJECTS,
+     'isTreeShakingDisabled': backend.isTreeShakingDisabled,
+     'precompiled': precompiledAccess,
+     'finishedClassesAccess': finishedClassesAccess,
+     'markerFun': emitter.markerFun,
+     'needsMixinSupport': emitter.needsMixinSupport,
+     'needsNativeSupport': program.needsNativeSupport,
+     'isInterceptorClass': namer.operatorIs(backend.jsInterceptorClass),
+     'isObject' : namer.operatorIs(compiler.objectClass),
+     'specProperty': js.string(namer.nativeSpecProperty),
+     'trivialNsmHandlers': emitter.buildTrivialNsmHandlers(),
+     'hasRetainedMetadata': backend.hasRetainedMetadata,
+     'types': typesAccess,
+     'objectClassName': js.string(namer.runtimeTypeName(compiler.objectClass)),
+     'needsStructuredMemberInfo': emitter.needsStructuredMemberInfo,
+     'usesMangledNames':
+          compiler.mirrorsLibrary != null || compiler.enabledFunctionApply,
+     'tearOffCode': buildTearOffCode(backend),
+     'nativeInfoHandler': nativeInfoHandler,
+     'operatorIsPrefix' : js.string(namer.operatorIsPrefix),
+     'deferredActionString': js.string(namer.deferredAction)};
+
+   String skeleton = '''
+function $setupProgramName(programData) {
+  "use strict";
+  if (#needsClassSupport) {
+
+    function generateAccessor(fieldDescriptor, accessors, cls) {
+      var fieldInformation = fieldDescriptor.split("-");
+      var field = fieldInformation[0];
+      var len = field.length;
+      var code = field.charCodeAt(len - 1);
+      var reflectable;
+      if (fieldInformation.length > 1) reflectable = true;
+           else reflectable = false;
+      code = ((code >= $RANGE1_FIRST) && (code <= $RANGE1_LAST))
+            ? code - $RANGE1_ADJUST
+            : ((code >= $RANGE2_FIRST) && (code <= $RANGE2_LAST))
+              ? code - $RANGE2_ADJUST
+              : ((code >= $RANGE3_FIRST) && (code <= $RANGE3_LAST))
+                ? code - $RANGE3_ADJUST
+                : $NO_FIELD_CODE;
+
+      if (code) {  // needsAccessor
+        var getterCode = code & 3;
+        var setterCode = code >> 2;
+        var accessorName = field = field.substring(0, len - 1);
+
+        var divider = field.indexOf(":");
+        if (divider > 0) { // Colon never in first position.
+          accessorName = field.substring(0, divider);
+          field = field.substring(divider + 1);
+        }
+
+        if (getterCode) {  // needsGetter
+          var args = (getterCode & 2) ? "$receiverParamName" : "";
+          var receiver = (getterCode & 1) ? "this" : "$receiverParamName";
+          var body = "return " + receiver + "." + field;
+          var property =
+              cls + ".prototype.${namer.getterPrefix}" + accessorName + "=";
+          var fn = "function(" + args + "){" + body + "}";
+          if (reflectable)
+            accessors.push(property + "\$reflectable(" + fn + ");\\n");
+          else
+            accessors.push(property + fn + ";\\n");
+        }
+
+        if (setterCode) {  // needsSetter
+          var args = (setterCode & 2)
+              ? "$receiverParamName,${_}$valueParamName"
+              : "$valueParamName";
+          var receiver = (setterCode & 1) ? "this" : "$receiverParamName";
+          var body = receiver + "." + field + "$_=$_$valueParamName";
+          var property =
+              cls + ".prototype.${namer.setterPrefix}" + accessorName + "=";
+          var fn = "function(" + args + "){" + body + "}";
+          if (reflectable)
+            accessors.push(property + "\$reflectable(" + fn + ");\\n");
+          else
+            accessors.push(property + fn + ";\\n");
+        }
+      }
+
+      return field;
+    }
+
+    // First the class name, then the field names in an array and the members
+    // (inside an Object literal).
+    // The caller can also pass in the constructor as a function if needed.
+    //
+    // Example:
+    // defineClass("A", ["x", "y"], {
+    //  foo\$1: function(y) {
+    //   print(this.x + y);
+    //  },
+    //  bar\$2: function(t, v) {
+    //   this.x = t - v;
+    //  },
+    // });
+    function defineClass(name, fields) {
+      var accessors = [];
+
+      var str = "function " + name + "(";
+      var body = "";
+      if (#hasIsolateSupport) { var fieldNames = ""; }
+
+      for (var i = 0; i < fields.length; i++) {
+        if(i != 0) str += ", ";
+
+        var field = generateAccessor(fields[i], accessors, name);
+        if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; }
+        var parameter = "p_" + field;
+        str += parameter;
+        body += ("this." + field + " = " + parameter + ";\\n");
+      }
+      if (supportsDirectProtoAccess) {
+        body += "this." + #deferredActionString + "();";
+      }
+      str += ") {\\n" + body + "}\\n";
+      str += name + ".builtin\$cls=\\"" + name + "\\";\\n";
+      str += "\$desc=\$collectedClasses." + name + "[1];\\n";
+      str += name + ".prototype = \$desc;\\n";
+      if (typeof defineClass.name != "string") {
+        str += name + ".name=\\"" + name + "\\";\\n";
+      }
+      if (#hasIsolateSupport) {
+        str += name + "." + #fieldNamesProperty + "=[" + fieldNames
+               + "];\\n";
+      }
+      str += accessors.join("");
+
+      return str;
+    }
+
+    if (#hasIncrementalSupport) {
+      #incrementalHelper.defineClass = defineClass;
+    }
+
+    if (#hasIsolateSupport) {
+      #createNewIsolateFunction = function() { return new #isolateName(); };
+
+      #classIdExtractor = function(o) { return o.constructor.name; };
+
+      #classFieldsExtractor = function(o) {
+        var fieldNames = o.constructor.#fieldNamesProperty;
+        if (!fieldNames) return [];  // TODO(floitsch): do something else here.
+        var result = [];
+        result.length = fieldNames.length;
+        for (var i = 0; i < fieldNames.length; i++) {
+          result[i] = o[fieldNames[i]];
+        }
+        return result;
+      };
+
+      #instanceFromClassId = function(name) { return new #allClasses[name](); };
+
+      #initializeEmptyInstance = function(name, o, fields) {
+        #allClasses[name].apply(o, fields);
+        return o; //
+      }
+    }
+
+    // If the browser supports changing the prototype via __proto__, we make
+    // use of that feature. Otherwise, we copy the properties into a new
+    // constructor.
+    var inheritFrom = supportsDirectProtoAccess ?
+      function(constructor, superConstructor) {
+        var prototype = constructor.prototype;
+        prototype.__proto__ = superConstructor.prototype;
+        // Use a function for `true` here, as functions are stored in the
+        // hidden class and not as properties in the object.
+        prototype.constructor = constructor;
+        prototype[#operatorIsPrefix + constructor.name] = constructor;
+        return convertToFastObject(prototype);
+      } :
+      function() {
+        function tmp() {}
+        return function (constructor, superConstructor) {
+          tmp.prototype = superConstructor.prototype;
+          var object = new tmp();
+          convertToSlowObject(object);
+          var properties = constructor.prototype;
+          var members = Object.keys(properties);
+          for (var i = 0; i < members.length; i++) {
+            var member = members[i];
+            object[member] = properties[member];
+          }
+          // Use a function for `true` here, as functions are stored in the
+          // hidden class and not as properties in the object.
+          object[#operatorIsPrefix + constructor.name] = constructor;
+          object.constructor = constructor;
+          constructor.prototype = object;
+          return object;
+        };
+      }();
+
+     if (#hasIncrementalSupport) {
+       #incrementalHelper.inheritFrom = inheritFrom;
+     }
+
+    // Class descriptions are collected in a JS object.
+    // 'finishClasses' takes all collected descriptions and sets up
+    // the prototype.
+    // Once set up, the constructors prototype field satisfy:
+    //  - it contains all (local) members.
+    //  - its internal prototype (__proto__) points to the superclass'
+    //    prototype field.
+    //  - the prototype's constructor field points to the JavaScript
+    //    constructor.
+    // For engines where we have access to the '__proto__' we can manipulate
+    // the object literal directly. For other engines we have to create a new
+    // object and copy over the members.
+    function finishClasses(processedClasses) {
+      if (#debugFastObjects)
+        print("Number of classes: " +
+              Object.getOwnPropertyNames(processedClasses.collected).length);
+
+      var allClasses = #allClasses;
+
+      if (#inCspMode) {
+        var constructors = #precompiled(processedClasses.collected);
+      }
+
+      if (#notInCspMode) {
+        processedClasses.combinedConstructorFunction +=
+          "return [\\n" + processedClasses.constructorsList.join(",\\n  ") +
+          "\\n]";
+       var constructors =
+         new Function("\$collectedClasses",
+             processedClasses.combinedConstructorFunction)
+                 (processedClasses.collected);
+        processedClasses.combinedConstructorFunction = null;
+      }
+
+      for (var i = 0; i < constructors.length; i++) {
+        var constructor = constructors[i];
+        var cls = constructor.name;
+        var desc = processedClasses.collected[cls];
+        var globalObject = desc[0];
+        desc = desc[1];
+        if (#isTreeShakingDisabled)
+          constructor["${namer.metadataField}"] = desc;
+        allClasses[cls] = constructor;
+        globalObject[cls] = constructor;
+      }
+      constructors = null;
+
+      var finishedClasses = #finishedClassesAccess;
+
+      function finishClass(cls) {
+
+        if (finishedClasses[cls]) return;
+        finishedClasses[cls] = true;
+
+        var superclass = processedClasses.pending[cls];
+
+        if (#needsMixinSupport) {
+          if (superclass && superclass.indexOf("+") > 0) {
+            var s = superclass.split("+");
+            superclass = s[0];
+            var mixinClass = s[1];
+            finishClass(mixinClass);
+            var mixin = allClasses[mixinClass];
+            var mixinPrototype = mixin.prototype;
+            var clsPrototype = allClasses[cls].prototype;
+
+            var properties = Object.keys(mixinPrototype);
+            for (var i = 0; i < properties.length; i++) {
+              var d = properties[i];
+              if (!hasOwnProperty.call(clsPrototype, d))
+                clsPrototype[d] = mixinPrototype[d];
+            }
+          }
+        }
+
+        // The superclass is only false (empty string) for the Dart Object
+        // class.  The minifier together with noSuchMethod can put methods on
+        // the Object.prototype object, and they show through here, so we check
+        // that we have a string.
+        if (!superclass || typeof superclass != "string") {
+          // Inlined special case of InheritFrom here for performance reasons.
+          // Fix up the the Dart Object class' prototype.
+          var constructor = allClasses[cls];
+          var prototype = constructor.prototype;
+          prototype.constructor = constructor;
+          prototype.#isObject = constructor;
+          prototype.#deferredAction = #markerFun;
+          return;
+        }
+        finishClass(superclass);
+        var superConstructor = allClasses[superclass];
+
+        if (!superConstructor) {
+          superConstructor = existingIsolateProperties[superclass];
+        }
+
+        var constructor = allClasses[cls];
+        var prototype = inheritFrom(constructor, superConstructor);
+
+        if (#needsNativeSupport) {
+          if (Object.prototype.hasOwnProperty.call(prototype, #specProperty)) {
+            #nativeInfoHandler;
+            // As native classes can come into existence without a constructor
+            // call, we have to ensure that the class has been fully
+            // initialized.
+            if (constructor.prototype.#deferredAction)
+              finishAddStubsHelper(constructor.prototype);
+          }
+        }
+        // Interceptors (or rather their prototypes) are also used without
+        // first instantiating them first.
+        if (prototype.#isInterceptorClass &&
+            constructor.prototype.#deferredAction) {
+          finishAddStubsHelper(constructor.prototype);
+        }
+      }
+
+      #trivialNsmHandlers;
+
+      var properties = Object.keys(processedClasses.pending);
+      for (var i = 0; i < properties.length; i++) finishClass(properties[i]);
+    }
+
+
+    // For convenience, this method can be called with a prototype as argument
+    // or, if it was bound to an object, by invoking it as a method. Therefore,
+    // if prototype is undefined, this is used as prototype.
+    function finishAddStubsHelper(prototype) {
+      var prototype = prototype || this;
+      var object;
+      while (prototype.#deferredAction != #markerFun) {
+        if (prototype.hasOwnProperty(#deferredActionString)) {
+          delete prototype.#deferredAction; // Intended to make it slow, too.
+          var properties = Object.keys(prototype);
+          for (var index = 0; index < properties.length; index++) {
+            var property = properties[index];
+            var firstChar = property.charCodeAt(0);
+            var elem;
+            // We have to filter out some special properties that are used for
+            // metadata in descriptors. Currently, we filter everything that
+            // starts with + or *. This has to stay in sync with the special
+            // properties that are used by processClassData below.
+            if (property !== "${namer.classDescriptorProperty}" &&
+                property !== "$reflectableField" &&
+                firstChar !== 43 && // 43 is aka "+".
+                firstChar !== 42 && // 42 is aka "*"
+                (elem = prototype[property]) != null &&
+                elem.constructor === Array &&
+                property !== "<>") {
+              addStubs(prototype, elem, property, false, []);
+            }
+          }
+          convertToFastObject(prototype);
+        }
+        prototype = prototype.__proto__;
+      }
+    }
+
+    function processClassData(cls, descriptor, processedClasses) {
+      descriptor = convertToSlowObject(descriptor); // Use a slow object.
+      var previousProperty;
+      var properties = Object.keys(descriptor);
+      var hasDeferredWork = false;
+      var shouldDeferWork =
+          supportsDirectProtoAccess && cls != #objectClassName;
+      for (var i = 0; i < properties.length; i++) {
+        var property = properties[i];
+        var firstChar = property.charCodeAt(0);
+        if (property === "static") {
+          processStatics(#statics[cls] = descriptor.static,
+                         processedClasses);
+          delete descriptor.static;
+        } else if (firstChar === 43) { // 43 is "+".
+          mangledNames[previousProperty] = property.substring(1);
+          var flag = descriptor[property];
+          if (flag > 0)
+            descriptor[previousProperty].$reflectableField = flag;
+        } else if (firstChar === 42) { // 42 is "*"
+          descriptor[previousProperty].$defaultValuesField =
+              descriptor[property];
+          var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
+          if (!optionalMethods) {
+            descriptor.$methodsWithOptionalArgumentsField = optionalMethods={}
+          }
+          optionalMethods[property] = previousProperty;
+        } else {
+          var elem = descriptor[property];
+          if (property !== "${namer.classDescriptorProperty}" &&
+              elem != null &&
+              elem.constructor === Array &&
+              property !== "<>") {
+            if (shouldDeferWork) {
+              hasDeferredWork = true;
+            } else {
+              addStubs(descriptor, elem, property, false, []);
+            }
+          } else {
+            previousProperty = property;
+          }
+        }
+      }
+
+      if (hasDeferredWork)
+        descriptor.#deferredAction = finishAddStubsHelper;
+
+      /* The 'fields' are either a constructor function or a
+       * string encoding fields, constructor and superclass. Gets the
+       * superclass and fields in the format
+       *   'Super;field1,field2'
+       * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor.
+       */
+      var classData = descriptor["${namer.classDescriptorProperty}"],
+          split, supr, fields = classData;
+
+      if (#hasRetainedMetadata)
+        if (typeof classData == "object" &&
+            classData instanceof Array) {
+          classData = fields = classData[0];
+        }
+      // ${ClassBuilder.fieldEncodingDescription}.
+      var s = fields.split(";");
+      fields = s[1] == "" ? [] : s[1].split(",");
+      supr = s[0];
+      // ${ClassBuilder.functionTypeEncodingDescription}.
+      split = supr.split(":");
+      if (split.length == 2) {
+        supr = split[0];
+        var functionSignature = split[1];
+        if (functionSignature)
+          descriptor.${namer.operatorSignature} = function(s) {
+            return function() {
+              return #types[s];
+            };
+          }(functionSignature);
+      }
+
+      if (supr) processedClasses.pending[cls] = supr;
+      if (#notInCspMode) {
+        processedClasses.combinedConstructorFunction +=
+            defineClass(cls, fields);
+        processedClasses.constructorsList.push(cls);
+      }
+      processedClasses.collected[cls] = [globalObject, descriptor];
+      classes.push(cls);
+    }
+  }
+
+  function processStatics(descriptor, processedClasses) {
+    var properties = Object.keys(descriptor);
+    for (var i = 0; i < properties.length; i++) {
+      var property = properties[i];
+      if (property === "${namer.classDescriptorProperty}") continue;
+      var element = descriptor[property];
+      var firstChar = property.charCodeAt(0);
+      var previousProperty;
+      if (firstChar === 43) { // 43 is "+".
+        mangledGlobalNames[previousProperty] = property.substring(1);
+        var flag = descriptor[property];
+        if (flag > 0)
+          descriptor[previousProperty].$reflectableField = flag;
+        if (element && element.length)
+          #typeInformation[previousProperty] = element;
+      } else if (firstChar === 42) { // 42 is "*"
+        globalObject[previousProperty].$defaultValuesField = element;
+        var optionalMethods = descriptor.$methodsWithOptionalArgumentsField;
+        if (!optionalMethods) {
+          descriptor.$methodsWithOptionalArgumentsField = optionalMethods = {}
+        }
+        optionalMethods[property] = previousProperty;
+      } else if (typeof element === "function") {
+        globalObject[previousProperty = property] = element;
+        functions.push(property);
+        #globalFunctions[property] = element;
+      } else if (element.constructor === Array) {
+        if (#needsStructuredMemberInfo) {
+          addStubs(globalObject, element, property, true, functions);
+        }
+      } else {
+        // We will not enter this case if no classes are defined.
+        if (#needsClassSupport) {
+          previousProperty = property;
+          processClassData(property, element, processedClasses);
+        }
+      }
+    }
+  }
+
+  if (#needsStructuredMemberInfo) {
+
+    // See [dart2js.js_emitter.ContainerBuilder.addMemberMethod] for format of
+    // [array].
+
+    // Processes the stub declaration given by [array] and stores the results
+    // in the corresponding [prototype]. [name] is the property name in
+    // [prototype] that the stub declaration belongs to.
+    // If [isStatic] is true, the property being processed belongs to a static
+    // function and thus is stored as a global. In that case we also add all
+    // generated functions to the [functions] array, which is used by the
+    // mirrors system to enumerate all static functions of a library. For
+    // non-static functions we might still add some functions to [functions] but
+    // the information is thrown away at the call site. This is to avoid
+    // conditionals.
+    function addStubs(prototype, array, name, isStatic, functions) {
+      var index = $FUNCTION_INDEX, alias = array[index], f;
+      if (typeof alias == "string") {
+        f = array[++index];
+      } else {
+        f = alias;
+        alias = name;
+      }
+      var funcs = [prototype[name] = prototype[alias] = f];
+      f.\$stubName = name;
+      functions.push(name);
+      for (; index < array.length; index += 2) {
+        f = array[index + 1];
+        if (typeof f != "function") break;
+        f.\$stubName = ${readString("array", "index + 2")};
+        funcs.push(f);
+        if (f.\$stubName) {
+          prototype[f.\$stubName] = f;
+          functions.push(f.\$stubName);
+        }
+      }
+      index++;
+      for (var i = 0; i < funcs.length; index++, i++) {
+        funcs[i].\$callName = ${readString("array", "index")};
+      }
+      var getterStubName = ${readString("array", "index")};
+      array = array.slice(++index);
+      var requiredParameterInfo = ${readInt("array", "0")};
+      var requiredParameterCount = requiredParameterInfo >> 1;
+      var isAccessor = (requiredParameterInfo & 1) === 1;
+      var isSetter = requiredParameterInfo === 3;
+      var isGetter = requiredParameterInfo === 1;
+      var optionalParameterInfo = ${readInt("array", "1")};
+      var optionalParameterCount = optionalParameterInfo >> 1;
+      var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1;
+      var isIntercepted =
+             requiredParameterCount + optionalParameterCount != funcs[0].length;
+      var functionTypeIndex = ${readFunctionType("array", "2")};
+      var unmangledNameIndex = $unmangledNameIndex;
+
+      if (getterStubName) {
+        f = tearOff(funcs, array, isStatic, name, isIntercepted);
+        prototype[name].\$getter = f;
+        f.\$getterStub = true;
+        // Used to create an isolate using spawnFunction.
+        if (isStatic) {
+          #globalFunctions[name] = f;
+          functions.push(getterStubName);
+        }
+        prototype[getterStubName] = f;
+        funcs.push(f);
+        f.\$stubName = getterStubName;
+        f.\$callName = null;
+        // Update the interceptedNames map (which only exists if `invokeOn` was
+        // enabled).
+        if (#enabledInvokeOn)
+          if (isIntercepted) #interceptedNames[getterStubName] = 1;
+      }
+
+      if (#usesMangledNames) {
+        var isReflectable = array.length > unmangledNameIndex;
+        if (isReflectable) {
+          for (var i = 0; i < funcs.length; i++) {
+            funcs[i].$reflectableField = 1;
+            funcs[i].$reflectionInfoField = array;
+          }
+          var mangledNames = isStatic ? #mangledGlobalNames : #mangledNames;
+          var unmangledName = ${readString("array", "unmangledNameIndex")};
+          // The function is either a getter, a setter, or a method.
+          // If it is a method, it might also have a tear-off closure.
+          // The unmangledName is the same as the getter-name.
+          var reflectionName = unmangledName;
+          if (getterStubName) mangledNames[getterStubName] = reflectionName;
+          if (isSetter) {
+            reflectionName += "=";
+          } else if (!isGetter) {
+            reflectionName += ":" + requiredParameterCount +
+              ":" + optionalParameterCount;
+          }
+          mangledNames[name] = reflectionName;
+          funcs[0].$reflectionNameField = reflectionName;
+          funcs[0].$metadataIndexField = unmangledNameIndex + 1;
+          if (optionalParameterCount) prototype[unmangledName + "*"] = funcs[0];
+        }
+      }
+    }
+
+    #tearOffCode;
+  }
+
+  if (#hasIncrementalSupport) {
+    #incrementalHelper.addStubs = addStubs;
+  }
+
+  var functionCounter = 0;
+  if (!#libraries) #libraries = [];
+  if (!#mangledNames) #mangledNames = map();
+  if (!#mangledGlobalNames) #mangledGlobalNames = map();
+  if (!#statics) #statics = map();
+  if (!#typeInformation) #typeInformation = map();
+  if (!#globalFunctions) #globalFunctions = map();
+  if (#enabledInvokeOn)
+    if (!#interceptedNames) #interceptedNames = #interceptedNamesSet;
+  var libraries = #libraries;
+  var mangledNames = #mangledNames;
+  var mangledGlobalNames = #mangledGlobalNames;
+  var hasOwnProperty = Object.prototype.hasOwnProperty;
+  var length = programData.length;
+  var processedClasses = map();
+  processedClasses.collected = map();
+  processedClasses.pending = map();
+  if (#notInCspMode) {
+    processedClasses.constructorsList = [];
+    // For every class processed [processedClasses.combinedConstructorFunction]
+    // will be updated with the corresponding constructor function.
+    processedClasses.combinedConstructorFunction =
+        "function \$reflectable(fn){fn.$reflectableField=1;return fn};\\n"+
+        "var \$desc;\\n";
+  }
+  for (var i = 0; i < length; i++) {
+    var data = programData[i];
+
+// [data] contains these elements:
+// 0. The library name (not unique).
+// 1. The library URI (unique).
+// 2. A function returning the metadata associated with this library.
+// 3. The global object to use for this library.
+// 4. An object literal listing the members of the library.
+// 5. This element is optional and if present it is true and signals that this
+// library is the root library (see dart:mirrors IsolateMirror.rootLibrary).
+//
+// The entries of [data] are built in [assembleProgram] above.
+
+    var name = data[0];
+    var uri = data[1];
+    var metadata = data[2];
+    var globalObject = data[3];
+    var descriptor = data[4];
+    var isRoot = !!data[5];
+    var fields = descriptor && descriptor["${namer.classDescriptorProperty}"];
+    if (fields instanceof Array) fields = fields[0];
+    var classes = [];
+    var functions = [];
+    processStatics(descriptor, processedClasses);
+    libraries.push([name, uri, classes, functions, metadata, fields, isRoot,
+                    globalObject]);
+  }
+  if (#needsClassSupport) finishClasses(processedClasses);
+}''';
+
+  // TODO(zarah): Remove empty else branches in output when if(#hole) is false.
+  return js.statement(skeleton, holes);
+}
+
+String readString(String array, String index) {
+  return readChecked(
+      array, index, 'result != null && typeof result != "string"', 'string');
+}
+
+String readInt(String array, String index) {
+  return readChecked(
+      array, index,
+      'result != null && (typeof result != "number" || (result|0) !== result)',
+      'int');
+}
+
+String readFunctionType(String array, String index) {
+  return readChecked(
+      array, index,
+      'result != null && '
+      '(typeof result != "number" || (result|0) !== result) && '
+      'typeof result != "function"',
+      'function or int');
+}
+
+String readChecked(String array, String index, String check, String type) {
+  if (!VALIDATE_DATA) return '$array[$index]';
+  return '''
+(function() {
+  var result = $array[$index];
+  if ($check) {
+    throw new Error(
+        name + ": expected value of type \'$type\' at index " + ($index) +
+        " but got " + (typeof result));
+  }
+  return result;
+})()''';
+}
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder.dart
index 02961bb..829ad37 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder.dart
@@ -358,7 +358,7 @@
         runtimeTypeGenerator.generateTypeVariableReaderStubs(element);
 
     List<StubMethod> noSuchMethodStubs = <StubMethod>[];
-    if (_compiler.enabledNoSuchMethod && element == _compiler.objectClass) {
+    if (backend.enabledNoSuchMethod && element == _compiler.objectClass) {
       Map<String, Selector> selectors =
           classStubGenerator.computeSelectorsForNsmHandlers();
       selectors.forEach((String name, Selector selector) {
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index 5cd5c60..0d3ca81 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -60,17 +60,39 @@
   final SideEffects sideEffects = new SideEffects.empty();
 
   /// Processes the type specification string of a call to JS and stores the
-  /// result in the [typesReturned] and [typesInstantiated].
+  /// result in the [typesReturned] and [typesInstantiated]. It furthermore
+  /// computes the side effects, and, if given, invokes [setSideEffects] with
+  /// the computed effects. If no side effects are encoded in the [specString]
+  /// the [setSideEffects] method is not invoked.
   ///
   /// Two forms of the string is supported:
   /// 1) A single type string of the form 'void', '', 'var' or 'T1|...|Tn'
   ///    which defines the types returned and for the later form also created by
   ///    the call to JS.
-  /// 2) A sequence of the form '<tag>:<type-string>;' where <tag> is either
-  ///    'returns' or 'creates' and where <type-string> is a type string like in
-  ///    1). The type string marked by 'returns' defines the types returned and
-  ///    'creates' defines the types created by the call to JS. Each tag kind
-  ///    can only occur once in the sequence.
+  /// 2) A sequence of the form
+  ///    '<type-tag>:<type-string>;<effect-tag>:<effect-string>'
+  ///    where <type-tag> is either 'returns' or 'creates' and where
+  ///    <type-string> is a type string like in 1). The type string marked by
+  ///    'returns' defines the types returned and 'creates' defines the types
+  ///    created by the call to JS.
+  ///
+  ///    The <effect-tag> is either 'effects' or 'depends' and
+  ///    <effect-string> is either 'all', 'none' or a comma-separated list of
+  ///    'no-index', 'no-instance', 'no-static'.
+  ///
+  ///    The flag 'all' indicates that the call affects/depends on every
+  ///    side-effect. The flag 'none' indicates that the call does not affect
+  ///    (resp. depends on) anything.
+  ///
+  ///    'no-index' indicates that the call does *not* do any array index-store
+  ///    (for 'effects'), or depends on any value in an array (for 'depends').
+  ///    The flag 'no-instance' indicates that the call does not modify (resp.
+  ///    depends on) any instance variable. Similarly static variables are
+  ///    indicated with 'no-static'. The flags 'effects' and 'depends' must be
+  ///    used in unison (either both are present or none is).
+  ///
+  ///    Each tag kind (including the 'type-tag's) can only occur once in the
+  ///    sequence.
   ///
   /// [specString] is the specification string, [resolveType] resolves named
   /// types into type values, [typesReturned] and [typesInstantiated] collects
@@ -82,7 +104,8 @@
       DiagnosticListener listener,
       Spannable spannable,
       String specString,
-      {dynamic resolveType(String typeString),
+      {void setSideEffects(SideEffects newEffects),
+       dynamic resolveType(String typeString),
        List typesReturned, List typesInstantiated,
        objectType, nullType}) {
 
@@ -110,10 +133,11 @@
       }
     }
 
+
     if (specString.contains(':')) {
-      /// Find and remove a substring of the form 'tag:<type-string>;' from
+      /// Find and remove a substring of the form 'tag:<string>;' from
       /// [specString].
-      String getTypesString(String tag) {
+      String getTagString(String tag) {
         String marker = '$tag:';
         int startPos = specString.indexOf(marker);
         if (startPos == -1) return null;
@@ -126,7 +150,7 @@
         return typeString;
       }
 
-      String returns = getTypesString('returns');
+      String returns = getTagString('returns');
       if (returns != null) {
         resolveTypesString(returns, onVar: () {
           typesReturned.add(objectType);
@@ -136,7 +160,7 @@
         });
       }
 
-      String creates = getTypesString('creates');
+      String creates = getTagString('creates');
       if (creates != null) {
         resolveTypesString(creates, onVoid: () {
           listener.internalError(spannable,
@@ -149,8 +173,77 @@
         });
       }
 
+      String effects = getTagString('effects');
+      String depends = getTagString('depends');
+      if (effects != null && depends == null ||
+          effects == null && depends != null) {
+        listener.internalError(spannable,
+            "Invalid JS spec string. "
+            "'effects' and 'depends' must occur together.");
+      }
+
+      if (effects != null) {
+        SideEffects sideEffects = new SideEffects();
+        if (effects == "none") {
+          sideEffects.clearAllSideEffects();
+        } else if (effects == "all") {
+          // Don't do anything.
+        } else {
+          List<String> splitEffects = effects.split(",");
+          if (splitEffects.isEmpty) {
+            listener.internalError(spannable, "Missing side-effect flag.");
+          }
+          for (String effect in splitEffects) {
+            switch (effect) {
+              case "no-index":
+                sideEffects.clearChangesIndex();
+                break;
+              case "no-instance":
+                sideEffects.clearChangesInstanceProperty();
+                break;
+              case "no-static":
+                sideEffects.clearChangesStaticProperty();
+                break;
+              default:
+                listener.internalError(spannable,
+                    "Unrecognized side-effect flag: $effect.");
+            }
+          }
+        }
+
+        if (depends == "none") {
+          sideEffects.clearAllDependencies();
+        } else if (depends == "all") {
+          // Don't do anything.
+        } else {
+          List<String> splitDependencies = depends.split(",");
+          if (splitDependencies.isEmpty) {
+            listener.internalError(spannable,
+                                   "Missing side-effect dependency flag.");
+          }
+          for (String dependency in splitDependencies) {
+            switch (dependency) {
+              case "no-index":
+                sideEffects.clearDependsOnIndexStore();
+                break;
+              case "no-instance":
+                sideEffects.clearDependsOnInstancePropertyStore();
+                break;
+              case "no-static":
+                sideEffects.clearDependsOnStaticPropertyStore();
+                break;
+              default:
+                listener.internalError(spannable,
+                    "Unrecognized side-effect flag: $dependency.");
+            }
+          }
+        }
+
+        setSideEffects(sideEffects);
+      }
+
       if (!specString.isEmpty) {
-        listener.internalError(spannable, "Invalid JS type string.");
+        listener.internalError(spannable, "Invalid JS spec string.");
       }
     } else {
       resolveTypesString(specString, onVar: () {
@@ -190,12 +283,10 @@
     NativeBehavior behavior = new NativeBehavior();
     behavior.codeTemplate =
         js.js.parseForeignJS(code.dartString.slowToString());
-    new SideEffectsVisitor(behavior.sideEffects)
-        .visit(behavior.codeTemplate.ast);
 
     String specString = specLiteral.dartString.slowToString();
 
-    resolveType(String typeString) {
+    dynamic resolveType(String typeString) {
       return _parseType(
           typeString,
           compiler,
@@ -203,14 +294,27 @@
           jsCall);
     }
 
+    bool sideEffectsAreEncodedInSpecString = false;
+
+    void setSideEffects(SideEffects newEffects) {
+      sideEffectsAreEncodedInSpecString = true;
+      behavior.sideEffects.setTo(newEffects);
+    }
+
     processSpecString(compiler, jsCall,
                       specString,
+                      setSideEffects: setSideEffects,
                       resolveType: resolveType,
                       typesReturned: behavior.typesReturned,
                       typesInstantiated: behavior.typesInstantiated,
                       objectType: compiler.objectClass.computeType(compiler),
                       nullType: compiler.nullClass.computeType(compiler));
 
+    if (!sideEffectsAreEncodedInSpecString) {
+      new SideEffectsVisitor(behavior.sideEffects)
+          .visit(behavior.codeTemplate.ast);
+    }
+
     return behavior;
   }
 
@@ -251,7 +355,7 @@
 
     String specString = specLiteral.dartString.slowToString();
 
-    resolveType(String typeString) {
+    dynamic resolveType(String typeString) {
       return _parseType(
           typeString,
           compiler,
@@ -259,8 +363,15 @@
           jsGlobalCall);
     }
 
+    void setSideEffects(SideEffects newEffects) {
+      compiler.internalError(jsGlobalCall,
+          'Embedded global calls may not have any side-effect overwrites: '
+          '$specString');
+    }
+
     processSpecString(compiler, jsGlobalCall,
                       specString,
+                      setSideEffects: setSideEffects,
                       resolveType: resolveType,
                       typesReturned: behavior.typesReturned,
                       typesInstantiated: behavior.typesInstantiated,
@@ -404,13 +515,13 @@
     }
   }
 
-  static _parseType(String typeString, Compiler compiler,
+  static dynamic _parseType(String typeString, Compiler compiler,
       lookup(name), locationNodeOrElement) {
     if (typeString == '=Object') return SpecialType.JsObject;
     if (typeString == 'dynamic') {
       return const DynamicType();
     }
-    DartType type = lookup(typeString);
+    var type = lookup(typeString);
     if (type != null) return type;
 
     int index = typeString.indexOf('<');
@@ -427,6 +538,7 @@
     compiler.internalError(
         _errorNode(locationNodeOrElement, compiler),
         "Type '$typeString' not found.");
+    return null;
   }
 
   static _errorNode(locationNodeOrElement, compiler) {
diff --git a/pkg/compiler/lib/src/native/ssa.dart b/pkg/compiler/lib/src/native/ssa.dart
index 0bd8d1b..09f4e03 100644
--- a/pkg/compiler/lib/src/native/ssa.dart
+++ b/pkg/compiler/lib/src/native/ssa.dart
@@ -85,7 +85,7 @@
     }
 
     builder.push(
-        new HForeign(
+        new HForeignCode(
             // TODO(sra): This could be cached.  The number of templates should
             // be proportional to the number of native methods, which is bounded
             // by the dart: libraries.
@@ -100,7 +100,7 @@
           'functions with zero parameters.');
     }
     LiteralString jsCode = nativeBody.asLiteralString();
-    builder.push(new HForeign.statement(
+    builder.push(new HForeignCode.statement(
         js.js.statementTemplateYielding(
             new js.LiteralStatement(jsCode.dartString.slowToString())),
         <HInstruction>[],
diff --git a/pkg/compiler/lib/src/resolution/access_semantics.dart b/pkg/compiler/lib/src/resolution/access_semantics.dart
new file mode 100644
index 0000000..6aaabf6
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/access_semantics.dart
@@ -0,0 +1,309 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// TODO(johnniwinther): Temporarily copied from analyzer2dart. Merge when
+// we shared code with the analyzer and this semantic visitor is complete.
+
+/**
+ * Code for classifying the semantics of identifiers appearing in a Dart file.
+ */
+library dart2js.access_semantics;
+
+import '../constants/expressions.dart';
+import '../elements/elements.dart';
+
+/// Enum representing the different kinds of destinations which a property
+/// access or method or function invocation might refer to.
+enum AccessKind {
+  /// The destination of the access is an instance method, property, or field
+  /// of a class, and thus must be determined dynamically.
+  DYNAMIC_PROPERTY,
+
+  // TODO(johnniwinther): Split these cases into captured and non-captured
+  // local access.
+  /// The destination of the access is a function that is defined locally within
+  /// an enclosing function or method.
+  LOCAL_FUNCTION,
+
+  /// The destination of the access is a variable that is defined locally within
+  /// an enclosing function or method.
+  LOCAL_VARIABLE,
+
+  /// The destination of the access is a variable that is defined as a parameter
+  /// to an enclosing function or method.
+  PARAMETER,
+
+  /// The destination of the access is a field that is defined statically within
+  /// a class.
+  STATIC_FIELD,
+
+  /// The destination of the access is a method that is defined statically
+  /// within a class.
+  STATIC_METHOD,
+
+  /// The destination of the access is a property getter that is defined
+  /// statically within a class.
+  STATIC_GETTER,
+
+  /// The destination of the access is a property setter that is defined
+  /// statically within a class.
+  STATIC_SETTER,
+
+  /// The destination of the access is a top level variable defined within a
+  /// library.
+  TOPLEVEL_FIELD,
+
+  /// The destination of the access is a top level method defined within a
+  /// library.
+  TOPLEVEL_METHOD,
+
+  /// The destination of the access is a top level property getter defined
+  /// within a library.
+  TOPLEVEL_GETTER,
+
+  /// The destination of the access is a top level property setter defined
+  /// within a library.
+  TOPLEVEL_SETTER,
+
+  /// The destination of the access is a toplevel class, or named mixin
+  /// application.
+  CLASS_TYPE_LITERAL,
+
+  /// The destination of the access is a function typedef.
+  TYPEDEF_TYPE_LITERAL,
+
+  /// The destination of the access is the built-in type "dynamic".
+  DYNAMIC_TYPE_LITERAL,
+
+  /// The destination of the access is a type parameter of the enclosing class.
+  TYPE_PARAMETER_TYPE_LITERAL,
+
+  /// The destination of the access is a (complex) expression. For instance the
+  /// function expression `(){}` in the function expression invocation `(){}()`.
+  EXPRESSION,
+
+  /// The destination of the access is `this` of the enclosing class.
+  THIS,
+
+  /// The destination of the access is an instance method, property, or field
+  /// of the enclosing class.
+  THIS_PROPERTY,
+
+  /// The destination of the access is a field of the super class of the
+  /// enclosing class.
+  SUPER_FIELD,
+
+  /// The destination of the access is a method of the super class of the
+  /// enclosing class.
+  SUPER_METHOD,
+
+  /// The destination of the access is a getter of the super class of the
+  /// enclosing class.
+  SUPER_GETTER,
+
+  /// The destination of the access is a setter of the super class of the
+  /// enclosing class.
+  SUPER_SETTER,
+
+  /// Compound access where read and write access different elements.
+  /// See [CompoundAccessKind].
+  COMPOUND,
+
+  /// The destination of the access is a compile-time constant.
+  CONSTANT,
+
+  /// The destination of the access is unresolved in a static context.
+  UNRESOLVED,
+}
+
+enum CompoundAccessKind {
+  /// Read from a static getter and write to static setter.
+  STATIC_GETTER_SETTER,
+  /// Read from a static method (closurize) and write to static setter.
+  STATIC_METHOD_SETTER,
+
+  /// Read from a top level getter and write to a top level setter.
+  TOPLEVEL_GETTER_SETTER,
+  /// Read from a top level method (closurize) and write to top level setter.
+  TOPLEVEL_METHOD_SETTER,
+
+  /// Read from one superclass field and write to another.
+  SUPER_FIELD_FIELD,
+  /// Read from a superclass field and write to a superclass setter.
+  SUPER_FIELD_SETTER,
+  /// Read from a superclass getter and write to a superclass setter.
+  SUPER_GETTER_SETTER,
+  /// Read from a superclass method (closurize) and write to a superclass
+  /// setter.
+  SUPER_METHOD_SETTER,
+  /// Read from a superclass getter and write to a superclass field.
+  SUPER_GETTER_FIELD,
+}
+
+/**
+ * Data structure used to classify the semantics of a property access or method
+ * or function invocation.
+ */
+class AccessSemantics {
+  /**
+   * The kind of access.
+   */
+  final AccessKind kind;
+
+  /**
+   * The element being accessed, if statically known.  This will be null if
+   * [kind] is DYNAMIC or if the element is undefined (e.g. an attempt to
+   * access a non-existent static method in a class).
+   */
+  Element get element => null;
+
+  /**
+   * The class containing the element being accessed, if this is a static
+   * reference to an element in a class.  This will be null if [kind] is
+   * DYNAMIC, LOCAL_FUNCTION, LOCAL_VARIABLE, PARAMETER, TOPLEVEL_CLASS, or
+   * TYPE_PARAMETER, or if the element being accessed is defined at toplevel
+   * within a library.
+   *
+   * Note: it is possible for [classElement] to be non-null and for [element]
+   * to be null; for example this occurs if the element being accessed is a
+   * non-existent static method or field inside an existing class.
+   */
+  ClassElement get classElement => null;
+
+  // TODO(paulberry): would it also be useful to store the libraryElement?
+
+  // TODO(johnniwinther): Do we need this?
+  /**
+   * When [kind] is DYNAMIC_PROPERTY, the expression whose runtime type
+   * determines the class in which [identifier] should be looked up.
+   *
+   * When [kind] is not DYNAMIC_PROPERTY, this field is always null.
+   */
+  /*Expression*/ get target => null;
+
+  ConstantExpression get constant => null;
+
+  AccessSemantics.expression()
+      : kind = AccessKind.EXPRESSION;
+
+  AccessSemantics.thisAccess()
+      : kind = AccessKind.THIS;
+
+  AccessSemantics.thisProperty()
+      : kind = AccessKind.THIS_PROPERTY;
+
+  AccessSemantics._(this.kind);
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('AccessSemantics[');
+    sb.write('kind=$kind,');
+    if (element != null) {
+      sb.write('element=');
+      if (classElement != null) {
+        sb.write('${classElement.name}.');
+      }
+      sb.write('${element}');
+    }
+    sb.write(']');
+    return sb.toString();
+  }
+}
+
+
+class DynamicAccess extends AccessSemantics {
+  final target;
+
+  DynamicAccess.dynamicProperty(this.target)
+      : super._(AccessKind.DYNAMIC_PROPERTY);
+}
+
+class ConstantAccess extends AccessSemantics {
+  final ConstantExpression constant;
+
+  ConstantAccess(AccessKind kind, this.constant)
+      : super._(kind);
+
+  ConstantAccess.classTypeLiteral(this.constant)
+      : super._(AccessKind.CLASS_TYPE_LITERAL);
+
+  ConstantAccess.typedefTypeLiteral(this.constant)
+      : super._(AccessKind.TYPEDEF_TYPE_LITERAL);
+
+  ConstantAccess.dynamicTypeLiteral(this.constant)
+      : super._(AccessKind.DYNAMIC_TYPE_LITERAL);
+}
+
+class StaticAccess extends AccessSemantics {
+  final Element element;
+
+  ClassElement get classElement => element.enclosingClass;
+
+  StaticAccess._(AccessKind kind, this.element)
+      : super._(kind);
+
+  StaticAccess.superSetter(MethodElement this.element)
+      : super._(AccessKind.SUPER_SETTER);
+
+  StaticAccess.superField(FieldElement this.element)
+      : super._(AccessKind.SUPER_FIELD);
+
+  StaticAccess.superMethod(MethodElement this.element)
+      : super._(AccessKind.SUPER_METHOD);
+
+  StaticAccess.superGetter(MethodElement this.element)
+      : super._(AccessKind.SUPER_GETTER);
+
+  StaticAccess.typeParameterTypeLiteral(TypeVariableElement this.element)
+      : super._(AccessKind.TYPE_PARAMETER_TYPE_LITERAL);
+
+  StaticAccess.localFunction(LocalFunctionElement this.element)
+      : super._(AccessKind.LOCAL_FUNCTION);
+
+  StaticAccess.localVariable(LocalVariableElement this.element)
+      : super._(AccessKind.LOCAL_VARIABLE);
+
+  StaticAccess.parameter(ParameterElement this.element)
+      : super._(AccessKind.PARAMETER);
+
+  StaticAccess.staticField(FieldElement this.element)
+      : super._(AccessKind.STATIC_FIELD);
+
+  StaticAccess.staticMethod(MethodElement this.element)
+      : super._(AccessKind.STATIC_METHOD);
+
+  StaticAccess.staticGetter(MethodElement this.element)
+      : super._(AccessKind.STATIC_GETTER);
+
+  StaticAccess.staticSetter(MethodElement this.element)
+      : super._(AccessKind.STATIC_SETTER);
+
+  StaticAccess.topLevelField(FieldElement this.element)
+      : super._(AccessKind.TOPLEVEL_FIELD);
+
+  StaticAccess.topLevelMethod(MethodElement this.element)
+      : super._(AccessKind.TOPLEVEL_METHOD);
+
+  StaticAccess.topLevelGetter(MethodElement this.element)
+      : super._(AccessKind.TOPLEVEL_GETTER);
+
+  StaticAccess.topLevelSetter(MethodElement this.element)
+      : super._(AccessKind.TOPLEVEL_SETTER);
+
+  StaticAccess.unresolved(this.element)
+      : super._(AccessKind.UNRESOLVED);
+}
+
+class CompoundAccessSemantics extends AccessSemantics {
+  final CompoundAccessKind compoundAccessKind;
+  final Element getter;
+  final Element setter;
+
+  CompoundAccessSemantics(this.compoundAccessKind,
+                          this.getter,
+                          this.setter)
+      : super._(AccessKind.COMPOUND);
+
+  Element get element => setter;
+}
diff --git a/pkg/compiler/lib/src/resolution/operators.dart b/pkg/compiler/lib/src/resolution/operators.dart
new file mode 100644
index 0000000..3207aca
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/operators.dart
@@ -0,0 +1,324 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.operators;
+
+enum UnaryOperatorKind {
+  NOT,
+  NEGATE,
+  COMPLEMENT,
+}
+
+class UnaryOperator {
+  final UnaryOperatorKind kind;
+  final String name;
+  final String selectorName;
+
+  const UnaryOperator(this.kind, this.name, this.selectorName);
+
+  bool get isUserDefinable => selectorName != null;
+
+  String toString() => name;
+
+  /// The unary ! operator.
+  static const UnaryOperator NOT =
+      const UnaryOperator(UnaryOperatorKind.NOT, '!', null);
+
+  /// The unary - operator.
+  static const UnaryOperator NEGATE =
+      const UnaryOperator(UnaryOperatorKind.NEGATE, '-', 'unary-');
+
+  /// The unary ~ operator.
+  static const UnaryOperator COMPLEMENT =
+      const UnaryOperator(UnaryOperatorKind.COMPLEMENT, '~', '~');
+
+  static UnaryOperator parse(String value) {
+    switch (value) {
+      case '!': return NOT;
+      case '-': return NEGATE;
+      case '~': return COMPLEMENT;
+      default: return null;
+    }
+  }
+}
+
+
+enum BinaryOperatorKind {
+  EQ,
+  NOT_EQ,
+  INDEX,
+  ADD,
+  SUB,
+  MUL,
+  DIV,
+  IDIV,
+  MOD,
+  SHL,
+  SHR,
+  GTEQ,
+  GT,
+  LTEQ,
+  LT,
+  AND,
+  OR,
+  XOR,
+}
+
+class BinaryOperator {
+  final BinaryOperatorKind kind;
+  final String name;
+
+  const BinaryOperator._(this.kind, this.name);
+
+  bool get isUserDefinable => true;
+  String get selectorName => name;
+
+  String toString() => name;
+
+  /// The == operator.
+  static const BinaryOperator EQ =
+      const BinaryOperator._(BinaryOperatorKind.EQ, '==');
+
+  /// The != operator.
+  static const BinaryOperator NOT_EQ = const _NotEqualsOperator();
+
+  /// The [] operator.
+  static const BinaryOperator INDEX =
+      const BinaryOperator._(BinaryOperatorKind.INDEX, '[]');
+
+  /// The binary + operator.
+  static const BinaryOperator ADD =
+      const BinaryOperator._(BinaryOperatorKind.ADD, '+');
+
+  /// The binary - operator.
+  static const BinaryOperator SUB =
+      const BinaryOperator._(BinaryOperatorKind.SUB, '-');
+
+  /// The binary * operator.
+  static const BinaryOperator MUL =
+      const BinaryOperator._(BinaryOperatorKind.MUL, '*');
+
+  /// The binary / operator.
+  static const BinaryOperator DIV =
+      const BinaryOperator._(BinaryOperatorKind.DIV, '/');
+
+  /// The binary ~/ operator.
+  static const BinaryOperator IDIV =
+      const BinaryOperator._(BinaryOperatorKind.IDIV, '~/');
+
+  /// The binary % operator.
+  static const BinaryOperator MOD =
+      const BinaryOperator._(BinaryOperatorKind.MOD, '%');
+
+  /// The binary << operator.
+  static const BinaryOperator SHL =
+      const BinaryOperator._(BinaryOperatorKind.SHL, '<<');
+
+  /// The binary >> operator.
+  static const BinaryOperator SHR =
+      const BinaryOperator._(BinaryOperatorKind.SHR, '>>');
+
+  /// The binary >= operator.
+  static const BinaryOperator GTEQ =
+      const BinaryOperator._(BinaryOperatorKind.GTEQ, '>=');
+
+  /// The binary > operator.
+  static const BinaryOperator GT =
+      const BinaryOperator._(BinaryOperatorKind.GT, '>');
+
+  /// The binary <= operator.
+  static const BinaryOperator LTEQ =
+      const BinaryOperator._(BinaryOperatorKind.LTEQ, '<=');
+
+  /// The binary < operator.
+  static const BinaryOperator LT =
+      const BinaryOperator._(BinaryOperatorKind.LT, '<');
+
+  /// The binary & operator.
+  static const BinaryOperator AND =
+      const BinaryOperator._(BinaryOperatorKind.AND, '&');
+
+  /// The binary | operator.
+  static const BinaryOperator OR =
+      const BinaryOperator._(BinaryOperatorKind.OR, '|');
+
+  /// The binary ^ operator.
+  static const BinaryOperator XOR =
+      const BinaryOperator._(BinaryOperatorKind.XOR, '^');
+
+  static BinaryOperator parse(String value) {
+    switch (value) {
+      case '==': return EQ;
+      case '!=': return NOT_EQ;
+      case '[]': return INDEX;
+      case '*': return MUL;
+      case '/': return DIV;
+      case '%': return MOD;
+      case '~/': return IDIV;
+      case '+': return ADD;
+      case '-': return SUB;
+      case '<<': return SHL;
+      case '>>': return SHR;
+      case '>=': return GTEQ;
+      case '>': return GT;
+      case '<=': return LTEQ;
+      case '<': return LT;
+      case '&': return AND;
+      case '^': return XOR;
+      case '|': return OR;
+      default: return null;
+    }
+  }
+}
+
+/// The operator !=, which is not user definable operator but instead is a negation
+class _NotEqualsOperator extends BinaryOperator {
+  const _NotEqualsOperator() : super._(BinaryOperatorKind.NOT_EQ, '!=');
+
+  bool get isUserDefinable => false;
+
+  String get selectorName => '==';
+}
+
+enum AssignmentOperatorKind {
+  ASSIGN,
+  ADD,
+  SUB,
+  MUL,
+  DIV,
+  IDIV,
+  MOD,
+  SHL,
+  SHR,
+  AND,
+  OR,
+  XOR,
+}
+
+class AssignmentOperator {
+  final AssignmentOperatorKind kind;
+  final BinaryOperator binaryOperator;
+  final String name;
+  final bool isUserDefinable;
+
+  const AssignmentOperator._(this.kind, this.name, this.binaryOperator,
+                             {this.isUserDefinable: true});
+
+  String get selectorName {
+    return binaryOperator != null ? binaryOperator.selectorName: null;
+  }
+
+  String toString() => name;
+
+  /// The = operator.
+  static const AssignmentOperator ASSIGN =
+      const AssignmentOperator._(AssignmentOperatorKind.ASSIGN, '=',
+                                 null, isUserDefinable: false);
+
+  /// The += assignment operator.
+  static const AssignmentOperator ADD =
+      const AssignmentOperator._(AssignmentOperatorKind.ADD, '+=',
+                                 BinaryOperator.ADD);
+
+  /// The -= assignment operator.
+  static const AssignmentOperator SUB =
+      const AssignmentOperator._(AssignmentOperatorKind.SUB, '-=',
+                                 BinaryOperator.SUB);
+
+  /// The *= assignment operator.
+  static const AssignmentOperator MUL =
+      const AssignmentOperator._(AssignmentOperatorKind.MUL, '*=',
+                                 BinaryOperator.MUL);
+
+  /// The /= assignment operator.
+  static const AssignmentOperator DIV =
+      const AssignmentOperator._(AssignmentOperatorKind.DIV, '/=',
+                                 BinaryOperator.DIV);
+
+  /// The ~/= assignment operator.
+  static const AssignmentOperator IDIV =
+      const AssignmentOperator._(AssignmentOperatorKind.IDIV, '~/=',
+                                 BinaryOperator.IDIV);
+
+  /// The %= assignment operator.
+  static const AssignmentOperator MOD =
+      const AssignmentOperator._(AssignmentOperatorKind.MOD, '%=',
+                                 BinaryOperator.MOD);
+
+  /// The <<= assignment operator.
+  static const AssignmentOperator SHL =
+      const AssignmentOperator._(AssignmentOperatorKind.SHL, '<<=',
+                                 BinaryOperator.SHL);
+
+  /// The >>= assignment operator.
+  static const AssignmentOperator SHR =
+      const AssignmentOperator._(AssignmentOperatorKind.SHR, '>>=',
+                                 BinaryOperator.SHR);
+
+  /// The &= assignment operator.
+  static const AssignmentOperator AND =
+      const AssignmentOperator._(AssignmentOperatorKind.AND, '&=',
+                                 BinaryOperator.AND);
+
+  /// The |= assignment operator.
+  static const AssignmentOperator OR =
+      const AssignmentOperator._(AssignmentOperatorKind.OR, '|=',
+                                 BinaryOperator.OR);
+
+  /// The ^= assignment operator.
+  static const AssignmentOperator XOR =
+      const AssignmentOperator._(AssignmentOperatorKind.XOR, '^=',
+                                 BinaryOperator.XOR);
+
+  static AssignmentOperator parse(String value) {
+    switch (value) {
+      case '=': return ASSIGN;
+      case '*=': return MUL;
+      case '/=': return DIV;
+      case '%=': return MOD;
+      case '~/=': return IDIV;
+      case '+=': return ADD;
+      case '-=': return SUB;
+      case '<<=': return SHL;
+      case '>>=': return SHR;
+      case '&=': return AND;
+      case '^=': return XOR;
+      case '|=': return OR;
+      default: return null;
+    }
+  }
+}
+
+
+enum IncDecOperatorKind {
+  INC, DEC
+}
+
+class IncDecOperator {
+  final IncDecOperatorKind kind;
+  final String name;
+  final BinaryOperator binaryOperator;
+
+  const IncDecOperator._(this.kind, this.name, this.binaryOperator);
+
+  String get selectorName => binaryOperator.selectorName;
+
+  String toString() => name;
+
+  /// The prefix/postfix ++ operator.
+  static const IncDecOperator INC =
+      const IncDecOperator._(IncDecOperatorKind.INC, '++', BinaryOperator.ADD);
+
+  /// The prefix/postfix -- operator.
+  static const IncDecOperator DEC =
+      const IncDecOperator._(IncDecOperatorKind.DEC, '--', BinaryOperator.SUB);
+
+  static IncDecOperator parse(String value) {
+    switch (value) {
+      case '++': return INC;
+      case '--': return DEC;
+      default: return null;
+    }
+  }
+}
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor.dart b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
new file mode 100644
index 0000000..7e259aa
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/semantic_visitor.dart
@@ -0,0 +1,2768 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.semantics_visitor;
+
+import '../constants/expressions.dart';
+import '../dart2jslib.dart' show invariant;
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../tree/tree.dart';
+import '../universe/universe.dart';
+import '../util/util.dart' show Spannable, SpannableAssertionFailure;
+import 'access_semantics.dart';
+import 'operators.dart';
+import 'resolution.dart';
+import 'send_structure.dart';
+
+part 'semantic_visitor_mixins.dart';
+part 'send_resolver.dart';
+
+abstract class SemanticVisitor<R, A> extends Visitor<R>
+    with SendResolverMixin {
+  TreeElements elements;
+
+  SemanticVisitor(this.elements);
+
+  SemanticSendVisitor<R, A> get sendVisitor;
+
+  @override
+  R visitIdentifier(Identifier node) {
+    // TODO(johnniwinther): Support argument.
+    A arg = null;
+    if (node.isThis()) {
+      // TODO(johnniwinther): Parse `this` as a [Send] whose selector is `this`
+      // to normalize with `this(...)`.
+      return sendVisitor.visitThisGet(node, arg);
+    }
+    return null;
+  }
+
+  @override
+  R visitSend(Send node) {
+    // TODO(johnniwinther): Support argument.
+    A arg = null;
+
+    SendStructure structure = computeSendStructure(node);
+    if (structure == null) {
+      return internalError(node, 'No structure for $node');
+    } else {
+      return structure.dispatch(sendVisitor, node, arg);
+    }
+  }
+
+  @override
+  R visitSendSet(SendSet node) {
+    return visitSend(node);
+  }
+}
+
+// TODO(johnniwinther): Add visits for [visitLocalConstantGet],
+// [visitLocalConstantInvoke], [visitStaticConstantGet], etc.
+abstract class SemanticSendVisitor<R, A> {
+  R apply(Node node, A arg);
+
+  /// Read of the [parameter].
+  ///
+  /// For instance:
+  ///     m(parameter) => parameter;
+  ///
+  R visitParameterGet(
+      Send node,
+      ParameterElement parameter,
+      A arg);
+
+  /// Assignment of [rhs] to the [parameter].
+  ///
+  /// For instance:
+  ///     m(parameter) {
+  ///       parameter = rhs;
+  ///     }
+  ///
+  R visitParameterSet(
+      SendSet node,
+      ParameterElement parameter,
+      Node rhs,
+      A arg);
+
+  /// Assignment of [rhs] to the final [parameter].
+  ///
+  /// For instance:
+  ///     m(final parameter) {
+  ///       parameter = rhs;
+  ///     }
+  ///
+  R errorFinalParameterSet(
+      SendSet node,
+      ParameterElement parameter,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the [parameter] with [arguments].
+  ///
+  /// For instance:
+  ///     m(parameter) {
+  ///       parameter(null, 42);
+  ///     }
+  ///
+  R visitParameterInvoke(
+      Send node,
+      ParameterElement parameter,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Read of the local [variable].
+  ///
+  /// For instance:
+  ///     m() {
+  ///       var variable;
+  ///       return variable;
+  ///     }
+  ///
+  R visitLocalVariableGet(
+      Send node,
+      LocalVariableElement variable,
+      A arg);
+
+  /// Assignment of [rhs] to the local [variable].
+  ///
+  /// For instance:
+  ///     m() {
+  ///       var variable;
+  ///       variable = rhs;
+  ///     }
+  ///
+  R visitLocalVariableSet(
+      SendSet node,
+      LocalVariableElement variable,
+      Node rhs,
+      A arg);
+
+  /// Assignment of [rhs] to the final local [variable].
+  ///
+  /// For instance:
+  ///     m() {
+  ///       final variable = null;
+  ///       variable = rhs;
+  ///     }
+  ///
+  R errorFinalLocalVariableSet(
+      SendSet node,
+      LocalVariableElement variable,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the local variable [variable] with [arguments].
+  ///
+  /// For instance:
+  ///     m() {
+  ///       var variable;
+  ///       variable(null, 42);
+  ///     }
+  ///
+  R visitLocalVariableInvoke(
+      Send node,
+      LocalVariableElement variable,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Closurization of the local [function].
+  ///
+  /// For instance:
+  ///     m() {
+  ///       o(a, b) {}
+  ///       return o;
+  ///     }
+  ///
+  R visitLocalFunctionGet(
+      Send node,
+      LocalFunctionElement function,
+      A arg);
+
+  /// Assignment of [rhs] to the local [function].
+  ///
+  /// For instance:
+  ///     m() {
+  ///       o(a, b) {}
+  ///       o = rhs;
+  ///     }
+  ///
+  R errorLocalFunctionSet(
+      SendSet node,
+      LocalFunctionElement function,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the local [function] with [arguments].
+  ///
+  /// For instance:
+  ///     m() {
+  ///       o(a, b) {}
+  ///       return o(null, 42);
+  ///     }
+  ///
+  R visitLocalFunctionInvoke(
+      Send node,
+      LocalFunctionElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Getter call on [receiver] of the property defined by [selector].
+  ///
+  /// For instance
+  ///     m(receiver) => receiver.foo;
+  ///
+  R visitDynamicPropertyGet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      A arg);
+
+  /// Setter call on [receiver] with argument [rhs] of the property defined by
+  /// [selector].
+  ///
+  /// For instance
+  ///     m(receiver) {
+  ///       receiver.foo = rhs;
+  ///     }
+  ///
+  R visitDynamicPropertySet(
+      SendSet node,
+      Node receiver,
+      Selector selector,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the property defined by [selector] on [receiver] with
+  /// [arguments].
+  ///
+  /// For instance
+  ///     m(receiver) {
+  ///       receiver.foo(null, 42);
+  ///     }
+  ///
+  R visitDynamicPropertyInvoke(
+      Send node,
+      Node receiver,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Getter call on `this` of the property defined by [selector].
+  ///
+  /// For instance
+  ///     class C {
+  ///       m() => this.foo;
+  ///     }
+  ///
+  /// or
+  ///
+  ///     class C {
+  ///       m() => foo;
+  ///     }
+  ///
+  R visitThisPropertyGet(
+      Send node,
+      Selector selector,
+      A arg);
+
+  /// Setter call on `this` with argument [rhs] of the property defined by
+  /// [selector].
+  ///     class C {
+  ///       m() { this.foo = rhs; }
+  ///     }
+  ///
+  /// or
+  ///
+  ///     class C {
+  ///       m() { foo = rhs; }
+  ///     }
+  ///
+  R visitThisPropertySet(
+      SendSet node,
+      Selector selector,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the property defined by [selector] on `this` with
+  /// [arguments].
+  ///
+  /// For instance
+  ///     class C {
+  ///       m() { this.foo(null, 42); }
+  ///     }
+  ///
+  /// or
+  ///
+  ///     class C {
+  ///       m() { foo(null, 42); }
+  ///     }
+  ///
+  ///
+  R visitThisPropertyInvoke(
+      Send node,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Read of `this`.
+  ///
+  /// For instance
+  ///     class C {
+  ///       m() => this;
+  ///     }
+  ///
+  R visitThisGet(
+      Identifier node,
+      A arg);
+
+  /// Invocation of `this` with [arguments].
+  ///
+  /// For instance
+  ///     class C {
+  ///       m() => this(null, 42);
+  ///     }
+  ///
+  R visitThisInvoke(
+      Send node,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+
+  /// Read of the super [field].
+  ///
+  /// For instance
+  ///     class B {
+  ///       var foo;
+  ///     }
+  ///     class C extends B {
+  ///        m() => super.foo;
+  ///     }
+  ///
+  R visitSuperFieldGet(
+      Send node,
+      FieldElement field,
+      A arg);
+
+  /// Assignment of [rhs] to the super [field].
+  ///
+  /// For instance
+  ///     class B {
+  ///       var foo;
+  ///     }
+  ///     class C extends B {
+  ///        m() { super.foo = rhs; }
+  ///     }
+  ///
+  R visitSuperFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg);
+
+  /// Assignment of [rhs] to the final static [field].
+  ///
+  /// For instance
+  ///     class B {
+  ///       final foo = null;
+  ///     }
+  ///     class C extends B {
+  ///        m() { super.foo = rhs; }
+  ///     }
+  ///
+  R errorFinalSuperFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the super [field] with [arguments].
+  ///
+  /// For instance
+  ///     class B {
+  ///       var foo;
+  ///     }
+  ///     class C extends B {
+  ///        m() { super.foo(null, 42); }
+  ///     }
+  ///
+  R visitSuperFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Closurization of the super [method].
+  ///
+  /// For instance
+  ///     class B {
+  ///       foo(a, b) {}
+  ///     }
+  ///     class C extends B {
+  ///        m() => super.foo;
+  ///     }
+  ///
+  R visitSuperMethodGet(
+      Send node,
+      MethodElement method,
+      A arg);
+
+  /// Invocation of the super [method] with [arguments].
+  ///
+  /// For instance
+  ///     class B {
+  ///       foo(a, b) {}
+  ///     }
+  ///     class C extends B {
+  ///        m() { super.foo(null, 42); }
+  ///     }
+  ///
+  R visitSuperMethodInvoke(
+      Send node,
+      MethodElement method,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Assignment of [rhs] to the super [method].
+  ///
+  /// For instance
+  ///     class B {
+  ///       foo(a, b) {}
+  ///     }
+  ///     class C extends B {
+  ///        m() { super.foo = rhs; }
+  ///     }
+  ///
+  R errorSuperMethodSet(
+      Send node,
+      MethodElement method,
+      Node rhs,
+      A arg);
+
+  /// Getter call to the super [getter].
+  ///
+  /// For instance
+  ///     class B {
+  ///       get foo => null;
+  ///     }
+  ///     class C extends B {
+  ///        m() => super.foo;
+  ///     }
+  ///
+  R visitSuperGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg);
+
+  /// Getter call the super [setter].
+  ///
+  /// For instance
+  ///     class B {
+  ///       set foo(_) {}
+  ///     }
+  ///     class C extends B {
+  ///        m() => super.foo;
+  ///     }
+  ///
+  R errorSuperSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg);
+
+  /// Setter call to the super [setter].
+  ///
+  /// For instance
+  ///     class B {
+  ///       set foo(_) {}
+  ///     }
+  ///     class C extends B {
+  ///        m() { super.foo = rhs; }
+  ///     }
+  ///
+  R visitSuperSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg);
+
+  /// Assignment of [rhs] to the super [getter].
+  ///
+  /// For instance
+  ///     class B {
+  ///       get foo => null;
+  ///     }
+  ///     class C extends B {
+  ///        m() { super.foo = rhs; }
+  ///     }
+  ///
+  R errorSuperGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the super [getter] with [arguments].
+  ///
+  /// For instance
+  ///     class B {
+  ///       get foo => null;
+  ///     }
+  ///     class C extends B {
+  ///        m() { super.foo(null, 42; }
+  ///     }
+  ///
+  R visitSuperGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Invocation of the super [setter] with [arguments].
+  ///
+  /// For instance
+  ///     class B {
+  ///       set foo(_) {}
+  ///     }
+  ///     class C extends B {
+  ///        m() { super.foo(null, 42; }
+  ///     }
+  ///
+  R errorSuperSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Invocation of a [expression] with [arguments].
+  ///
+  /// For instance
+  ///     m() => (a, b){}(null, 42);
+  ///
+  R visitExpressionInvoke(
+      Send node,
+      Node expression,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Read of the static [field].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static var foo;
+  ///     }
+  ///     m() => C.foo;
+  ///
+  R visitStaticFieldGet(
+      Send node,
+      FieldElement field,
+      A arg);
+
+  /// Assignment of [rhs] to the static [field].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static var foo;
+  ///     }
+  ///     m() { C.foo = rhs; }
+  ///
+  R visitStaticFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg);
+
+  /// Assignment of [rhs] to the final static [field].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static final foo;
+  ///     }
+  ///     m() { C.foo = rhs; }
+  ///
+  R errorFinalStaticFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the static [field] with [arguments].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static var foo;
+  ///     }
+  ///     m() { C.foo(null, 42); }
+  ///
+  R visitStaticFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Closurization of the static [function].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static foo(a, b) {}
+  ///     }
+  ///     m() => C.foo;
+  ///
+  R visitStaticFunctionGet(
+      Send node,
+      MethodElement function,
+      A arg);
+
+  /// Invocation of the static [function] with [arguments].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static foo(a, b) {}
+  ///     }
+  ///     m() { C.foo(null, 42); }
+  ///
+  R visitStaticFunctionInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Assignment of [rhs] to the static [function].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static foo(a, b) {}
+  ///     }
+  ///     m() { C.foo = rhs; }
+  ///
+  R errorStaticFunctionSet(
+      Send node,
+      MethodElement function,
+      Node rhs,
+      A arg);
+
+  /// Getter call to the static [getter].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static get foo => null;
+  ///     }
+  ///     m() => C.foo;
+  ///
+  R visitStaticGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg);
+
+  /// Getter call the static [setter].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static set foo(_) {}
+  ///     }
+  ///     m() => C.foo;
+  ///
+  R errorStaticSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg);
+
+  /// Setter call to the static [setter].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static set foo(_) {}
+  ///     }
+  ///     m() { C.foo = rhs; }
+  ///
+  R visitStaticSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg);
+
+  /// Assignment of [rhs] to the static [getter].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static get foo => null;
+  ///     }
+  ///     m() { C.foo = rhs; }
+  ///
+  R errorStaticGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the static [getter] with [arguments].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static get foo => null;
+  ///     }
+  ///     m() { C.foo(null, 42; }
+  ///
+  R visitStaticGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Invocation of the static [setter] with [arguments].
+  ///
+  /// For instance
+  ///     class C {
+  ///       static set foo(_) {}
+  ///     }
+  ///     m() { C.foo(null, 42; }
+  ///
+  R errorStaticSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Read of the top level [field].
+  ///
+  /// For instance
+  ///     var foo;
+  ///     m() => foo;
+  ///
+  R visitTopLevelFieldGet(
+      Send node,
+      FieldElement field,
+      A arg);
+
+  /// Assignment of [rhs] to the top level [field].
+  ///
+  /// For instance
+  ///     var foo;
+  ///     m() { foo = rhs; }
+  ///
+  R visitTopLevelFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg);
+
+  /// Assignment of [rhs] to the final top level [field].
+  ///
+  /// For instance
+  ///     final foo = null;
+  ///     m() { foo = rhs; }
+  ///
+  R errorFinalTopLevelFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the top level [field] with [arguments].
+  ///
+  /// For instance
+  ///     var foo;
+  ///     m() { foo(null, 42); }
+  ///
+  R visitTopLevelFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Closurization of the top level [function].
+  ///
+  /// For instance
+  ///     foo(a, b) {};
+  ///     m() => foo;
+  ///
+  R visitTopLevelFunctionGet(
+      Send node,
+      MethodElement function,
+      A arg);
+
+  /// Invocation of the top level [function] with [arguments].
+  ///
+  /// For instance
+  ///     foo(a, b) {};
+  ///     m() { foo(null, 42); }
+  ///
+  R visitTopLevelFunctionInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Assignment of [rhs] to the top level [function].
+  ///
+  /// For instance
+  ///     foo(a, b) {};
+  ///     m() { foo = rhs; }
+  ///
+  R errorTopLevelFunctionSet(
+      Send node,
+      MethodElement function,
+      Node rhs,
+      A arg);
+
+  /// Getter call to the top level [getter].
+  ///
+  /// For instance
+  ///     get foo => null;
+  ///     m() => foo;
+  ///
+  R visitTopLevelGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg);
+
+  /// Getter call the top level [setter].
+  ///
+  /// For instance
+  ///     set foo(_) {}
+  ///     m() => foo;
+  ///
+  R errorTopLevelSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg);
+
+  /// Setter call to the top level [setter].
+  ///
+  /// For instance
+  ///     set foo(_) {}
+  ///     m() { foo = rhs; }
+  ///
+  R visitTopLevelSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg);
+
+  /// Assignment of [rhs] to the top level [getter].
+  ///
+  /// For instance
+  ///     get foo => null;
+  ///     m() { foo = rhs; }
+  ///
+  R errorTopLevelGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the top level [getter] with [arguments].
+  ///
+  /// For instance
+  ///     get foo => null;
+  ///     m() { foo(null, 42); }
+  ///
+  R visitTopLevelGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Invocation of the top level [setter] with [arguments].
+  ///
+  /// For instance
+  ///     set foo(_) {};
+  ///     m() { foo(null, 42); }
+  ///
+  R errorTopLevelSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Read of the type literal for class [element].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m() => C;
+  ///
+  R visitClassTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg);
+
+  /// Invocation of the type literal for class [element] with [arguments].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m() => C(null, 42);
+  ///
+  R visitClassTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Assignment of [rhs] to the type literal for class [element].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m() { C = rhs; }
+  ///
+  R errorClassTypeLiteralSet(
+      SendSet node,
+      TypeConstantExpression constant,
+      Node rhs,
+      A arg);
+
+  /// Read of the type literal for typedef [element].
+  ///
+  /// For instance
+  ///     typedef F();
+  ///     m() => F;
+  ///
+  R visitTypedefTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg);
+
+  /// Invocation of the type literal for typedef [element] with [arguments].
+  ///
+  /// For instance
+  ///     typedef F();
+  ///     m() => F(null, 42);
+  ///
+  R visitTypedefTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Assignment of [rhs] to the type literal for typedef [element].
+  ///
+  /// For instance
+  ///     typedef F();
+  ///     m() { F = rhs; }
+  ///
+  R errorTypedefTypeLiteralSet(
+      SendSet node,
+      TypeConstantExpression constant,
+      Node rhs,
+      A arg);
+
+  /// Read of the type literal for type variable [element].
+  ///
+  /// For instance
+  ///     class C<T> {
+  ///       m() => T;
+  ///     }
+  ///
+  R visitTypeVariableTypeLiteralGet(
+      Send node,
+      TypeVariableElement element,
+      A arg);
+
+  /// Invocation of the type literal for type variable [element] with
+  /// [arguments].
+  ///
+  /// For instance
+  ///     class C<T> {
+  ///       m() { T(null, 42); }
+  ///     }
+  ///
+  R visitTypeVariableTypeLiteralInvoke(
+      Send node,
+      TypeVariableElement element,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Assignment of [rhs] to the type literal for type variable [element].
+  ///
+  /// For instance
+  ///     class C<T> {
+  ///       m() { T = rhs; }
+  ///     }
+  ///
+  R errorTypeVariableTypeLiteralSet(
+      SendSet node,
+      TypeVariableElement element,
+      Node rhs,
+      A arg);
+
+  /// Read of the type literal for `dynamic`.
+  ///
+  /// For instance
+  ///     m() => dynamic;
+  ///
+  R visitDynamicTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg);
+
+  /// Invocation of the type literal for `dynamic` with [arguments].
+  ///
+  /// For instance
+  ///     m() { dynamic(null, 42); }
+  ///
+  R visitDynamicTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Assignment of [rhs] to the type literal for `dynamic`.
+  ///
+  /// For instance
+  ///     m() { dynamic = rhs; }
+  ///
+  R errorDynamicTypeLiteralSet(
+      SendSet node,
+      TypeConstantExpression constant,
+      Node rhs,
+      A arg);
+
+  /// Call to `assert` with [expression] as the condition.
+  ///
+  /// For instance:
+  ///     m() { assert(expression); }
+  ///
+  R visitAssert(
+      Send node,
+      Node expression,
+      A arg);
+
+  /// Call to `assert` with the wrong number of [arguments].
+  ///
+  /// For instance:
+  ///     m() { assert(); }
+  /// or
+  ///     m() { assert(expression1, expression2); }
+  ///
+  R errorInvalidAssert(
+      Send node,
+      NodeList arguments,
+      A arg);
+
+  /// Binary expression `left operator right` where [operator] is a user
+  /// definable operator. Binary expressions using operator `==` are handled
+  /// by [visitEquals] and index operations `a[b]` are handled by [visitIndex].
+  ///
+  /// For instance:
+  ///     add(a, b) => a + b;
+  ///     sub(a, b) => a - b;
+  ///     mul(a, b) => a * b;
+  ///
+  R visitBinary(
+      Send node,
+      Node left,
+      BinaryOperator operator,
+      Node right,
+      A arg);
+
+  /// Binary expression `super operator argument` where [operator] is a user
+  /// definable operator implemented on a superclass by [function]. Binary
+  /// expressions using operator `==` are handled by [visitSuperEquals].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       operator +(_) => null;
+  ///     }
+  ///     class C extends B {
+  ///       m(a) => super + a;
+  ///     }
+  ///
+  R visitSuperBinary(
+      Send node,
+      FunctionElement function,
+      BinaryOperator operator,
+      Node argument,
+      A arg);
+
+  /// Index expression `receiver[index]`.
+  ///
+  /// For instance:
+  ///     lookup(a, b) => a[b];
+  ///
+  R visitIndex(
+      Send node,
+      Node receiver,
+      Node index,
+      A arg);
+
+  /// Prefix operation on an index expression `operator receiver[index]` where
+  /// the operation is defined by [operator].
+  ///
+  /// For instance:
+  ///     lookup(a, b) => --a[b];
+  ///
+  R visitIndexPrefix(
+      Send node,
+      Node receiver,
+      Node index,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix operation on an index expression `receiver[index] operator` where
+  /// the operation is defined by [operator].
+  ///
+  /// For instance:
+  ///     lookup(a, b) => a[b]++;
+  ///
+  R visitIndexPostfix(
+      Send node,
+      Node receiver,
+      Node index,
+      IncDecOperator operator,
+      A arg);
+
+  /// Index expression `super[index]` where 'operator []' is implemented on a
+  /// superclass by [function].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       operator [](_) => null;
+  ///     }
+  ///     class C extends B {
+  ///       m(a) => super[a];
+  ///     }
+  ///
+  R visitSuperIndex(
+      Send node,
+      FunctionElement function,
+      Node index,
+      A arg);
+
+  /// Prefix operation on an index expression `operator super[index]` where
+  /// 'operator []' is implemented on a superclass by [indexFunction] and
+  /// 'operator []=' is implemented on by [indexSetFunction] and the operation
+  /// is defined by [operator].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       operator [](_) => null;
+  ///       operator []=(a, b) {}
+  ///     }
+  ///     class C extends B {
+  ///       m(a) => --super[a];
+  ///     }
+  ///
+  R visitSuperIndexPrefix(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix operation on an index expression `super[index] operator` where
+  /// 'operator []' is implemented on a superclass by [indexFunction] and
+  /// 'operator []=' is implemented on by [indexSetFunction] and the operation
+  /// is defined by [operator].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       operator [](_) => null;
+  ///       operator []=(a, b) {}
+  ///     }
+  ///     class C extends B {
+  ///       m(a) => super[a]++;
+  ///     }
+  ///
+  R visitSuperIndexPostfix(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      IncDecOperator operator,
+      A arg);
+
+  /// Index expression `super[index]` where 'operator []' is unresolved.
+  ///
+  /// For instance:
+  ///     class B {}
+  ///     class C extends B {
+  ///       m(a) => super[a];
+  ///     }
+  ///
+  R errorUnresolvedSuperIndex(
+      Send node,
+      Element element,
+      Node index,
+      A arg);
+
+  /// Prefix operation on an index expression `operator super[index]` where
+  /// 'operator []' or 'operator []=' is unresolved and the operation
+  /// is defined by [operator].
+  ///
+  /// For instance:
+  ///     class B {}
+  ///     class C extends B {
+  ///       m(a) => --super[a];
+  ///     }
+  ///
+  R errorUnresolvedSuperIndexPrefix(
+      Send node,
+      Element function,
+      Node index,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix operation on an index expression `super[index] operator` where
+  /// 'operator []' or 'operator []=' is unresolved and the operation
+  /// is defined by [operator].
+  ///
+  /// For instance:
+  ///     class B {}
+  ///     class C extends B {
+  ///       m(a) => super[a]++;
+  ///     }
+  ///
+  R errorUnresolvedSuperIndexPostfix(
+      Send node,
+      Element function,
+      Node index,
+      IncDecOperator operator,
+      A arg);
+
+  /// Binary expression `left == right`.
+  ///
+  /// For instance:
+  ///     neq(a, b) => a != b;
+  ///
+  R visitNotEquals(
+      Send node,
+      Node left,
+      Node right,
+      A arg);
+
+  /// Binary expression `super != argument` where `==` is implemented on a
+  /// superclass by [function].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       operator +(_) => null;
+  ///     }
+  ///     class C extends B {
+  ///       m(a) => super + a;
+  ///     }
+  ///
+  R visitSuperNotEquals(
+      Send node,
+      FunctionElement function,
+      Node argument,
+      A arg);
+
+  /// Binary expression `left == right`.
+  ///
+  /// For instance:
+  ///     eq(a, b) => a == b;
+  ///
+  R visitEquals(
+      Send node,
+      Node left,
+      Node right,
+      A arg);
+
+  /// Binary expression `super == argument` where `==` is implemented on a
+  /// superclass by [function].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       operator ==(_) => null;
+  ///     }
+  ///     class C extends B {
+  ///       m(a) => super == a;
+  ///     }
+  ///
+  R visitSuperEquals(
+      Send node,
+      FunctionElement function,
+      Node argument,
+      A arg);
+
+  /// Unary expression `operator expression` where [operator] is a user
+  /// definable operator.
+  ///
+  /// For instance:
+  ///     neg(a, b) => -a;
+  ///     comp(a, b) => ~a;
+  ///
+  R visitUnary(
+      Send node,
+      UnaryOperator operator,
+      Node expression,
+      A arg);
+
+  /// Unary expression `operator super` where [operator] is a user definable
+  /// operator implemented on a superclass by [function].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       operator -() => null;
+  ///     }
+  ///     class C extends B {
+  ///       m(a) => -super;
+  ///     }
+  ///
+  R visitSuperUnary(
+      Send node,
+      UnaryOperator operator,
+      FunctionElement function,
+      A arg);
+
+  /// Unary expression `!expression`.
+  ///
+  /// For instance:
+  ///     not(a) => !a;
+  ///
+  R visitNot(
+      Send node,
+      Node expression,
+      A arg);
+
+  /// Index set expression `receiver[index] = rhs`.
+  ///
+  /// For instance:
+  ///     m(receiver, index, rhs) => receiver[index] = rhs;
+  ///
+  R visitIndexSet(
+      SendSet node,
+      Node receiver,
+      Node index,
+      Node rhs,
+      A arg);
+
+  /// Index set expression `super[index] = rhs` where `operator []=` is defined
+  /// on a superclass by [function].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       operator []=(a, b) {}
+  ///     }
+  ///     class C extends B {
+  ///       m(a, b) => super[a] = b;
+  ///     }
+  ///
+  R visitSuperIndexSet(
+      SendSet node,
+      FunctionElement function,
+      Node index,
+      Node rhs,
+      A arg);
+
+  /// Logical and, &&, expression with operands [left] and [right].
+  ///
+  /// For instance
+  ///     m() => left && right;
+  ///
+  R visitLogicalAnd(
+      Send node,
+      Node left,
+      Node right,
+      A arg);
+
+  /// Logical or, ||, expression with operands [left] and [right].
+  ///
+  /// For instance
+  ///     m() => left || right;
+  ///
+  R visitLogicalOr(
+      Send node,
+      Node left,
+      Node right,
+      A arg);
+
+  /// Is test of [expression] against [type].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m() => expression is C;
+  ///
+  R visitIs(
+      Send node,
+      Node expression,
+      DartType type,
+      A arg);
+
+  /// Is not test of [expression] against [type].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m() => expression is! C;
+  ///
+  R visitIsNot(
+      Send node,
+      Node expression,
+      DartType type,
+      A arg);
+
+  /// As cast of [expression] to [type].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m() => expression as C;
+  ///
+  R visitAs(
+      Send node,
+      Node expression,
+      DartType type,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] of the property on
+  /// [receiver] whose getter and setter are defined by [getterSelector] and
+  /// [setterSelector], respectively.
+  ///
+  /// For instance:
+  ///     m(receiver, rhs) => receiver.foo += rhs;
+  ///
+  R visitDynamicPropertyCompound(
+      Send node,
+      Node receiver,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] of the property on
+  /// `this` whose getter and setter are defined by [getterSelector] and
+  /// [setterSelector], respectively.
+  ///
+  /// For instance:
+  ///     class C {
+  ///       m(rhs) => this.foo += rhs;
+  ///     }
+  /// or
+  ///     class C {
+  ///       m(rhs) => foo += rhs;
+  ///     }
+  ///
+  R visitThisPropertyCompound(
+      Send node,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a [parameter].
+  ///
+  /// For instance:
+  ///     m(parameter, rhs) => parameter += rhs;
+  ///
+  R visitParameterCompound(
+      Send node,
+      ParameterElement parameter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a final
+  /// [parameter].
+  ///
+  /// For instance:
+  ///     m(final parameter, rhs) => parameter += rhs;
+  ///
+  R errorFinalParameterCompound(
+      Send node,
+      ParameterElement parameter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a local
+  /// [variable].
+  ///
+  /// For instance:
+  ///     m(rhs) {
+  ///       var variable;
+  ///       variable += rhs;
+  ///     }
+  ///
+  R visitLocalVariableCompound(
+      Send node,
+      LocalVariableElement variable,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a final local
+  /// [variable].
+  ///
+  /// For instance:
+  ///     m(rhs) {
+  ///       final variable = 0;
+  ///       variable += rhs;
+  ///     }
+  ///
+  R errorFinalLocalVariableCompound(
+      Send node,
+      LocalVariableElement variable,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a local
+  /// [function].
+  ///
+  /// For instance:
+  ///     m(rhs) {
+  ///       function() {}
+  ///       function += rhs;
+  ///     }
+  ///
+  R errorLocalFunctionCompound(
+      Send node,
+      LocalFunctionElement function,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a static
+  /// [field].
+  ///
+  /// For instance:
+  ///     class C {
+  ///       static var field;
+  ///       m(rhs) => field += rhs;
+  ///     }
+  ///
+  R visitStaticFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a final static
+  /// [field].
+  ///
+  /// For instance:
+  ///     class C {
+  ///       static final field = 0;
+  ///       m(rhs) => field += rhs;
+  ///     }
+  ///
+  R errorFinalStaticFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] reading from a
+  /// static [getter] and writing to a static [setter].
+  ///
+  /// For instance:
+  ///     class C {
+  ///       static get o => 0;
+  ///       static set o(_) {}
+  ///       m(rhs) => o += rhs;
+  ///     }
+  ///
+  R visitStaticGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] reading from a
+  /// static [method], that is, closurizing [method], and writing to a static
+  /// [setter].
+  ///
+  /// For instance:
+  ///     class C {
+  ///       static o() {}
+  ///       static set o(_) {}
+  ///       m(rhs) => o += rhs;
+  ///     }
+  ///
+  R visitStaticMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a top level
+  /// [field].
+  ///
+  /// For instance:
+  ///     var field;
+  ///     m(rhs) => field += rhs;
+  ///
+  R visitTopLevelFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a final top
+  /// level [field].
+  ///
+  /// For instance:
+  ///     final field = 0;
+  ///     m(rhs) => field += rhs;
+  ///
+  R errorFinalTopLevelFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] reading from a
+  /// top level [getter] and writing to a top level [setter].
+  ///
+  /// For instance:
+  ///     get o => 0;
+  ///     set o(_) {}
+  ///     m(rhs) => o += rhs;
+  ///
+  R visitTopLevelGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] reading from a
+  /// top level [method], that is, closurizing [method], and writing to a top
+  /// level [setter].
+  ///
+  /// For instance:
+  ///     o() {}
+  ///     set o(_) {}
+  ///     m(rhs) => o += rhs;
+  ///
+  R visitTopLevelMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a super
+  /// [field].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       var field;
+  ///     }
+  ///     class C extends B {
+  ///       m(rhs) => super.field += rhs;
+  ///     }
+  ///
+  R visitSuperFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a final super
+  /// [field].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       final field = 0;
+  ///     }
+  ///     class C extends B {
+  ///       m(rhs) => super.field += rhs;
+  ///     }
+  ///
+  R errorFinalSuperFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] reading from a
+  /// super [getter] and writing to a super [setter].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       get o => 0;
+  ///       set o(_) {}
+  ///     }
+  ///     class C extends B {
+  ///       m(rhs) => super.o += rhs;
+  ///     }
+  ///
+  R visitSuperGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] reading from a
+  /// super [method], that is, closurizing [method], and writing to a super
+  /// [setter].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       o() {}
+  ///       set o(_) {}
+  ///     }
+  ///     class C extends B {
+  ///       m(rhs) => super.o += rhs;
+  ///     }
+  ///
+  R visitSuperMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] reading from a
+  /// super [field] and writing to a super [setter].
+  ///
+  /// For instance:
+  ///     class A {
+  ///       var o;
+  ///     }
+  ///     class B extends A {
+  ///       set o(_) {}
+  ///     }
+  ///     class C extends B {
+  ///       m(rhs) => super.o += rhs;
+  ///     }
+  ///
+  R visitSuperFieldSetterCompound(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] reading from a
+  /// super [getter] and writing to a super [field].
+  ///
+  /// For instance:
+  ///     class A {
+  ///       var o;
+  ///     }
+  ///     class B extends A {
+  ///       get o => 0;
+  ///     }
+  ///     class C extends B {
+  ///       m(rhs) => super.o += rhs;
+  ///     }
+  ///
+  R visitSuperGetterFieldCompound(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a type literal
+  /// for class [element].
+  ///
+  /// For instance:
+  ///     class C {}
+  ///     m(rhs) => C += rhs;
+  ///
+  R errorClassTypeLiteralCompound(
+      Send node,
+      TypeConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a type literal
+  /// for typedef [element].
+  ///
+  /// For instance:
+  ///     typedef F();
+  ///     m(rhs) => F += rhs;
+  ///
+  R errorTypedefTypeLiteralCompound(
+      Send node,
+      TypeConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on a type literal
+  /// for type variable [element].
+  ///
+  /// For instance:
+  ///     class C<T> {
+  ///       m(rhs) => T += rhs;
+  ///     }
+  ///
+  R errorTypeVariableTypeLiteralCompound(
+      Send node,
+      TypeVariableElement element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on the type
+  /// literal for `dynamic`.
+  ///
+  /// For instance:
+  ///     m(rhs) => dynamic += rhs;
+  ///
+  R errorDynamicTypeLiteralCompound(
+      Send node,
+      TypeConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on the index
+  /// operators of [receiver] whose getter and setter are defined by
+  /// [getterSelector] and [setterSelector], respectively.
+  ///
+  /// For instance:
+  ///     m(receiver, index, rhs) => receiver[index] += rhs;
+  ///
+  R visitCompoundIndexSet(
+      SendSet node,
+      Node receiver,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Compound assignment expression of [rhs] with [operator] on the index
+  /// operators of a super class defined by [getter] and [setter].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       operator [](index) {}
+  ///       operator [](index, value) {}
+  ///     }
+  ///     class C extends B {
+  ///       m(index, rhs) => super[index] += rhs;
+  ///     }
+  ///
+  R visitSuperCompoundIndexSet(
+      SendSet node,
+      FunctionElement getter,
+      FunctionElement setter,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Prefix expression with [operator] of the property on [receiver] whose
+  /// getter and setter are defined by [getterSelector] and [setterSelector],
+  /// respectively.
+  ///
+  /// For instance:
+  ///     m(receiver) => ++receiver.foo;
+  ///
+  R visitDynamicPropertyPrefix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg);
+
+  /// Prefix expression with [operator] on a [parameter].
+  ///
+  /// For instance:
+  ///     m(parameter) => ++parameter;
+  ///
+  R visitParameterPrefix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] on a local [variable].
+  ///
+  /// For instance:
+  ///     m() {
+  ///     var variable;
+  ///      ++variable;
+  ///     }
+  ///
+  R visitLocalVariablePrefix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] on a local [function].
+  ///
+  /// For instance:
+  ///     m() {
+  ///     function() {}
+  ///      ++function;
+  ///     }
+  ///
+  R errorLocalFunctionPrefix(
+      Send node,
+      LocalFunctionElement function,
+      IncDecOperator operator,
+      A arg);
+
+
+  /// Prefix expression with [operator] of the property on `this` whose getter
+  /// and setter are defined by [getterSelector] and [setterSelector],
+  /// respectively.
+  ///
+  /// For instance:
+  ///     class C {
+  ///       m() => ++foo;
+  ///     }
+  /// or
+  ///     class C {
+  ///       m() => ++this.foo;
+  ///     }
+  ///
+  R visitThisPropertyPrefix(
+      Send node,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg);
+
+  /// Prefix expression with [operator] on a static [field].
+  ///
+  /// For instance:
+  ///     class C {
+  ///       static var field;
+  ///       m() => ++field;
+  ///     }
+  ///
+  R visitStaticFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] reading from a static [getter] and
+  /// writing to a static [setter].
+  ///
+  /// For instance:
+  ///     class C {
+  ///       static get o => 0;
+  ///       static set o(_) {}
+  ///       m() => ++o;
+  ///     }
+  ///
+  R visitStaticGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+
+  /// Prefix expression with [operator] reading from a static [method], that is,
+  /// closurizing [method], and writing to a static [setter].
+  ///
+  /// For instance:
+  ///     class C {
+  ///       static o() {}
+  ///       static set o(_) {}
+  ///       m() => ++o;
+  ///     }
+  ///
+  R visitStaticMethodSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] on a top level [field].
+  ///
+  /// For instance:
+  ///     var field;
+  ///     m() => ++field;
+  ///
+  R visitTopLevelFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] reading from a top level [getter] and
+  /// writing to a top level [setter].
+  ///
+  /// For instance:
+  ///     get o => 0;
+  ///     set o(_) {}
+  ///     m() => ++o;
+  ///
+  R visitTopLevelGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] reading from a top level [method], that
+  /// is, closurizing [method], and writing to a top level [setter].
+  ///
+  /// For instance:
+  ///     o() {}
+  ///     set o(_) {}
+  ///     m() => ++o;
+  ///
+  R visitTopLevelMethodSetterPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] on a super [field].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       var field;
+  ///     }
+  ///     class C extends B {
+  ///       m() => ++super.field;
+  ///     }
+  ///
+  R visitSuperFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] reading from the super field [readField]
+  /// and writing to the different super field [writtenField].
+  ///
+  /// For instance:
+  ///     class A {
+  ///       var field;
+  ///     }
+  ///     class B extends A {
+  ///       final field;
+  ///     }
+  ///     class C extends B {
+  ///       m() => ++super.field;
+  ///     }
+  ///
+  R visitSuperFieldFieldPrefix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] reading from a super [field] and writing
+  /// to a super [setter].
+  ///
+  /// For instance:
+  ///     class A {
+  ///       var field;
+  ///     }
+  ///     class B extends A {
+  ///       set field(_) {}
+  ///     }
+  ///     class C extends B {
+  ///       m() => ++super.field;
+  ///     }
+  ///
+  R visitSuperFieldSetterPrefix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+
+  /// Prefix expression with [operator] reading from a super [getter] and
+  /// writing to a super [setter].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       get field => 0;
+  ///       set field(_) {}
+  ///     }
+  ///     class C extends B {
+  ///       m() => ++super.field;
+  ///     }
+  ///
+  R visitSuperGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] reading from a super [getter] and
+  /// writing to a super [field].
+  ///
+  /// For instance:
+  ///     class A {
+  ///       var field;
+  ///     }
+  ///     class B extends A {
+  ///       get field => 0;
+  ///     }
+  ///     class C extends B {
+  ///       m() => ++super.field;
+  ///     }
+  ///
+  R visitSuperGetterFieldPrefix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] reading from a super [method], that is,
+  /// closurizing [method], and writing to a super [setter].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       o() {}
+  ///       set o(_) {}
+  ///     }
+  ///     class C extends B {
+  ///       m() => ++super.o;
+  ///     }
+  ///
+  R visitSuperMethodSetterPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] on a type literal for a class [element].
+  ///
+  /// For instance:
+  ///     class C {}
+  ///     m() => ++C;
+  ///
+  R errorClassTypeLiteralPrefix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] on a type literal for a typedef
+  /// [element].
+  ///
+  /// For instance:
+  ///     typedef F();
+  ///     m() => ++F;
+  ///
+  R errorTypedefTypeLiteralPrefix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] on a type literal for a type variable
+  /// [element].
+  ///
+  /// For instance:
+  ///     class C<T> {
+  ///       m() => ++T;
+  ///     }
+  ///
+  R errorTypeVariableTypeLiteralPrefix(
+      Send node,
+      TypeVariableElement element,
+      IncDecOperator operator,
+      A arg);
+
+  /// Prefix expression with [operator] on the type literal for `dynamic`.
+  ///
+  /// For instance:
+  ///     m() => ++dynamic;
+  ///
+  R errorDynamicTypeLiteralPrefix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] of the property on [receiver] whose
+  /// getter and setter are defined by [getterSelector] and [setterSelector],
+  /// respectively.
+  ///
+  /// For instance:
+  ///     m(receiver) => receiver.foo++;
+  ///
+  R visitDynamicPropertyPostfix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg);
+
+  /// Postfix expression with [operator] on a [parameter].
+  ///
+  /// For instance:
+  ///     m(parameter) => parameter++;
+  ///
+  R visitParameterPostfix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] on a local [variable].
+  ///
+  /// For instance:
+  ///     m() {
+  ///     var variable;
+  ///      variable++;
+  ///     }
+  ///
+  R visitLocalVariablePostfix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] on a local [function].
+  ///
+  /// For instance:
+  ///     m() {
+  ///     function() {}
+  ///      function++;
+  ///     }
+  ///
+  R errorLocalFunctionPostfix(
+      Send node,
+      LocalFunctionElement function,
+      IncDecOperator operator,
+      A arg);
+
+
+  /// Postfix expression with [operator] of the property on `this` whose getter
+  /// and setter are defined by [getterSelector] and [setterSelector],
+  /// respectively.
+  ///
+  /// For instance:
+  ///     class C {
+  ///       m() => foo++;
+  ///     }
+  /// or
+  ///     class C {
+  ///       m() => this.foo++;
+  ///     }
+  ///
+  R visitThisPropertyPostfix(
+      Send node,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg);
+
+  /// Postfix expression with [operator] on a static [field].
+  ///
+  /// For instance:
+  ///     class C {
+  ///       static var field;
+  ///       m() => field++;
+  ///     }
+  ///
+  R visitStaticFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] reading from a static [getter] and
+  /// writing to a static [setter].
+  ///
+  /// For instance:
+  ///     class C {
+  ///       static get o => 0;
+  ///       static set o(_) {}
+  ///       m() => o++;
+  ///     }
+  ///
+  R visitStaticGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+
+  /// Postfix expression with [operator] reading from a static [method], that
+  /// is, closurizing [method], and writing to a static [setter].
+  ///
+  /// For instance:
+  ///     class C {
+  ///       static o() {}
+  ///       static set o(_) {}
+  ///       m() => o++;
+  ///     }
+  ///
+  R visitStaticMethodSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] on a top level [field].
+  ///
+  /// For instance:
+  ///     var field;
+  ///     m() => field++;
+  ///
+  R visitTopLevelFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] reading from a top level [getter] and
+  /// writing to a top level [setter].
+  ///
+  /// For instance:
+  ///     get o => 0;
+  ///     set o(_) {}
+  ///     m() => o++;
+  ///
+  R visitTopLevelGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] reading from a top level [method], that
+  /// is, closurizing [method], and writing to a top level [setter].
+  ///
+  /// For instance:
+  ///     o() {}
+  ///     set o(_) {}
+  ///     m() => o++;
+  ///
+  R visitTopLevelMethodSetterPostfix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] on a super [field].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       var field;
+  ///     }
+  ///     class C extends B {
+  ///       m() => super.field++;
+  ///     }
+  ///
+  R visitSuperFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] reading from the super field
+  /// [readField] and writing to the different super field [writtenField].
+  ///
+  /// For instance:
+  ///     class A {
+  ///       var field;
+  ///     }
+  ///     class B extends A {
+  ///       final field;
+  ///     }
+  ///     class C extends B {
+  ///       m() => super.field++;
+  ///     }
+  ///
+  R visitSuperFieldFieldPostfix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] reading from a super [field] and
+  /// writing to a super [setter].
+  ///
+  /// For instance:
+  ///     class A {
+  ///       var field;
+  ///     }
+  ///     class B extends A {
+  ///       set field(_) {}
+  ///     }
+  ///     class C extends B {
+  ///       m() => super.field++;
+  ///     }
+  ///
+  R visitSuperFieldSetterPostfix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+
+  /// Postfix expression with [operator] reading from a super [getter] and
+  /// writing to a super [setter].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       get field => 0;
+  ///       set field(_) {}
+  ///     }
+  ///     class C extends B {
+  ///       m() => super.field++;
+  ///     }
+  ///
+  R visitSuperGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] reading from a super [getter] and
+  /// writing to a super [field].
+  ///
+  /// For instance:
+  ///     class A {
+  ///       var field;
+  ///     }
+  ///     class B extends A {
+  ///       get field => 0;
+  ///     }
+  ///     class C extends B {
+  ///       m() => super.field++;
+  ///     }
+  ///
+  R visitSuperGetterFieldPostfix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] reading from a super [method], that is,
+  /// closurizing [method], and writing to a super [setter].
+  ///
+  /// For instance:
+  ///     class B {
+  ///       o() {}
+  ///       set o(_) {}
+  ///     }
+  ///     class C extends B {
+  ///       m() => super.o++;
+  ///     }
+  ///
+  R visitSuperMethodSetterPostfix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] on a type literal for a class
+  /// [element].
+  ///
+  /// For instance:
+  ///     class C {}
+  ///     m() => C++;
+  ///
+  R errorClassTypeLiteralPostfix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] on a type literal for a typedef
+  /// [element].
+  ///
+  /// For instance:
+  ///     typedef F();
+  ///     m() => F++;
+  ///
+  R errorTypedefTypeLiteralPostfix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] on a type literal for a type variable
+  /// [element].
+  ///
+  /// For instance:
+  ///     class C<T> {
+  ///       m() => T++;
+  ///     }
+  ///
+  R errorTypeVariableTypeLiteralPostfix(
+      Send node,
+      TypeVariableElement element,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix expression with [operator] on the type literal for `dynamic`.
+  ///
+  /// For instance:
+  ///     m() => dynamic++;
+  ///
+  R errorDynamicTypeLiteralPostfix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg);
+
+  /// Read of the [constant].
+  ///
+  /// For instance
+  ///     const c = c;
+  ///     m() => c;
+  ///
+  R visitConstantGet(
+      Send node,
+      ConstantExpression constant,
+      A arg);
+
+  /// Invocation of the [constant] with [arguments].
+  ///
+  /// For instance
+  ///     const c = null;
+  ///     m() => c(null, 42);
+  ///
+  R visitConstantInvoke(
+      Send node,
+      ConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Read of the unresolved [element].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m1() => unresolved;
+  ///     m2() => prefix.unresolved;
+  ///     m3() => Unresolved.foo;
+  ///     m4() => unresolved.foo;
+  ///     m5() => unresolved.Foo.bar;
+  ///     m6() => C.unresolved;
+  ///     m7() => prefix.C.unresolved;
+  ///
+  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
+  R errorUnresolvedGet(
+      Send node,
+      Element element,
+      A arg);
+
+  /// Assignment of [rhs] to the unresolved [element].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m1() => unresolved = 42;
+  ///     m2() => prefix.unresolved = 42;
+  ///     m3() => Unresolved.foo = 42;
+  ///     m4() => unresolved.foo = 42;
+  ///     m5() => unresolved.Foo.bar = 42;
+  ///     m6() => C.unresolved = 42;
+  ///     m7() => prefix.C.unresolved = 42;
+  ///
+  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
+  R errorUnresolvedSet(
+      Send node,
+      Element element,
+      Node rhs,
+      A arg);
+
+  /// Invocation of the unresolved [element] with [arguments].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m1() => unresolved(null, 42);
+  ///     m2() => prefix.unresolved(null, 42);
+  ///     m3() => Unresolved.foo(null, 42);
+  ///     m4() => unresolved.foo(null, 42);
+  ///     m5() => unresolved.Foo.bar(null, 42);
+  ///     m6() => C.unresolved(null, 42);
+  ///     m7() => prefix.C.unresolved(null, 42);
+  ///
+  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
+  R errorUnresolvedInvoke(
+      Send node,
+      Element element,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  /// Compound assignment of [rhs] on the unresolved [element].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m1() => unresolved += 42;
+  ///     m2() => prefix.unresolved += 42;
+  ///     m3() => Unresolved.foo += 42;
+  ///     m4() => unresolved.foo += 42;
+  ///     m5() => unresolved.Foo.bar += 42;
+  ///     m6() => C.unresolved += 42;
+  ///     m7() => prefix.C.unresolved += 42;
+  ///
+  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
+  R errorUnresolvedCompound(
+      Send node,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Prefix operation on the unresolved [element].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m1() => ++unresolved;
+  ///     m2() => ++prefix.unresolved;
+  ///     m3() => ++Unresolved.foo;
+  ///     m4() => ++unresolved.foo;
+  ///     m5() => ++unresolved.Foo.bar;
+  ///     m6() => ++C.unresolved;
+  ///     m7() => ++prefix.C.unresolved;
+  ///
+  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
+  R errorUnresolvedPrefix(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      A arg);
+
+  /// Postfix operation on the unresolved [element].
+  ///
+  /// For instance
+  ///     class C {}
+  ///     m1() => unresolved++;
+  ///     m2() => prefix.unresolved++;
+  ///     m3() => Unresolved.foo++;
+  ///     m4() => unresolved.foo++;
+  ///     m5() => unresolved.Foo.bar++;
+  ///     m6() => C.unresolved++;
+  ///     m7() => prefix.C.unresolved++;
+  ///
+  // TODO(johnniwinther): Split the cases in which a prefix is resolved.
+  R errorUnresolvedPostfix(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      A arg);
+
+  /// Index set operation on the unresolved super [element].
+  ///
+  /// For instance
+  ///     class B {
+  ///     }
+  ///     class C extends B {
+  ///       m() => super[1] = 42;
+  ///     }
+  ///
+  R errorUnresolvedSuperIndexSet(
+      Send node,
+      Element element,
+      Node index,
+      Node rhs,
+      A arg);
+
+  /// Compound index set operation on the unresolved super [element].
+  ///
+  /// For instance
+  ///     class B {
+  ///     }
+  ///     class C extends B {
+  ///       m() => super[1] += 42;
+  ///     }
+  ///
+  // TODO(johnniwinther): Split this case into unresolved getter/setter cases.
+  R errorUnresolvedSuperCompoundIndexSet(
+      Send node,
+      Element element,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  /// Unary operation on the unresolved super [element].
+  ///
+  /// For instance
+  ///     class B {
+  ///     }
+  ///     class C extends B {
+  ///       m() => -super;
+  ///     }
+  ///
+  R errorUnresolvedSuperUnary(
+      Send node,
+      UnaryOperator operator,
+      Element element,
+      A arg);
+
+  /// Binary operation on the unresolved super [element].
+  ///
+  /// For instance
+  ///     class B {
+  ///     }
+  ///     class C extends B {
+  ///       m() => super + 42;
+  ///     }
+  ///
+  R errorUnresolvedSuperBinary(
+      Send node,
+      Element element,
+      BinaryOperator operator,
+      Node argument,
+      A arg);
+
+  /// Invocation of an undefined unary [operator] on [expression].
+  R errorUndefinedUnaryExpression(
+      Send node,
+      Operator operator,
+      Node expression,
+      A arg);
+
+  /// Invocation of an undefined unary [operator] with operands
+  /// [left] and [right].
+  R errorUndefinedBinaryExpression(
+      Send node,
+      Node left,
+      Operator operator,
+      Node right,
+      A arg);
+}
diff --git a/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart b/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
new file mode 100644
index 0000000..47846a6
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart
@@ -0,0 +1,5212 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart2js.semantics_visitor;
+
+/// Mixin that implements all `errorX` methods of [SemanticSendVisitor] by
+/// delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for all `errorX` methods.
+abstract class ErrorBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  R bulkHandleError(Send node) {
+    return bulkHandleNode(node, "Error expression `$node` unhandled.");
+  }
+
+  @override
+  R errorInvalidAssert(
+      Send node,
+      NodeList arguments,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorClassTypeLiteralCompound(
+      Send node,
+      TypeConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorClassTypeLiteralPostfix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorClassTypeLiteralPrefix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorClassTypeLiteralSet(
+      SendSet node,
+      TypeConstantExpression constant,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorDynamicTypeLiteralCompound(
+      Send node,
+      TypeConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorDynamicTypeLiteralPostfix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorDynamicTypeLiteralPrefix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorDynamicTypeLiteralSet(
+      SendSet node,
+      TypeConstantExpression constant,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorFinalLocalVariableCompound(
+      Send node,
+      LocalVariableElement
+      variable,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorFinalLocalVariableSet(
+      SendSet node,
+      LocalVariableElement variable,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorFinalParameterCompound(
+      Send node,
+      ParameterElement parameter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorFinalParameterSet(
+      SendSet node,
+      ParameterElement parameter,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorFinalStaticFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorFinalStaticFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorFinalSuperFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorFinalSuperFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorFinalTopLevelFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorFinalTopLevelFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorLocalFunctionCompound(
+      Send node,
+      LocalFunctionElement function,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorLocalFunctionPostfix(
+      Send node,
+      LocalFunctionElement function,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorLocalFunctionPrefix(
+      Send node,
+      LocalFunctionElement function,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorLocalFunctionSet(
+      SendSet node,
+      LocalFunctionElement function,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorStaticFunctionSet(
+      Send node,
+      MethodElement function,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorStaticGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorStaticSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorStaticSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorSuperGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorSuperMethodSet(
+      Send node,
+      MethodElement method,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorSuperSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorSuperSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTopLevelFunctionSet(
+      Send node,
+      MethodElement function,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTopLevelGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTopLevelSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTopLevelSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTypeVariableTypeLiteralCompound(
+      Send node,
+      TypeVariableElement element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTypeVariableTypeLiteralPostfix(
+      Send node,
+      TypeVariableElement element,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTypeVariableTypeLiteralPrefix(
+      Send node,
+      TypeVariableElement element,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTypeVariableTypeLiteralSet(
+      SendSet node,
+      TypeVariableElement element,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTypedefTypeLiteralCompound(
+      Send node,
+      TypeConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTypedefTypeLiteralPostfix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTypedefTypeLiteralPrefix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorTypedefTypeLiteralSet(
+      SendSet node,
+      TypeConstantExpression constant,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedCompound(
+      Send node,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedGet(
+      Send node,
+      Element element,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedInvoke(
+      Send node,
+      Element element,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedPostfix(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedPrefix(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedSet(
+      Send node,
+      Element element,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedSuperCompoundIndexSet(
+      SendSet node,
+      Element element,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedSuperIndex(
+      Send node,
+      Element function,
+      Node index,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedSuperIndexPostfix(
+      Send node,
+      Element function,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedSuperIndexPrefix(
+      Send node,
+      Element function,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedSuperIndexSet(
+      SendSet node,
+      Element element,
+      Node index,
+      Node rhs,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedSuperBinary(
+      Send node,
+      Element element,
+      BinaryOperator operator,
+      Node argument,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUnresolvedSuperUnary(
+      Send node,
+      UnaryOperator operator,
+      Element element,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUndefinedBinaryExpression(
+      Send node,
+      Node left,
+      Operator operator,
+      Node right,
+      A arg) {
+    return bulkHandleError(node);
+  }
+
+  @override
+  R errorUndefinedUnaryExpression(
+      Send node,
+      Operator operator,
+      Node expression,
+      A arg) {
+    return bulkHandleError(node);
+  }
+}
+
+/// Mixin that implements all `visitXPrefix` methods of [SemanticSendVisitor] by
+/// delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for all `visitXPrefix`
+/// methods.
+abstract class PrefixBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  R bulkHandlePrefix(Send node) {
+    return bulkHandleNode(node, "Prefix expression `$node` unhandled.");
+  }
+
+  @override
+  R visitDynamicPropertyPrefix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitIndexPrefix(
+      Send node,
+      Node receiver,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitLocalVariablePrefix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitParameterPrefix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitStaticFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitStaticGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitStaticMethodSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitSuperFieldFieldPrefix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitSuperFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitSuperFieldSetterPrefix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitSuperGetterFieldPrefix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitSuperGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitSuperIndexPrefix(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitSuperMethodSetterPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitThisPropertyPrefix(
+      Send node,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitTopLevelFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitTopLevelGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+
+  @override
+  R visitTopLevelMethodSetterPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePrefix(node);
+  }
+}
+
+/// Mixin that implements all `visitXPostfix` methods of [SemanticSendVisitor]
+/// by delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for all `visitXPostfix`
+/// methods.
+abstract class PostfixBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  R bulkHandlePostfix(Send node) {
+    return bulkHandleNode(node, "Postfix expression `$node` unhandled.");
+  }
+
+  @override
+  R visitDynamicPropertyPostfix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitIndexPostfix(
+      Send node,
+      Node receiver,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitLocalVariablePostfix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitParameterPostfix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitStaticFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitStaticGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitStaticMethodSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitSuperFieldFieldPostfix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitSuperFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitSuperFieldSetterPostfix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitSuperGetterFieldPostfix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitSuperGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitSuperIndexPostfix(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitSuperMethodSetterPostfix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitThisPropertyPostfix(
+      Send node,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitTopLevelFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitTopLevelGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+
+  @override
+  R visitTopLevelMethodSetterPostfix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandlePostfix(node);
+  }
+}
+
+/// Mixin that implements all `visitXCompound` methods of [SemanticSendVisitor]
+/// by delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for all `xCompound`
+/// methods.
+abstract class CompoundBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  R bulkHandleCompound(Send node) {
+    return bulkHandleNode(node, "Compound assignment `$node` unhandled.");
+  }
+
+  @override
+  R visitDynamicPropertyCompound(
+      Send node,
+      Node receiver,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitLocalVariableCompound(
+      Send node,
+      LocalVariableElement variable,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitParameterCompound(
+      Send node,
+      ParameterElement parameter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitStaticFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitStaticGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitStaticMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitSuperFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitSuperFieldSetterCompound(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitSuperGetterFieldCompound(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitSuperGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitSuperMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitThisPropertyCompound(
+      Send node,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitTopLevelFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitTopLevelGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+
+  @override
+  R visitTopLevelMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleCompound(node);
+  }
+}
+
+/// Mixin that implements all `visitXInvoke` methods of [SemanticSendVisitor] by
+/// delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for all `visitXInvoke`
+/// methods.
+abstract class InvokeBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  R bulkHandleInvoke(Send node) {
+    return bulkHandleNode(node, "Invocation `$node` unhandled.");
+  }
+
+  @override
+  R visitClassTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitDynamicPropertyInvoke(
+      Send node,
+      Node receiver,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitDynamicTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitExpressionInvoke(
+      Send node,
+      Node expression,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitLocalFunctionInvoke(
+      Send node,
+      LocalFunctionElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitLocalVariableInvoke(
+      Send node,
+      LocalVariableElement variable,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitParameterInvoke(
+      Send node,
+      ParameterElement parameter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitStaticFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitStaticFunctionInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitStaticGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitSuperFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitSuperGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitSuperMethodInvoke(
+      Send node,
+      MethodElement method,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitThisInvoke(
+      Send node,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitThisPropertyInvoke(
+      Send node,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitTopLevelFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitTopLevelFunctionInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitTopLevelGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitTypeVariableTypeLiteralInvoke(
+      Send node,
+      TypeVariableElement element,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitTypedefTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+
+  @override
+  R visitConstantInvoke(
+      Send node,
+      ConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleInvoke(node);
+  }
+}
+
+/// Mixin that implements all `visitXGet` methods of [SemanticSendVisitor] by
+/// delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for all `visitXGet`
+/// methods.
+abstract class GetBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  R bulkHandleGet(Node node) {
+    return bulkHandleNode(node, "Read `$node` unhandled.");
+  }
+
+  @override
+  R visitClassTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitDynamicPropertyGet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitDynamicTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitLocalFunctionGet(
+      Send node,
+      LocalFunctionElement function,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitLocalVariableGet(
+      Send node,
+      LocalVariableElement variable,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitParameterGet(
+      Send node,
+      ParameterElement parameter,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitStaticFieldGet(
+      Send node,
+      FieldElement field,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitStaticFunctionGet(
+      Send node,
+      MethodElement function,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitStaticGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitSuperFieldGet(
+      Send node,
+      FieldElement field,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitSuperGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitSuperMethodGet(
+      Send node,
+      MethodElement method,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitThisGet(Identifier node, A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitThisPropertyGet(
+      Send node,
+      Selector selector,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitTopLevelFieldGet(
+      Send node,
+      FieldElement field,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitTopLevelFunctionGet(
+      Send node,
+      MethodElement function,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitTopLevelGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitTypeVariableTypeLiteralGet(
+      Send node,
+      TypeVariableElement element,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitTypedefTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+
+  @override
+  R visitConstantGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg) {
+    return bulkHandleGet(node);
+  }
+}
+
+/// Mixin that implements all `visitXSet` methods of [SemanticSendVisitor] by
+/// delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for all `visitXSet`
+/// methods.
+abstract class SetBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  R bulkHandleSet(Send node) {
+    return bulkHandleNode(node, "Assignment `$node` unhandled.");
+  }
+
+  @override
+  R visitDynamicPropertySet(
+      SendSet node,
+      Node receiver,
+      Selector selector,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node);
+  }
+
+  @override
+  R visitLocalVariableSet(
+      SendSet node,
+      LocalVariableElement variable,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node);
+  }
+
+  @override
+  R visitParameterSet(
+      SendSet node,
+      ParameterElement parameter,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node);
+  }
+
+  @override
+  R visitStaticFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node);
+  }
+
+  @override
+  R visitStaticSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node);
+  }
+
+  @override
+  R visitSuperFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node);
+  }
+
+  @override
+  R visitSuperSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node);
+  }
+
+  @override
+  R visitThisPropertySet(
+      SendSet node,
+      Selector selector,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node);
+  }
+
+  @override
+  R visitTopLevelFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node);
+  }
+
+  @override
+  R visitTopLevelSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg) {
+    return bulkHandleSet(node);
+  }
+}
+
+/// Mixin that implements all `visitXIndexSet` methods of [SemanticSendVisitor]
+/// by delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for all `visitXIndexSet`
+/// methods.
+abstract class IndexSetBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  R bulkHandleIndexSet(Send node) {
+    return bulkHandleNode(node, "Index set expression `$node` unhandled.");
+  }
+
+  @override
+  R visitCompoundIndexSet(
+      SendSet node,
+      Node receiver,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleIndexSet(node);
+  }
+
+  @override
+  R visitIndexSet(
+      SendSet node,
+      Node receiver,
+      Node index,
+      Node rhs,
+      A arg) {
+    return bulkHandleIndexSet(node);
+  }
+
+  @override
+  R visitSuperCompoundIndexSet(
+      SendSet node,
+      FunctionElement getter,
+      FunctionElement setter,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleIndexSet(node);
+  }
+
+  @override
+  R visitSuperIndexSet(
+      SendSet node,
+      FunctionElement function,
+      Node index,
+      Node rhs,
+      A arg) {
+    return bulkHandleIndexSet(node);
+  }
+}
+
+/// Mixin that implements all binary visitor methods in [SemanticSendVisitor] by
+/// delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for all binary visitor
+/// methods.
+abstract class BinaryBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  R bulkHandleBinary(Send node) {
+    return bulkHandleNode(node, "Binary expression `$node` unhandled.");
+  }
+
+  @override
+  R visitBinary(
+      Send node,
+      Node left,
+      BinaryOperator operator,
+      Node right,
+      A arg) {
+    return bulkHandleBinary(node);
+  }
+
+  @override
+  R visitEquals(
+      Send node,
+      Node left,
+      Node right,
+      A arg) {
+    return bulkHandleBinary(node);
+  }
+
+  @override
+  R visitNotEquals(
+      Send node,
+      Node left,
+      Node right,
+      A arg) {
+    return bulkHandleBinary(node);
+  }
+
+  @override
+  R visitIndex(
+      Send node,
+      Node receiver,
+      Node index,
+      A arg) {
+    return bulkHandleBinary(node);
+  }
+
+  @override
+  R visitSuperBinary(
+      Send node,
+      FunctionElement function,
+      BinaryOperator operator,
+      Node argument,
+      A arg) {
+    return bulkHandleBinary(node);
+  }
+
+  @override
+  R visitSuperEquals(
+      Send node,
+      FunctionElement function,
+      Node argument,
+      A arg) {
+    return bulkHandleBinary(node);
+  }
+
+  @override
+  R visitSuperNotEquals(
+      Send node,
+      FunctionElement function,
+      Node argument,
+      A arg) {
+    return bulkHandleBinary(node);
+  }
+
+  @override
+  R visitSuperIndex(
+      Send node,
+      FunctionElement function,
+      Node index,
+      A arg) {
+    return bulkHandleBinary(node);
+  }
+}
+
+/// Mixin that implements all unary visitor methods in [SemanticSendVisitor] by
+/// delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for all unary visitor
+/// methods.
+abstract class UnaryBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  R bulkHandleUnary(Send node) {
+    return bulkHandleNode(node, "Unary expression `$node` unhandled.");
+  }
+
+  @override
+  R visitNot(
+      Send node,
+      Node expression,
+      A arg) {
+    return bulkHandleUnary(node);
+  }
+
+  @override
+  R visitSuperUnary(Send node, UnaryOperator operator,
+                    FunctionElement function, A arg) {
+    return bulkHandleUnary(node);
+  }
+
+  @override
+  R visitUnary(
+      Send node,
+      UnaryOperator operator,
+      Node expression,
+      A arg) {
+    return bulkHandleUnary(node);
+  }
+}
+
+/// Mixin that implements all purely structural visitor methods in
+/// [SemanticSendVisitor] by delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for all purely structural
+/// visitor methods.
+abstract class BaseBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  @override
+  R visitAs(
+      Send node,
+      Node expression,
+      DartType type,
+      A arg) {
+    return bulkHandleNode(node, 'As cast `$node` unhandled.');
+  }
+
+  @override
+  R visitAssert(
+      Send node,
+      Node expression,
+      A arg) {
+    return bulkHandleNode(node, 'Assert `$node` unhandled.');
+  }
+
+  @override
+  R visitIs(
+      Send node,
+      Node expression,
+      DartType type,
+      A arg) {
+    return bulkHandleNode(node, 'Is test `$node` unhandled.');
+  }
+
+  @override
+  R visitIsNot(
+      Send node,
+      Node expression,
+      DartType type,
+      A arg) {
+    return bulkHandleNode(node, 'Is not test `$node` unhandled.');
+  }
+
+  @override
+  R visitLogicalAnd(
+      Send node,
+      Node left,
+      Node right,
+      A arg) {
+    return bulkHandleNode(node, 'Lazy and `$node` unhandled.');
+  }
+
+  @override
+  R visitLogicalOr(
+      Send node,
+      Node left,
+      Node right,
+      A arg) {
+    return bulkHandleNode(node, 'Lazy or `$node` unhandled.');
+  }
+}
+
+/// Mixin that implements all visitor methods for `super` calls in
+/// [SemanticSendVisitor] by delegating to a bulk handler.
+///
+/// Use this mixin to provide a trivial implementation for `super` calls
+/// visitor methods.
+abstract class SuperBulkMixin<R, A> implements SemanticSendVisitor<R, A> {
+  R bulkHandleNode(Node node, String message);
+
+  R bulkHandleSuper(Send node) {
+    return bulkHandleNode(node, "Super call `$node` unhandled.");
+  }
+
+  @override
+  R visitSuperBinary(
+      Send node,
+      FunctionElement function,
+      BinaryOperator operator,
+      Node argument,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperCompoundIndexSet(
+      SendSet node,
+      FunctionElement getter,
+      FunctionElement setter,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperEquals(
+      Send node,
+      FunctionElement function,
+      Node argument,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperFieldFieldPostfix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperFieldFieldPrefix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperFieldGet(
+      Send node,
+      FieldElement field,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperFieldSetterCompound(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperFieldSetterPostfix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperFieldSetterPrefix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperGetterFieldCompound(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperGetterFieldPostfix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperGetterFieldPrefix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperIndexSet(
+      SendSet node,
+      FunctionElement function,
+      Node index,
+      Node rhs,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperMethodGet(
+      Send node,
+      MethodElement method,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperMethodInvoke(
+      Send node,
+      MethodElement method,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperMethodSetterPostfix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperMethodSetterPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperNotEquals(
+      Send node,
+      FunctionElement function,
+      Node argument,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+
+  @override
+  R visitSuperUnary(
+      Send node,
+      UnaryOperator operator,
+      FunctionElement function,
+      A arg) {
+    return bulkHandleSuper(node);
+  }
+}
+
+/// Visitor that implements [SemanticSendVisitor] by the use of `BulkX` mixins.
+///
+/// This class is useful in itself, but shows how to use the `BulkX` mixins and
+/// tests that the union of the `BulkX` mixins implement all `visit` and `error`
+/// methods of [SemanticSendVisitor].
+class BulkVisitor<R, A> extends SemanticSendVisitor<R, A>
+    with GetBulkMixin<R, A>,
+         SetBulkMixin<R, A>,
+         ErrorBulkMixin<R, A>,
+         InvokeBulkMixin<R, A>,
+         IndexSetBulkMixin<R, A>,
+         CompoundBulkMixin<R, A>,
+         UnaryBulkMixin<R, A>,
+         BaseBulkMixin<R, A>,
+         BinaryBulkMixin<R, A>,
+         PrefixBulkMixin<R, A>,
+         PostfixBulkMixin<R, A> {
+
+  @override
+  R apply(Node node, A arg) {
+    throw new UnimplementedError("BulkVisitor.apply unimplemented");
+  }
+
+  @override
+  R bulkHandleNode(Node node, String message) {
+    throw new UnimplementedError("BulkVisitor.bulkHandleNode unimplemented");
+  }
+}
+
+/// [SemanticSendVisitor] that visits subnodes.
+class TraversalMixin<R, A> implements SemanticSendVisitor<R, A> {
+  @override
+  R apply(Node node, A arg) {
+    throw new UnimplementedError("TraversalMixin.apply unimplemented");
+  }
+
+  @override
+  R errorInvalidAssert(
+      Send node,
+      NodeList arguments,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R errorClassTypeLiteralSet(
+      SendSet node,
+      TypeConstantExpression constant,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorDynamicTypeLiteralSet(
+      SendSet node,
+      TypeConstantExpression constant,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorFinalLocalVariableCompound(
+      Send node,
+      LocalVariableElement variable,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorFinalLocalVariableSet(
+      SendSet node,
+      LocalVariableElement variable,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorFinalParameterCompound(
+      Send node,
+      ParameterElement parameter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorFinalParameterSet(
+      SendSet node,
+      ParameterElement parameter,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorFinalStaticFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorFinalStaticFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorFinalSuperFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorFinalSuperFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorFinalTopLevelFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorFinalTopLevelFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorLocalFunctionCompound(
+      Send node,
+      LocalFunctionElement function,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorLocalFunctionPostfix(
+      Send node,
+      LocalFunctionElement function,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorLocalFunctionPrefix(
+      Send node,
+      LocalFunctionElement function,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorLocalFunctionSet(
+      SendSet node,
+      LocalFunctionElement function,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorStaticFunctionSet(
+      Send node,
+      MethodElement function,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorStaticGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorStaticSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorStaticSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R errorSuperGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorSuperMethodSet(
+      Send node,
+      MethodElement method,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorSuperSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorSuperSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R errorTopLevelFunctionSet(
+      Send node,
+      MethodElement function,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorTopLevelGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorTopLevelSetterGet(
+      Send node,
+      FunctionElement setter,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorTopLevelSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R errorTypeVariableTypeLiteralSet(
+      SendSet node,
+      TypeVariableElement element,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorTypedefTypeLiteralSet(
+      SendSet node,
+      TypeConstantExpression constant,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorUnresolvedSuperIndex(
+      Send node,
+      Element function,
+      Node index,
+      A arg) {
+    apply(index, arg);
+    return null;
+  }
+
+  @override
+  R visitAs(
+      Send node,
+      Node expression,
+      DartType type,
+      A arg) {
+    apply(expression, arg);
+    return null;
+  }
+
+  @override
+  R visitAssert(
+      Send node,
+      Node expression,
+      A arg) {
+    apply(expression, arg);
+    return null;
+  }
+
+  @override
+  R visitBinary(
+      Send node,
+      Node left,
+      BinaryOperator operator,
+      Node right,
+      A arg) {
+    apply(left, arg);
+    apply(right, arg);
+    return null;
+  }
+
+  @override
+  R errorClassTypeLiteralCompound(
+      Send node,
+      TypeConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitClassTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitClassTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R errorClassTypeLiteralPostfix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorClassTypeLiteralPrefix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitCompoundIndexSet(
+      SendSet node,
+      Node receiver,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(receiver, arg);
+    apply(index, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitConstantGet(
+      Send node,
+      ConstantExpression constant,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitConstantInvoke(
+      Send node,
+      ConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitDynamicPropertyCompound(
+      Send node,
+      Node receiver,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    apply(receiver, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitDynamicPropertyGet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      A arg) {
+    apply(receiver, arg);
+    return null;
+  }
+
+  @override
+  R visitDynamicPropertyInvoke(
+      Send node,
+      Node receiver,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(receiver, arg);
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitDynamicPropertyPostfix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    apply(receiver, arg);
+    return null;
+  }
+
+  @override
+  R visitDynamicPropertyPrefix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    apply(receiver, arg);
+    return null;
+  }
+
+  @override
+  R visitDynamicPropertySet(
+      SendSet node,
+      Node receiver,
+      Selector selector,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorDynamicTypeLiteralCompound(
+      Send node,
+      TypeConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitDynamicTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitDynamicTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R errorDynamicTypeLiteralPostfix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorDynamicTypeLiteralPrefix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitEquals(
+      Send node,
+      Node left,
+      Node right,
+      A arg) {
+    apply(left, arg);
+    apply(right, arg);
+    return null;
+  }
+
+  @override
+  R visitExpressionInvoke(
+      Send node,
+      Node expression,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(expression, arg);
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitIndex(
+      Send node,
+      Node receiver,
+      Node index,
+      A arg) {
+    apply(receiver, arg);
+    apply(index, arg);
+    return null;
+  }
+
+  @override
+  R visitIndexSet(
+      SendSet node,
+      Node receiver,
+      Node index,
+      Node rhs,
+      A arg) {
+    apply(receiver, arg);
+    apply(index, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitIs(
+      Send node,
+      Node expression,
+      DartType type,
+      A arg) {
+    apply(expression, arg);
+    return null;
+  }
+
+  @override
+  R visitIsNot(
+      Send node,
+      Node expression,
+      DartType type,
+      A arg) {
+    apply(expression, arg);
+    return null;
+  }
+
+  @override
+  R visitLocalFunctionGet(
+      Send node,
+      LocalFunctionElement function,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitLocalFunctionInvoke(
+      Send node,
+      LocalFunctionElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitLocalVariableCompound(
+      Send node,
+      LocalVariableElement variable,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitLocalVariableGet(
+      Send node,
+      LocalVariableElement variable,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitLocalVariableInvoke(
+      Send node,
+      LocalVariableElement variable,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitLocalVariablePostfix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitLocalVariablePrefix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitLocalVariableSet(
+      SendSet node,
+      LocalVariableElement variable,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitLogicalAnd(
+      Send node,
+      Node left,
+      Node right,
+      A arg) {
+    apply(left, arg);
+    apply(right, arg);
+    return null;
+  }
+
+  @override
+  R visitLogicalOr(
+      Send node,
+      Node left,
+      Node right,
+      A arg) {
+    apply(left, arg);
+    apply(right, arg);
+    return null;
+  }
+
+  @override
+  R visitNot(
+      Send node,
+      Node expression,
+      A arg) {
+    apply(expression, arg);
+    return null;
+  }
+
+  @override
+  R visitNotEquals(
+      Send node,
+      Node left,
+      Node right,
+      A arg) {
+    apply(left, arg);
+    apply(right, arg);
+    return null;
+  }
+
+  @override
+  R visitParameterCompound(
+      Send node,
+      ParameterElement parameter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitParameterGet(
+      Send node,
+      ParameterElement parameter,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitParameterInvoke(
+      Send node,
+      ParameterElement parameter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitParameterPostfix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitParameterPrefix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitParameterSet(
+      SendSet node,
+      ParameterElement parameter,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitStaticFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitStaticFieldGet(
+      Send node,
+      FieldElement field,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitStaticFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitStaticFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitStaticFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitStaticFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitStaticFunctionGet(
+      Send node,
+      MethodElement function,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitStaticFunctionInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitStaticGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitStaticGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitStaticGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitStaticGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitStaticGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitStaticMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitStaticMethodSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitStaticMethodSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitStaticSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperBinary(
+      Send node,
+      FunctionElement function,
+      BinaryOperator operator,
+      Node argument,
+      A arg) {
+    apply(argument, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperCompoundIndexSet(
+      SendSet node,
+      FunctionElement getter,
+      FunctionElement setter,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperEquals(
+      Send node,
+      FunctionElement function,
+      Node argument,
+      A arg) {
+    apply(argument, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperFieldFieldPostfix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperFieldFieldPrefix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperFieldGet(
+      Send node,
+      FieldElement field,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperFieldSetterCompound(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperFieldSetterPostfix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperFieldSetterPrefix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperGetterFieldCompound(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperGetterFieldPostfix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperGetterFieldPrefix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperIndex(
+      Send node,
+      FunctionElement function,
+      Node index,
+      A arg) {
+    apply(index, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperIndexSet(
+      SendSet node,
+      FunctionElement function,
+      Node index,
+      Node rhs,
+      A arg) {
+    apply(index, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperMethodGet(
+      Send node,
+      MethodElement method,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperMethodInvoke(
+      Send node,
+      MethodElement method,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperMethodSetterPostfix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperMethodSetterPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitSuperNotEquals(
+      Send node,
+      FunctionElement function,
+      Node argument,
+      A arg) {
+    apply(argument, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitSuperUnary(
+      Send node,
+      UnaryOperator operator,
+      FunctionElement function,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitThisGet(Identifier node, A arg) {
+    return null;
+  }
+
+  @override
+  R visitThisInvoke(
+      Send node,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitThisPropertyCompound(
+      Send node,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitThisPropertyGet(
+      Send node,
+      Selector selector,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitThisPropertyInvoke(
+      Send node,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitThisPropertyPostfix(
+      Send node,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitThisPropertyPrefix(
+      Send node,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitThisPropertySet(
+      SendSet node,
+      Selector selector,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitTopLevelFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitTopLevelFieldGet(
+      Send node,
+      FieldElement field,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitTopLevelFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitTopLevelFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitTopLevelFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitTopLevelFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitTopLevelFunctionGet(
+      Send node,
+      MethodElement function,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitTopLevelFunctionInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitTopLevelGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitTopLevelGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R visitTopLevelGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitTopLevelGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitTopLevelGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitTopLevelMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitTopLevelMethodSetterPostfix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitTopLevelMethodSetterPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitTopLevelSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorTypeVariableTypeLiteralCompound(
+      Send node,
+      TypeVariableElement element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitTypeVariableTypeLiteralGet(
+      Send node,
+      TypeVariableElement element,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitTypeVariableTypeLiteralInvoke(
+      Send node,
+      TypeVariableElement element,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R errorTypeVariableTypeLiteralPostfix(
+      Send node,
+      TypeVariableElement element,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorTypeVariableTypeLiteralPrefix(
+      Send node,
+      TypeVariableElement element,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorTypedefTypeLiteralCompound(
+      Send node,
+      TypeConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R visitTypedefTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitTypedefTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R errorTypedefTypeLiteralPostfix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorTypedefTypeLiteralPrefix(
+      Send node,
+      TypeConstantExpression constant,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R visitUnary(
+      Send node,
+      UnaryOperator operator,
+      Node expression,
+      A arg) {
+    apply(expression, arg);
+    return null;
+  }
+
+  @override
+  R errorUnresolvedCompound(
+      Send node,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorUnresolvedGet(
+      Send node,
+      Element element,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorUnresolvedInvoke(
+      Send node,
+      Element element,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    apply(arguments, arg);
+    return null;
+  }
+
+  @override
+  R errorUnresolvedPostfix(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorUnresolvedPrefix(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorUnresolvedSet(
+      Send node,
+      Element element,
+      Node rhs,
+      A arg) {
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorUndefinedBinaryExpression(
+      Send node,
+      Node left,
+      Operator operator,
+      Node right,
+      A arg) {
+    apply(left, arg);
+    apply(right, arg);
+    return null;
+  }
+
+  @override
+  R errorUndefinedUnaryExpression(
+      Send node,
+      Operator operator,
+      Node expression,
+      A arg) {
+    apply(expression, arg);
+    return null;
+  }
+
+  @override
+  R errorUnresolvedSuperIndexSet(
+      Send node,
+      Element element,
+      Node index,
+      Node rhs,
+      A arg) {
+    apply(index, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorUnresolvedSuperCompoundIndexSet(
+      SendSet node,
+      Element element,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    apply(index, arg);
+    apply(rhs, arg);
+    return null;
+  }
+
+  @override
+  R errorUnresolvedSuperBinary(
+      Send node,
+      Element element,
+      BinaryOperator operator,
+      Node argument,
+      A arg) {
+    apply(argument, arg);
+    return null;
+  }
+
+  @override
+  R errorUnresolvedSuperUnary(
+      Send node,
+      UnaryOperator operator,
+      Element element,
+      A arg) {
+    return null;
+  }
+
+  @override
+  R errorUnresolvedSuperIndexPostfix(
+      Send node,
+      Element function,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    // TODO: implement errorUnresolvedSuperIndexPostfix
+  }
+
+  @override
+  R errorUnresolvedSuperIndexPrefix(
+      Send node,
+      Element function,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    // TODO: implement errorUnresolvedSuperIndexPrefix
+  }
+
+  @override
+  R visitIndexPostfix(
+      Send node,
+      Node receiver,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    // TODO: implement visitIndexPostfix
+  }
+
+  @override
+  R visitIndexPrefix(
+      Send node,
+      Node receiver,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    // TODO: implement visitIndexPrefix
+  }
+
+  @override
+  R visitSuperIndexPostfix(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    // TODO: implement visitSuperIndexPostfix
+  }
+
+  @override
+  R visitSuperIndexPrefix(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    // TODO: implement visitSuperIndexPrefix
+  }
+}
+
+/// AST visitor that visits all normal [Send] and [SendSet] nodes using the
+/// [SemanticVisitor].
+class TraversalVisitor<R, A> extends SemanticVisitor<R, A>
+    with TraversalMixin<R, A> {
+  TraversalVisitor(TreeElements elements) : super(elements);
+
+  SemanticSendVisitor<R, A> get sendVisitor => this;
+
+  R apply(Node node, A arg) {
+    node.accept(this);
+    return null;
+  }
+
+  @override
+  internalError(Spannable spannable, String message) {
+    throw new SpannableAssertionFailure(spannable, message);
+  }
+
+  @override
+  R visitNode(Node node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
+  R visitNewExpression(NewExpression node) {
+    // Bypass the [Send] holding the class/constructor name.
+    return apply(node.send.argumentsNode, null);
+  }
+
+  void visitParameters(NodeList parameters) {
+
+  }
+
+  void visitInitializers(NodeList initializers) {
+    // TODO(johnniwinther): Visit subnodes of initializers.
+  }
+
+  @override
+  R visitFunctionExpression(FunctionExpression node) {
+    if (node.parameters != null) {
+      visitParameters(node.parameters);
+    }
+    if (node.initializers != null) {
+      visitInitializers(node.initializers);
+    }
+    if (node.body != null) {
+      apply(node.body, null);
+    }
+    return null;
+  }
+}
+
+/// Mixin that groups all `visitStaticX` and `visitTopLevelX` method by
+/// delegating calls to `handleStaticX` methods.
+///
+/// This mixin is useful for the cases where both top level members and static
+/// class members are handled uniformly.
+abstract class BaseImplementationOfStaticsMixin<R, A>
+    implements SemanticSendVisitor<R, A> {
+  R handleStaticFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  R handleStaticFieldGet(
+      Send node,
+      FieldElement field,
+      A arg);
+
+  R handleStaticFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  R handleStaticFieldPostfixPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  R handleStaticFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg);
+
+  R handleStaticFunctionGet(
+      Send node,
+      MethodElement function,
+      A arg);
+
+  R handleStaticFunctionInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  R handleStaticGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg);
+
+  R handleStaticGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  R handleStaticGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  R handleStaticGetterSetterPostfixPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  R handleStaticMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  R handleStaticMethodSetterPostfixPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  R handleStaticSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg);
+
+  @override
+  R visitStaticFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return handleStaticFieldCompound(node, field, operator, rhs, arg);
+  }
+
+  @override
+  R visitStaticFieldGet(
+      Send node,
+      FieldElement field,
+      A arg) {
+    return handleStaticFieldGet(node, field, arg);
+  }
+
+  @override
+  R visitStaticFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleStaticFieldInvoke(node, field, arguments, selector, arg);
+  }
+
+  @override
+  R visitStaticFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticFieldPostfixPrefix(
+        node, field, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitStaticFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticFieldPostfixPrefix(
+        node, field, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitStaticFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    return handleStaticFieldSet(node, field, rhs, arg);
+  }
+
+  @override
+  R visitStaticFunctionGet(
+      Send node,
+      MethodElement function,
+      A arg) {
+    return handleStaticFunctionGet(node, function, arg);
+  }
+
+  @override
+  R visitStaticFunctionInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleStaticFunctionInvoke(node, function, arguments, selector, arg);
+  }
+
+  @override
+  R visitStaticGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg) {
+    return handleStaticGetterGet(node, getter, arg);
+  }
+
+  @override
+  R visitStaticGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleStaticGetterInvoke(node, getter, arguments, selector, arg);
+  }
+
+  @override
+  R visitStaticGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return handleStaticGetterSetterCompound(
+        node, getter, setter, operator, rhs, arg);
+  }
+
+  @override
+  R visitStaticGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticGetterSetterPostfixPrefix(
+        node, getter, setter, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitStaticGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticGetterSetterPostfixPrefix(
+        node, getter, setter, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitStaticMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return handleStaticMethodSetterCompound(
+        node, method, setter, operator, rhs, arg);
+  }
+
+  @override
+  R visitStaticMethodSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticMethodSetterPostfixPrefix(
+        node, getter, setter, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitStaticMethodSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticMethodSetterPostfixPrefix(
+        node, getter, setter, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitStaticSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg) {
+    return handleStaticSetterSet(node, setter, rhs, arg);
+  }
+
+  @override
+  R visitTopLevelFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return handleStaticFieldCompound(node, field, operator, rhs, arg);
+  }
+
+  @override
+  R visitTopLevelFieldGet(
+      Send node,
+      FieldElement field,
+      A arg) {
+    return handleStaticFieldGet(node, field, arg);
+  }
+
+  @override
+  R visitTopLevelFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleStaticFieldInvoke(node, field, arguments, selector, arg);
+  }
+
+  @override
+  R visitTopLevelFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticFieldPostfixPrefix(
+        node, field, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitTopLevelFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticFieldPostfixPrefix(
+        node, field, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitTopLevelFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      A arg) {
+    return handleStaticFieldSet(node, field, rhs, arg);
+  }
+
+  @override
+  R visitTopLevelFunctionGet(
+      Send node,
+      MethodElement function,
+      A arg) {
+    return handleStaticFunctionGet(node, function, arg);
+  }
+
+  @override
+  R visitTopLevelFunctionInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleStaticFunctionInvoke(node, function, arguments, selector, arg);
+  }
+
+  @override
+  R visitTopLevelGetterGet(
+      Send node,
+      FunctionElement getter,
+      A arg) {
+    return handleStaticGetterGet(node, getter, arg);
+  }
+
+  @override
+  R visitTopLevelGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleStaticGetterInvoke(node, getter, arguments, selector, arg);
+  }
+
+  @override
+  R visitTopLevelGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return handleStaticGetterSetterCompound(
+        node, getter, setter, operator, rhs, arg);
+  }
+
+  @override
+  R visitTopLevelGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticGetterSetterPostfixPrefix(
+        node, getter, setter, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitTopLevelGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticGetterSetterPostfixPrefix(
+        node, getter, setter, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitTopLevelMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return handleStaticMethodSetterCompound(
+        node, method, setter, operator, rhs, arg);
+  }
+
+  @override
+  R visitTopLevelMethodSetterPostfix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticMethodSetterPostfixPrefix(
+        node, method, setter, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitTopLevelMethodSetterPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleStaticMethodSetterPostfixPrefix(
+        node, method, setter, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitTopLevelSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      A arg) {
+    return handleStaticSetterSet(node, setter, rhs, arg);
+  }
+}
+
+/// Mixin that groups all `visitLocalX` and `visitParameterX` method by
+/// delegating calls to `handleLocalX` methods.
+///
+/// This mixin is useful for the cases where both parameters, local variables,
+/// and local functions, captured or not, are handled uniformly.
+abstract class BaseImplementationOfLocalsMixin<R, A>
+    implements SemanticSendVisitor<R, A> {
+  R handleLocalCompound(
+      Send node,
+      LocalElement element,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg);
+
+  R handleLocalGet(
+      Send node,
+      LocalElement element,
+      A arg);
+
+  R handleLocalInvoke(
+      Send node,
+      LocalElement element,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  R handleLocalPostfixPrefix(
+      Send node,
+      LocalElement element,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  R handleLocalSet(
+      SendSet node,
+      LocalElement element,
+      Node rhs,
+      A arg);
+
+  @override
+  R visitLocalFunctionGet(
+      Send node,
+      LocalFunctionElement function,
+      A arg) {
+    return handleLocalGet(node, function, arg);
+  }
+
+  @override
+  R visitLocalFunctionInvoke(
+      Send node,
+      LocalFunctionElement function,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleLocalInvoke(node, function, arguments, selector, arg);
+  }
+
+  @override
+  R visitLocalVariableCompound(
+      Send node,
+      LocalVariableElement variable,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return handleLocalCompound(node, variable, operator, rhs, arg);
+  }
+
+  @override
+  R visitLocalVariableGet(
+      Send node,
+      LocalVariableElement variable,
+      A arg) {
+    return handleLocalGet(node, variable, arg);
+  }
+
+  @override
+  R visitLocalVariableInvoke(
+      Send node,
+      LocalVariableElement variable,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleLocalInvoke(node, variable, arguments, selector, arg);
+  }
+
+  @override
+  R visitLocalVariablePostfix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      A arg) {
+    return handleLocalPostfixPrefix(
+        node, variable, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitLocalVariablePrefix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      A arg) {
+    return handleLocalPostfixPrefix(
+        node, variable, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitLocalVariableSet(
+      SendSet node,
+      LocalVariableElement variable,
+      Node rhs,
+      A arg) {
+    return handleLocalSet(node, variable, rhs, arg);
+  }
+
+  @override
+  R visitParameterCompound(
+      Send node,
+      ParameterElement parameter,
+      AssignmentOperator operator,
+      Node rhs,
+      A arg) {
+    return handleLocalCompound(node, parameter, operator, rhs, arg);
+  }
+
+  @override
+  R visitParameterGet(
+      Send node,
+      ParameterElement parameter,
+      A arg) {
+    return handleLocalGet(node, parameter, arg);
+  }
+
+  @override
+  R visitParameterInvoke(
+      Send node,
+      ParameterElement parameter,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleLocalInvoke(node, parameter, arguments, selector, arg);
+  }
+
+  @override
+  R visitParameterPostfix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      A arg) {
+    return handleLocalPostfixPrefix(
+        node, parameter, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitParameterPrefix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      A arg) {
+    return handleLocalPostfixPrefix(
+        node, parameter, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitParameterSet(
+      SendSet node,
+      ParameterElement parameter,
+      Node rhs,
+      A arg) {
+    return handleLocalSet(node, parameter, rhs, arg);
+  }
+}
+
+/// Mixin that groups all `visitConstantX` and `visitXTypeLiteralY` methods for
+/// constant type literals by delegating calls to `handleConstantX` methods.
+///
+/// This mixin is useful for the cases where expressions on constants are
+/// handled uniformly.
+abstract class BaseImplementationOfConstantsMixin<R, A>
+    implements SemanticSendVisitor<R, A> {
+  R handleConstantGet(
+      Send node,
+      ConstantExpression constant,
+      A arg);
+
+  R handleConstantInvoke(
+      Send node,
+      ConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  @override
+  R visitClassTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg) {
+    return handleConstantGet(node, constant, arg);
+  }
+
+  @override
+  R visitClassTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleConstantInvoke(node, constant, arguments, selector, arg);
+  }
+
+  @override
+  R visitConstantGet(
+      Send node,
+      ConstantExpression constant,
+      A arg) {
+    return handleConstantGet(node, constant, arg);
+  }
+
+  @override
+  R visitConstantInvoke(
+      Send node,
+      ConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleConstantInvoke(node, constant, arguments, selector, arg);
+  }
+
+  @override
+  R visitDynamicTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg) {
+    return handleConstantGet(node, constant, arg);
+  }
+
+  @override
+  R visitDynamicTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleConstantInvoke(node, constant, arguments, selector, arg);
+  }
+
+  @override
+  R visitTypedefTypeLiteralGet(
+      Send node,
+      TypeConstantExpression constant,
+      A arg) {
+    return handleConstantGet(node, constant, arg);
+  }
+
+  @override
+  R visitTypedefTypeLiteralInvoke(
+      Send node,
+      TypeConstantExpression constant,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleConstantInvoke(node, constant, arguments, selector, arg);
+  }
+}
+
+/// Mixin that groups all `visitDynamicPropertyX` and `visitThisPropertyY`
+/// methods for by delegating calls to `handleDynamicX` methods, providing
+/// `null` as the receiver for the this properties.
+///
+/// This mixin is useful for the cases where dynamic and this properties are
+/// handled uniformly.
+abstract class BaseImplementationOfDynamicsMixin<R, A>
+    implements SemanticSendVisitor<R, A> {
+  R handleDynamicCompound(
+      Send node,
+      Node receiver,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg);
+
+  R handleDynamicGet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      A arg);
+
+  R handleDynamicInvoke(
+      Send node,
+      Node receiver,
+      NodeList arguments,
+      Selector selector,
+      A arg);
+
+  R handleDynamicPostfixPrefix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg,
+      {bool isPrefix});
+
+  R handleDynamicSet(
+      SendSet node,
+      Node receiver,
+      Selector selector,
+      Node rhs,
+      A arg);
+
+  R handleDynamicIndexPostfixPrefix(
+      Send node,
+      Node receiver,
+      Node index,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  @override
+  R visitDynamicPropertyCompound(
+      Send node,
+      Node receiver,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicCompound(
+        node, receiver, operator, rhs, getterSelector, setterSelector, arg);
+  }
+
+  @override
+  R visitDynamicPropertyGet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      A arg) {
+    return handleDynamicGet(node, receiver, selector, arg);
+  }
+
+  @override
+  R visitDynamicPropertyInvoke(
+      Send node,
+      Node receiver,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleDynamicInvoke(node, receiver, arguments, selector, arg);
+  }
+
+  @override
+  R visitDynamicPropertyPostfix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicPostfixPrefix(
+        node, receiver, operator,
+        getterSelector, setterSelector, arg, isPrefix: false);
+  }
+
+  @override
+  R visitDynamicPropertyPrefix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicPostfixPrefix(
+        node, receiver, operator,
+        getterSelector, setterSelector, arg, isPrefix: true);
+  }
+
+  @override
+  R visitDynamicPropertySet(
+      SendSet node,
+      Node receiver,
+      Selector selector,
+      Node rhs,
+      A arg) {
+    return handleDynamicSet(node, receiver, selector, rhs, arg);
+  }
+
+  @override
+  R visitThisPropertyCompound(
+      Send node,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicCompound(
+        node, null, operator, rhs, getterSelector, setterSelector, arg);
+  }
+
+  @override
+  R visitThisPropertyGet(
+      Send node,
+      Selector selector,
+      A arg) {
+    return handleDynamicGet(node, null, selector, arg);
+  }
+
+  @override
+  R visitThisPropertyInvoke(
+      Send node,
+      NodeList arguments,
+      Selector selector,
+      A arg) {
+    return handleDynamicInvoke(node, null, arguments, selector, arg);
+  }
+
+  @override
+  R visitThisPropertyPostfix(
+      Send node,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicPostfixPrefix(
+        node, null, operator,
+        getterSelector, setterSelector, arg, isPrefix: false);
+  }
+
+  @override
+  R visitThisPropertyPrefix(
+      Send node,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      A arg) {
+    return handleDynamicPostfixPrefix(
+        node, null, operator,
+        getterSelector, setterSelector, arg, isPrefix: true);
+  }
+
+  @override
+  R visitThisPropertySet(
+      SendSet node,
+      Selector selector,
+      Node rhs,
+      A arg) {
+    return handleDynamicSet(node, null, selector, rhs, arg);
+  }
+
+  @override
+  R visitIndexPostfix(
+      Send node,
+      Node receiver,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return handleDynamicIndexPostfixPrefix(
+        node, receiver, index, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitIndexPrefix(
+      Send node,
+      Node receiver,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return handleDynamicIndexPostfixPrefix(
+        node, receiver, index, operator, arg, isPrefix: true);
+  }
+}
+
+/// Mixin that groups all `visitSuperXPrefix`, `visitSuperXPostfix` methods for
+/// by delegating calls to `handleSuperXPostfixPrefix` methods.
+///
+/// This mixin is useful for the cases where super prefix/postfix expression are
+/// handled uniformly.
+abstract class BaseImplementationOfSuperIncDecsMixin<R, A>
+    implements SemanticSendVisitor<R, A> {
+  R handleSuperFieldFieldPostfixPrefix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  R handleSuperFieldSetterPostfixPrefix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  R handleSuperGetterFieldPostfixPrefix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  R handleSuperGetterSetterPostfixPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  R handleSuperMethodSetterPostfixPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  R handleSuperIndexPostfixPrefix(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      IncDecOperator operator,
+      A arg,
+      {bool isPrefix});
+
+  @override
+  R visitSuperFieldFieldPostfix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperFieldFieldPostfixPrefix(
+        node, readField, writtenField, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitSuperFieldFieldPrefix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperFieldFieldPostfixPrefix(
+        node, readField, writtenField, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitSuperFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperFieldFieldPostfixPrefix(
+        node, field, field, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitSuperFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperFieldFieldPostfixPrefix(
+        node, field, field, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitSuperFieldSetterPostfix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperFieldSetterPostfixPrefix(
+        node, field, setter, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitSuperFieldSetterPrefix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperFieldSetterPostfixPrefix(
+        node, field, setter, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitSuperGetterFieldPostfix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperGetterFieldPostfixPrefix(
+        node, getter, field, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitSuperGetterFieldPrefix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperGetterFieldPostfixPrefix(
+        node, getter, field, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitSuperGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperGetterSetterPostfixPrefix(
+        node, getter, setter, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitSuperGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperGetterSetterPostfixPrefix(
+        node, getter, setter, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitSuperMethodSetterPostfix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperMethodSetterPostfixPrefix(
+        node, method, setter, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitSuperMethodSetterPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperMethodSetterPostfixPrefix(
+        node, method, setter, operator, arg, isPrefix: true);
+  }
+
+  @override
+  R visitSuperIndexPostfix(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperIndexPostfixPrefix(
+        node, indexFunction, indexSetFunction,
+        index, operator, arg, isPrefix: false);
+  }
+
+  @override
+  R visitSuperIndexPrefix(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      IncDecOperator operator,
+      A arg) {
+    return handleSuperIndexPostfixPrefix(
+        node, indexFunction, indexSetFunction,
+        index, operator, arg, isPrefix: true);
+  }
+}
diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
new file mode 100644
index 0000000..aa5a747
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/send_resolver.dart
@@ -0,0 +1,401 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart2js.semantics_visitor;
+
+enum SendStructureKind {
+  GET,
+  SET,
+  INVOKE,
+  UNARY,
+  NOT,
+  BINARY,
+  EQ,
+  NOT_EQ,
+  COMPOUND,
+  INDEX,
+  INDEX_SET,
+  COMPOUND_INDEX_SET,
+  PREFIX,
+  POSTFIX,
+  INDEX_PREFIX,
+  INDEX_POSTFIX,
+}
+
+abstract class SendResolverMixin {
+  TreeElements get elements;
+
+  internalError(Spannable spannable, String message);
+
+  AccessSemantics handleStaticallyResolvedAccess(Send node,
+                                                 Element element,
+                                                 Element getter) {
+    if (element.isErroneous) {
+      return new StaticAccess.unresolved(element);
+    } else if (element.isParameter) {
+      return new StaticAccess.parameter(element);
+    } else if (element.isLocal) {
+      if (element.isFunction) {
+        return new StaticAccess.localFunction(element);
+      } else {
+        return new StaticAccess.localVariable(element);
+      }
+    } else if (element.isStatic) {
+      if (element.isField) {
+        return new StaticAccess.staticField(element);
+      } else if (element.isGetter) {
+        return new StaticAccess.staticGetter(element);
+      } else if (element.isSetter) {
+        if (getter != null) {
+          CompoundAccessKind accessKind;
+          if (getter.isGetter) {
+            accessKind = CompoundAccessKind.STATIC_GETTER_SETTER;
+          } else {
+            accessKind = CompoundAccessKind.STATIC_METHOD_SETTER;
+          }
+          return new CompoundAccessSemantics(
+              accessKind, getter, element);
+        } else {
+          return new StaticAccess.staticSetter(element);
+        }
+      } else {
+        return new StaticAccess.staticMethod(element);
+      }
+    } else if (element.isTopLevel) {
+      if (element.isField) {
+        return new StaticAccess.topLevelField(element);
+      } else if (element.isGetter) {
+        return new StaticAccess.topLevelGetter(element);
+      } else if (element.isSetter) {
+        if (getter != null) {
+          CompoundAccessKind accessKind;
+          if (getter.isGetter) {
+            accessKind = CompoundAccessKind.TOPLEVEL_GETTER_SETTER;
+          } else {
+            accessKind = CompoundAccessKind.TOPLEVEL_METHOD_SETTER;
+          }
+          return new CompoundAccessSemantics(
+              accessKind, getter, element);
+        } else {
+          return new StaticAccess.topLevelSetter(element);
+        }
+      } else {
+        return new StaticAccess.topLevelMethod(element);
+      }
+    } else {
+      return internalError(
+          node, "Unhandled resolved property access: $element");
+    }
+  }
+
+  SendStructure computeSendStructure(Send node) {
+    if (elements.isAssert(node)) {
+      if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) {
+        return const AssertStructure();
+      } else {
+        return const InvalidAssertStructure();
+      }
+    }
+
+    AssignmentOperator assignmentOperator;
+    UnaryOperator unaryOperator;
+    BinaryOperator binaryOperator;
+    IncDecOperator incDecOperator;
+
+    if (node.isOperator) {
+      String operatorText = node.selector.asOperator().source;
+      if (operatorText == 'is') {
+        if (node.isIsNotCheck) {
+          return new IsNotStructure(
+              elements.getType(node.arguments.single.asSend().receiver));
+        } else {
+          return new IsStructure(elements.getType(node.arguments.single));
+        }
+      } else if (operatorText == 'as') {
+        return new AsStructure(elements.getType(node.arguments.single));
+      } else if (operatorText == '&&') {
+        return const LogicalAndStructure();
+      } else if (operatorText == '||') {
+        return const LogicalOrStructure();
+      }
+    }
+
+    SendStructureKind kind;
+
+    if (node.asSendSet() != null) {
+      SendSet sendSet = node.asSendSet();
+      String operatorText = sendSet.assignmentOperator.source;
+      if (sendSet.isPrefix || sendSet.isPostfix) {
+        kind = sendSet.isPrefix
+            ? SendStructureKind.PREFIX
+            : SendStructureKind.POSTFIX;
+        incDecOperator = IncDecOperator.parse(operatorText);
+        if (incDecOperator == null) {
+          return internalError(
+              node, "No inc/dec operator for '$operatorText'.");
+        }
+      } else {
+        assignmentOperator = AssignmentOperator.parse(operatorText);
+        if (assignmentOperator != null) {
+          switch (assignmentOperator.kind) {
+            case AssignmentOperatorKind.ASSIGN:
+              kind = SendStructureKind.SET;
+              break;
+            default:
+              kind = SendStructureKind.COMPOUND;
+          }
+        } else {
+          return internalError(
+              node, "No assignment operator for '$operatorText'.");
+        }
+      }
+    } else if (!node.isPropertyAccess) {
+      kind = SendStructureKind.INVOKE;
+    } else {
+      kind = SendStructureKind.GET;
+    }
+
+    if (node.isOperator) {
+      String operatorText = node.selector.asOperator().source;
+      if (node.arguments.isEmpty) {
+        unaryOperator = UnaryOperator.parse(operatorText);
+        if (unaryOperator != null) {
+          switch (unaryOperator.kind) {
+            case UnaryOperatorKind.NOT:
+              kind = SendStructureKind.NOT;
+              break;
+            default:
+              kind = SendStructureKind.UNARY;
+              break;
+          }
+        } else {
+          return const InvalidUnaryStructure();
+        }
+      } else {
+        binaryOperator = BinaryOperator.parse(operatorText);
+        if (binaryOperator != null) {
+          switch (binaryOperator.kind) {
+            case BinaryOperatorKind.EQ:
+              kind = SendStructureKind.EQ;
+              break;
+            case BinaryOperatorKind.NOT_EQ:
+              if (node.isSuperCall) {
+                // `super != foo` is a compile-time error.
+                return const InvalidBinaryStructure();
+              }
+              kind = SendStructureKind.NOT_EQ;
+              break;
+            case BinaryOperatorKind.INDEX:
+              if (node.isPrefix) {
+                kind = SendStructureKind.INDEX_PREFIX;
+              } else if (node.isPostfix) {
+                kind = SendStructureKind.INDEX_POSTFIX;
+              } else if (node.arguments.tail.isEmpty) {
+                // a[b]
+                kind = SendStructureKind.INDEX;
+              } else {
+                if (kind == SendStructureKind.COMPOUND) {
+                  // a[b] += c
+                  kind = SendStructureKind.COMPOUND_INDEX_SET;
+                } else {
+                  // a[b] = c
+                  kind = SendStructureKind.INDEX_SET;
+                }
+              }
+              break;
+            default:
+              kind = SendStructureKind.BINARY;
+              break;
+          }
+        } else {
+          return const InvalidBinaryStructure();
+        }
+      }
+    }
+    AccessSemantics semantics = computeAccessSemantics(
+        node,
+        isGetOrSet: kind == SendStructureKind.GET ||
+                    kind == SendStructureKind.SET,
+        isInvoke: kind == SendStructureKind.INVOKE,
+        isCompound: kind == SendStructureKind.COMPOUND ||
+                    kind == SendStructureKind.COMPOUND_INDEX_SET ||
+                    kind == SendStructureKind.PREFIX ||
+                    kind == SendStructureKind.POSTFIX ||
+                    kind == SendStructureKind.INDEX_PREFIX ||
+                    kind == SendStructureKind.INDEX_POSTFIX);
+    if (semantics == null) {
+      return internalError(node, 'No semantics for $node');
+    }
+    Selector selector = elements.getSelector(node);
+    switch (kind) {
+      case SendStructureKind.GET:
+        return new GetStructure(semantics, selector);
+      case SendStructureKind.SET:
+        return new SetStructure(semantics, selector);
+      case SendStructureKind.INVOKE:
+        return new InvokeStructure(semantics, selector);
+      case SendStructureKind.UNARY:
+        return new UnaryStructure(semantics, unaryOperator, selector);
+      case SendStructureKind.NOT:
+        assert(selector == null);
+        return new NotStructure(semantics, selector);
+      case SendStructureKind.BINARY:
+        return new BinaryStructure(semantics, binaryOperator, selector);
+      case SendStructureKind.INDEX:
+        return new IndexStructure(semantics, selector);
+      case SendStructureKind.EQ:
+        return new EqualsStructure(semantics, selector);
+      case SendStructureKind.NOT_EQ:
+        return new NotEqualsStructure(semantics, selector);
+      case SendStructureKind.COMPOUND:
+        Selector getterSelector =
+            elements.getGetterSelectorInComplexSendSet(node);
+        return new CompoundStructure(
+            semantics,
+            assignmentOperator,
+            getterSelector,
+            selector);
+      case SendStructureKind.INDEX_SET:
+        return new IndexSetStructure(semantics, selector);
+      case SendStructureKind.COMPOUND_INDEX_SET:
+        Selector getterSelector =
+            elements.getGetterSelectorInComplexSendSet(node);
+        return new CompoundIndexSetStructure(
+            semantics,
+            assignmentOperator,
+            getterSelector,
+            selector);
+      case SendStructureKind.INDEX_PREFIX:
+        Selector getterSelector =
+            elements.getGetterSelectorInComplexSendSet(node);
+        return new IndexPrefixStructure(
+            semantics,
+            incDecOperator,
+            getterSelector,
+            selector);
+      case SendStructureKind.INDEX_POSTFIX:
+        Selector getterSelector =
+            elements.getGetterSelectorInComplexSendSet(node);
+        return new IndexPostfixStructure(
+            semantics,
+            incDecOperator,
+            getterSelector,
+            selector);
+      case SendStructureKind.PREFIX:
+        Selector getterSelector =
+            elements.getGetterSelectorInComplexSendSet(node);
+        return new PrefixStructure(
+            semantics,
+            incDecOperator,
+            getterSelector,
+            selector);
+      case SendStructureKind.POSTFIX:
+        Selector getterSelector =
+            elements.getGetterSelectorInComplexSendSet(node);
+        return new PostfixStructure(
+            semantics,
+            incDecOperator,
+            getterSelector,
+            selector);
+    }
+  }
+
+  AccessSemantics computeAccessSemantics(Send node,
+                                         {bool isGetOrSet: false,
+                                          bool isInvoke: false,
+                                          bool isCompound: false}) {
+    Element element = elements[node];
+    Element getter = isCompound ? elements[node.selector] : null;
+    if (elements.isTypeLiteral(node)) {
+      DartType dartType = elements.getTypeLiteralType(node);
+      TypeConstantExpression constant = elements.getConstant(
+          isInvoke ? node.selector : node);
+      switch (dartType.kind) {
+        case TypeKind.INTERFACE:
+          return new ConstantAccess.classTypeLiteral(constant);
+        case TypeKind.TYPEDEF:
+          return new ConstantAccess.typedefTypeLiteral(constant);
+        case TypeKind.TYPE_VARIABLE:
+          return new StaticAccess.typeParameterTypeLiteral(dartType.element);
+        case TypeKind.DYNAMIC:
+          return new ConstantAccess.dynamicTypeLiteral(constant);
+        default:
+          return internalError(node, "Unexpected type literal type: $dartType");
+      }
+    } else if (node.isSuperCall) {
+      if (Elements.isUnresolved(element)) {
+        return new StaticAccess.unresolved(element);
+      } else if (isCompound && Elements.isUnresolved(getter)) {
+        // TODO(johnniwinther): Ensure that [getter] is not null. This happens
+        // in the case of missing super getter.
+        return new StaticAccess.unresolved(getter);
+      } else if (element.isField) {
+        if (getter != null && getter != element) {
+          CompoundAccessKind accessKind;
+          if (getter.isField) {
+            accessKind = CompoundAccessKind.SUPER_FIELD_FIELD;
+          } else if (getter.isGetter) {
+            accessKind = CompoundAccessKind.SUPER_GETTER_FIELD;
+          } else {
+            return internalError(node,
+               "Unsupported super call: $node : $element/$getter.");
+          }
+          return new CompoundAccessSemantics(accessKind, getter, element);
+        }
+        return new StaticAccess.superField(element);
+      } else if (element.isGetter) {
+        return new StaticAccess.superGetter(element);
+      } else if (element.isSetter) {
+        if (getter != null) {
+          CompoundAccessKind accessKind;
+          if (getter.isField) {
+            accessKind = CompoundAccessKind.SUPER_FIELD_SETTER;
+          } else if (getter.isGetter) {
+            accessKind = CompoundAccessKind.SUPER_GETTER_SETTER;
+          } else {
+            accessKind = CompoundAccessKind.SUPER_METHOD_SETTER;
+          }
+          return new CompoundAccessSemantics(accessKind, getter, element);
+        }
+        return new StaticAccess.superSetter(element);
+      } else if (isCompound) {
+        return new CompoundAccessSemantics(
+            CompoundAccessKind.SUPER_GETTER_SETTER, getter, element);
+      } else {
+        return new StaticAccess.superMethod(element);
+      }
+    } else if (node.isOperator) {
+      return new DynamicAccess.dynamicProperty(node.receiver);
+    } else if (Elements.isClosureSend(node, element)) {
+      if (element == null) {
+        if (node.selector.isThis()) {
+          return new AccessSemantics.thisAccess();
+        } else {
+          return new AccessSemantics.expression();
+        }
+      } else if (Elements.isErroneous(element)) {
+        return new StaticAccess.unresolved(element);
+      } else {
+        return handleStaticallyResolvedAccess(node, element, getter);
+      }
+    } else {
+      if (Elements.isErroneous(element)) {
+        return new StaticAccess.unresolved(element);
+      } else if (element == null || element.isInstanceMember) {
+        if (node.receiver == null || node.receiver.isThis()) {
+          return new AccessSemantics.thisProperty();
+        } else {
+          return new DynamicAccess.dynamicProperty(node.receiver);
+        }
+      } else if (element.impliesType) {
+        // TODO(johnniwinther): Provide an [ErroneousElement].
+        // This happens for code like `C.this`.
+        return new StaticAccess.unresolved(null);
+      } else {
+        return handleStaticallyResolvedAccess(node, element, getter);
+      }
+    }
+  }
+}
+
diff --git a/pkg/compiler/lib/src/resolution/send_structure.dart b/pkg/compiler/lib/src/resolution/send_structure.dart
new file mode 100644
index 0000000..c233b35
--- /dev/null
+++ b/pkg/compiler/lib/src/resolution/send_structure.dart
@@ -0,0 +1,1766 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.send_structure;
+
+import 'access_semantics.dart';
+import 'operators.dart';
+import 'semantic_visitor.dart';
+import '../tree/tree.dart';
+import '../dart_types.dart';
+import '../universe/universe.dart';
+import '../util/util.dart';
+
+/// Interface for the structure of the semantics of a [Send] node.
+///
+/// Subclasses handle each of the [Send] variations; `assert(e)`, `a && b`,
+/// `a.b`, `a.b(c)`, etc.
+abstract class SendStructure<R, A> {
+  /// Calls the matching visit method on [visitor] with [send] and [arg].
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send send, A arg);
+}
+
+/// The structure for a [Send] of the form `assert(e)`.
+class AssertStructure<R, A> implements SendStructure<R, A> {
+  const AssertStructure();
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    return visitor.visitAssert(
+        node,
+        node.arguments.single,
+        arg);
+  }
+}
+
+/// The structure for a [Send] of the form an `assert` with less or more than
+/// one argument.
+class InvalidAssertStructure<R, A> implements SendStructure<R, A> {
+  const InvalidAssertStructure();
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    return visitor.errorInvalidAssert(
+        node,
+        node.argumentsNode,
+        arg);
+  }
+}
+
+/// The structure for a [Send] of the form `a && b`.
+class LogicalAndStructure<R, A> implements SendStructure<R, A> {
+  const LogicalAndStructure();
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    return visitor.visitLogicalAnd(
+        node,
+        node.receiver,
+        node.arguments.single,
+        arg);
+  }
+}
+
+/// The structure for a [Send] of the form `a || b`.
+class LogicalOrStructure<R, A> implements SendStructure<R, A> {
+  const LogicalOrStructure();
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    return visitor.visitLogicalOr(
+        node,
+        node.receiver,
+        node.arguments.single,
+        arg);
+  }
+}
+
+/// The structure for a [Send] of the form `a is T`.
+class IsStructure<R, A> implements SendStructure<R, A> {
+  /// The type that the expression is tested against.
+  final DartType type;
+
+  IsStructure(this.type);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    return visitor.visitIs(
+        node,
+        node.receiver,
+        type,
+        arg);
+  }
+}
+
+/// The structure for a [Send] of the form `a is! T`.
+class IsNotStructure<R, A> implements SendStructure<R, A> {
+  /// The type that the expression is tested against.
+  final DartType type;
+
+  IsNotStructure(this.type);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    return visitor.visitIsNot(
+        node,
+        node.receiver,
+        type,
+        arg);
+  }
+}
+
+/// The structure for a [Send] of the form `a as T`.
+class AsStructure<R, A> implements SendStructure<R, A> {
+  /// The type that the expression is cast to.
+  final DartType type;
+
+  AsStructure(this.type);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    return visitor.visitAs(
+        node,
+        node.receiver,
+        type,
+        arg);
+  }
+}
+
+/// The structure for a [Send] that is an invocation.
+class InvokeStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the invocation.
+  final AccessSemantics semantics;
+
+  /// The [Selector] for the invocation.
+  final Selector selector;
+
+  InvokeStructure(this.semantics, this.selector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitDynamicPropertyInvoke(
+            node,
+            node.receiver,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.LOCAL_FUNCTION:
+        return visitor.visitLocalFunctionInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            // TODO(johnniwinther): Store the call selector instead of the
+            // selector using the name of the function.
+            new Selector.callClosureFrom(selector),
+            arg);
+      case AccessKind.LOCAL_VARIABLE:
+        return visitor.visitLocalVariableInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            // TODO(johnniwinther): Store the call selector instead of the
+            // selector using the name of the variable.
+            new Selector.callClosureFrom(selector),
+            arg);
+      case AccessKind.PARAMETER:
+        return visitor.visitParameterInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            // TODO(johnniwinther): Store the call selector instead of the
+            // selector using the name of the parameter.
+            new Selector.callClosureFrom(selector),
+            arg);
+      case AccessKind.STATIC_FIELD:
+        return visitor.visitStaticFieldInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.STATIC_METHOD:
+        return visitor.visitStaticFunctionInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.STATIC_GETTER:
+        return visitor.visitStaticGetterInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.STATIC_SETTER:
+        return visitor.errorStaticSetterInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.TOPLEVEL_FIELD:
+        return visitor.visitTopLevelFieldInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.TOPLEVEL_METHOD:
+        return visitor.visitTopLevelFunctionInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.TOPLEVEL_GETTER:
+        return visitor.visitTopLevelGetterInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.TOPLEVEL_SETTER:
+        return visitor.errorTopLevelSetterInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.CLASS_TYPE_LITERAL:
+        return visitor.visitClassTypeLiteralInvoke(
+            node,
+            semantics.constant,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.TYPEDEF_TYPE_LITERAL:
+        return visitor.visitTypedefTypeLiteralInvoke(
+            node,
+            semantics.constant,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.DYNAMIC_TYPE_LITERAL:
+        return visitor.visitDynamicTypeLiteralInvoke(
+            node,
+            semantics.constant,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+        return visitor.visitTypeVariableTypeLiteralInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.EXPRESSION:
+        return visitor.visitExpressionInvoke(
+            node,
+            node.selector,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.THIS:
+        return visitor.visitThisInvoke(
+            node,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.THIS_PROPERTY:
+        return visitor.visitThisPropertyInvoke(
+            node,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.SUPER_FIELD:
+        return visitor.visitSuperFieldInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        return visitor.visitSuperMethodInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.SUPER_GETTER:
+        return visitor.visitSuperGetterInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.SUPER_SETTER:
+        return visitor.errorSuperSetterInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.CONSTANT:
+        return visitor.visitConstantInvoke(
+            node,
+            semantics.constant,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedInvoke(
+            node,
+            semantics.element,
+            node.argumentsNode,
+            selector,
+            arg);
+      case AccessKind.COMPOUND:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(node, "Invalid invoke: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is a read access.
+class GetStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the read access.
+  final AccessSemantics semantics;
+
+  /// The [Selector] for the getter invocation.
+  final Selector selector;
+
+  GetStructure(this.semantics, this.selector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitDynamicPropertyGet(
+            node,
+            node.receiver,
+            selector,
+            arg);
+      case AccessKind.LOCAL_FUNCTION:
+        return visitor.visitLocalFunctionGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.LOCAL_VARIABLE:
+        return visitor.visitLocalVariableGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.PARAMETER:
+        return visitor.visitParameterGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.STATIC_FIELD:
+        return visitor.visitStaticFieldGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.STATIC_METHOD:
+        return visitor.visitStaticFunctionGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.STATIC_GETTER:
+        return visitor.visitStaticGetterGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.STATIC_SETTER:
+        return visitor.errorStaticSetterGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.TOPLEVEL_FIELD:
+        return visitor.visitTopLevelFieldGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.TOPLEVEL_METHOD:
+        return visitor.visitTopLevelFunctionGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.TOPLEVEL_GETTER:
+        return visitor.visitTopLevelGetterGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.TOPLEVEL_SETTER:
+        return visitor.errorTopLevelSetterGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.CLASS_TYPE_LITERAL:
+        return visitor.visitClassTypeLiteralGet(
+            node,
+            semantics.constant,
+            arg);
+      case AccessKind.TYPEDEF_TYPE_LITERAL:
+        return visitor.visitTypedefTypeLiteralGet(
+            node,
+            semantics.constant,
+            arg);
+      case AccessKind.DYNAMIC_TYPE_LITERAL:
+        return visitor.visitDynamicTypeLiteralGet(
+            node,
+            semantics.constant,
+            arg);
+      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+        return visitor.visitTypeVariableTypeLiteralGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.EXPRESSION:
+        // This is not a valid case.
+        break;
+      case AccessKind.THIS:
+        // TODO(johnniwinther): Handle this when `this` is a [Send].
+        break;
+      case AccessKind.THIS_PROPERTY:
+        return visitor.visitThisPropertyGet(
+            node,
+            selector,
+            arg);
+      case AccessKind.SUPER_FIELD:
+        return visitor.visitSuperFieldGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        return visitor.visitSuperMethodGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.SUPER_GETTER:
+        return visitor.visitSuperGetterGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.SUPER_SETTER:
+        return visitor.errorSuperSetterGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.CONSTANT:
+        return visitor.visitConstantGet(
+            node,
+            semantics.constant,
+            arg);
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedGet(
+            node,
+            semantics.element,
+            arg);
+      case AccessKind.COMPOUND:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(node, "Invalid getter: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is an assignment.
+class SetStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the assignment.
+  final AccessSemantics semantics;
+
+  /// The [Selector] for the setter invocation.
+  final Selector selector;
+
+  SetStructure(this.semantics, this.selector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+          return visitor.visitDynamicPropertySet(
+            node,
+            node.receiver,
+            selector,
+            node.arguments.single,
+            arg);
+      case AccessKind.LOCAL_FUNCTION:
+        return visitor.errorLocalFunctionSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.LOCAL_VARIABLE:
+        return visitor.visitLocalVariableSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.PARAMETER:
+        return visitor.visitParameterSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.STATIC_FIELD:
+        return visitor.visitStaticFieldSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.STATIC_METHOD:
+        return visitor.errorStaticFunctionSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.STATIC_GETTER:
+        return visitor.errorStaticGetterSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.STATIC_SETTER:
+        return visitor.visitStaticSetterSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.TOPLEVEL_FIELD:
+        return visitor.visitTopLevelFieldSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.TOPLEVEL_METHOD:
+        return visitor.errorTopLevelFunctionSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.TOPLEVEL_GETTER:
+        return visitor.errorTopLevelGetterSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.TOPLEVEL_SETTER:
+        return visitor.visitTopLevelSetterSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.CLASS_TYPE_LITERAL:
+        return visitor.errorClassTypeLiteralSet(
+            node,
+            semantics.constant,
+            node.arguments.single,
+            arg);
+      case AccessKind.TYPEDEF_TYPE_LITERAL:
+        return visitor.errorTypedefTypeLiteralSet(
+            node,
+            semantics.constant,
+            node.arguments.single,
+            arg);
+      case AccessKind.DYNAMIC_TYPE_LITERAL:
+        return visitor.errorDynamicTypeLiteralSet(
+            node,
+            semantics.constant,
+            node.arguments.single,
+            arg);
+      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+        return visitor.errorTypeVariableTypeLiteralSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.EXPRESSION:
+        // This is not a valid case.
+        break;
+      case AccessKind.THIS:
+        // This is not a valid case.
+        break;
+      case AccessKind.THIS_PROPERTY:
+        return visitor.visitThisPropertySet(
+            node,
+            selector,
+            node.arguments.single,
+            arg);
+      case AccessKind.SUPER_FIELD:
+        return visitor.visitSuperFieldSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        return visitor.errorSuperMethodSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.SUPER_GETTER:
+        return visitor.errorSuperGetterSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.SUPER_SETTER:
+        return visitor.visitSuperSetterSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.CONSTANT:
+        // TODO(johnniwinther): Should this be a valid case?
+        break;
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedSet(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.COMPOUND:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(node, "Invalid setter: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is a negation, i.e. of the form `!e`.
+class NotStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the negation.
+  final AccessSemantics semantics;
+
+  // TODO(johnniwinther): Should we store this?
+  final Selector selector;
+
+  NotStructure(this.semantics, this.selector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitNot(
+            node,
+            node.receiver,
+            arg);
+      default:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(node, "Invalid setter: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is an invocation of a user definable unary
+/// operator.
+class UnaryStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the unary operation.
+  final AccessSemantics semantics;
+
+  /// The user definable unary operator.
+  final UnaryOperator operator;
+
+  // TODO(johnniwinther): Should we store this?
+  /// The [Selector] for the unary operator invocation.
+  final Selector selector;
+
+  UnaryStructure(this.semantics, this.operator, this.selector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitUnary(
+            node,
+            operator,
+            node.receiver,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        return visitor.visitSuperUnary(
+            node,
+            operator,
+            semantics.element,
+            arg);
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedSuperUnary(
+            node,
+            operator,
+            semantics.element,
+            arg);
+      default:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(node, "Invalid setter: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is an invocation of a undefined unary
+/// operator.
+class InvalidUnaryStructure<R, A> implements SendStructure<R, A> {
+  const InvalidUnaryStructure();
+
+  @override
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    return visitor.errorUndefinedUnaryExpression(
+        node,
+        node.selector,
+        node.receiver,
+        arg);
+  }
+}
+
+/// The structure for a [Send] that is an index expression, i.e. of the form
+/// `a[b]`.
+class IndexStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the left operand.
+  final AccessSemantics semantics;
+
+  // TODO(johnniwinther): Should we store this?
+  /// The [Selector] for the `[]` invocation.
+  final Selector selector;
+
+  IndexStructure(this.semantics, this.selector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitIndex(
+            node,
+            node.receiver,
+            node.arguments.single,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        return visitor.visitSuperIndex(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedSuperIndex(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      default:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(node, "Invalid index: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is an equals test, i.e. of the form
+/// `a == b`.
+class EqualsStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the left operand.
+  final AccessSemantics semantics;
+
+  // TODO(johnniwinther): Should we store this?
+  /// The [Selector] for the `==` invocation.
+  final Selector selector;
+
+  EqualsStructure(this.semantics, this.selector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitEquals(
+            node,
+            node.receiver,
+            node.arguments.single,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        return visitor.visitSuperEquals(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      default:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(node, "Invalid equals: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is a not-equals test, i.e. of the form
+/// `a != b`.
+class NotEqualsStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the left operand.
+  final AccessSemantics semantics;
+
+  // TODO(johnniwinther): Should we store this?
+  /// The [Selector] for the underlying `==` invocation.
+  final Selector selector;
+
+  NotEqualsStructure(this.semantics, this.selector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitNotEquals(
+            node,
+            node.receiver,
+            node.arguments.single,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        return visitor.visitSuperNotEquals(
+            node,
+            semantics.element,
+            node.arguments.single,
+            arg);
+      default:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(
+        node, "Invalid not equals: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is an invocation of a user-definable binary
+/// operator.
+class BinaryStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the left operand.
+  final AccessSemantics semantics;
+
+  /// The user definable binary operator.
+  final BinaryOperator operator;
+
+  // TODO(johnniwinther): Should we store this?
+  /// The [Selector] for the binary operator invocation.
+  final Selector selector;
+
+  BinaryStructure(this.semantics, this.operator, this.selector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitBinary(
+            node,
+            node.receiver,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        return visitor.visitSuperBinary(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedSuperBinary(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
+      default:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(
+        node, "Invalid binary: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is an invocation of a undefined binary
+/// operator.
+class InvalidBinaryStructure<R, A> implements SendStructure<R, A> {
+  const InvalidBinaryStructure();
+
+  @override
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    return visitor.errorUndefinedBinaryExpression(
+        node,
+        node.receiver,
+        node.selector,
+        node.arguments.single,
+        arg);
+  }
+}
+
+/// The structure for a [Send] that is of the form `a[b] = c`.
+class IndexSetStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the index set operation.
+  final AccessSemantics semantics;
+
+  // TODO(johnniwinther): Should we store this?
+  /// The [Selector] for the `[]=` operator invocation.
+  final Selector selector;
+
+  IndexSetStructure(this.semantics, this.selector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitIndexSet(
+            node,
+            node.receiver,
+            node.arguments.first,
+            node.arguments.tail.head,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        return visitor.visitSuperIndexSet(
+            node,
+            semantics.element,
+            node.arguments.first,
+            node.arguments.tail.head,
+            arg);
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedSuperIndexSet(
+            node,
+            semantics.element,
+            node.arguments.first,
+            node.arguments.tail.head,
+            arg);
+      default:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(
+        node, "Invalid index set: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is an prefix operation on an index
+/// expression, i.e. of the form `--a[b]`.
+class IndexPrefixStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the left operand.
+  final AccessSemantics semantics;
+
+  /// The `++` or `--` operator used in the operation.
+  final IncDecOperator operator;
+
+  // TODO(johnniwinther): Should we store this?
+  /// The [Selector] for the `[]` invocation.
+  final Selector getterSelector;
+
+  // TODO(johnniwinther): Should we store this?
+  /// The [Selector] for the `[]=` invocation.
+  final Selector setterSelector;
+
+  IndexPrefixStructure(this.semantics,
+                       this.operator,
+                       this.getterSelector,
+                       this.setterSelector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitIndexPrefix(
+            node,
+            node.receiver,
+            node.arguments.single,
+            operator,
+            arg);
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedSuperIndexPrefix(
+            node,
+            semantics.element,
+            node.arguments.single,
+            operator,
+            arg);
+      case AccessKind.COMPOUND:
+        CompoundAccessSemantics compoundSemantics = semantics;
+        switch (compoundSemantics.compoundAccessKind) {
+          case CompoundAccessKind.SUPER_GETTER_SETTER:
+            return visitor.visitSuperIndexPrefix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                node.arguments.single,
+                operator,
+                arg);
+          default:
+            // This is not a valid case.
+            break;
+        }
+        break;
+      default:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(
+        node, "Invalid index prefix: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is an postfix operation on an index
+/// expression, i.e. of the form `a[b]++`.
+class IndexPostfixStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the left operand.
+  final AccessSemantics semantics;
+
+  /// The `++` or `--` operator used in the operation.
+  final IncDecOperator operator;
+
+  // TODO(johnniwinther): Should we store this?
+  /// The [Selector] for the `[]` invocation.
+  final Selector getterSelector;
+
+  // TODO(johnniwinther): Should we store this?
+  /// The [Selector] for the `[]=` invocation.
+  final Selector setterSelector;
+
+  IndexPostfixStructure(this.semantics,
+                        this.operator,
+                        this.getterSelector,
+                        this.setterSelector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitIndexPostfix(
+            node,
+            node.receiver,
+            node.arguments.single,
+            operator,
+            arg);
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedSuperIndexPostfix(
+            node,
+            semantics.element,
+            node.arguments.single,
+            operator,
+            arg);
+      case AccessKind.COMPOUND:
+        CompoundAccessSemantics compoundSemantics = semantics;
+        switch (compoundSemantics.compoundAccessKind) {
+          case CompoundAccessKind.SUPER_GETTER_SETTER:
+            return visitor.visitSuperIndexPostfix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                node.arguments.single,
+                operator,
+                arg);
+          default:
+            // This is not a valid case.
+            break;
+        }
+        break;
+      default:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(
+        node, "Invalid index postfix: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is a compound assignment. For instance
+/// `a += b`.
+class CompoundStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the compound assignment, i.e. the left-hand side.
+  final AccessSemantics semantics;
+
+  /// The assignment operator used in the compound assignment.
+  final AssignmentOperator operator;
+
+  /// The [Selector] for the getter invocation.
+  final Selector getterSelector;
+
+  /// The [Selector] for the setter invocation.
+  final Selector setterSelector;
+
+  CompoundStructure(this.semantics,
+                    this.operator,
+                    this.getterSelector,
+                    this.setterSelector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitDynamicPropertyCompound(
+            node,
+            node.receiver,
+            operator,
+            node.arguments.single,
+            getterSelector,
+            setterSelector,
+            arg);
+      case AccessKind.LOCAL_FUNCTION:
+        return visitor.errorLocalFunctionCompound(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.LOCAL_VARIABLE:
+        return visitor.visitLocalVariableCompound(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.PARAMETER:
+        return visitor.visitParameterCompound(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.STATIC_FIELD:
+        return visitor.visitStaticFieldCompound(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.STATIC_METHOD:
+        // TODO(johnniwinther): Handle this.
+        break;
+      case AccessKind.STATIC_GETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.STATIC_SETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.TOPLEVEL_FIELD:
+        return visitor.visitTopLevelFieldCompound(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.TOPLEVEL_METHOD:
+        // TODO(johnniwinther): Handle this.
+        break;
+      case AccessKind.TOPLEVEL_GETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.TOPLEVEL_SETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.CLASS_TYPE_LITERAL:
+        return visitor.errorClassTypeLiteralCompound(
+            node,
+            semantics.constant,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.TYPEDEF_TYPE_LITERAL:
+        return visitor.errorTypedefTypeLiteralCompound(
+            node,
+            semantics.constant,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.DYNAMIC_TYPE_LITERAL:
+        return visitor.errorDynamicTypeLiteralCompound(
+            node,
+            semantics.constant,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+        return visitor.errorTypeVariableTypeLiteralCompound(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.EXPRESSION:
+        // This is not a valid case.
+        break;
+      case AccessKind.THIS:
+        // This is not a valid case.
+        break;
+      case AccessKind.THIS_PROPERTY:
+        return visitor.visitThisPropertyCompound(
+            node,
+            operator,
+            node.arguments.single,
+            getterSelector,
+            setterSelector,
+            arg);
+      case AccessKind.SUPER_FIELD:
+        return visitor.visitSuperFieldCompound(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        // TODO(johnniwinther): Handle this.
+        break;
+      case AccessKind.SUPER_GETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.SUPER_SETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.CONSTANT:
+        // TODO(johnniwinther): Should this be a valid case?
+        break;
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedCompound(
+            node,
+            semantics.element,
+            operator,
+            node.arguments.single,
+            arg);
+      case AccessKind.COMPOUND:
+        CompoundAccessSemantics compoundSemantics = semantics;
+        switch (compoundSemantics.compoundAccessKind) {
+          case CompoundAccessKind.STATIC_GETTER_SETTER:
+            return visitor.visitStaticGetterSetterCompound(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                node.arguments.single,
+                arg);
+          case CompoundAccessKind.STATIC_METHOD_SETTER:
+            return visitor.visitStaticMethodSetterCompound(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                node.arguments.single,
+                arg);
+          case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
+            return visitor.visitTopLevelGetterSetterCompound(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                node.arguments.single,
+                arg);
+          case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
+            return visitor.visitTopLevelMethodSetterCompound(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                node.arguments.single,
+                arg);
+          case CompoundAccessKind.SUPER_FIELD_FIELD:
+            // TODO(johnniwinther): Handle this.
+            break;
+          case CompoundAccessKind.SUPER_GETTER_SETTER:
+            return visitor.visitSuperGetterSetterCompound(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                node.arguments.single,
+                arg);
+          case CompoundAccessKind.SUPER_GETTER_FIELD:
+            return visitor.visitSuperGetterFieldCompound(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                node.arguments.single,
+                arg);
+          case CompoundAccessKind.SUPER_METHOD_SETTER:
+            return visitor.visitSuperMethodSetterCompound(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                node.arguments.single,
+                arg);
+          case CompoundAccessKind.SUPER_FIELD_SETTER:
+            return visitor.visitSuperFieldSetterCompound(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                node.arguments.single,
+                arg);
+        }
+        break;
+    }
+    throw new SpannableAssertionFailure(node,
+        "Invalid compound assigment: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is a compound assignment on the index
+/// operator. For instance `a[b] += c`.
+class CompoundIndexSetStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the index operations.
+  final AccessSemantics semantics;
+
+  /// The assignment operator used in the compound assignment.
+  final AssignmentOperator operator;
+
+  /// The [Selector] for the `[]` operator invocation.
+  final Selector getterSelector;
+
+  /// The [Selector] for the `[]=` operator invocation.
+  final Selector setterSelector;
+
+  CompoundIndexSetStructure(this.semantics, this.operator,
+                            this.getterSelector,
+                            this.setterSelector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitCompoundIndexSet(
+            node,
+            node.receiver,
+            node.arguments.first,
+            operator,
+            node.arguments.tail.head,
+            arg);
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedSuperCompoundIndexSet(
+            node,
+            semantics.element,
+            node.arguments.first,
+            operator,
+            node.arguments.tail.head,
+            arg);
+      case AccessKind.COMPOUND:
+        CompoundAccessSemantics compoundSemantics = semantics;
+        switch (compoundSemantics.compoundAccessKind) {
+          case CompoundAccessKind.SUPER_GETTER_SETTER:
+            return visitor.visitSuperCompoundIndexSet(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                node.arguments.first,
+                operator,
+                node.arguments.tail.head,
+                arg);
+          default:
+            // This is not a valid case.
+            break;
+        }
+        break;
+      default:
+        // This is not a valid case.
+        break;
+    }
+    throw new SpannableAssertionFailure(
+        node, "Invalid compound index set: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is a prefix operations. For instance
+/// `++a`.
+class PrefixStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the prefix operation.
+  final AccessSemantics semantics;
+
+  /// The `++` or `--` operator used in the operation.
+  final IncDecOperator operator;
+
+  /// The [Selector] for the getter invocation.
+  final Selector getterSelector;
+
+  /// The [Selector] for the setter invocation.
+  final Selector setterSelector;
+
+  PrefixStructure(this.semantics,
+                  this.operator,
+                  this.getterSelector,
+                  this.setterSelector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitDynamicPropertyPrefix(
+            node,
+            node.receiver,
+            operator,
+            getterSelector,
+            setterSelector,
+            arg);
+      case AccessKind.LOCAL_FUNCTION:
+        return visitor.errorLocalFunctionPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.LOCAL_VARIABLE:
+        return visitor.visitLocalVariablePrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.PARAMETER:
+        return visitor.visitParameterPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.STATIC_FIELD:
+        return visitor.visitStaticFieldPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.STATIC_METHOD:
+        // TODO(johnniwinther): Handle this.
+        break;
+      case AccessKind.STATIC_GETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.STATIC_SETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.TOPLEVEL_FIELD:
+        return visitor.visitTopLevelFieldPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.TOPLEVEL_METHOD:
+        // TODO(johnniwinther): Handle this.
+        break;
+      case AccessKind.TOPLEVEL_GETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.TOPLEVEL_SETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.CLASS_TYPE_LITERAL:
+        return visitor.errorClassTypeLiteralPrefix(
+            node,
+            semantics.constant,
+            operator,
+            arg);
+      case AccessKind.TYPEDEF_TYPE_LITERAL:
+        return visitor.errorTypedefTypeLiteralPrefix(
+            node,
+            semantics.constant,
+            operator,
+            arg);
+      case AccessKind.DYNAMIC_TYPE_LITERAL:
+        return visitor.errorDynamicTypeLiteralPrefix(
+            node,
+            semantics.constant,
+            operator,
+            arg);
+      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+        return visitor.errorTypeVariableTypeLiteralPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.EXPRESSION:
+        // This is not a valid case.
+        break;
+      case AccessKind.THIS:
+        // This is not a valid case.
+        break;
+      case AccessKind.THIS_PROPERTY:
+        return visitor.visitThisPropertyPrefix(
+            node,
+            operator,
+            getterSelector,
+            setterSelector,
+            arg);
+      case AccessKind.SUPER_FIELD:
+        return visitor.visitSuperFieldPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        // TODO(johnniwinther): Handle this.
+        break;
+      case AccessKind.SUPER_GETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.SUPER_SETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.CONSTANT:
+        // TODO(johnniwinther): Should this be a valid case?
+        break;
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedPrefix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.COMPOUND:
+        CompoundAccessSemantics compoundSemantics = semantics;
+        switch (compoundSemantics.compoundAccessKind) {
+          case CompoundAccessKind.STATIC_GETTER_SETTER:
+            return visitor.visitStaticGetterSetterPrefix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.STATIC_METHOD_SETTER:
+            return visitor.visitStaticMethodSetterPrefix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
+            return visitor.visitTopLevelGetterSetterPrefix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
+            return visitor.visitTopLevelMethodSetterPrefix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.SUPER_FIELD_FIELD:
+            return visitor.visitSuperFieldFieldPrefix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.SUPER_GETTER_SETTER:
+            return visitor.visitSuperGetterSetterPrefix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.SUPER_GETTER_FIELD:
+            return visitor.visitSuperGetterFieldPrefix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.SUPER_METHOD_SETTER:
+            return visitor.visitSuperMethodSetterPrefix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.SUPER_FIELD_SETTER:
+            return visitor.visitSuperFieldSetterPrefix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+        }
+    }
+    throw new SpannableAssertionFailure(node,
+        "Invalid compound assigment: ${semantics}");
+  }
+}
+
+/// The structure for a [Send] that is a postfix operations. For instance
+/// `a++`.
+class PostfixStructure<R, A> implements SendStructure<R, A> {
+  /// The target of the postfix operation.
+  final AccessSemantics semantics;
+
+  /// The `++` or `--` operator used in the operation.
+  final IncDecOperator operator;
+
+  /// The [Selector] for the getter invocation.
+  final Selector getterSelector;
+
+  /// The [Selector] for the setter invocation.
+  final Selector setterSelector;
+
+  PostfixStructure(this.semantics,
+                   this.operator,
+                   this.getterSelector,
+                   this.setterSelector);
+
+  R dispatch(SemanticSendVisitor<R, A> visitor, Send node, A arg) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC_PROPERTY:
+        return visitor.visitDynamicPropertyPostfix(
+            node,
+            node.receiver,
+            operator,
+            getterSelector,
+            setterSelector,
+            arg);
+      case AccessKind.LOCAL_FUNCTION:
+        return visitor.errorLocalFunctionPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.LOCAL_VARIABLE:
+        return visitor.visitLocalVariablePostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.PARAMETER:
+        return visitor.visitParameterPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.STATIC_FIELD:
+        return visitor.visitStaticFieldPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.STATIC_METHOD:
+        // TODO(johnniwinther): Handle this.
+        break;
+      case AccessKind.STATIC_GETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.STATIC_SETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.TOPLEVEL_FIELD:
+        return visitor.visitTopLevelFieldPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.TOPLEVEL_METHOD:
+        // TODO(johnniwinther): Handle this.
+        break;
+      case AccessKind.TOPLEVEL_GETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.TOPLEVEL_SETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.CLASS_TYPE_LITERAL:
+        return visitor.errorClassTypeLiteralPostfix(
+            node,
+            semantics.constant,
+            operator,
+            arg);
+      case AccessKind.TYPEDEF_TYPE_LITERAL:
+        return visitor.errorTypedefTypeLiteralPostfix(
+            node,
+            semantics.constant,
+            operator,
+            arg);
+      case AccessKind.DYNAMIC_TYPE_LITERAL:
+        return visitor.errorDynamicTypeLiteralPostfix(
+            node,
+            semantics.constant,
+            operator,
+            arg);
+      case AccessKind.TYPE_PARAMETER_TYPE_LITERAL:
+        return visitor.errorTypeVariableTypeLiteralPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.EXPRESSION:
+        // This is not a valid case.
+        break;
+      case AccessKind.THIS:
+        // This is not a valid case.
+        break;
+      case AccessKind.THIS_PROPERTY:
+        return visitor.visitThisPropertyPostfix(
+            node,
+            operator,
+            getterSelector,
+            setterSelector,
+            arg);
+      case AccessKind.SUPER_FIELD:
+        return visitor.visitSuperFieldPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.SUPER_METHOD:
+        // TODO(johnniwinther): Handle this.
+        break;
+      case AccessKind.SUPER_GETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.SUPER_SETTER:
+        // This is not a valid case.
+        break;
+      case AccessKind.CONSTANT:
+        // TODO(johnniwinther): Should this be a valid case?
+        break;
+      case AccessKind.UNRESOLVED:
+        return visitor.errorUnresolvedPostfix(
+            node,
+            semantics.element,
+            operator,
+            arg);
+      case AccessKind.COMPOUND:
+        CompoundAccessSemantics compoundSemantics = semantics;
+        switch (compoundSemantics.compoundAccessKind) {
+          case CompoundAccessKind.STATIC_GETTER_SETTER:
+            return visitor.visitStaticGetterSetterPostfix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.STATIC_METHOD_SETTER:
+            return visitor.visitStaticMethodSetterPostfix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.TOPLEVEL_GETTER_SETTER:
+            return visitor.visitTopLevelGetterSetterPostfix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.TOPLEVEL_METHOD_SETTER:
+            return visitor.visitTopLevelMethodSetterPostfix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.SUPER_FIELD_FIELD:
+            return visitor.visitSuperFieldFieldPostfix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.SUPER_GETTER_SETTER:
+            return visitor.visitSuperGetterSetterPostfix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.SUPER_GETTER_FIELD:
+            return visitor.visitSuperGetterFieldPostfix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.SUPER_METHOD_SETTER:
+            return visitor.visitSuperMethodSetterPostfix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+          case CompoundAccessKind.SUPER_FIELD_SETTER:
+            return visitor.visitSuperFieldSetterPostfix(
+                node,
+                compoundSemantics.getter,
+                compoundSemantics.setter,
+                operator,
+                arg);
+        }
+    }
+    throw new SpannableAssertionFailure(node,
+        "Invalid compound assigment: ${semantics}");
+  }
+}
+
diff --git a/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart b/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart
index c2adeb4..d919596 100644
--- a/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart
+++ b/pkg/compiler/lib/src/scanner/utf8_bytes_scanner.dart
@@ -9,7 +9,11 @@
  * that points to substrings.
  */
 class Utf8BytesScanner extends ArrayBasedScanner {
-  /** The file content. */
+  /**
+   * The file content.
+   *
+   * The content is zero-terminated.
+   */
   List<int> bytes;
 
   /**
@@ -66,9 +70,9 @@
    * is not the case, the entire array is copied before scanning.
    */
   Utf8BytesScanner(SourceFile file, {bool includeComments: false})
-      : bytes = file.slowUtf8Bytes(),
+      : bytes = file.slowUtf8ZeroTerminatedBytes(),
         super(file, includeComments) {
-    ensureZeroTermination();
+    assert(bytes.last == 0);
     // Skip a leading BOM.
     if (_containsBomAt(0)) byteOffset += 3;
   }
@@ -80,21 +84,11 @@
    * the file. If this is not the case, the entire array is copied before
    * scanning.
    */
-  Utf8BytesScanner.fromBytes(this.bytes, {bool includeComments: false})
-      : super(null, includeComments) {
-    ensureZeroTermination();
-  }
-
-  void ensureZeroTermination() {
-    if (bytes.isEmpty || bytes[bytes.length - 1] != 0) {
-      // TODO(lry): abort instead of copying the array, or warn?
-      var newBytes =  new Uint8List(bytes.length + 1);
-      for (int i = 0; i < bytes.length; i++) {
-        newBytes[i] = bytes[i];
-      }
-      newBytes[bytes.length] = 0;
-      bytes = newBytes;
-    }
+  Utf8BytesScanner.fromBytes(List<int> zeroTerminatedBytes,
+                             {bool includeComments: false})
+      : this.bytes = zeroTerminatedBytes,
+        super(null, includeComments) {
+    assert(bytes.last == 0);
   }
 
   bool _containsBomAt(int offset) {
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 93b0896..590dd80 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -25,7 +25,7 @@
       JavaScriptBackend backend = builder.backend;
 
       AsyncRewriterBase rewriter = null;
-
+      String name = backend.namer.methodPropertyName(element);
       if (element.asyncMarker == AsyncMarker.ASYNC) {
         rewriter = new AsyncRewriter(
             backend.compiler,
@@ -34,7 +34,8 @@
                 backend.emitter.staticFunctionAccess(backend.getAsyncHelper()),
             newCompleter: backend.emitter.staticFunctionAccess(
                 backend.getCompleterConstructor()),
-            safeVariableName: backend.namer.safeVariableName);
+            safeVariableName: backend.namer.safeVariableName,
+            bodyName: name);
       } else if (element.asyncMarker == AsyncMarker.SYNC_STAR) {
         rewriter = new SyncStarRewriter(
             backend.compiler,
@@ -47,7 +48,8 @@
                 backend.getYieldStar()),
             uncaughtErrorExpression: backend.emitter.staticFunctionAccess(
                 backend.getSyncStarUncaughtError()),
-            safeVariableName: backend.namer.safeVariableName);
+            safeVariableName: backend.namer.safeVariableName,
+            bodyName: name);
       }
       else if (element.asyncMarker == AsyncMarker.ASYNC_STAR) {
         rewriter = new AsyncStarRewriter(
@@ -63,7 +65,8 @@
             yieldExpression: backend.emitter.staticFunctionAccess(
                 backend.getYieldSingle()),
             yieldStarExpression: backend.emitter.staticFunctionAccess(
-                backend.getYieldStar()));
+                backend.getYieldStar()),
+            bodyName: name);
       }
       if (rewriter != null) {
         result = rewriter.rewrite(result);
@@ -237,9 +240,9 @@
     // TODO(floitsch): Clean up this hack. Should we create a box-object by
     // just creating an empty object literal?
     JavaScriptBackend backend = builder.backend;
-    HInstruction box = new HForeign(js.js.parseForeignJS('{}'),
-                                    backend.nonNullType,
-                                    <HInstruction>[]);
+    HInstruction box = new HForeignCode(js.js.parseForeignJS('{}'),
+                                        backend.nonNullType,
+                                        <HInstruction>[]);
     builder.add(box);
     return box;
   }
@@ -1363,10 +1366,9 @@
         return reductiveHeuristic();
       }
 
-      if (cachedCanBeInlined == true) return cachedCanBeInlined;
-
-      if (backend.functionsToAlwaysInline.contains(function)) {
-        // Inline this function regardless of it's size.
+      if (cachedCanBeInlined == true) {
+        // We may have forced the inlining of some methods. Therefore check
+        // if we can inline this method regardless of size.
         assert(InlineWeeder.canBeInlined(function, -1, false,
                                          allowLoops: true));
         return true;
@@ -1484,7 +1486,7 @@
 
   /// A stack of [DartType]s the have been seen during inlining of factory
   /// constructors.  These types are preserved in [HInvokeStatic]s and
-  /// [HForeignNews] inside the inline code and registered during code
+  /// [HForeignNew]s inside the inline code and registered during code
   /// generation for these nodes.
   // TODO(karlklose): consider removing this and keeping the (substituted)
   // types of the type variables in an environment (like the [LocalsHandler]).
@@ -3374,10 +3376,10 @@
     return interceptor;
   }
 
-  HForeign createForeign(js.Template code,
-                         TypeMask type,
-                         List<HInstruction> inputs) {
-    return new HForeign(code, type, inputs);
+  HForeignCode createForeign(js.Template code,
+                             TypeMask type,
+                             List<HInstruction> inputs) {
+    return new HForeignCode(code, type, inputs);
   }
 
   HLiteralList buildLiteralList(List<HInstruction> inputs) {
@@ -3638,15 +3640,15 @@
         TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
 
     if (nativeBehavior.codeTemplate.isExpression) {
-      push(new HForeign(nativeBehavior.codeTemplate, ssaType, inputs,
-                        effects: nativeBehavior.sideEffects,
-                        nativeBehavior: nativeBehavior));
+      push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs,
+                            effects: nativeBehavior.sideEffects,
+                            nativeBehavior: nativeBehavior));
     } else {
-      push(new HForeign(nativeBehavior.codeTemplate, ssaType, inputs,
-                        isStatement: true,
-                        effects: nativeBehavior.sideEffects,
-                        nativeBehavior: nativeBehavior,
-                        canThrow: true));
+      push(new HForeignCode(nativeBehavior.codeTemplate, ssaType, inputs,
+                            isStatement: true,
+                            effects: nativeBehavior.sideEffects,
+                            nativeBehavior: nativeBehavior,
+                            canThrow: true));
     }
   }
 
@@ -3669,9 +3671,9 @@
       // If the isolate library is not used, we just generate code
       // to fetch the current isolate.
       String name = backend.namer.currentIsolate;
-      push(new HForeign(js.js.parseForeignJS(name),
-                        backend.dynamicType,
-                        <HInstruction>[]));
+      push(new HForeignCode(js.js.parseForeignJS(name),
+                            backend.dynamicType,
+                            <HInstruction>[]));
     } else {
       // Call a helper method from the isolate library. The isolate
       // library uses its own isolate structure, that encapsulates
@@ -3805,7 +3807,7 @@
         compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node);
     TypeMask ssaType =
         TypeMaskFactory.fromNativeBehavior(nativeBehavior, compiler);
-    push(new HForeign(expr, ssaType, const []));
+    push(new HForeignCode(expr, ssaType, const []));
   }
 
   void handleJsInterceptorConstant(ast.Send node) {
@@ -3877,10 +3879,10 @@
     }
 
     registry.registerStaticUse(element);
-    push(new HForeign(js.js.expressionTemplateYielding(
+    push(new HForeignCode(js.js.expressionTemplateYielding(
                           backend.emitter.staticFunctionAccess(element)),
-                      backend.dynamicType,
-                      <HInstruction>[]));
+                          backend.dynamicType,
+                          <HInstruction>[]));
     return params;
   }
 
@@ -3900,29 +3902,29 @@
     String isolateName = backend.namer.currentIsolate;
     SideEffects sideEffects = new SideEffects.empty();
     sideEffects.setAllSideEffects();
-    push(new HForeign(js.js.parseForeignJS("$isolateName = #"),
-                      backend.dynamicType,
-                      <HInstruction>[pop()],
-                      effects: sideEffects));
+    push(new HForeignCode(js.js.parseForeignJS("$isolateName = #"),
+                          backend.dynamicType,
+                          <HInstruction>[pop()],
+                          effects: sideEffects));
   }
 
   void handleForeignDartObjectJsConstructorFunction(ast.Send node) {
     if (!node.arguments.isEmpty) {
       compiler.internalError(node.argumentsNode, 'Too many arguments.');
     }
-    push(new HForeign(js.js.expressionTemplateYielding(
+    push(new HForeignCode(js.js.expressionTemplateYielding(
                           backend.emitter.typeAccess(compiler.objectClass)),
-                      backend.dynamicType,
-                      <HInstruction>[]));
+                          backend.dynamicType,
+                          <HInstruction>[]));
   }
 
   void handleForeignJsCurrentIsolate(ast.Send node) {
     if (!node.arguments.isEmpty) {
       compiler.internalError(node.argumentsNode, 'Too many arguments.');
     }
-    push(new HForeign(js.js.parseForeignJS(backend.namer.currentIsolate),
-                      backend.dynamicType,
-                      <HInstruction>[]));
+    push(new HForeignCode(js.js.parseForeignJS(backend.namer.currentIsolate),
+                          backend.dynamicType,
+                          <HInstruction>[]));
   }
 
   visitForeignSend(ast.Send node) {
@@ -4412,7 +4414,7 @@
         var constant = inputs[0];
         if (constant.constant.primitiveValue >= 0) canThrow = false;
       }
-      HForeign foreign = new HForeign(
+      HForeignCode foreign = new HForeignCode(
           code, elementType, inputs, nativeBehavior: behavior,
           canThrow: canThrow);
       push(foreign);
@@ -4421,7 +4423,7 @@
         js.Template code = js.js.parseForeignJS(r'#.fixed$length = Array');
         // We set the instruction as [canThrow] to avoid it being dead code.
         // We need a finer grained side effect.
-        add(new HForeign(
+        add(new HForeignCode(
               code, backend.nullType, [stack.last], canThrow: true));
       }
     } else if (isGrowableListConstructorCall) {
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 752df17..60403c3 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -1743,7 +1743,7 @@
     });
   }
 
-  visitForeign(HForeign node) {
+  visitForeignCode(HForeignCode node) {
     List<HInstruction> inputs = node.inputs;
     if (node.isJsStatement()) {
       List<js.Expression> interpolatedExpressions = <js.Expression>[];
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index c298e06..531f323 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -335,6 +335,8 @@
 
   SsaInstructionMerger(this.generateAtUseSite, this.compiler);
 
+  JavaScriptBackend get backend => compiler.backend;
+
   void visitGraph(HGraph graph) {
     visitDominatorTree(graph);
   }
@@ -384,6 +386,26 @@
     analyzeInputs(instruction, 0);
   }
 
+  void visitInvokeSuper(HInvokeSuper instruction) {
+    Element superMethod = instruction.element;
+    Selector selector = instruction.selector;
+    // If aliased super members cannot be used, we will generate code like
+    //
+    //     C.prototype.method.call(instance)
+    //
+    // where instance is the [this] object for the method. In such a case, the
+    // get of prototype might be evaluated before instance is created if we
+    // generate instance at use site, which in turn might update the prototype
+    // after first access if we use lazy initialization.
+    // In this case, we therefore don't allow the receiver (the first argument)
+    // to be generated at use site, and only analyze all other arguments.
+    if (!backend.canUseAliasedSuperMember(superMethod, selector)) {
+      analyzeInputs(instruction, 1);
+    } else {
+      super.visitInvokeSuper(instruction);
+    }
+  }
+
   void visitIs(HIs instruction) {
     // In the general case the input might be used multple multiple times, so it
     // must not be set generate at use site.  If the code will generate
@@ -615,6 +637,9 @@
   }
 
   bool isSafeToGenerateAtUseSite(HInstruction user, HInstruction input) {
+    // HForeignNew evaluates arguments in order and passes them to a
+    // constructor.
+    if (user is HForeignNew) return true;
     // A [HForeign] instruction uses operators and if we generate
     // [input] at use site, the precedence might be wrong.
     if (user is HForeign) return false;
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index e6db5e3..f4e813b 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -21,7 +21,7 @@
   R visitExitTry(HExitTry node);
   R visitFieldGet(HFieldGet node);
   R visitFieldSet(HFieldSet node);
-  R visitForeign(HForeign node);
+  R visitForeignCode(HForeignCode node);
   R visitForeignNew(HForeignNew node);
   R visitGoto(HGoto node);
   R visitGreater(HGreater node);
@@ -292,8 +292,8 @@
   visitExitTry(HExitTry node) => visitControlFlow(node);
   visitFieldGet(HFieldGet node) => visitFieldAccess(node);
   visitFieldSet(HFieldSet node) => visitFieldAccess(node);
-  visitForeign(HForeign node) => visitInstruction(node);
-  visitForeignNew(HForeignNew node) => visitForeign(node);
+  visitForeignCode(HForeignCode node) => visitInstruction(node);
+  visitForeignNew(HForeignNew node) => visitInstruction(node);
   visitGoto(HGoto node) => visitControlFlow(node);
   visitGreater(HGreater node) => visitRelational(node);
   visitGreaterEqual(HGreaterEqual node) => visitRelational(node);
@@ -1698,13 +1698,25 @@
   bool isJsStatement() => true;
 }
 
-class HForeign extends HInstruction {
+abstract class HForeign extends HInstruction {
+  HForeign(TypeMask type, List<HInstruction> inputs) : super(inputs, type);
+
+  bool get isStatement => false;
+  native.NativeBehavior get nativeBehavior => null;
+
+  bool canThrow() {
+    return sideEffects.hasSideEffects()
+        || sideEffects.dependsOnSomething();
+  }
+}
+
+class HForeignCode extends HForeign {
   final js.Template codeTemplate;
   final bool isStatement;
   final bool _canThrow;
   final native.NativeBehavior nativeBehavior;
 
-  HForeign(this.codeTemplate,
+  HForeignCode(this.codeTemplate,
            TypeMask type,
            List<HInstruction> inputs,
            {this.isStatement: false,
@@ -1713,28 +1725,25 @@
             canThrow: false})
       : this.nativeBehavior = nativeBehavior,
         this._canThrow = canThrow,
-        super(inputs, type) {
+        super(type, inputs) {
+    if(codeTemplate == null) throw this;
     if (effects == null && nativeBehavior != null) {
       effects = nativeBehavior.sideEffects;
     }
     if (effects != null) sideEffects.add(effects);
   }
 
-  HForeign.statement(codeTemplate, List<HInstruction> inputs,
+  HForeignCode.statement(codeTemplate, List<HInstruction> inputs,
                      SideEffects effects,
                      native.NativeBehavior nativeBehavior,
                      TypeMask type)
       : this(codeTemplate, type, inputs, isStatement: true,
              effects: effects, nativeBehavior: nativeBehavior);
 
-  accept(HVisitor visitor) => visitor.visitForeign(this);
+  accept(HVisitor visitor) => visitor.visitForeignCode(this);
 
   bool isJsStatement() => isStatement;
-  bool canThrow() {
-    return _canThrow
-        || sideEffects.hasSideEffects()
-        || sideEffects.dependsOnSomething();
-  }
+  bool canThrow() => _canThrow || super.canThrow();
 }
 
 class HForeignNew extends HForeign {
@@ -1748,7 +1757,7 @@
 
   HForeignNew(this.element, TypeMask type, List<HInstruction> inputs,
               [this.instantiatedTypes])
-      : super(null, type, inputs);
+      : super(type, inputs);
 
   accept(HVisitor visitor) => visitor.visitForeignNew(this);
 }
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 04ac400..0692383 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -12,30 +12,23 @@
 class SsaOptimizerTask extends CompilerTask {
   final JavaScriptBackend backend;
   SsaOptimizerTask(JavaScriptBackend backend)
-    : this.backend = backend,
-      super(backend.compiler);
+      : this.backend = backend,
+        super(backend.compiler);
   String get name => 'SSA optimizer';
   Compiler get compiler => backend.compiler;
   Map<HInstruction, Range> ranges = <HInstruction, Range>{};
 
-  void runPhases(HGraph graph, List<OptimizationPhase> phases) {
-    for (OptimizationPhase phase in phases) {
-      runPhase(graph, phase);
-    }
-  }
-
-  void runPhase(HGraph graph, OptimizationPhase phase) {
-    phase.visitGraph(graph);
-    compiler.tracer.traceGraph(phase.name, graph);
-    assert(graph.isValid());
-  }
-
   void optimize(CodegenWorkItem work, HGraph graph) {
+    void runPhase(OptimizationPhase phase) {
+      phase.visitGraph(graph);
+      compiler.tracer.traceGraph(phase.name, graph);
+      assert(graph.isValid());
+    }
+
     ConstantSystem constantSystem = compiler.backend.constantSystem;
     JavaScriptItemCompilationContext context = work.compilationContext;
     bool trustPrimitives = compiler.trustPrimitives;
     measure(() {
-      SsaDeadCodeEliminator dce;
       List<OptimizationPhase> phases = <OptimizationPhase>[
           // Run trivial instruction simplification first to optimize
           // some patterns useful for type conversion.
@@ -70,12 +63,19 @@
           new SsaInstructionSimplifier(constantSystem, backend, this, work),
           new SsaCheckInserter(
               trustPrimitives, backend, work, context.boundsChecked),
-          new SsaSimplifyInterceptors(compiler, constantSystem, work),
-          dce = new SsaDeadCodeEliminator(compiler, this),
-          new SsaTypePropagator(compiler)];
-      runPhases(graph, phases);
+      ];
+      phases.forEach(runPhase);
+
+      // Simplifying interceptors is not strictly just an optimization, it is
+      // required for implementation correctness because the code generator
+      // assumes it is always performed.
+      runPhase(new SsaSimplifyInterceptors(compiler, constantSystem, work));
+
+      SsaDeadCodeEliminator dce = new SsaDeadCodeEliminator(compiler, this);
+      runPhase(dce);
       if (dce.eliminatedSideEffects) {
         phases = <OptimizationPhase>[
+            new SsaTypePropagator(compiler),
             new SsaGlobalValueNumberer(compiler),
             new SsaCodeMotion(),
             new SsaValueRangeAnalyzer(compiler, constantSystem, this, work),
@@ -83,14 +83,17 @@
             new SsaCheckInserter(
                 trustPrimitives, backend, work, context.boundsChecked),
             new SsaSimplifyInterceptors(compiler, constantSystem, work),
-            new SsaDeadCodeEliminator(compiler, this)];
+            new SsaDeadCodeEliminator(compiler, this),
+        ];
       } else {
         phases = <OptimizationPhase>[
-            // Run the simplifier to remove unneeded type checks inserted
-            // by type propagation.
-            new SsaInstructionSimplifier(constantSystem, backend, this, work)];
+            new SsaTypePropagator(compiler),
+            // Run the simplifier to remove unneeded type checks inserted by
+            // type propagation.
+            new SsaInstructionSimplifier(constantSystem, backend, this, work),
+        ];
       }
-      runPhases(graph, phases);
+      phases.forEach(runPhase);
     });
   }
 }
@@ -998,6 +1001,33 @@
     return zapInstructionCache;
   }
 
+  /// Returns true of [foreign] will throw an noSuchMethod error if
+  /// receiver is `null` before having any other side-effects.
+  bool templateThrowsNSMonNull(HForeignCode foreign, HInstruction receiver) {
+    // We look for a template of the form
+    //
+    // #.something -or- #.something()
+    //
+    // where # is substituted by receiver.
+    js.Template template = foreign.codeTemplate;
+    js.Node node = template.ast;
+    // #.something = ...
+    if (node is js.Assignment) {
+      js.Assignment assignment = node;
+      node = assignment.leftHandSide;
+    }
+
+    // #.something
+    if (node is js.PropertyAccess) {
+      js.PropertyAccess access = node;
+      if (access.receiver is js.InterpolatedExpression) {
+        js.InterpolatedExpression hole = access.receiver;
+        return hole.isPositional && foreign.inputs.first == receiver;
+      }
+    }
+    return false;
+  }
+
   /// Returns whether the next throwing instruction that may have side
   /// effects after [instruction], throws [NoSuchMethodError] on the
   /// same receiver of [instruction].
@@ -1009,17 +1039,34 @@
           && current.canThrow()) {
         return true;
       }
+      if (current is HForeignCode &&
+          templateThrowsNSMonNull(current, receiver)) {
+        return true;
+      }
       if (current.canThrow() || current.sideEffects.hasSideEffects()) {
         return false;
       }
-      if (current.next == null && current is HGoto) {
-        // We do not merge blocks in our SSA graph, so if this block
-        // just jumps to a single predecessor, visit this predecessor.
-        assert(current.block.successors.length == 1);
-        current = current.block.successors[0].first;
-      } else {
-        current = current.next;
+      HInstruction next = current.next;
+      if (next == null) {
+        // We do not merge blocks in our SSA graph, so if this block just jumps
+        // to a single successor, visit the successor, avoiding back-edges.
+        HBasicBlock successor;
+        if (current is HGoto) {
+          successor = current.block.successors.single;
+        } else if (current is HIf) {
+          // We also leave HIf nodes in place when one branch is dead.
+          HInstruction condition = current.inputs.first;
+          if (condition is HConstant) {
+            bool isTrue = condition.constant.isTrue;
+            successor = isTrue ? current.thenBlock : current.elseBlock;
+            assert(!analyzer.isDeadBlock(successor));
+          }
+        }
+        if (successor != null && successor.id > current.block.id) {
+          next = successor.first;
+        }
       }
+      current = next;
     } while (current != null);
     return false;
   }
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index ebac199..ccecc67 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -331,8 +331,9 @@
     return visitGenericInvoke("Invoke constructor body", target, invoke.inputs);
   }
 
-  String visitForeign(HForeign foreign) {
-    return visitGenericInvoke("Foreign", "${foreign.codeTemplate.ast}", foreign.inputs);
+  String visitForeignCode(HForeignCode foreign) {
+    return visitGenericInvoke("Foreign", "${foreign.codeTemplate.ast}",
+                              foreign.inputs);
   }
 
   String visitForeignNew(HForeignNew node) {
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/copy_propagator.dart b/pkg/compiler/lib/src/tree_ir/optimization/copy_propagator.dart
index 2f3761d..f7e5369 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/copy_propagator.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/copy_propagator.dart
@@ -11,6 +11,7 @@
 /// variables with local temporaries that were left behind when translating
 /// out of CPS (where closure variables live in a separate space).
 class CopyPropagator extends RecursiveVisitor with PassMixin {
+  String get passName => 'Copy propagation';
 
   /// After visitStatement returns, [move] maps a variable v to an
   /// assignment A of form w := v, under the following conditions:
@@ -23,6 +24,9 @@
 
   ExecutableElement currentElement;
 
+  /// Number of try blocks enclosing the currently visited node.
+  int enclosingTrys = 0;
+
   void rewriteExecutableDefinition(ExecutableDefinition root) {
     currentElement = root.element;
     root.body = visitStatement(root.body);
@@ -111,8 +115,8 @@
   void invalidateMovingAssignment(Variable w) {
     Assign movingAssignment = inverseMove.remove(w);
     if (movingAssignment != null) {
-      VariableUse def = movingAssignment.definition;
-      move.remove(def.variable);
+      VariableUse value = movingAssignment.value;
+      move.remove(value.variable);
     }
   }
 
@@ -144,7 +148,7 @@
       // Make w := w.
       // We can't remove the statement from here because we don't have
       // parent pointers. So just make it a no-op so it can be removed later.
-      movingAssign.definition = new VariableUse(w);
+      movingAssign.value = new VariableUse(w);
 
       // The intermediate variable 'v' should now be orphaned, so don't bother
       // updating its read/write counters.
@@ -164,16 +168,22 @@
     // the moving assignment is no longer a candidate for copy propagation.
     invalidateMovingAssignment(node.variable);
 
-    visitExpression(node.definition);
+    visitExpression(node.value);
 
     // If this is a moving assignment w := v, with this being the only use of v,
-    // try to propagate it backwards.  Do not propagate assignments where w
-    // is from an outer function scope.
-    if (node.definition is VariableUse) {
-      VariableUse definition = node.definition;
-      if (definition.variable.readCount == 1 &&
-          node.variable.host == currentElement) {
-        move[definition.variable] = node;
+    // try to propagate it backwards.
+    // Do not propagate assignments where w is captured or if where are inside a
+    // try block, because then we can't isolate the uses of w to a single block.
+    // We currently do not support propagation if the assignment is a
+    // declaration. To support this we would need to ensure that the target
+    // assignment is turned into a declaration as well.
+    if (node.value is VariableUse &&
+        !node.variable.isCaptured &&
+        enclosingTrys == 0 &&
+        !node.isDeclaration) {
+      VariableUse value = node.value;
+      if (value.variable.readCount == 1) {
+        move[value.variable] = node;
         inverseMove[node.variable] = node;
       }
     }
@@ -217,7 +227,9 @@
   }
 
   Statement visitTry(Try node) {
+    enclosingTrys++;
     node.tryBody = visitBasicBlock(node.tryBody);
+    enclosingTrys--;
     node.catchBody = visitBasicBlock(node.catchBody);
     return node;
   }
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
index a34e87f..f68677b 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
@@ -55,6 +55,7 @@
 ///   x && y            (double negation removed by [putInBooleanContext])
 ///
 class LogicalRewriter extends Visitor<Statement, Expression> with PassMixin {
+  String get passName => 'Logical rewriter';
 
   /// Statement to be executed next by natural fallthrough. Although fallthrough
   /// is not introduced in this phase, we need to reason about fallthrough when
@@ -97,7 +98,7 @@
   }
 
   Statement visitAssign(Assign node) {
-    node.definition = visitExpression(node.definition);
+    node.value = visitExpression(node.value);
     node.next = visitStatement(node.next);
     return node;
   }
@@ -342,6 +343,16 @@
     return node;
   }
 
+  Expression visitReifyRuntimeType(ReifyRuntimeType node) {
+    node.value = visitExpression(node.value);
+    return node;
+  }
+
+  Expression visitReadTypeVariable(ReadTypeVariable node) {
+    node.target = visitExpression(node.target);
+    return node;
+  }
+
   /// True if the given expression is known to evaluate to a boolean.
   /// This will not recursively traverse [Conditional] expressions, but if
   /// applied to the result of [visitExpression] conditionals will have been
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
index 0913a11..d02e1ac 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/loop_rewriter.dart
@@ -28,6 +28,7 @@
 /// Note that the above pattern needs no iteration since nested ifs
 /// have been collapsed previously in the [StatementRewriter] phase.
 class LoopRewriter extends RecursiveVisitor with PassMixin {
+  String get passName => 'Loop rewriter';
 
   Set<Label> usedContinueLabels = new Set<Label>();
 
@@ -43,13 +44,13 @@
 
   Statement visitAssign(Assign node) {
     // Clean up redundant assignments left behind in the previous phase.
-    Expression def = node.definition;
-    if (def is VariableUse && node.variable == def.variable) {
+    Expression value = node.value;
+    if (value is VariableUse && node.variable == value.variable) {
       --node.variable.readCount;
       --node.variable.writeCount;
       return visitStatement(node.next);
     }
-    visitExpression(node.definition);
+    visitExpression(node.value);
     node.next = visitStatement(node.next);
     return node;
   }
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/optimization.dart b/pkg/compiler/lib/src/tree_ir/optimization/optimization.dart
index ff815ba..fc7aca1 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/optimization.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/optimization.dart
@@ -16,6 +16,8 @@
   void rewriteFieldDefinition(FieldDefinition root);
   void rewriteFunctionDefinition(FunctionDefinition root);
   void rewriteConstructorDefinition(ConstructorDefinition root);
+
+  String get passName;
 }
 
 
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
index 61f0a31..1902e8f 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -92,6 +92,8 @@
  * separated two ifs.
  */
 class StatementRewriter extends Visitor<Statement, Expression> with PassMixin {
+  String get passName => 'Statement rewriter';
+
   // The binding environment.  The rightmost element of the list is the nearest
   // available enclosing binding.
   List<Assign> environment;
@@ -169,7 +171,10 @@
   Expression visitVariableUse(VariableUse node) {
     // Propagate constant to use site.
     Expression constant = constantEnvironment[node.variable];
-    if (constant != null) return constant;
+    if (constant != null) {
+      --node.variable.readCount;
+      return constant;
+    }
 
     // Propagate a variable's definition to its use site if:
     // 1.  It has a single use, to avoid code growth and potential duplication
@@ -178,8 +183,9 @@
     //     reorder expressions with side effects.
     if (!environment.isEmpty &&
         environment.last.variable == node.variable &&
-        environment.last.hasExactlyOneUse) {
-      return visitExpression(environment.removeLast().definition);
+        node.variable.readCount == 1) {
+      --node.variable.readCount;
+      return visitExpression(environment.removeLast().value);
     }
 
     // If the definition could not be propagated, leave the variable use.
@@ -199,21 +205,22 @@
   }
 
   Statement visitAssign(Assign node) {
-    if (isEffectivelyConstant(node.definition) &&
+    if (isEffectivelyConstant(node.value) &&
         node.variable.writeCount == 1) {
       // Handle constant assignments specially.
       // They are always safe to propagate (though we should avoid duplication).
       // Moreover, they should not prevent other expressions from propagating.
       if (node.variable.readCount <= 1) {
         // A single-use constant should always be propagted to its use site.
-        constantEnvironment[node.variable] = visitExpression(node.definition);
+        constantEnvironment[node.variable] = visitExpression(node.value);
+        --node.variable.writeCount;
         return visitStatement(node.next);
       } else {
         // With more than one use, we cannot propagate the constant.
         // Visit the following statement without polluting [environment] so
         // that any preceding non-constant assignments might still propagate.
         node.next = visitStatement(node.next);
-        node.definition = visitExpression(node.definition);
+        node.value = visitExpression(node.value);
         return node;
       }
     } else {
@@ -225,10 +232,11 @@
         // The definition could not be propagated. Residualize the let binding.
         node.next = next;
         environment.removeLast();
-        node.definition = visitExpression(node.definition);
+        node.value = visitExpression(node.value);
         return node;
       }
       assert(!environment.contains(node));
+      --node.variable.writeCount; // This assignment was removed.
       return next;
     }
   }
@@ -412,11 +420,13 @@
   }
 
   Statement visitTry(Try node) {
-    Set<Label> saved = safeForInlining;
-    safeForInlining = new Set<Label>();
-    node.tryBody = visitStatement(node.tryBody);
-    safeForInlining = saved;
-    node.catchBody = visitStatement(node.catchBody);
+    inEmptyEnvironment(() {
+      Set<Label> saved = safeForInlining;
+      safeForInlining = new Set<Label>();
+      node.tryBody = visitStatement(node.tryBody);
+      safeForInlining = saved;
+      node.catchBody = visitStatement(node.catchBody);
+    });
     return node;
   }
 
@@ -491,6 +501,16 @@
     return node;
   }
 
+  Expression visitReifyRuntimeType(ReifyRuntimeType node) {
+    node.value = visitExpression(node.value);
+    return node;
+  }
+
+  Expression visitReadTypeVariable(ReadTypeVariable node) {
+    node.target = visitExpression(node.target);
+    return node;
+  }
+
   /// If [s] and [t] are similar statements we extract their subexpressions
   /// and returns a new statement of the same type using expressions combined
   /// with the [combine] callback. For example:
@@ -517,9 +537,12 @@
     if (s is Assign && t is Assign && s.variable == t.variable) {
       Statement next = combineStatements(s.next, t.next);
       if (next != null) {
-        --t.variable.writeCount; // Two assignments become one.
+        // Destroy both original assignments to the variable.
+        --s.variable.writeCount;
+        --t.variable.writeCount;
+        // The Assign constructor will increment the reference count again.
         return new Assign(s.variable,
-                          combine(s.definition, t.definition),
+                          combine(s.value, t.value),
                           next);
       }
     }
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
index 78ce88c..f61630c 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -43,7 +43,7 @@
  * particular, intermediate values and blocks used for local control flow are
  * still all named.
  */
-class Builder extends cps_ir.Visitor<Node> {
+class Builder implements cps_ir.Visitor<Node> {
   final dart2js.InternalErrorFunction internalError;
 
   /// Maps variable/parameter elements to the Tree variables that represent it.
@@ -67,6 +67,8 @@
   List<cps_ir.Continuation> safeForInlining = <cps_ir.Continuation>[];
 
   ExecutableElement currentElement;
+  /// The 'this' Parameter for currentElement or the enclosing method.
+  cps_ir.Parameter thisParameter;
   cps_ir.Continuation returnContinuation;
 
   Builder parent;
@@ -82,9 +84,7 @@
   Variable phiTempVar;
 
   Variable addMutableVariable(cps_ir.MutableVariable irVariable) {
-    if (irVariable.host != currentElement) {
-      return parent.addMutableVariable(irVariable);
-    }
+    assert(irVariable.host == currentElement);
     assert(!local2mutable.containsKey(irVariable));
     Variable variable = new Variable(currentElement, irVariable.hint);
     local2mutable[irVariable] = variable;
@@ -93,7 +93,7 @@
 
   Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) {
     if (mutableVariable.host != currentElement) {
-      return parent.getMutableVariable(mutableVariable);
+      return parent.getMutableVariable(mutableVariable)..isCaptured = true;
     }
     return local2mutable[mutableVariable];
   }
@@ -122,9 +122,14 @@
   /// referred to by [reference].
   /// This increments the reference count for the given variable, so the
   /// returned expression must be used in the tree.
-  VariableUse getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) {
+  Expression getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) {
+    if (thisParameter != null && reference.definition == thisParameter) {
+      return new This();
+    }
     Variable variable = getVariable(reference.definition);
     if (variable == null) {
+      // Note: this may fail because you forgot to implement a visit-function
+      // in the RegisterAllocator.
       internalError(
           CURRENT_ELEMENT_SPANNABLE,
           "Reference to ${reference.definition} has no register");
@@ -170,6 +175,12 @@
 
   FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) {
     currentElement = node.element;
+    if (parent != null) {
+      // Local function's 'this' refers to enclosing method's 'this'
+      thisParameter = parent.thisParameter;
+    } else {
+      thisParameter = node.thisParameter;
+    }
     List<Variable> parameters =
         node.parameters.map(addFunctionParameter).toList();
     Statement body;
@@ -185,6 +196,7 @@
 
   ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) {
     currentElement = node.element;
+    thisParameter = node.thisParameter;
     List<Variable> parameters =
         node.parameters.map(addFunctionParameter).toList();
     List<Initializer> initializers;
@@ -214,17 +226,6 @@
          growable: false);
   }
 
-  /// Returns the list of variables corresponding to the arguments to a join
-  /// continuation.
-  ///
-  /// The `readCount` of these variables will not be incremented. Instead,
-  /// [buildPhiAssignments] will handle the increment, if necessary.
-  List<Variable> translatePhiArguments(List<cps_ir.Reference> args) {
-    return new List<Variable>.generate(args.length,
-         (int index) => getVariable(args[index].definition),
-         growable: false);
-  }
-
   Statement buildContinuationAssignment(
       cps_ir.Parameter parameter,
       Expression argument,
@@ -244,7 +245,7 @@
   /// then continues at the statement created by [buildRest].
   Statement buildPhiAssignments(
       List<cps_ir.Parameter> parameters,
-      List<Variable> arguments,
+      List<Expression> arguments,
       Statement buildRest()) {
     assert(parameters.length == arguments.length);
     // We want a parallel assignment to all parameters simultaneously.
@@ -258,43 +259,51 @@
     Map<Variable, List<int>> rightHand = <Variable, List<int>>{};
     for (int i = 0; i < parameters.length; i++) {
       Variable param = getVariable(parameters[i]);
-      Variable arg = arguments[i];
-      if (param == null || param == arg) {
-        continue; // No assignment necessary.
+      Expression arg = arguments[i];
+      if (arg is VariableUse) {
+        if (param == null || param == arg.variable) {
+          // No assignment necessary.
+          --arg.variable.readCount;
+          continue;
+        }
+        // v1 = v0
+        List<int> list = rightHand[arg.variable];
+        if (list == null) {
+          rightHand[arg.variable] = list = <int>[];
+        }
+        list.add(i);
+      } else {
+        // v1 = this;
       }
-      List<int> list = rightHand[arg];
-      if (list == null) {
-        rightHand[arg] = list = <int>[];
-      }
-      list.add(i);
     }
 
     Statement first, current;
-    void addAssignment(Variable dst, Variable src) {
+    void addAssignment(Variable dst, Expression src) {
       if (first == null) {
-        first = current = new Assign(dst, new VariableUse(src), null);
+        first = current = new Assign(dst, src, null);
       } else {
-        current = current.next = new Assign(dst, new VariableUse(src), null);
+        current = current.next = new Assign(dst, src, null);
       }
     }
 
-    List<Variable> assignmentSrc = new List<Variable>(parameters.length);
-    List<bool> done = new List<bool>(parameters.length);
+    List<Expression> assignmentSrc = new List<Expression>(parameters.length);
+    List<bool> done = new List<bool>.filled(parameters.length, false);
     void visitAssignment(int i) {
-      if (done[i] == true) {
+      if (done[i]) {
         return;
       }
       Variable param = getVariable(parameters[i]);
-      Variable arg = arguments[i];
-      if (param == null || param == arg) {
+      Expression arg = arguments[i];
+      if (param == null || (arg is VariableUse && param == arg.variable)) {
         return; // No assignment necessary.
       }
       if (assignmentSrc[i] != null) {
         // Cycle found; store argument in a temporary variable.
         // The temporary will then be used as right-hand side when the
         // assignment gets added.
-        if (assignmentSrc[i] != phiTempVar) { // Only move to temporary once.
-          assignmentSrc[i] = phiTempVar;
+        VariableUse source = assignmentSrc[i];
+        if (source.variable != phiTempVar) { // Only move to temporary once.
+          assignmentSrc[i] = new VariableUse(phiTempVar);
           addAssignment(phiTempVar, arg);
         }
         return;
@@ -311,7 +320,7 @@
     }
 
     for (int i = 0; i < parameters.length; i++) {
-      if (done[i] == null) {
+      if (!done[i]) {
         visitAssignment(i);
       }
     }
@@ -324,12 +333,30 @@
     return first;
   }
 
-  visitNode(cps_ir.Node node) {
-    if (node is cps_ir.JsSpecificNode) {
-      throw "Cannot handle JS specific IR nodes in this visitor";
-    } else {
-      throw "Unhandled node: $node";
-    }
+  visit(cps_ir.Node node) => node.accept(this);
+
+  unexpectedNode(cps_ir.Node node) {
+    internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node');
+  }
+
+  // JS-specific nodes are handled by a subclass.
+  visitSetField(cps_ir.SetField node) => unexpectedNode(node);
+  visitIdentical(cps_ir.Identical node) => unexpectedNode(node);
+  visitInterceptor(cps_ir.Interceptor node) => unexpectedNode(node);
+  visitCreateInstance(cps_ir.CreateInstance node) => unexpectedNode(node);
+  visitGetField(cps_ir.GetField node) => unexpectedNode(node);
+  visitCreateBox(cps_ir.CreateBox node) => unexpectedNode(node);
+
+  // Executable definitions are not visited directly.  They have 'build'
+  // functions as entry points.
+  visitFieldDefinition(cps_ir.FieldDefinition node) {
+    return unexpectedNode(node);
+  }
+  visitFunctionDefinition(cps_ir.FunctionDefinition node) {
+    return unexpectedNode(node);
+  }
+  visitConstructorDefinition(cps_ir.ConstructorDefinition node) {
+    return unexpectedNode(node);
   }
 
   Initializer visitFieldInitializer(cps_ir.FieldInitializer node) {
@@ -460,7 +487,11 @@
   Statement visitLetMutable(cps_ir.LetMutable node) {
     Variable variable = addMutableVariable(node.variable);
     Expression value = getVariableUse(node.value);
-    return new Assign(variable, value, visit(node.body), isDeclaration: true);
+    Statement body = visit(node.body);
+    // If the variable was captured by an inner function in the body, this
+    // must be declared here so we assign to a fresh copy of the variable.
+    bool needsDeclaration = variable.isCaptured;
+    return new Assign(variable, value, body, isDeclaration: needsDeclaration);
   }
 
   Expression visitGetMutableVariable(cps_ir.GetMutableVariable node) {
@@ -504,7 +535,7 @@
       assert(node.arguments.length == 1);
       return new Return(getVariableUse(node.arguments.single));
     } else {
-      List<Variable> arguments = translatePhiArguments(node.arguments);
+      List<Expression> arguments = translateArguments(node.arguments);
       return buildPhiAssignments(cont.parameters, arguments,
           () {
             // Translate invocations of recursive and non-recursive
@@ -553,10 +584,6 @@
     return new Constant(node.expression);
   }
 
-  Expression visitThis(cps_ir.This node) {
-    return new This();
-  }
-
   Expression visitReifyTypeVar(cps_ir.ReifyTypeVar node) {
     return new ReifyTypeVar(node.typeVariable);
   }
@@ -595,22 +622,33 @@
     }
   }
 
-  Expression visitParameter(cps_ir.Parameter node) {
+  visitParameter(cps_ir.Parameter node) {
     // Continuation parameters are not visited (continuations themselves are
     // not visited yet).
-    internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node');
-    return null;
+    unexpectedNode(node);
   }
 
-  Expression visitContinuation(cps_ir.Continuation node) {
+  visitContinuation(cps_ir.Continuation node) {
     // Until continuations with multiple uses are supported, they are not
     // visited.
-    internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.');
-    return null;
+    unexpectedNode(node);
+  }
+
+  visitMutableVariable(cps_ir.MutableVariable node) {
+    // These occur as parameters or bound by LetMutable.  They are not visited
+    // directly.
+    unexpectedNode(node);
   }
 
   Expression visitIsTrue(cps_ir.IsTrue node) {
     return getVariableUse(node.value);
   }
-}
 
+  Expression visitReifyRuntimeType(cps_ir.ReifyRuntimeType node) {
+    return new ReifyRuntimeType(getVariableUse(node.value));
+  }
+
+  Expression visitReadTypeVariable(cps_ir.ReadTypeVariable node) {
+    return new ReadTypeVariable(node.variable, getVariableUse(node.target));
+  }
+}
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart
new file mode 100644
index 0000000..01eaa9c
--- /dev/null
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart
@@ -0,0 +1,186 @@
+library tree_ir.integrity;
+
+import 'tree_ir_nodes.dart';
+
+/// Performs integrity checks on the tree_ir.
+///
+/// Should only be run for debugging purposes, not in production.
+///
+/// - Reference counts on must match the actual number of references.
+/// - Labels must be in scope when referenced.
+/// - Breaks must target a [LabeledStatement].
+/// - Continues must target a [Loop].
+/// - Variables must only be used after their first assignment
+///   (checked on a best-effort basis).
+/// - Variables with a declaration must only be referenced in scope.
+/// - Variables must not have more than one declaration.
+///
+class CheckTreeIntegrity extends RecursiveVisitor {
+  ExecutableDefinition topLevelNode;
+
+  Map<Variable, int> varReads = <Variable, int>{};
+  Map<Variable, int> varWrites = <Variable, int>{};
+  Map<Label, int> labelUses = <Label, int>{};
+  Map<Label, JumpTarget> label2declaration = <Label, JumpTarget>{};
+
+  /// Variables that are currently in scope.
+  Set<Variable> scope = new Set<Variable>();
+
+  /// Variables for which we have seen a declaration.
+  Set<Variable> seenDeclaration = new Set<Variable>();
+
+  void write(Variable variable) {
+    if (!seenDeclaration.contains(variable)) {
+      // Implicitly-declared variables are in scope after the first assignment.
+      scope.add(variable);
+    } else if (!scope.contains(variable)) {
+      // There is a declaration for variable but it is no longer in scope.
+      error('$variable assigned out of scope');
+    }
+    varWrites.putIfAbsent(variable, () => 0);
+    varWrites[variable]++;
+  }
+
+  void read(Variable variable) {
+    if (!scope.contains(variable)) {
+      error('$variable used out of scope');
+    }
+    varReads.putIfAbsent(variable, () => 0);
+    varReads[variable]++;
+  }
+
+  void declare(Variable variable) {
+    if (!scope.add(variable) || !seenDeclaration.add(variable)) {
+      error('Redeclared $variable');
+    }
+    varWrites.putIfAbsent(variable, () => 0);
+    varWrites[variable]++;
+  }
+
+  void undeclare(Variable variable) {
+    scope.remove(variable);
+  }
+
+  visitVariableUse(VariableUse node) {
+    read(node.variable);
+  }
+
+  visitAssign(Assign node) {
+    visitExpression(node.value);
+    if (node.isDeclaration) {
+      declare(node.variable);
+    } else {
+      write(node.variable);
+    }
+    visitStatement(node.next);
+    if (node.isDeclaration) {
+      undeclare(node.variable);
+    }
+  }
+
+  visitTry(Try node) {
+    visitStatement(node.tryBody);
+    node.catchParameters.forEach(declare);
+    visitStatement(node.catchBody);
+    node.catchParameters.forEach(undeclare);
+  }
+
+  visitFunctionDefinition(FunctionDefinition node) {
+    node.parameters.forEach(declare);
+    if (node.body != null) visitStatement(node.body);
+    node.parameters.forEach(undeclare);
+  }
+
+  visitConstructorDefinition(ConstructorDefinition node) {
+    node.parameters.forEach(declare);
+    if (node.initializers != null) node.initializers.forEach(visitInitializer);
+    if (node.body != null) visitStatement(node.body);
+    node.parameters.forEach(undeclare);
+  }
+
+  visitFunctionDeclaration(FunctionDeclaration node) {
+    declare(node.variable);
+    visitFunctionDefinition(node.definition);
+    visitStatement(node.next);
+    undeclare(node.variable);
+    if (varWrites[node.variable] > 1) {
+      error('Assignment to function declaration ${node.variable}');
+    }
+  }
+
+  visitJumpTargetBody(JumpTarget target) {
+    Label label = target.label;
+    if (label2declaration.containsKey(label)) {
+      error('Duplicate declaration of label $label');
+    }
+    label2declaration[label] = target;
+    labelUses[label] = 0;
+    visitStatement(target.body);
+    label2declaration.remove(target);
+
+    if (labelUses[label] != label.useCount) {
+      error('Label $label has ${labelUses[label]} uses '
+            'but its reference count is ${label.useCount}');
+    }
+  }
+
+  visitLabeledStatement(LabeledStatement node) {
+    visitJumpTargetBody(node);
+    visitStatement(node.next);
+  }
+
+  visitWhileTrue(WhileTrue node) {
+    visitJumpTargetBody(node);
+  }
+
+  visitWhileCondition(WhileCondition node) {
+    visitExpression(node.condition);
+    visitJumpTargetBody(node);
+    visitStatement(node.next);
+  }
+
+  visitBreak(Break node) {
+    if (!label2declaration.containsKey(node.target)) {
+      error('Break to label that is not in scope');
+    }
+    if (label2declaration[node.target] is! LabeledStatement) {
+      error('Break to non-labeled statement ${label2declaration[node.target]}');
+    }
+    labelUses[node.target]++;
+  }
+
+  visitContinue(Continue node) {
+    if (!label2declaration.containsKey(node.target)) {
+      error('Continue to label that is not in scope');
+    }
+    if (label2declaration[node.target] is! Loop) {
+      error('Continue to non-loop statement ${label2declaration[node.target]}');
+    }
+    labelUses[node.target]++;
+  }
+
+  dynamic error(String message) {
+    throw 'Tree IR integrity violation in ${topLevelNode.element}:\n$message';
+  }
+
+  void check(ExecutableDefinition node) {
+    topLevelNode = node;
+    visitExecutableDefinition(node);
+
+    // Verify reference counters for all variables.
+    List<Variable> seenVariables = new List<Variable>();
+    seenVariables.addAll(varReads.keys);
+    seenVariables.addAll(varWrites.keys);
+    for (Variable variable in seenVariables) {
+      int reads = varReads.putIfAbsent(variable, () => 0);
+      int writes = varWrites.putIfAbsent(variable, () => 0);
+      if (reads != variable.readCount || writes != variable.writeCount) {
+        error('Invalid reference count for $variable:\n'
+              '- Variable has $reads reads and $writes writes\n'
+              '- Reference count is ${variable.readCount} reads and '
+              '${variable.writeCount} writes');
+      }
+    }
+  }
+
+}
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
index e0adf01..005d082 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -6,7 +6,7 @@
 
 import '../constants/expressions.dart';
 import '../constants/values.dart' as values;
-import '../dart_types.dart' show DartType, GenericType;
+import '../dart_types.dart' show DartType, GenericType, TypeVariableType;
 import '../elements/elements.dart';
 import '../io/source_information.dart' show SourceInformation;
 import '../universe/universe.dart';
@@ -116,9 +116,17 @@
   /// - catch parameter in a [Try]
   int writeCount = 0;
 
+  /// True if a nested function reads or writes this variable.
+  ///
+  /// Always false in JS-mode because closure conversion eliminated nested
+  /// functions.
+  bool isCaptured = false;
+
   Variable(this.host, this.element) {
     assert(host != null);
   }
+
+  String toString() => element == null ? 'Variable' : element.toString();
 }
 
 /// Read the value of a variable.
@@ -258,7 +266,7 @@
   accept1(ExpressionVisitor1 visitor, arg) => visitor.visitThis(this, arg);
 }
 
-class ReifyTypeVar extends Expression {
+class ReifyTypeVar extends Expression implements DartSpecificNode {
   TypeVariableElement typeVariable;
 
   ReifyTypeVar(this.typeVariable);
@@ -518,7 +526,7 @@
 class Assign extends Statement {
   Statement next;
   Variable variable;
-  Expression definition;
+  Expression value;
 
   /// If true, this assignes to a fresh variable scoped to the [next]
   /// statement.
@@ -527,7 +535,7 @@
   bool isDeclaration;
 
   /// Creates an assignment to [variable] and updates its `writeCount`.
-  Assign(this.variable, this.definition, this.next,
+  Assign(this.variable, this.value, this.next,
          { this.isDeclaration: false }) {
     variable.writeCount++;
   }
@@ -755,6 +763,35 @@
   accept1(StatementVisitor1 visitor, arg) => visitor.visitSetField(this, arg);
 }
 
+class ReifyRuntimeType extends Expression implements JsSpecificNode {
+  Expression value;
+
+  ReifyRuntimeType(this.value);
+
+  accept(ExpressionVisitor visitor) {
+    return visitor.visitReifyRuntimeType(this);
+  }
+
+  accept1(ExpressionVisitor1 visitor, arg) {
+    return visitor.visitReifyRuntimeType(this, arg);
+  }
+}
+
+class ReadTypeVariable extends Expression implements JsSpecificNode {
+  final TypeVariableType variable;
+  Expression target;
+
+  ReadTypeVariable(this.variable, this.target);
+
+  accept(ExpressionVisitor visitor) {
+    return visitor.visitReadTypeVariable(this);
+  }
+
+  accept1(ExpressionVisitor1 visitor, arg) {
+    return visitor.visitReadTypeVariable(this, arg);
+  }
+}
+
 abstract class ExpressionVisitor<E> {
   E visitExpression(Expression e) => e.accept(this);
   E visitVariableUse(VariableUse node);
@@ -778,6 +815,8 @@
   E visitGetField(GetField node);
   E visitCreateBox(CreateBox node);
   E visitCreateInstance(CreateInstance node);
+  E visitReifyRuntimeType(ReifyRuntimeType node);
+  E visitReadTypeVariable(ReadTypeVariable node);
 }
 
 abstract class ExpressionVisitor1<E, A> {
@@ -803,6 +842,8 @@
   E visitGetField(GetField node, A arg);
   E visitCreateBox(CreateBox node, A arg);
   E visitCreateInstance(CreateInstance node, A arg);
+  E visitReifyRuntimeType(ReifyRuntimeType reifyRuntimeType, A arg);
+  E visitReadTypeVariable(ReadTypeVariable readTypeVariable, A arg);
 }
 
 abstract class StatementVisitor<S> {
@@ -850,11 +891,47 @@
 }
 
 class RecursiveVisitor extends Visitor {
+  // TODO(asgerf): Clean up the tree visitor.
+  
+  visitExecutableDefinition(ExecutableDefinition node) {
+    if (node is ConstructorDefinition) return visitConstructorDefinition(node);
+    if (node is FunctionDefinition) return visitFunctionDefinition(node);
+    if (node is FieldDefinition) return visitFieldDefinition(node);
+    throw 'Unexpected ExecutableDefinition: $node';
+  }
+
   visitFunctionDefinition(FunctionDefinition node) {
     node.parameters.forEach(visitVariable);
+    if (node.body != null) visitStatement(node.body);
+  }
+
+  visitConstructorDefinition(ConstructorDefinition node) {
+    if (node.initializers != null) node.initializers.forEach(visitInitializer);
+    visitFunctionDefinition(node);
+  }
+
+  visitFieldDefinition(FieldDefinition node) {
+    if (node.body != null) {
+      visitStatement(node.body);
+    }
+  }
+
+  visitInitializer(Initializer node) {
+    if (node is FieldInitializer) {
+      return visitFieldInitializer(node);
+    } else {
+      return visitSuperInitializer(node);
+    }
+  }
+
+  visitFieldInitializer(FieldInitializer node) {
     visitStatement(node.body);
   }
 
+  visitSuperInitializer(SuperInitializer node) {
+    node.arguments.forEach(visitStatement);
+  }
+
   visitVariable(Variable node) {}
 
   visitVariableUse(VariableUse node) {
@@ -929,7 +1006,7 @@
   }
 
   visitAssign(Assign node) {
-    visitExpression(node.definition);
+    visitExpression(node.value);
     visitVariable(node.variable);
     visitStatement(node.next);
   }
@@ -973,14 +1050,6 @@
     visitStatement(node.catchBody);
   }
 
-  visitFieldInitializer(FieldInitializer node) {
-    visitStatement(node.body);
-  }
-
-  visitSuperInitializer(SuperInitializer node) {
-    node.arguments.forEach(visitStatement);
-  }
-
   visitGetField(GetField node) {
     visitExpression(node.object);
   }
@@ -997,4 +1066,12 @@
   visitCreateInstance(CreateInstance node) {
     node.arguments.forEach(visitExpression);
   }
+
+  visitReifyRuntimeType(ReifyRuntimeType node) {
+    visitExpression(node.value);
+  }
+
+  visitReadTypeVariable(ReadTypeVariable node) {
+    visitExpression(node.target);
+  }
 }
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
index 2259fbe..5bea4f5 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
@@ -184,6 +184,9 @@
 }
 
 class TreeTracer extends TracerUtil with StatementVisitor, PassMixin {
+  // TODO(asgerf): Fix visitors so we don't have to use PassMixin here.
+  String get passName => null;
+
   final EventSink<String> output;
 
   TreeTracer(this.output);
@@ -265,7 +268,7 @@
 
   visitAssign(Assign node) {
     String name = names.varName(node.variable);
-    String rhs = expr(node.definition);
+    String rhs = expr(node.value);
     Variable v = node.variable;
     String extra = "(r=${v.readCount}, w=${v.writeCount})";
     printStatement(null, "assign $name = $rhs $extra");
@@ -489,6 +492,16 @@
     return 'CreateInstance $className($arguments)';
   }
 
+
+  @override
+  String visitReadTypeVariable(ReadTypeVariable node) {
+    return 'read ${node.variable.element} ${visitExpression(node.target)}';
+  }
+
+  @override
+  String visitReifyRuntimeType(ReifyRuntimeType node) {
+    return 'reify ${node.value}';
+  }
 }
 
 /**
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
index 68684a4..04a7a43 100644
--- a/pkg/compiler/lib/src/typechecker.dart
+++ b/pkg/compiler/lib/src/typechecker.dart
@@ -1590,7 +1590,7 @@
         // The resolver already emitted an error for this expression.
       } else {
         if (currentAsyncMarker == AsyncMarker.ASYNC) {
-          expressionType = coreTypes.futureType(flatten(expressionType));
+          expressionType = coreTypes.futureType(types.flatten(expressionType));
         }
         if (expectedReturnType.isVoid &&
             !types.isAssignable(expressionType, const VoidType())) {
@@ -1618,28 +1618,9 @@
     return const DynamicType();
   }
 
-  /// Flatten [type] by recursively removing enclosing `Future` annotations.
-  ///
-  /// For instance:
-  ///     flatten(T) = T
-  ///     flatten(Future<T>) = T
-  ///     flatten(Future<Future<T>>) = T
-  ///
-  /// This method is used in the static typing of await and type checking of
-  /// return.
-  DartType flatten(DartType type) {
-    if (type is InterfaceType) {
-      InterfaceType futureType = type.asInstanceOf(compiler.futureClass);
-      if (futureType != null) {
-        return flatten(futureType.typeArguments.first);
-      }
-    }
-    return type;
-  }
-
   DartType visitAwait(Await node) {
     DartType expressionType = analyze(node.expression);
-    return flatten(expressionType);
+    return types.flatten(expressionType);
   }
 
   DartType visitYield(Yield node) {
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index 91023a3..bd52426 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -5,7 +5,7 @@
 part of types;
 
 /**
- * A flat type mask is a type mask that has been flatten to contain a
+ * A flat type mask is a type mask that has been flattened to contain a
  * base type.
  */
 class FlatTypeMask implements TypeMask {
diff --git a/pkg/compiler/lib/src/universe/side_effects.dart b/pkg/compiler/lib/src/universe/side_effects.dart
index e4a1fa4..01e4407 100644
--- a/pkg/compiler/lib/src/universe/side_effects.dart
+++ b/pkg/compiler/lib/src/universe/side_effects.dart
@@ -21,7 +21,7 @@
   static const int FLAG_DEPENDS_ON_COUNT =
       FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE + 1;
 
-  int flags = 0;
+  int _flags = 0;
 
   SideEffects() {
     setAllSideEffects();
@@ -30,63 +30,84 @@
 
   SideEffects.empty();
 
-  bool operator==(other) => flags == other.flags;
+  bool operator==(other) => _flags == other._flags;
 
   int get hashCode => throw new UnsupportedError('SideEffects.hashCode');
 
-  bool getFlag(int position) => (flags & (1 << position)) != 0;
-  void setFlag(int position) { flags |= (1 << position); }
+  bool _getFlag(int position) => (_flags & (1 << position)) != 0;
+  void _setFlag(int position) { _flags |= (1 << position); }
+  bool _clearFlag(int position) { _flags &= ~(1 << position); }
 
-  int getChangesFlags() => flags & ((1 << FLAG_CHANGES_COUNT) - 1);
+  int getChangesFlags() => _flags & ((1 << FLAG_CHANGES_COUNT) - 1);
   int getDependsOnFlags() {
-    return (flags & ((1 << FLAG_DEPENDS_ON_COUNT) - 1)) >> FLAG_CHANGES_COUNT;
+    return (_flags & ((1 << FLAG_DEPENDS_ON_COUNT) - 1)) >> FLAG_CHANGES_COUNT;
   }
 
   bool hasSideEffects() => getChangesFlags() != 0;
   bool dependsOnSomething() => getDependsOnFlags() != 0;
 
-  void setAllSideEffects() { flags |= ((1 << FLAG_CHANGES_COUNT) - 1); }
+  void setAllSideEffects() { _flags |= ((1 << FLAG_CHANGES_COUNT) - 1); }
 
-  void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); }
+  void clearAllSideEffects() { _flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); }
 
   void setDependsOnSomething() {
     int count = FLAG_DEPENDS_ON_COUNT - FLAG_CHANGES_COUNT;
-    flags |= (((1 << count) - 1) << FLAG_CHANGES_COUNT);
+    _flags |= (((1 << count) - 1) << FLAG_CHANGES_COUNT);
   }
   void clearAllDependencies() {
     int count = FLAG_DEPENDS_ON_COUNT - FLAG_CHANGES_COUNT;
-    flags &= ~(((1 << count) - 1) << FLAG_CHANGES_COUNT);
+    _flags &= ~(((1 << count) - 1) << FLAG_CHANGES_COUNT);
   }
 
   bool dependsOnStaticPropertyStore() {
-    return getFlag(FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE);
+    return _getFlag(FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE);
   }
   void setDependsOnStaticPropertyStore() {
-    setFlag(FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE);
+    _setFlag(FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE);
   }
-  void setChangesStaticProperty() { setFlag(FLAG_CHANGES_STATIC_PROPERTY); }
-  bool changesStaticProperty() => getFlag(FLAG_CHANGES_STATIC_PROPERTY);
+  void clearDependsOnStaticPropertyStore() {
+    _clearFlag(FLAG_DEPENDS_ON_STATIC_PROPERTY_STORE);
+  }
+  void setChangesStaticProperty() { _setFlag(FLAG_CHANGES_STATIC_PROPERTY); }
+  void clearChangesStaticProperty() {
+    _clearFlag(FLAG_CHANGES_STATIC_PROPERTY);
+  }
+  bool changesStaticProperty() => _getFlag(FLAG_CHANGES_STATIC_PROPERTY);
 
-  bool dependsOnIndexStore() => getFlag(FLAG_DEPENDS_ON_INDEX_STORE);
-  void setDependsOnIndexStore() { setFlag(FLAG_DEPENDS_ON_INDEX_STORE); }
-  void setChangesIndex() { setFlag(FLAG_CHANGES_INDEX); }
-  bool changesIndex() => getFlag(FLAG_CHANGES_INDEX);
+  bool dependsOnIndexStore() => _getFlag(FLAG_DEPENDS_ON_INDEX_STORE);
+  void setDependsOnIndexStore() { _setFlag(FLAG_DEPENDS_ON_INDEX_STORE); }
+  void clearDependsOnIndexStore() { _clearFlag(FLAG_DEPENDS_ON_INDEX_STORE); }
+  void setChangesIndex() { _setFlag(FLAG_CHANGES_INDEX); }
+  void clearChangesIndex() { _clearFlag(FLAG_CHANGES_INDEX); }
+  bool changesIndex() => _getFlag(FLAG_CHANGES_INDEX);
 
   bool dependsOnInstancePropertyStore() {
-    return getFlag(FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE);
+    return _getFlag(FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE);
   }
   void setDependsOnInstancePropertyStore() {
-    setFlag(FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE);
+    _setFlag(FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE);
   }
-  void setChangesInstanceProperty() { setFlag(FLAG_CHANGES_INSTANCE_PROPERTY); }
-  bool changesInstanceProperty() => getFlag(FLAG_CHANGES_INSTANCE_PROPERTY);
+  void clearDependsOnInstancePropertyStore() {
+    _setFlag(FLAG_DEPENDS_ON_INSTANCE_PROPERTY_STORE);
+  }
+  void setChangesInstanceProperty() {
+    _setFlag(FLAG_CHANGES_INSTANCE_PROPERTY);
+  }
+  void clearChangesInstanceProperty() {
+    _clearFlag(FLAG_CHANGES_INSTANCE_PROPERTY);
+  }
+  bool changesInstanceProperty() => _getFlag(FLAG_CHANGES_INSTANCE_PROPERTY);
 
   static int computeDependsOnFlags(int flags) => flags << FLAG_CHANGES_COUNT;
 
-  bool dependsOn(int dependsFlags) => (flags & dependsFlags) != 0;
+  bool dependsOn(int dependsFlags) => (_flags & dependsFlags) != 0;
 
   void add(SideEffects other) {
-    flags |= other.flags;
+    _flags |= other._flags;
+  }
+
+  void setTo(SideEffects other) {
+    _flags = other._flags;
   }
 
   String toString() {
diff --git a/pkg/compiler/lib/src/use_unused_api.dart b/pkg/compiler/lib/src/use_unused_api.dart
index bf44322..aee8529 100644
--- a/pkg/compiler/lib/src/use_unused_api.dart
+++ b/pkg/compiler/lib/src/use_unused_api.dart
@@ -13,6 +13,7 @@
 import 'colors.dart' as colors;
 import 'constants/values.dart' as constants;
 import 'cps_ir/cps_ir_builder.dart' as ir_builder;
+import 'cps_ir/cps_ir_builder_task.dart' as ir_builder;
 import 'cps_ir/cps_ir_nodes_sexpr.dart' as cps_ir_nodes_sexpr;
 import 'dart_types.dart' as dart_types;
 import 'dart2js.dart' as dart2js;
@@ -28,6 +29,7 @@
 import 'js_backend/js_backend.dart' as js_backend;
 import 'js_emitter/js_emitter.dart' as js_emitter;
 import 'js_emitter/program_builder.dart' as program_builder;
+import 'resolution/semantic_visitor.dart' as semantic_visitor;
 import 'source_file_provider.dart' as source_file_provider;
 import 'ssa/ssa.dart' as ssa;
 import 'tree/tree.dart' as tree;
@@ -69,6 +71,7 @@
   useCodeEmitterTask(null);
   useScript(null);
   useProgramBuilder(null);
+  useSemanticVisitor();
 }
 
 useApi() {
@@ -276,3 +279,8 @@
   builder.buildMethodHackForIncrementalCompilation(null);
   builder.buildFieldsHackForIncrementalCompilation(null);
 }
+
+useSemanticVisitor() {
+  new semantic_visitor.BulkVisitor().apply(null, null);
+  new semantic_visitor.TraversalVisitor(null).apply(null, null);
+}
diff --git a/pkg/dart2js_incremental/lib/library_updater.dart b/pkg/dart2js_incremental/lib/library_updater.dart
index 6558866..57d4142 100644
--- a/pkg/dart2js_incremental/lib/library_updater.dart
+++ b/pkg/dart2js_incremental/lib/library_updater.dart
@@ -928,7 +928,7 @@
 (new Function(
     "$collectedClasses", "$desc",
     this.defineClass(#name, #computeFields) +"\n;return " + #name))(
-        {#name: #descriptor})''',
+        {#name: [,#descriptor]})''',
         {'name': js.string(name),
          'computeFields': js.stringArray(computeFields(cls)),
          'descriptor': descriptor});
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 11d7ccb..b24c089 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -25,8 +25,7 @@
 analysis_server/test/completion_test: SkipSlow  # Times out
 analysis_server/test/domain_context_test: SkipSlow  # Times out
 analysis_server/test/domain_server_test: SkipSlow  # Times out
-analysis_server/test/integration/analysis/reanalyze_concurrent_test: SkipSlow # Times out
-analysis_server/test/integration/analysis/update_content_test: SkipSlow # Times out
+analysis_server/test/integration/*: SkipSlow # Times out
 analysis_server/tool/spec/check_all_test: SkipSlow # Times out
 analyzer/test/generated/element_test: SkipSlow  # Times out
 analyzer/test/generated/parser_test: SkipSlow  # Times out
@@ -176,15 +175,14 @@
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 third_party/angular_tests/vm_test: StaticWarning # Uses removed APIs. See issue 18733.
-analyzer2dart/test/driver_test: StaticWarning # Issue 22418
-analyzer2dart/test/sexpr_test: StaticWarning # Issue 22418
-analyzer2dart/test/tree_shaker_test: StaticWarning # Issue 22418
-analyzer2dart/test/end2end_test: StaticWarning # Issue 22418
 
 [ $runtime == safari || $runtime == safarimobilesim || $runtime == chrome || $runtime == ff || $ie ]
 # Various issues due to limited browser testing in Angular.
 third_party/angular_tests/*: Skip
 
+[ $compiler == dart2js && $runtime == chrome && $system == macos ]
+third_party/di_tests/di_test: Pass, Slow # Issue 22896
+
 [ $unchecked ]
 third_party/angular_tests/browser_test/angular: SkipByDesign # Requires checked mode.
 third_party/angular_tests/browser_test/core/scope: SkipByDesign # Requires checked mode.
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index d8c586c..59338260 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -3,83 +3,12 @@
 // BSD-style license that can be found in the LICENSE file.
 
 library builtin;
+// NOTE: Do not import 'dart:io' in builtin.
 import 'dart:async';
 import 'dart:convert';
 import 'dart:isolate';
 
 
-//////////////////////
-/* Support for loading within the isolate via dart:io */
-import 'dart:io';
-
-// Enable by setting the #define LOAD_VIA_SERVICE_ISOLATE (see dartutils.cc)
-bool _load_via_service_isolate = false;
-
-var _httpClient;
-void _httpGet(int tag,
-              Uri uri,
-              String libraryUri,
-              loadCallback(List<int> data)) {
-  if (_httpClient == null) {
-    _httpClient = new HttpClient()..maxConnectionsPerHost = 6;
-  }
-  _httpClient.getUrl(uri)
-    .then((HttpClientRequest request) => request.close())
-    .then((HttpClientResponse response) {
-      var builder = new BytesBuilder(copy: false);
-      response.listen(
-          builder.add,
-          onDone: () {
-            if (response.statusCode != 200) {
-              var msg = 'Failure getting $uri: '
-                        '${response.statusCode} ${response.reasonPhrase}';
-              _asyncLoadError(tag, uri.toString(), libraryUri, msg);
-            }
-            loadCallback(builder.takeBytes());
-          },
-          onError: (error) {
-            _asyncLoadError(tag, uri.toString(), libraryUri, error);
-          });
-    })
-    .catchError((error) {
-      _asyncLoadError(tag, uri.toString(), libraryUri, error);
-    });
-  // TODO(floitsch): remove this line. It's just here to push an event on the
-  // event loop so that we invoke the scheduled microtasks. Also remove the
-  // import of dart:async when this line is not needed anymore.
-  Timer.run(() {});
-}
-
-
-void _cleanup() {
-  if (_httpClient != null) {
-    _httpClient.close();
-    _httpClient = null;
- }
-}
-
-_loadDataAsyncDartIO(int tag,
-                       String uri,
-                       String libraryUri,
-                       Uri resourceUri) {
-  _startingOneLoadRequest(uri);
-  if ((resourceUri.scheme == 'http') || (resourceUri.scheme == 'https')) {
-    _httpGet(tag, resourceUri, libraryUri, (data) {
-      _loadScript(tag, uri, libraryUri, data);
-    });
-  } else {
-    var sourceFile = new File(resourceUri.toFilePath());
-    sourceFile.readAsBytes().then((data) {
-      _loadScript(tag, uri, libraryUri, data);
-    },
-    onError: (e) {
-      _asyncLoadError(tag, uri, libraryUri, e);
-    });
-  }
-}
-
-//////////////////////
-
 /* See Dart_LibraryTag in dart_api.h */
 const Dart_kScriptTag = null;
 const Dart_kImportTag = 0;
@@ -112,7 +41,7 @@
 
 _getPrintClosure() => _print;
 
-_getCurrentDirectoryPath() native "Directory_Current";
+_getCurrentDirectoryPath() native "Builtin_GetCurrentDirectory";
 
 // Corelib 'Uri.base' implementation.
 Uri _uriBase() {
@@ -120,10 +49,6 @@
   // on dart:io. This code is the same as:
   //   return new Uri.file(Directory.current.path + "/");
   var result = _getCurrentDirectoryPath();
-  if (result is OSError) {
-    throw new FileSystemException(
-        "Getting current working directory failed", "", result);
-  }
   return new Uri.file(result + "/");
 }
 
@@ -290,6 +215,7 @@
   var uri = Uri.parse(userUri);
   switch (uri.scheme) {
     case '':
+    case 'data':
     case 'file':
     case 'http':
     case 'https':
@@ -316,7 +242,6 @@
   }
   if (_numOutstandingLoadRequests == 0) {
     _signalDoneLoading();
-    _cleanup();
   }
 }
 
@@ -350,7 +275,7 @@
   _finishedOneLoadRequest(uri);
 }
 
-void _asyncLoadError(tag, uri, libraryUri, error) {
+void _asyncLoadError(int tag, String uri, String libraryUri, LoadError error) {
   if (_logBuiltin) {
     _print("_asyncLoadError($uri), error: $error");
   }
@@ -359,7 +284,7 @@
     // uri.
     libraryUri = uri;
   }
-  _asyncLoadErrorCallback(uri, libraryUri, new LoadError(error.toString()));
+  _asyncLoadErrorCallback(uri, libraryUri, error);
   _finishedOneLoadRequest(uri);
 }
 
@@ -370,13 +295,20 @@
                        Uri resourceUri) {
   var receivePort = new ReceivePort();
   receivePort.first.then((dataOrError) {
+    receivePort.close();
     if (dataOrError is List<int>) {
       _loadScript(tag, uri, libraryUri, dataOrError);
     } else {
-      _asyncLoadError(tag, uri, libraryUri, dataOrError);
+      assert(dataOrError is String);
+      var error = new LoadError(dataOrError.toString());
+      _asyncLoadError(tag, uri, libraryUri, error);
     }
   }).catchError((e) {
-    _asyncLoadError(tag, uri, libraryUri, e.toString());
+    receivePort.close();
+    // Wrap inside a LoadError unless we are already propagating a previously
+    // seen LoadError.
+    var error = (e is LoadError) ? e : new LoadError(e.toString);
+    _asyncLoadError(tag, uri, libraryUri, error);
   });
 
   try {
@@ -387,7 +319,10 @@
     if (_logBuiltin) {
       _print("Exception when communicating with service isolate: $e");
     }
-    _asyncLoadError(tag, uri, libraryUri, e.toString());
+    // Wrap inside a LoadError unless we are already propagating a previously
+    // seen LoadError.
+    var error = (e is LoadError) ? e : new LoadError(e.toString);
+    _asyncLoadError(tag, uri, libraryUri, error);
     receivePort.close();
   }
 }
@@ -400,12 +335,7 @@
 
   Uri resourceUri = _createUri(uri);
 
-  if (_load_via_service_isolate) {
-    _loadDataAsyncLoadPort(tag, uri, libraryUri, resourceUri);
-  } else {
-    _loadDataAsyncDartIO(tag, uri, libraryUri, resourceUri);
-  }
-
+  _loadDataAsyncLoadPort(tag, uri, libraryUri, resourceUri);
 }
 
 // Returns either a file path or a URI starting with http[s]:, as a String.
@@ -422,6 +352,7 @@
       return uri.toFilePath();
     case 'package':
       return _filePathFromUri(_resolvePackageUri(uri).toString());
+    case 'data':
     case 'http':
     case 'https':
       return uri.toString();
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 63a5fb0..a7bb6d2 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -69,6 +69,7 @@
   V(Builtin_AsyncLoadError, 3)                                                 \
   V(Builtin_DoneLoading, 0)                                                    \
   V(Builtin_NativeLibraryExtension, 0)                                         \
+  V(Builtin_GetCurrentDirectory, 0)                                            \
 
 
 BUILTIN_NATIVE_LIST(DECLARE_FUNCTION);
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 5778489..fc8b0c5 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -47,10 +47,6 @@
 }
 
 
-// Experimental flag that offloads all script loading I/O onto
-// the service isolate. Disabled for now.
-// #define LOAD_VIA_SERVICE_ISOLATE
-
 const char* DartUtils::MapLibraryUrl(CommandLineOptions* url_mapping,
                                      const char* url_string) {
   ASSERT(url_mapping != NULL);
@@ -483,13 +479,11 @@
                                   Dart_Handle builtin_lib) {
   Dart_Handle uri = Dart_NewStringFromCString(script_uri);
 
-#if defined(LOAD_VIA_SERVICE_ISOLATE)
   Dart_Port load_port = Dart_ServiceWaitForLoadPort();
   if (load_port == ILLEGAL_PORT) {
     return NewDartUnsupportedError("Service did not return load port.");
   }
   Builtin::SetLoadPort(load_port);
-#endif
 
   return LoadDataAsync_Invoke(Dart_Null(), uri, Dart_Null(), builtin_lib);
 }
@@ -615,6 +609,18 @@
 }
 
 
+void FUNCTION_NAME(Builtin_GetCurrentDirectory)(Dart_NativeArguments args) {
+  char* current = Directory::Current();
+  if (current != NULL) {
+    Dart_SetReturnValue(args, DartUtils::NewString(current));
+    free(current);
+  } else {
+    Dart_Handle err = DartUtils::NewError("Failed to get current directory.");
+    Dart_PropagateError(err);
+  }
+}
+
+
 void DartUtils::PrepareBuiltinLibrary(Dart_Handle builtin_lib,
                                       Dart_Handle internal_lib,
                                       bool is_service_isolate,
@@ -634,12 +640,6 @@
     DART_CHECK_VALID(result);
   }
 
-#if defined(LOAD_VIA_SERVICE_ISOLATE)
-  result = Dart_SetField(builtin_lib, NewString("_load_via_service_isolate"),
-                         Dart_True());
-  DART_CHECK_VALID(result);
-#endif
-
   if (!is_service_isolate) {
     // Set current working directory.
     result = SetWorkingDirectory(builtin_lib);
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index c866977..94285aa 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -287,6 +287,7 @@
   bool isClosed = false;
   bool isClosing = false;
   bool isClosedRead = false;
+  bool closedReadEventSent = false;
   bool isClosedWrite = false;
   Completer closeCompleter = new Completer.sync();
 
@@ -302,7 +303,7 @@
   int localPort = 0;
 
   // Holds the address used to connect or bind the socket.
-  InternetAddress address;
+  InternetAddress localAddress;
 
   int available = 0;
 
@@ -416,7 +417,7 @@
             }
             var address = it.current;
             var socket = new _NativeSocket.normal();
-            socket.address = address;
+            socket.localAddress = address;
             var result;
             if (sourceAddress == null) {
               result = socket.nativeCreateConnect(address._in_addr, port);
@@ -432,7 +433,8 @@
               }
               connectNext();
             } else {
-              socket.port;  // Query the local port, for error messages.
+              // Query the local port, for error messages.
+              socket.port;
               // Set up timer for when we should retry the next address
               // (if any).
               var duration = address.isLoopback ?
@@ -489,7 +491,7 @@
         })
         .then((address) {
           var socket = new _NativeSocket.listen();
-          socket.address = address;
+          socket.localAddress = address;
 
           var result = socket.nativeCreateBindListen(address._in_addr,
                                                      port,
@@ -536,7 +538,7 @@
         });
   }
 
-  _NativeSocket.datagram(this.address)
+  _NativeSocket.datagram(this.localAddress)
     : typeFlags = TYPE_NORMAL_SOCKET | TYPE_UDP_SOCKET;
 
   _NativeSocket.normal() : typeFlags = TYPE_NORMAL_SOCKET | TYPE_TCP_SOCKET;
@@ -670,7 +672,7 @@
     var socket = new _NativeSocket.normal();
     if (nativeAccept(socket) != true) return null;
     socket.localPort = localPort;
-    socket.address = address;
+    socket.localAddress = address;
     totalRead += 1;
     lastRead = timestamp;
     return socket;
@@ -678,22 +680,32 @@
 
   int get port {
     if (localPort != 0) return localPort;
+    if (isClosing || isClosed) throw const SocketException.closed();
     var result = nativeGetPort();
     if (result is OSError) throw result;
     return localPort = result;
   }
 
   int get remotePort {
-    return nativeGetRemotePeer()[1];
+    if (isClosing || isClosed) throw const SocketException.closed();
+    var result = nativeGetRemotePeer();
+    if (result is OSError) throw result;
+    return result[1];
   }
 
+  InternetAddress get address => localAddress;
+
   InternetAddress get remoteAddress {
-    var result = nativeGetRemotePeer()[0];
-    var type = new InternetAddressType._from(result[0]);
-    return new _InternetAddress(result[1], null, result[2]);
+    if (isClosing || isClosed) throw const SocketException.closed();
+    var result = nativeGetRemotePeer();
+    if (result is OSError) throw result;
+    var addr = result[0];
+    var type = new InternetAddressType._from(addr[0]);
+    return new _InternetAddress(addr[1], null, addr[2]);
   }
 
   void issueReadEvent() {
+    if (closedReadEventSent) return;
     if (readEventIssued) return;
     readEventIssued = true;
     void issue() {
@@ -701,10 +713,11 @@
       if (isClosing) return;
       if (!sendReadEvents) return;
       if (available == 0) {
-        if (isClosedRead) {
+        if (isClosedRead && !closedReadEventSent) {
           if (isClosedWrite) close();
           var handler = eventHandlers[CLOSED_EVENT];
           if (handler == null) return;
+          closedReadEventSent = true;
           handler();
         }
         return;
@@ -860,7 +873,7 @@
 
   void shutdownWrite() {
     if (!isClosing && !isClosed) {
-      if (isClosedRead) {
+      if (closedReadEventSent) {
         close();
       } else {
         sendToEventHandler(1 << SHUTDOWN_WRITE_COMMAND);
@@ -1350,6 +1363,7 @@
   factory _RawSocket._writePipe() {
     var native = new _NativeSocket.pipe();
     native.isClosedRead = true;
+    native.closedReadEventSent = true;
     return new _RawSocket(native);
   }
 
@@ -1701,10 +1715,25 @@
     return _raw.setOption(option, enabled);
   }
 
-  int get port => _raw.port;
-  InternetAddress get address => _raw.address;
-  int get remotePort => _raw.remotePort;
-  InternetAddress get remoteAddress => _raw.remoteAddress;
+  int get port {
+    if (_raw == null) throw const SocketException.closed();;
+    return _raw.port;
+  }
+
+  InternetAddress get address {
+    if (_raw == null) throw const SocketException.closed();;
+    return _raw.address;
+  }
+
+  int get remotePort {
+    if (_raw == null) throw const SocketException.closed();;
+    return _raw.remotePort;
+  }
+
+  InternetAddress get remoteAddress {
+    if (_raw == null) throw const SocketException.closed();;
+    return _raw.remoteAddress;
+  }
 
   Future _detachRaw() {
     _detachReady = new Completer();
diff --git a/runtime/bin/vmservice/loader.dart b/runtime/bin/vmservice/loader.dart
index 6d81f04..1c4ae95 100644
--- a/runtime/bin/vmservice/loader.dart
+++ b/runtime/bin/vmservice/loader.dart
@@ -47,6 +47,37 @@
   });
 }
 
+var dataUriRegex = new RegExp(
+    r"data:([\w-]+/[\w-]+)?(;charset=([\w-]+))?(;base64)?,(.*)");
+
+void _loadDataUri(sendPort, uri) {
+  try {
+    var match = dataUriRegex.firstMatch(uri.toString());
+    if (match == null) throw "Malformed data uri";
+
+    var mimeType = match.group(1);
+    var encoding = match.group(3);
+    var maybeBase64 = match.group(4);
+    var encodedData = match.group(5);
+
+    if (mimeType != "application/dart") {
+      throw "MIME-type must be application/dart";
+    }
+    if (encoding != "utf-8") {
+      // Default is ASCII. The C++ portion of the embedder assumes UTF-8.
+      throw "Only utf-8 encoding is supported";
+    }
+    if (maybeBase64 != null) {
+      throw "Only percent encoding is supported";
+    }
+
+    var data = UTF8.encode(Uri.decodeComponent(encodedData));
+    sendPort.send(data);
+  } catch (e) {
+    sendPort.send("Invalid data uri ($uri) $e");
+  }
+}
+
 _processLoadRequest(request) {
   var sp = request[0];
   var uri = Uri.parse(request[1]);
@@ -54,6 +85,8 @@
     _loadFile(sp, uri.toFilePath());
   } else if ((uri.scheme == 'http') || (uri.scheme == 'https')) {
     _loadHttp(sp, uri);
+  } else if ((uri.scheme == 'data')) {
+    _loadDataUri(sp, uri);
   } else {
     sp.send('Unknown scheme for $uri');
   }
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index c6e7ce4..a847828 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -180,6 +180,13 @@
     });
   }
 
+  close(bool force) {
+    if (_server == null) {
+      return new Future.value(null);
+    }
+    return _server.close(force: force);
+  }
+
   Future shutdown(bool forced) {
     if (_server == null) {
       // Not started.
@@ -192,7 +199,7 @@
     // Shutdown HTTP server and subscription.
     var ip = _server.address.address.toString();
     var port = _server.port.toString();
-    return _server.close(force: forced).then((_) {
+    return close(forced).then((_) {
       if (_displayMessages) {
         print('Observatory no longer listening on http://$ip:$port');
       }
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
index 2d99e17..070a25c 100644
--- a/runtime/bin/vmservice/vmservice_io.dart
+++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -23,25 +23,37 @@
 bool _isWindows = false;
 
 var _signalWatch;
+var _signalSubscription;
 
 // HTTP servr.
 Server server;
 Future<Server> serverFuture;
 
-void _bootServer() {
+_onShutdown() {
+  if (server != null) {
+    server.close(true).catchError((e, st) => assert(e));
+  }
+  if (_signalSubscription != null) {
+    _signalSubscription.cancel();
+    _signalSubscription = null;
+  }
+}
+
+_bootServer() {
   // Load resources.
   _triggerResourceLoad();
   // Lazily create service.
   var service = new VMService();
+  service.onShutdown = _onShutdown;
   // Lazily create server.
   server = new Server(service, _ip, _port);
 }
 
-void _clearFuture(_) {
+_clearFuture(_) {
   serverFuture = null;
 }
 
-void _onSignal(ProcessSignal signal) {
+_onSignal(ProcessSignal signal) {
   if (serverFuture != null) {
     // Still waiting.
     return;
@@ -57,12 +69,12 @@
   }
 }
 
-void _registerSignalHandler() {
+_registerSignalHandler() {
   if (_isWindows) {
     // Cannot register for signals on Windows.
     return;
   }
-  _signalWatch(ProcessSignal.SIGQUIT).listen(_onSignal);
+  _signalSubscription = _signalWatch(ProcessSignal.SIGQUIT).listen(_onSignal);
 }
 
 const _shortDelay = const Duration(milliseconds: 10);
diff --git a/runtime/lib/class_id.cc b/runtime/lib/class_id.cc
index 2f99138..2d9f67d 100644
--- a/runtime/lib/class_id.cc
+++ b/runtime/lib/class_id.cc
@@ -9,7 +9,7 @@
 
 DEFINE_NATIVE_ENTRY(ClassID_getID, 1) {
   const Instance& instance =
-      Instance::CheckedHandle(isolate, arguments->NativeArgAt(0));
+      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   return Smi::New(instance.GetClassId());
 }
 
diff --git a/runtime/lib/collection_patch.dart b/runtime/lib/collection_patch.dart
index ebaba41..8ed4e91 100644
--- a/runtime/lib/collection_patch.dart
+++ b/runtime/lib/collection_patch.dart
@@ -918,17 +918,15 @@
         if (equals == null) {
           if (_useInternalCached) {
             return new _InternalLinkedHashMap<K, V>();
-          } else if (_useCompactCached) {
-            return new _CompactLinkedHashMap<K, V>();
           } else {
-            return new _LinkedHashMap<K, V>();
+            return new _CompactLinkedHashMap<K, V>();
           }
         }
         hashCode = _defaultHashCode;
       } else {
         if (identical(identityHashCode, hashCode) &&
             identical(identical, equals)) {
-          return new _LinkedIdentityHashMap<K, V>();
+          return new _CompactLinkedIdentityHashMap<K, V>();
         }
         if (equals == null) {
           equals = _defaultEquals;
@@ -942,124 +940,16 @@
         equals = _defaultEquals;
       }
     }
-    return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
+    return new _CompactLinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
   }
 
-  /* patch */ factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>;
+  /* patch */ factory LinkedHashMap.identity() =
+      _CompactLinkedIdentityHashMap<K, V>;
 
   static final bool _useInternalCached = _useInternal;
   static bool get _useInternal native "LinkedHashMap_useInternal";
-  static final bool _useCompactCached = _useCompact;
-  static bool get _useCompact native "LinkedHashMap_useCompact";
 }
 
-// Methods that are exactly the same in all three linked hash map variants.
-abstract class _LinkedHashMapMixin<K, V> implements LinkedHashMap<K, V> {
-  var _nextEntry;
-  var _previousEntry;
-
-
-  bool containsValue(Object value) {
-    int modificationCount = _modificationCount;
-    var cursor = _nextEntry;
-    while (!identical(cursor, this)) {
-      _HashMapEntry entry = cursor;
-      if (entry.value == value) return true;
-      if (modificationCount != _modificationCount) {
-        throw new ConcurrentModificationError(this);
-      }
-      cursor = cursor._nextEntry;
-    }
-    return false;
-  }
-
-  void forEach(void action(K key, V value)) {
-    int modificationCount = _modificationCount;
-    var cursor = _nextEntry;
-    while (!identical(cursor, this)) {
-      _HashMapEntry entry = cursor;
-      action(entry.key, entry.value);
-      if (modificationCount != _modificationCount) {
-        throw new ConcurrentModificationError(this);
-      }
-      cursor = cursor._nextEntry;
-    }
-  }
-
-  void clear() {
-    _nextEntry = _previousEntry = this;
-    _buckets = new List(_HashMap._INITIAL_CAPACITY);
-    if (_elementCount > 0) {
-      _elementCount = 0;
-      _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
-    }
-  }
-
-  void _addEntry(List buckets, int index, int length,
-                 K key, V value, int hashCode) {
-    _HashMapEntry entry =
-        new _LinkedHashMapEntry(key, value, hashCode, buckets[index],
-                                _previousEntry, this);
-    buckets[index] = entry;
-    int newElements = _elementCount + 1;
-    _elementCount = newElements;
-
-    // If we end up with more than 75% non-empty entries, we
-    // resize the backing store.
-    if ((newElements << 2) > ((length << 1) + length)) _resize();
-    _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
-  }
-
-  void _removeEntry(_LinkedHashMapEntry entry,
-                    _HashMapEntry previousInBucket,
-                    int bucketIndex) {
-    var previousInChain = entry._previousEntry;
-    var nextInChain = entry._nextEntry;
-    previousInChain._nextEntry = nextInChain;
-    nextInChain._previousEntry = previousInChain;
-    if (previousInBucket == null) {
-      _buckets[bucketIndex] = entry.next;
-    } else {
-      previousInBucket.next = entry.next;
-    }
-  }
-
-
-  Iterable<K> get keys => new _LinkedHashMapKeyIterable<K>(this);
-  Iterable<V> get values => new _LinkedHashMapValueIterable<V>(this);
-}
-
-class _LinkedHashMap<K, V> extends _HashMap<K, V>
-                           with _LinkedHashMapMixin<K, V> {
-  _LinkedHashMap() {
-    _nextEntry = _previousEntry = this;
-  }
-
-  Set<K> _newKeySet() => new _LinkedHashSet<K>();
-}
-
-class _LinkedIdentityHashMap<K, V> extends _IdentityHashMap<K, V>
-                                   with _LinkedHashMapMixin<K, V> {
-  _LinkedIdentityHashMap() {
-    _nextEntry = _previousEntry = this;
-  }
-
-  Set<K> _newKeySet() => new _LinkedIdentityHashSet<K>();
-}
-
-class _LinkedCustomHashMap<K, V> extends _CustomHashMap<K, V>
-                                 with _LinkedHashMapMixin<K, V> {
-  _LinkedCustomHashMap(bool equals(K key1, K key2),
-                       int hashCode(K key),
-                       bool isValidKey(potentialKey))
-      : super(equals, hashCode, isValidKey) {
-    _nextEntry = _previousEntry = this;
-  }
-  Set<K> _newKeySet() =>
-      new _LinkedCustomHashSet<K>(_equals, _hashCode, _validKey);
-}
-
-
 patch class LinkedHashSet<E> {
   /* patch */ factory LinkedHashSet({ bool equals(E e1, E e2),
                                       int hashCode(E e),
@@ -1067,17 +957,13 @@
     if (isValidKey == null) {
       if (hashCode == null) {
         if (equals == null) {
-          if (LinkedHashMap._useCompactCached) {
-            return new _CompactLinkedHashSet<E>();
-          } else {
-            return new _LinkedHashSet<E>();
-          }
+          return new _CompactLinkedHashSet<E>();
         }
         hashCode = _defaultHashCode;
       } else {
         if (identical(identityHashCode, hashCode) &&
             identical(identical, equals)) {
-          return new _LinkedIdentityHashSet<E>();
+          return new _CompactLinkedIdentityHashSet<E>();
         }
         if (equals == null) {
           equals = _defaultEquals;
@@ -1091,196 +977,9 @@
         equals = _defaultEquals;
       }
     }
-    return new _LinkedCustomHashSet<E>(equals, hashCode, isValidKey);
+    return new _CompactLinkedCustomHashSet<E>(equals, hashCode, isValidKey);
   }
 
-  /* patch */ factory LinkedHashSet.identity() = _LinkedIdentityHashSet<E>;
-}
-
-class _LinkedHashSetEntry extends _HashSetEntry {
-  /// Links this element into a double-linked list of elements of a hash set.
-  /// The hash set object itself is used as the head entry of the list, so
-  /// the field is typed as "var".
-  /// Both links are initialized to `this` when the object is created.
-  var _nextEntry;
-  var _previousEntry;
-  _LinkedHashSetEntry(var key, int hashCode, _LinkedHashSetEntry next,
-                      this._previousEntry, this._nextEntry)
-      : super(key, hashCode, next) {
-    _previousEntry._nextEntry = _nextEntry._previousEntry = this;
-  }
-
-  _LinkedHashSetEntry remove() {
-    _previousEntry._nextEntry = _nextEntry;
-    _nextEntry._previousEntry = _previousEntry;
-    _nextEntry = _previousEntry = this;
-    return super.remove();
-  }
-}
-
-class _LinkedHashSet<E> extends _HashSet<E>
-                        implements LinkedHashSet<E> {
-  /// Holds a double linked list of the element entries of the set in
-  /// insertion order.
-  /// The fields have the same names as the ones in [_LinkedHashSetEntry],
-  /// allowing this object to be used as the head entry of the list.
-  /// The fields are initialized to `this` when created, representing the
-  /// empty list that only contains the head entry.
-  var _nextEntry;
-  var _previousEntry;
-
-  _LinkedHashSet() {
-    _nextEntry = _previousEntry = this;
-  }
-
-  // Iterable.
-
-  Iterator<E> get iterator => new _LinkedHashSetIterator<E>(this);
-
-  void forEach(void action(E element)) {
-    var cursor = _nextEntry;
-    int modificationCount = _modificationCount;
-    while (!identical(cursor, this)) {
-      _LinkedHashSetEntry entry = cursor;
-      action(entry.key);
-      if (_modificationCount != modificationCount) {
-        throw new ConcurrentModificationError(this);
-      }
-      cursor = entry._nextEntry;
-    }
-  }
-
-  E get first {
-    if (identical(_nextEntry, this)) {
-      throw new StateError("No elements");
-    }
-    _LinkedHashSetEntry entry = _nextEntry;
-    return entry.key;
-  }
-
-  E get last {
-    if (identical(_previousEntry, this)) {
-      throw new StateError("No elements");
-    }
-    _LinkedHashSetEntry entry = _previousEntry;
-    return entry.key;
-  }
-
-  // Set.
-
-  void _filterWhere(bool test(E element), bool removeMatching) {
-    var cursor = _nextEntry;
-    while (!identical(cursor, this)) {
-      _LinkedHashSetEntry entry = cursor;
-      int modificationCount = _modificationCount;
-      bool testResult = test(entry.key);
-      if (modificationCount != _modificationCount) {
-        throw new ConcurrentModificationError(this);
-      }
-      cursor = entry._nextEntry;
-      if (testResult == removeMatching) {
-        _remove(entry.key, entry.hashCode);
-      }
-    }
-  }
-
-  void _addEntry(E key, int hashCode, int index) {
-    _buckets[index] =
-        new _LinkedHashSetEntry(key, hashCode, _buckets[index],
-                                _previousEntry, this);
-    int newElements = _elementCount + 1;
-    _elementCount = newElements;
-    int length = _buckets.length;
-    // If we end up with more than 75% non-empty entries, we
-    // resize the backing store.
-    if ((newElements << 2) > ((length << 1) + length)) _resize();
-    _modificationCount = (_modificationCount + 1) & _MODIFICATION_COUNT_MASK;
-  }
-
-  void clear() {
-    _nextEntry = _previousEntry = this;
-    super.clear();
-  }
-
-  HashSet<E> _newSet() => new _LinkedHashSet<E>();
-}
-
-class _LinkedIdentityHashSet<E> extends _LinkedHashSet<E> {
-  int _hashCode(e) => identityHashCode(e);
-  bool _equals(e1, e2) => identical(e1, e2);
-  HashSet<E> _newSet() => new _LinkedIdentityHashSet<E>();
-}
-
-class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> {
-  final _Equality<E> _equality;
-  final _Hasher<E> _hasher;
-  final _Predicate _validKey;
-
-  _LinkedCustomHashSet(this._equality, this._hasher, bool validKey(Object o))
-      : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
-
-  bool _equals(e1, e2) => _equality(e1, e2);
-
-  int _hashCode(e) => _hasher(e);
-
-  bool contains(Object o) {
-    if (!_validKey(o)) return false;
-    return super.contains(o);
-  }
-
-  E lookup(Object o) {
-    if (!_validKey(o)) return null;
-    return super.lookup(o);
-  }
-
-  bool remove(Object o) {
-    if (!_validKey(o)) return false;
-    return super.remove(o);
-  }
-
-  bool containsAll(Iterable<Object> elements) {
-    for (Object element in elements) {
-      if (!_validKey(element) || !this.contains(element)) return false;
-    }
-    return true;
-  }
-
-  void removeAll(Iterable<Object> elements) {
-    for (Object element in elements) {
-      if (_validKey(element)) {
-        super._remove(element, _hasher(element));
-      }
-    }
-  }
-
-  HashSet<E> _newSet() =>
-      new _LinkedCustomHashSet<E>(_equality, _hasher, _validKey);
-}
-
-class _LinkedHashSetIterator<E> implements Iterator<E> {
-  final _LinkedHashSet _set;
-  final int _modificationCount;
-  var _next;
-  E _current;
-
-  _LinkedHashSetIterator(_LinkedHashSet hashSet)
-      : _set = hashSet,
-        _modificationCount = hashSet._modificationCount,
-        _next = hashSet._nextEntry;
-
-  bool moveNext() {
-    if (_modificationCount != _set._modificationCount) {
-      throw new ConcurrentModificationError(_set);
-    }
-    if (identical(_set, _next)) {
-      _current = null;
-      return false;
-    }
-    _LinkedHashSetEntry entry = _next;
-    _current = entry.key;
-    _next = entry._nextEntry;
-    return true;
-  }
-
-  E get current => _current;
+  /* patch */ factory LinkedHashSet.identity() =
+      _CompactLinkedIdentityHashSet<E>;
 }
diff --git a/runtime/lib/compact_hash.dart b/runtime/lib/compact_hash.dart
index 8e3fce9..f093b49 100644
--- a/runtime/lib/compact_hash.dart
+++ b/runtime/lib/compact_hash.dart
@@ -17,14 +17,14 @@
   // The length of _index is twice the number of entries in _data, and both
   // are doubled when _data is full. Thus, _index will have a max load factor
   // of 1/2, which enables one more bit to be used for the hash.
-  // TODO(koda): Consider growing _data by factor sqrt(2), twice as often. 
+  // TODO(koda): Consider growing _data by factor sqrt(2), twice as often.
   static const int _INITIAL_INDEX_BITS = 3;
   static const int _INITIAL_INDEX_SIZE = 1 << (_INITIAL_INDEX_BITS + 1);
-  
+
   // Unused and deleted entries are marked by 0 and 1, respectively.
   static const int _UNUSED_PAIR = 0;
   static const int _DELETED_PAIR = 1;
-  
+
   // Cached in-place mask for the hash pattern component. On 32-bit, the top
   // bits are wasted to avoid Mint allocation.
   // TODO(koda): Reclaim the bits by making the compiler treat hash patterns
@@ -46,14 +46,14 @@
     return ((i << 1) + i) & sizeMask;
   }
   static int _nextProbe(int i, int sizeMask) => (i + 1) & sizeMask;
-  
+
   // Fixed-length list of keys (set) or key/value at even/odd indices (map).
   List _data;
   // Length of _data that is used (i.e., keys + values for a map).
   int _usedData = 0;
   // Number of deleted keys.
   int _deletedKeys = 0;
-  
+
   // A self-loop is used to mark a deleted key or value.
   static bool _isDeleted(List data, Object keyOrValue) =>
       identical(keyOrValue, data);
@@ -68,24 +68,34 @@
       !identical(_data, oldData) || (_checkSum != oldCheckSum);
 }
 
+class _OperatorEqualsAndHashCode {
+  int _hashCode(e) => e.hashCode;
+  bool _equals(e1, e2) => e1 == e2;
+}
+
+class _IdenticalAndIdentityHashCode {
+  int _hashCode(e) => identityHashCode(e);
+  bool _equals(e1, e2) => identical(e1, e2);
+}
+
 // Map with iteration in insertion order (hence "Linked"). New keys are simply
 // appended to _data.
 class _CompactLinkedHashMap<K, V>
-    extends MapBase<K, V> with _HashBase
-    implements HashMap<K, V>, LinkedHashMap<K, V> {
+    extends MapBase<K, V> with _HashBase, _OperatorEqualsAndHashCode
+    implements LinkedHashMap<K, V> {
 
   _CompactLinkedHashMap() {
     assert(_HashBase._UNUSED_PAIR == 0);
     _index = new Uint32List(_HashBase._INITIAL_INDEX_SIZE);
     _data = new List(_HashBase._INITIAL_INDEX_SIZE);
   }
-  
+
   int get length => (_usedData >> 1) - _deletedKeys;
   bool get isEmpty => length == 0;
   bool get isNotEmpty => !isEmpty;
-  
+
   void _rehash() {
-    if ((_deletedKeys << 1) > _usedData) {
+    if ((_deletedKeys << 2) > _usedData) {
       // TODO(koda): Consider shrinking.
       // TODO(koda): Consider in-place compaction and more costly CME check.
       _init(_index.length, _hashMask, _data, _usedData);
@@ -94,7 +104,7 @@
       _init(_index.length << 1, _hashMask >> 1, _data, _usedData);
     }
   }
-  
+
   void clear() {
     if (!isEmpty) {
       _init(_index.length, _hashMask);
@@ -120,7 +130,7 @@
       }
     }
   }
-  
+
   void _insert(K key, V value, int hashPattern, int i) {
     if (_usedData == _data.length) {
       _rehash();
@@ -134,7 +144,7 @@
       _data[_usedData++] = value;
     }
   }
-  
+
   // If key is present, returns the index of the value in _data, else returns
   // the negated insertion point in _index.
   int _findValueOrInsertPoint(K key, int fullHash, int hashPattern, int size) {
@@ -152,7 +162,7 @@
         final int entry = hashPattern ^ pair;
         if (entry < maxEntries) {
           final int d = entry << 1;
-          if (key == _data[d]) {
+          if (_equals(key, _data[d])) {
             return d + 1;
           }
         }
@@ -162,11 +172,11 @@
     }
     return firstDeleted >= 0 ? -firstDeleted : -i;
   }
-  
+
   void operator[]=(K key, V value) {
     final int size = _index.length;
     final int sizeMask = size - 1;
-    final int fullHash = key.hashCode;
+    final int fullHash = _hashCode(key);
     final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
     final int d = _findValueOrInsertPoint(key, fullHash, hashPattern, size);
     if (d > 0) {
@@ -176,12 +186,12 @@
       _insert(key, value, hashPattern, i);
     }
   }
-  
+
   V putIfAbsent(K key, V ifAbsent()) {
     final int size = _index.length;
     final int sizeMask = size - 1;
     final int maxEntries = size >> 1;
-    final int fullHash = key.hashCode;
+    final int fullHash = _hashCode(key);
     final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
     final int d = _findValueOrInsertPoint(key, fullHash, hashPattern, size);
     if (d > 0) {
@@ -199,12 +209,12 @@
     }
     return value;
   }
-  
+
   V remove(Object key) {
     final int size = _index.length;
     final int sizeMask = size - 1;
     final int maxEntries = size >> 1;
-    final int fullHash = key.hashCode;
+    final int fullHash = _hashCode(key);
     final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
     int i = _HashBase._firstProbe(fullHash, sizeMask);
     int pair = _index[i];
@@ -213,7 +223,7 @@
         final int entry = hashPattern ^ pair;
         if (entry < maxEntries) {
           final int d = entry << 1;
-          if (key == _data[d]) {
+          if (_equals(key, _data[d])) {
             _index[i] = _HashBase._DELETED_PAIR;
             _HashBase._setDeletedAt(_data, d);
             V value = _data[d + 1];
@@ -228,13 +238,13 @@
     }
     return null;
   }
-  
+
   // If key is absent, return _data (which is never a value).
   Object _getValueOrData(Object key) {
     final int size = _index.length;
     final int sizeMask = size - 1;
     final int maxEntries = size >> 1;
-    final int fullHash = key.hashCode;
+    final int fullHash = _hashCode(key);
     final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
     int i = _HashBase._firstProbe(fullHash, sizeMask);
     int pair = _index[i];
@@ -243,7 +253,7 @@
         final int entry = hashPattern ^ pair;
         if (entry < maxEntries) {
           final int d = entry << 1;
-          if (key == _data[d]) {
+          if (_equals(key, _data[d])) {
             return _data[d + 1];
           }
         }
@@ -253,16 +263,17 @@
     }
     return _data;
   }
-  
+
   bool containsKey(Object key) => !identical(_data, _getValueOrData(key));
-  
+
   V operator[](Object key) {
     var v = _getValueOrData(key);
     return identical(_data, v) ? null : v;
   }
-  
+
   bool containsValue(Object value) {
     for (var v in values) {
+      // Spec. says this should always use "==", also for identity maps, etc.
       if (v == value) {
         return true;
       }
@@ -285,6 +296,28 @@
       new _CompactIterable<V>(this, _data, _usedData, -1, 2);
 }
 
+class _CompactLinkedIdentityHashMap<K, V>
+    extends _CompactLinkedHashMap<K, V> with _IdenticalAndIdentityHashCode {
+}
+
+class _CompactLinkedCustomHashMap<K, V>
+    extends _CompactLinkedHashMap<K, V> {
+  final _equality;
+  final _hasher;
+  final _validKey;
+
+  // TODO(koda): Ask gbracha why I cannot have fields _equals/_hashCode.
+  int _hashCode(e) => _hasher(e);
+  bool _equals(e1, e2) => _equality(e1, e2);
+
+  bool containsKey(Object o) => _validKey(o) ? super.containsKey(o) : false;
+  V operator[](Object o) => _validKey(o) ? super[o] : null;
+  V remove(Object o) => _validKey(o) ? super.remove(o) : null;
+
+  _CompactLinkedCustomHashMap(this._equality, this._hasher, validKey)
+      : _validKey = (validKey != null) ? validKey : new _TypeTest<K>().test;
+}
+
 // Iterates through _data[_offset + _step], _data[_offset + 2*_step], ...
 // and checks for concurrent modification.
 class _CompactIterable<E> extends IterableBase<E> {
@@ -335,9 +368,9 @@
 }
 
 // Set implementation, analogous to _CompactLinkedHashMap.
-class _CompactLinkedHashSet<K>
-    extends SetBase<K> with _HashBase
-    implements LinkedHashSet<K> {
+class _CompactLinkedHashSet<E>
+    extends SetBase<E> with _HashBase, _OperatorEqualsAndHashCode
+    implements LinkedHashSet<E> {
 
   _CompactLinkedHashSet() {
     assert(_HashBase._UNUSED_PAIR == 0);
@@ -354,13 +387,13 @@
       _init(_index.length << 1, _hashMask >> 1, _data, _usedData);
     }
   }
-  
+
   void clear() {
     if (!isEmpty) {
       _init(_index.length, _hashMask);
     }
   }
-  
+
   void _init(int size, int hashMask, [List oldData, int oldUsed]) {
     _index = new Uint32List(size);
     _hashMask = hashMask;
@@ -377,11 +410,11 @@
     }
   }
 
-  bool add(K key) {
+  bool add(E key) {
     final int size = _index.length;
     final int sizeMask = size - 1;
     final int maxEntries = size >> 1;
-    final int fullHash = key.hashCode;
+    final int fullHash = _hashCode(key);
     final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
     int i = _HashBase._firstProbe(fullHash, sizeMask);
     int firstDeleted = -1;
@@ -393,7 +426,7 @@
         }
       } else {
         final int d = hashPattern ^ pair;
-        if (d < maxEntries && key == _data[d]) {
+        if (d < maxEntries && _equals(key, _data[d])) {
           return false;
         }
       }
@@ -412,48 +445,48 @@
     }
     return true;
   }
-  
+
   // If key is absent, return _data (which is never a value).
   Object _getKeyOrData(Object key) {
     final int size = _index.length;
     final int sizeMask = size - 1;
     final int maxEntries = size >> 1;
-    final int fullHash = key.hashCode;
+    final int fullHash = _hashCode(key);
     final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
     int i = _HashBase._firstProbe(fullHash, sizeMask);
     int pair = _index[i];
     while (pair != _HashBase._UNUSED_PAIR) {
       if (pair != _HashBase._DELETED_PAIR) {
         final int d = hashPattern ^ pair;
-        if (d < maxEntries && key == _data[d]) {
+        if (d < maxEntries && _equals(key, _data[d])) {
           return _data[d];  // Note: Must return the existing key.
         }
       }
       i = _HashBase._nextProbe(i, sizeMask);
       pair = _index[i];
     }
-    return _data;    
+    return _data;
   }
 
-  K lookup(Object key) {
+  E lookup(Object key) {
     var k = _getKeyOrData(key);
     return identical(_data, k) ? null : k;
   }
-  
+
   bool contains(Object key) => !identical(_data, _getKeyOrData(key));
 
   bool remove(Object key) {
     final int size = _index.length;
     final int sizeMask = size - 1;
     final int maxEntries = size >> 1;
-    final int fullHash = key.hashCode;
+    final int fullHash = _hashCode(key);
     final int hashPattern = _HashBase._hashPattern(fullHash, _hashMask, size);
     int i = _HashBase._firstProbe(fullHash, sizeMask);
     int pair = _index[i];
     while (pair != _HashBase._UNUSED_PAIR) {
       if (pair != _HashBase._DELETED_PAIR) {
         final int d = hashPattern ^ pair;
-        if (d < maxEntries && key == _data[d]) {
+        if (d < maxEntries && _equals(key, _data[d])) {
           _index[i] = _HashBase._DELETED_PAIR;
           _HashBase._setDeletedAt(_data, d);
           ++_deletedKeys;
@@ -465,9 +498,38 @@
     }
     return false;
   }
-                                                
-  Iterator<K> get iterator =>
-      new _CompactIterator<K>(this, _data, _usedData, -1, 1);
 
-  Set<K> toSet() => new Set<K>()..addAll(this);  
+  Iterator<E> get iterator =>
+      new _CompactIterator<E>(this, _data, _usedData, -1, 1);
+
+  // Returns a set of the same type, although this
+  // is not required by the spec. (For instance, always using an identity set
+  // would be technically correct, albeit surprising.)
+  Set<E> toSet() => new _CompactLinkedHashSet<E>()..addAll(this);
+}
+
+class _CompactLinkedIdentityHashSet<E>
+    extends _CompactLinkedHashSet<E> with _IdenticalAndIdentityHashCode {
+  Set<E> toSet() => new _CompactLinkedIdentityHashSet<E>()..addAll(this);
+}
+
+class _CompactLinkedCustomHashSet<E>
+    extends _CompactLinkedHashSet<E> {
+  final _equality;
+  final _hasher;
+  final _validKey;
+
+  int _hashCode(e) => _hasher(e);
+  bool _equals(e1, e2) => _equality(e1, e2);
+
+  bool contains(Object o) => _validKey(o) ? super.contains(o) : false;
+  E lookup(Object o) => _validKey(o) ? super.lookup(o) : null;
+  bool remove(Object o) => _validKey(o) ? super.remove(o) : false;
+
+  _CompactLinkedCustomHashSet(this._equality, this._hasher, validKey)
+      : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
+
+  Set<E> toSet() =>
+      new _CompactLinkedCustomHashSet<E>(_equality, _hasher, _validKey)
+          ..addAll(this);
 }
diff --git a/runtime/lib/core_patch.dart b/runtime/lib/core_patch.dart
index 5a26fc5..f3f9da3 100644
--- a/runtime/lib/core_patch.dart
+++ b/runtime/lib/core_patch.dart
@@ -36,6 +36,7 @@
   bool isAdding = false;
   bool onListenReceived = false;
   bool isScheduled = false;
+  Completer cancellationCompleter = null;
 
   Stream get stream => controller.stream;
 
@@ -93,6 +94,12 @@
   }
 
   void addError(error, stackTrace) {
+    if ((cancellationCompleter != null) && !cancellationCompleter.isCompleted) {
+      // If the stream has been cancelled, complete the cancellation future
+      // with the error.
+      cancellationCompleter.completeError(error, stackTrace);
+      return;
+    }
     // If stream is cancelled, tell caller to exit the async generator.
     if (!controller.hasListener) return;
     controller.addError(error, stackTrace);
@@ -103,6 +110,11 @@
   }
 
   close() {
+    if ((cancellationCompleter != null) && !cancellationCompleter.isCompleted) {
+      // If the stream has been cancelled, complete the cancellation future
+      // with the error.
+      cancellationCompleter.complete();
+    }
     controller.close();
   }
 
@@ -123,7 +135,14 @@
   }
 
   onCancel() {
-    scheduleGenerator();
+    if (controller.isClosed) {
+      return null;
+    }
+    if (cancellationCompleter == null) {
+      cancellationCompleter = new Completer();
+      scheduleGenerator();
+    }
+    return cancellationCompleter.future;
   }
 }
 
@@ -177,7 +196,7 @@
         yieldEachIterator = (current as Iterable).iterator;
         continue;
       }
-      return true;    
+      return true;
     }
   }
 }
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
index 801ad54..607e29e 100644
--- a/runtime/lib/function.cc
+++ b/runtime/lib/function.cc
@@ -30,7 +30,7 @@
 
 DEFINE_NATIVE_ENTRY(FunctionImpl_equals, 2) {
   const Instance& receiver = Instance::CheckedHandle(
-      isolate, arguments->NativeArgAt(0));
+      zone, arguments->NativeArgAt(0));
   ASSERT(receiver.IsClosure());
   GET_NATIVE_ARGUMENT(Instance, other, arguments->NativeArgAt(1));
   ASSERT(!other.IsNull());
@@ -55,7 +55,7 @@
 
 DEFINE_NATIVE_ENTRY(FunctionImpl_hashCode, 1) {
   const Instance& receiver = Instance::CheckedHandle(
-      isolate, arguments->NativeArgAt(0));
+      zone, arguments->NativeArgAt(0));
   if (receiver.IsClosure()) {
     const Function& func = Function::Handle(Closure::function(receiver));
     // Hash together name, class name and signature.
@@ -77,17 +77,17 @@
 
 DEFINE_NATIVE_ENTRY(FunctionImpl_clone, 1) {
   const Instance& receiver = Instance::CheckedHandle(
-      isolate, arguments->NativeArgAt(0));
+      zone, arguments->NativeArgAt(0));
   ASSERT(receiver.IsClosure());
   if (receiver.IsClosure()) {
     const Function& func =
-        Function::Handle(isolate, Closure::function(receiver));
+        Function::Handle(zone, Closure::function(receiver));
     const Context& ctx =
-        Context::Handle(isolate, Closure::context(receiver));
+        Context::Handle(zone, Closure::context(receiver));
     Context& cloned_ctx =
-        Context::Handle(isolate, Context::New(ctx.num_variables()));
-    cloned_ctx.set_parent(Context::Handle(isolate, ctx.parent()));
-    Object& inst = Object::Handle(isolate);
+        Context::Handle(zone, Context::New(ctx.num_variables()));
+    cloned_ctx.set_parent(Context::Handle(zone, ctx.parent()));
+    Object& inst = Object::Handle(zone);
     for (int i = 0; i < ctx.num_variables(); i++) {
       inst = ctx.At(i);
       cloned_ctx.SetAt(i, inst);
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 23b942a..9f78df3 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -265,7 +265,6 @@
   char* utf8_package_root = NULL;
   if (!package_root.IsNull()) {
     const intptr_t len = Utf8::Length(package_root);
-    Zone* zone = isolate->current_zone();
     utf8_package_root = zone->Alloc<char>(len + 1);
     package_root.ToUTF8(reinterpret_cast<uint8_t*>(utf8_package_root), len);
     utf8_package_root[len] = '\0';
diff --git a/runtime/lib/linked_hash_map.cc b/runtime/lib/linked_hash_map.cc
index 90d92af..b69910a 100644
--- a/runtime/lib/linked_hash_map.cc
+++ b/runtime/lib/linked_hash_map.cc
@@ -14,7 +14,7 @@
 namespace dart {
 
 DEFINE_FLAG(bool, use_internal_hash_map, false, "Use internal hash map.");
-DEFINE_FLAG(bool, use_compact_hash, true, "Use compact hash map and set.");
+
 
 DEFINE_NATIVE_ENTRY(LinkedHashMap_allocate, 1) {
   const TypeArguments& type_arguments =
@@ -91,14 +91,7 @@
 
 
 DEFINE_NATIVE_ENTRY(LinkedHashMap_useInternal, 0) {
-  ASSERT(!(FLAG_use_internal_hash_map && FLAG_use_compact_hash));
   return Bool::Get(FLAG_use_internal_hash_map).raw();
 }
 
-
-DEFINE_NATIVE_ENTRY(LinkedHashMap_useCompact, 0) {
-  ASSERT(!(FLAG_use_internal_hash_map && FLAG_use_compact_hash));
-  return Bool::Get(FLAG_use_compact_hash).raw();
-}
-
 }  // namespace dart
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index ac62a2e..7fb8fd0 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -73,17 +73,18 @@
   // Only generative constructors can have initializing formals.
   if (!func.IsGenerativeConstructor()) return;
 
-  Isolate* isolate = Isolate::Current();
-  const Class& cls = Class::Handle(isolate, func.Owner());
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  const Class& cls = Class::Handle(zone, func.Owner());
   const Error& error = Error::Handle(
-      isolate, cls.EnsureIsFinalized(Isolate::Current()));
+      zone, cls.EnsureIsFinalized(thread->isolate()));
   if (!error.IsNull()) {
     Exceptions::PropagateError(error);
     UNREACHABLE();
   }
   if (!func.HasCode()) {
     const Error& error = Error::Handle(
-        isolate, Compiler::CompileFunction(isolate, func));
+        zone, Compiler::CompileFunction(thread, func));
     if (!error.IsNull()) {
       Exceptions::PropagateError(error);
       UNREACHABLE();
@@ -1365,6 +1366,13 @@
   Function& function = Function::Handle();
   bool callable = closure.IsCallable(&function);
   if (callable) {
+    if (function.IsImplicitClosureFunction()) {
+      // The VM uses separate Functions for tear-offs, but the mirrors consider
+      // the tear-offs to be the same as the torn-off methods. Avoid handing out
+      // a reference to the tear-off here to avoid a special case in the
+      // the equality test.
+      function = function.parent_function();
+    }
     return CreateMethodMirror(function, Instance::null_instance());
   }
   return Instance::null();
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 3113f94..221dd5f 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -158,15 +158,15 @@
 
 DEFINE_NATIVE_ENTRY(Object_instanceOf, 5) {
   const Instance& instance =
-      Instance::CheckedHandle(isolate, arguments->NativeArgAt(0));
+      Instance::CheckedHandle(zone, arguments->NativeArgAt(0));
   // Instantiator at position 1 is not used. It is passed along so that the call
   // can be easily converted to an optimized implementation. Instantiator is
   // used to populate the subtype cache.
   const TypeArguments& instantiator_type_arguments =
-      TypeArguments::CheckedHandle(isolate, arguments->NativeArgAt(2));
+      TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(2));
   const AbstractType& type =
-      AbstractType::CheckedHandle(isolate, arguments->NativeArgAt(3));
-  const Bool& negate = Bool::CheckedHandle(isolate, arguments->NativeArgAt(4));
+      AbstractType::CheckedHandle(zone, arguments->NativeArgAt(3));
+  const Bool& negate = Bool::CheckedHandle(zone, arguments->NativeArgAt(4));
   ASSERT(type.IsFinalized());
   ASSERT(!type.IsMalformed());
   ASSERT(!type.IsMalbounded());
@@ -176,7 +176,7 @@
     WarnOnJSIntegralNumTypeTest(instance, instantiator_type_arguments, type);
   }
 
-  Error& bound_error = Error::Handle(isolate, Error::null());
+  Error& bound_error = Error::Handle(zone, Error::null());
   const bool is_instance_of = instance.IsInstanceOf(type,
                                                     instantiator_type_arguments,
                                                     &bound_error);
@@ -198,7 +198,7 @@
     ASSERT(caller_frame != NULL);
     const intptr_t location = caller_frame->GetTokenPos();
     String& bound_error_message = String::Handle(
-        isolate, String::New(bound_error.ToErrorCString()));
+        zone, String::New(bound_error.ToErrorCString()));
     Exceptions::CreateAndThrowTypeError(
         location, Symbols::Empty(), Symbols::Empty(),
         Symbols::Empty(), bound_error_message);
diff --git a/runtime/lib/regexp.cc b/runtime/lib/regexp.cc
index ba26324..0adb8d2 100644
--- a/runtime/lib/regexp.cc
+++ b/runtime/lib/regexp.cc
@@ -8,6 +8,7 @@
 #include "vm/native_entry.h"
 #include "vm/object.h"
 #include "vm/regexp_parser.h"
+#include "vm/thread.h"
 
 #include "lib/regexp_jsc.h"
 
@@ -39,7 +40,7 @@
   }
 
   // Create a JSRegExp object containing only the initial parameters.
-  return RegExpEngine::CreateJSRegExp(isolate,
+  return RegExpEngine::CreateJSRegExp(zone,
                                       pattern,
                                       multi_line,
                                       ignore_case);
@@ -102,7 +103,7 @@
   ASSERT(!fn.IsNull());
 
   // And finally call the generated code.
-  return IRRegExpMacroAssembler::Execute(fn, str, start_index, isolate);
+  return IRRegExpMacroAssembler::Execute(fn, str, start_index, zone);
 }
 
 }  // namespace dart
diff --git a/runtime/lib/string.cc b/runtime/lib/string.cc
index c72f14f..9d4137d 100644
--- a/runtime/lib/string.cc
+++ b/runtime/lib/string.cc
@@ -57,14 +57,12 @@
     Exceptions::ThrowArgumentError(end_obj);
   }
 
-  Zone* zone = isolate->current_zone();
-
   // Unbox the array and determine the maximum element width.
   bool is_one_byte_string = true;
   intptr_t array_len = end - start;
   intptr_t utf16_len = array_len;
   int32_t* utf32_array = zone->Alloc<int32_t>(array_len);
-  Instance& index_object = Instance::Handle(isolate);
+  Instance& index_object = Instance::Handle(zone);
   for (intptr_t i = 0; i < array_len; i++) {
     index_object ^= a.At(start + i);
     if (!index_object.IsSmi()) {
@@ -110,7 +108,7 @@
   ASSERT(string.IsTwoByteString() || string.IsExternalTwoByteString());
   // Maybe do loop unrolling, and handle two uint16_t in a single uint32_t
   // operation.
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   uint16_t result = 0;
   if (string.IsTwoByteString()) {
     for (intptr_t i = start; i < end; i++) {
@@ -172,7 +170,7 @@
   GET_NON_NULL_NATIVE_ARGUMENT(Bool, is_onebyte_obj, arguments->NativeArgAt(3));
 
   intptr_t len = matches_growable.Length();
-  const Array& matches = Array::Handle(isolate, matches_growable.data());
+  const Array& matches = Array::Handle(zone, matches_growable.data());
 
   const intptr_t length = length_obj.Value();
   if (length < 0) {
@@ -190,13 +188,13 @@
   }
 
   const intptr_t base_length = base.Length();
-  String& result = String::Handle(isolate);
+  String& result = String::Handle(zone);
   if (is_onebyte) {
     result ^= OneByteString::New(length, Heap::kNew);
   } else {
     result ^= TwoByteString::New(length, Heap::kNew);
   }
-  Instance& object = Instance::Handle(isolate);
+  Instance& object = Instance::Handle(zone);
   intptr_t write_index = 0;
   for (intptr_t i = 0; i < len; i++) {
     object ^= matches.At(i);
@@ -266,16 +264,16 @@
 
 // This is high-performance code.
 DEFINE_NATIVE_ENTRY(OneByteString_splitWithCharCode, 2) {
-  const String& receiver = String::CheckedHandle(isolate,
+  const String& receiver = String::CheckedHandle(zone,
                                                  arguments->NativeArgAt(0));
   ASSERT(receiver.IsOneByteString());
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_split_code, arguments->NativeArgAt(1));
   const intptr_t len = receiver.Length();
   const intptr_t split_code = smi_split_code.Value();
   const GrowableObjectArray& result = GrowableObjectArray::Handle(
-      isolate,
+      zone,
       GrowableObjectArray::New(16, Heap::kNew));
-  String& str = String::Handle(isolate);
+  String& str = String::Handle(zone);
   intptr_t start = 0;
   intptr_t i = 0;
   for (; i < len; i++) {
@@ -449,7 +447,7 @@
     if (end > Smi::Value(TypedDataView::Length(list))) {
       Exceptions::ThrowArgumentError(end_obj);
     }
-    const Instance& data_obj = Instance::Handle(isolate,
+    const Instance& data_obj = Instance::Handle(zone,
                                                 TypedDataView::Data(list));
     intptr_t data_offset = Smi::Value(TypedDataView::OffsetInBytes(list));
     if (data_obj.IsTypedData()) {
@@ -466,7 +464,7 @@
     if (end > array.Length()) {
       Exceptions::ThrowArgumentError(end_obj);
     }
-    const String& string = String::Handle(isolate,
+    const String& string = String::Handle(zone,
                                           TwoByteString::New(length, space));
     for (int i = 0; i < length; i++) {
       intptr_t value =
@@ -479,7 +477,7 @@
     if (end > array.Length()) {
       Exceptions::ThrowArgumentError(end_obj);
     }
-    const String& string = String::Handle(isolate,
+    const String& string = String::Handle(zone,
                                           TwoByteString::New(length, space));
     for (int i = 0; i < length; i++) {
       intptr_t value =
@@ -608,7 +606,7 @@
   const String& result = isLatin1.value()
       ? String::Handle(OneByteString::New(length_value, Heap::kNew))
       : String::Handle(TwoByteString::New(length_value, Heap::kNew));
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
 
   uint16_t* data_position = reinterpret_cast<uint16_t*>(codeUnits.DataAddr(0));
   String::Copy(result, 0, data_position, length_value);
diff --git a/runtime/observatory/lib/src/elements/heap_profile.html b/runtime/observatory/lib/src/elements/heap_profile.html
index 3d0bfec..460a021 100644
--- a/runtime/observatory/lib/src/elements/heap_profile.html
+++ b/runtime/observatory/lib/src/elements/heap_profile.html
@@ -57,9 +57,11 @@
     <nav-refresh callback="{{ resetAccumulator }}" label="Reset Accumulator"></nav-refresh>
     <nav-refresh callback="{{ refreshGC }}" label="GC"></nav-refresh>
     <nav-refresh callback="{{ refresh }}"></nav-refresh>
+    <!-- Disabled dartbug.com/22970
     <div class="nav-option">
       <input type="checkbox" checked="{{ autoRefresh }}">Auto-refresh on GC
     </div>
+    -->
     <nav-control></nav-control>
   </nav-bar>
   <div class="content">
diff --git a/runtime/observatory/lib/src/elements/library_ref.html b/runtime/observatory/lib/src/elements/library_ref.html
index d73050a..30272a4 100644
--- a/runtime/observatory/lib/src/elements/library_ref.html
+++ b/runtime/observatory/lib/src/elements/library_ref.html
@@ -2,14 +2,14 @@
 <link rel="import" href="service_ref.html">
 
 <polymer-element name="library-ref" extends="service-ref">
-  <template><link rel="stylesheet" href="css/shared.css">
-    <template if="{{ nameIsEmpty }}">
-      <a on-click="{{ goto }}" _href="{{ url }}">unnamed</a>
-    </template>
-    <template if="{{ !nameIsEmpty }}">
-      <a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a>
-    </template>
-  </template>
+  <template><link rel="stylesheet" href="css/shared.css"><!--
+    --><template if="{{ nameIsEmpty }}"><!--
+      --><a on-click="{{ goto }}" _href="{{ url }}">unnamed</a><!--
+    --></template><!--
+    --><template if="{{ !nameIsEmpty }}"><!--
+      --><a on-click="{{ goto }}" _href="{{ url }}">{{ name }}</a><!--
+    --></template><!--
+  --></template>
 </polymer-element>
 
-<script type="application/dart" src="library_ref.dart"></script>
\ No newline at end of file
+<script type="application/dart" src="library_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/observatory_element.dart b/runtime/observatory/lib/src/elements/observatory_element.dart
index 46f1ef5..da2735e 100644
--- a/runtime/observatory/lib/src/elements/observatory_element.dart
+++ b/runtime/observatory/lib/src/elements/observatory_element.dart
@@ -164,7 +164,18 @@
 
   void clearShadowRoot() {
     // Remove all non-style elements.
-    shadowRoot.children.removeWhere((e) => e is! StyleElement);
+    // Have to do the following because removeWhere doesn't work on DOM child
+    // node lists. i.e. removeWhere((e) => e is! StyleElement);
+    var styleElements = [];
+    for (var child in shadowRoot.children) {
+      if (child is StyleElement) {
+        styleElements.add(child);
+      }
+    }
+    shadowRoot.children.clear();
+    for (var style in styleElements) {
+      shadowRoot.children.add(style);
+    }
   }
 
   void insertTextSpanIntoShadowRoot(String text) {
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 73ee457..2acb390 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -7,20 +7,105 @@
 import 'dart:async';
 import 'dart:html';
 import 'observatory_element.dart';
+import 'service_ref.dart';
 import 'package:observatory/service.dart';
 import 'package:polymer/polymer.dart';
 
 const nbsp = "\u00A0";
 
-class Annotation {
+void addInfoBox(content, infoBox) {
+  infoBox.style.position = 'absolute';
+  infoBox.style.padding = '1em';
+  infoBox.style.border = 'solid black 2px';
+  infoBox.style.zIndex = '10';
+  infoBox.style.backgroundColor = 'white';
+
+  infoBox.style.display = 'none';  // Initially hidden.
+
+  var show = false;
+  content.onClick.listen((event) {
+    show = !show;
+    infoBox.style.display = show ? 'block' : 'none';
+  });
+
+  // Causes infoBox to be positioned relative to the bottom-left of content.
+  content.style.display = 'inline-block';
+  content.append(infoBox);
+}
+
+abstract class Annotation {
   int line;
   int columnStart;
   int columnStop;
-  String title;
+
+  void applyStyleTo(element);
+}
+
+class CurrentExecutionAnnotation extends Annotation {
+  void applyStyleTo(element) {
+    if (element == null) {
+      return;  // TODO(rmacnak): Handling overlapping annotations.
+    }
+    element.classes.add("currentCol");
+    element.title = "Current execution";
+  }
+}
+
+class CallSiteAnnotation extends Annotation {
+  CallSite callSite;
+
+  Element row() {
+    var e = new DivElement();
+    e.style.display = "table-row";
+    return e;
+  }
+
+  Element cell(content) {
+    var e = new DivElement();
+    e.style.display = "table-cell";
+    e.style.padding = "3px";
+    if (content is String) e.text = content;
+    if (content is Element) e.children.add(content);
+    return e;
+  }
+
+  Element serviceRef(object) {
+    AnyServiceRefElement e = new Element.tag("any-service-ref");
+    e.ref = object;
+    return e;
+  }
+
+  Element entriesTable() {
+    var e = new DivElement();
+    e.style.display = "table";
+    e.style.color = "#333";
+    e.style.font = "400 14px 'Montserrat', sans-serif";
+
+    var r = row();
+    r.append(cell("Container"));
+    r.append(cell("Count"));
+    r.append(cell("Target"));
+    e.append(r);
+
+    for (var entry in callSite.entries) {
+      var r = row();
+      r.append(cell(serviceRef(entry.receiverContainer)));
+      r.append(cell(entry.count.toString()));
+      r.append(cell(serviceRef(entry.target)));
+      e.append(r);
+    }
+
+    return e;
+  }
 
   void applyStyleTo(element) {
-    element.classes.add("currentCol");
-    element.title = title;
+    if (element == null) {
+      return;  // TODO(rmacnak): Handling overlapping annotations.
+    }
+    element.style.fontWeight = "bold";
+    element.title = "Call site: ${callSite.name}";
+
+    addInfoBox(element, entriesTable());
   }
 }
 
@@ -150,15 +235,29 @@
 
     annotations.clear();
     if (currentLine != null) {
-      var a = new Annotation();
+      var a = new CurrentExecutionAnnotation();
       a.line = currentLine;
       a.columnStart = currentCol;
       a.columnStop = currentCol + 1;
-      a.title = "Point of interest";
       annotations.add(a);
     }
 
-    // TODO(rmacnak): Call site data.
+    for (var callSite in script.callSites) {
+      var a = new CallSiteAnnotation();
+      a.line = callSite.line;
+      a.columnStart = callSite.column - 1;  // Call site is 1-origin.
+      var tokenLength = callSite.name.length;  // Approximate.
+      a.columnStop = a.columnStart + tokenLength;
+      a.callSite = callSite;
+      annotations.add(a);
+    }
+
+    annotations.sort((a, b) {
+      if (a.line == b.line) {
+        return a.columnStart.compareTo(b.columnStart);
+      }
+      return a.line.compareTo(b.line);
+    });
   }
 
   Element linesTable() {
@@ -250,8 +349,13 @@
       var position = 0;
       consumeUntil(var stop) {
         if (stop <= position) {
-          return;  // Empty gap between annotations/boundries.
+          return null;  // Empty gap between annotations/boundries.
         }
+        if (stop > line.text.length) {
+          // Approximated token length can run past the end of the line.
+          stop = line.text.length;
+        }
+
         var chunk = line.text.substring(position, stop);
         var chunkNode = span(chunk);
         e.append(chunkNode);
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 2bd63a2..4a006d2 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -293,26 +293,30 @@
   String get id;
   Isolate get isolate;
 
+  Future refreshCoverage() {
+    return refreshCallSiteData();
+  }
+
   /// Default handler for coverage data.
-  void processCoverageData(List coverageData) {
+  void processCallSiteData(List coverageData) {
     coverageData.forEach((scriptCoverage) {
       assert(scriptCoverage['script'] != null);
-      scriptCoverage['script']._processHits(scriptCoverage['hits']);
+      scriptCoverage['script']._processCallSites(scriptCoverage['callSites']);
     });
   }
 
-  Future refreshCoverage() {
+  Future refreshCallSiteData() {
     Map params = {};
     if (this is! Isolate) {
       params['targetId'] = id;
     }
-    return isolate.invokeRpcNoUpgrade('getCoverage', params).then(
+    return isolate.invokeRpcNoUpgrade('getCallSiteData', params).then(
         (ObservableMap map) {
           var coverage = new ServiceObject._fromMap(isolate, map);
           assert(coverage.type == 'CodeCoverage');
           var coverageList = coverage['coverage'];
           assert(coverageList != null);
-          processCoverageData(coverageList);
+          processCallSiteData(coverageList);
           return this;
         });
   }
@@ -2073,7 +2077,61 @@
   }
 }
 
+class CallSite {
+  final String name;
+  final Script script;
+  final int tokenPos;
+  final List<CallSiteEntry> entries;
+
+  CallSite(this.name, this.script, this.tokenPos, this.entries);
+
+  int get line => script.tokenToLine(tokenPos);
+  int get column => script.tokenToCol(tokenPos);
+
+  int get aggregateCount {
+    var count = 0;
+    for (var entry in entries) {
+      count += entry.count;
+    }
+    return count;
+  }
+
+  factory CallSite.fromMap(Map siteMap, Script script) {
+    var name = siteMap['name'];
+    var tokenPos = siteMap['tokenPos'];
+    var entries = new List<CallSiteEntry>();
+    for (var entryMap in siteMap['cacheEntries']) {
+      entries.add(new CallSiteEntry.fromMap(entryMap));
+    }
+    return new CallSite(name, script, tokenPos, entries);
+  }
+
+  operator ==(other) {
+    return (script == other.script) && (tokenPos == other.tokenPos);
+  }
+  int get hashCode => (script.hashCode << 8) | tokenPos;
+
+  String toString() => "CallSite($name, $tokenPos)";
+}
+
+class CallSiteEntry {
+  final /* Class | Library */ receiverContainer;
+  final int count;
+  final ServiceFunction target;
+
+  CallSiteEntry(this.receiverContainer, this.count, this.target);
+
+  factory CallSiteEntry.fromMap(Map entryMap) {
+    return new CallSiteEntry(entryMap['receiverContainer'],
+                             entryMap['count'],
+                             entryMap['target']);
+  }
+
+  String toString() => "CallSiteEntry(${receiverContainer.name}, $count)";
+}
+
 class Script extends ServiceObject with Coverage {
+  Set<CallSite> callSites = new Set<CallSite>();
   final lines = new ObservableList<ScriptLine>();
   final _hits = new Map<int, int>();
   @observable String kind;
@@ -2158,11 +2216,14 @@
     }
   }
 
-  void _processHits(List scriptHits) {
-    // Update hits table.
-    for (var i = 0; i < scriptHits.length; i += 2) {
-      var line = scriptHits[i];
-      var hit = scriptHits[i + 1]; // hit status.
+  void _processCallSites(List newCallSiteMaps) {
+    var mergedCallSites = new Set<CallSite>();
+    for (var callSiteMap in newCallSiteMaps) {
+      var newSite = new CallSite.fromMap(callSiteMap, this);
+      mergedCallSites.add(newSite);
+
+      var line = newSite.line;
+      var hit = newSite.aggregateCount;
       assert(line >= 1); // Lines start at 1.
       var oldHits = _hits[line];
       if (oldHits != null) {
@@ -2170,6 +2231,9 @@
       }
       _hits[line] = hit;
     }
+
+    mergedCallSites.addAll(callSites);
+    callSites = mergedCallSites;
     _applyHitsToLines();
     // Notify any Observers that this Script's state has changed.
     notifyChange(null);
diff --git a/runtime/observatory/test/async_generator_breakpoint_test.dart b/runtime/observatory/test/async_generator_breakpoint_test.dart
new file mode 100644
index 0000000..5e8d802
--- /dev/null
+++ b/runtime/observatory/test/async_generator_breakpoint_test.dart
@@ -0,0 +1,89 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--verbose-debug
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+import 'dart:async';
+
+printSync() {  // Line 12
+  print('sync');
+}
+printAsync() async {  // Line 15
+  print('async');
+}
+printAsyncStar() async* {  // Line 18
+  print('async*');
+}
+printSyncStar() sync* {  // Line 21
+  print('sync*');
+}
+
+var testerReady = false;
+testeeDo() {
+  // We block here rather than allowing the isolate to enter the
+  // paused-on-exit state before the tester gets a chance to set
+  // the breakpoints because we need the event loop to remain
+  // operational for the async bodies to run.
+  print('testee waiting');
+  while(!testerReady);
+
+  printSync();
+  var future = printAsync();
+  var stream = printAsyncStar();
+  var iterator = printSyncStar();
+
+  print('middle');  // Line 39.
+
+  future.then((v) => print(v));
+  stream.toList();
+  iterator.toList();
+}
+
+testAsync(Isolate isolate) async {
+  await isolate.rootLib.load();
+  var script = isolate.rootLib.scripts[0];
+
+  var bp1 = await isolate.addBreakpoint(script, 12);
+  expect(bp1, isNotNull);
+  expect(bp1 is Breakpoint, isTrue);
+  var bp2 = await isolate.addBreakpoint(script, 15);
+  expect(bp2, isNotNull);
+  expect(bp2 is Breakpoint, isTrue);
+  var bp3 = await isolate.addBreakpoint(script, 18);
+  expect(bp3, isNotNull);
+  expect(bp3 is Breakpoint, isTrue);
+  var bp4 = await isolate.addBreakpoint(script, 21);
+  expect(bp4, isNotNull);
+  expect(bp4 is Breakpoint, isTrue);
+  var bp5 = await isolate.addBreakpoint(script, 39);
+  expect(bp5, isNotNull);
+  expect(bp5 is Breakpoint, isTrue);
+
+  var hits = [];
+
+  isolate.eval(isolate.rootLib, 'testerReady = true;')
+      .then((ServiceObject result) {
+        expect(result.valueAsString, equals('true'));
+      });
+
+  await for (ServiceEvent event in isolate.vm.events.stream) {
+    if (event.eventType == ServiceEvent.kPauseBreakpoint) {
+      var bp = event.breakpoint;
+      print('Hit $bp');
+      hits.add(bp);
+      isolate.resume();
+
+      if (hits.length == 5) break;
+    }
+  }
+
+  expect(hits, equals([bp1, bp5, bp4, bp2, bp3]));
+}
+
+var tests = [testAsync];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testeeDo);
diff --git a/runtime/observatory/test/call_site_data_test.dart b/runtime/observatory/test/call_site_data_test.dart
index 2bd23f7..366c721 100644
--- a/runtime/observatory/test/call_site_data_test.dart
+++ b/runtime/observatory/test/call_site_data_test.dart
@@ -31,6 +31,26 @@
   return null;
 }
 
+class Static {
+  static staticMethod() => 2;
+}
+staticCall() {
+  Static.staticMethod();
+  return null;
+}
+constructorCall() {
+  new Static();
+  return null;
+}
+topLevelMethod() => "TOP";
+topLevelCall() {
+  topLevelMethod();
+  return null;
+}
+
+class Super { bar() => "Super"; }
+class Sub extends Super { bar() => super.bar(); }
+
 script() {
   for (int i = 0; i < 10; i++) monomorphic(new A());
 
@@ -46,73 +66,123 @@
   for (int i = 0; i < 60; i++) megamorphic(new F());
   for (int i = 0; i < 70; i++) megamorphic(new G());
   for (int i = 0; i < 80; i++) megamorphic(new H());
+
+  for (int i = 0; i < 10; i++) staticCall();
+
+  for (int i = 0; i < 10; i++) constructorCall();
+
+  for (int i = 0; i < 10; i++) topLevelCall();
+
+  for (int i = 0; i < 15; i++) new Sub().bar();
 }
 
 
 Set<String> stringifyCacheEntries(Map callSite) {
   return callSite['cacheEntries'].map((entry) {
-    return "${entry['receiverClass']['name']}:${entry['count']}";
+    return "${entry['receiverContainer']['name']}:${entry['count']}";
   }).toSet();
 }
 
+
+testMonomorphic(Isolate isolate) async {
+  Library lib = await isolate.rootLib.load();
+  ServiceFunction func =
+     lib.functions.singleWhere((f) => f.name == 'monomorphic');
+  Map response = await isolate.invokeRpcNoUpgrade('getCallSiteData',
+                                                  { 'targetId': func.id });
+  expect(response['type'], equals('CodeCoverage'));
+  Map callSite = response['coverage'].single['callSites'].single;
+  expect(callSite['name'], equals('foo'));
+  expect(stringifyCacheEntries(callSite),
+         equals(['A:10'].toSet()));
+}
+
+testPolymorphic(Isolate isolate) async {
+  Library lib = await isolate.rootLib.load();
+  ServiceFunction func =
+     lib.functions.singleWhere((f) => f.name == 'polymorphic');
+  Map response = await isolate.invokeRpcNoUpgrade('getCallSiteData',
+                                                  { 'targetId': func.id });
+  expect(response['type'], equals('CodeCoverage'));
+  Map callSite = response['coverage'].single['callSites'].single;
+  expect(callSite['name'], equals('foo'));
+  expect(stringifyCacheEntries(callSite),
+         equals(['A:10', 'B:20', 'C:30'].toSet()));
+}
+
+testMegamorphic(Isolate isolate) async {
+  Library lib = await isolate.rootLib.load();
+  ServiceFunction func =
+     lib.functions.singleWhere((f) => f.name == 'megamorphic');
+  Map response = await isolate.invokeRpcNoUpgrade('getCallSiteData',
+                                                  { 'targetId': func.id });
+  expect(response['type'], equals('CodeCoverage'));
+  Map callSite = response['coverage'].single['callSites'].single;
+  expect(callSite['name'], equals('foo'));
+  expect(stringifyCacheEntries(callSite),
+         equals(['A:10', 'B:20', 'C:30', 'D:40',
+                 'E:50', 'F:60', 'G:70', 'H:80'].toSet()));
+}
+
+testStaticCall(Isolate isolate) async {
+  Library lib = await isolate.rootLib.load();
+  ServiceFunction func =
+     lib.functions.singleWhere((f) => f.name == 'staticCall');
+  Map response = await isolate.invokeRpcNoUpgrade('getCallSiteData',
+                                                  { 'targetId': func.id });
+  expect(response['type'], equals('CodeCoverage'));
+  Map callSite = response['coverage'].single['callSites'].single;
+  expect(callSite['name'], equals('staticMethod'));
+  expect(stringifyCacheEntries(callSite),
+         equals(['Static:10'].toSet()));
+}
+
+testConstructorCall(Isolate isolate) async {
+  Library lib = await isolate.rootLib.load();
+  ServiceFunction func =
+     lib.functions.singleWhere((f) => f.name == 'constructorCall');
+  Map response = await isolate.invokeRpcNoUpgrade('getCallSiteData',
+                                                  { 'targetId': func.id });
+  expect(response['type'], equals('CodeCoverage'));
+  Map callSite = response['coverage'].single['callSites'].single;
+  expect(callSite['name'], equals('Static.'));
+  expect(stringifyCacheEntries(callSite),
+         equals(['Static:10'].toSet()));
+}
+
+testTopLevelCall(Isolate isolate) async {
+  Library lib = await isolate.rootLib.load();
+  ServiceFunction func =
+     lib.functions.singleWhere((f) => f.name == 'topLevelCall');
+  Map response = await isolate.invokeRpcNoUpgrade('getCallSiteData',
+                                                  { 'targetId': func.id });
+  expect(response['type'], equals('CodeCoverage'));
+  Map callSite = response['coverage'].single['callSites'].single;
+  expect(callSite['name'], equals('topLevelMethod'));
+  expect(stringifyCacheEntries(callSite),
+         equals(['call_site_data_test:10'].toSet()));
+}
+
+testSuperCall(Isolate isolate) async {
+  Library lib = await isolate.rootLib.load();
+  Class cls = await lib.classes.singleWhere((f) => f.name == 'Sub').load();
+  ServiceFunction func = cls.functions.singleWhere((f) => f.name == 'bar');
+  Map response = await isolate.invokeRpcNoUpgrade('getCallSiteData',
+                                                  { 'targetId': func.id });
+  expect(response['type'], equals('CodeCoverage'));
+  Map callSite = response['coverage'].single['callSites'].single;
+  expect(callSite['name'], equals('bar'));
+  expect(stringifyCacheEntries(callSite),
+         equals(['Super:15'].toSet()));
+}
+
 var tests = [
-(Isolate isolate) {
-  return isolate.rootLib.load().then((Library lib) {
-    var monomorphic = lib.functions.singleWhere((f) => f.name == 'monomorphic');
-    var polymorphic = lib.functions.singleWhere((f) => f.name == 'polymorphic');
-    var megamorphic = lib.functions.singleWhere((f) => f.name == 'megamorphic');
-
-    List tests = [];
-    tests.add(isolate.invokeRpcNoUpgrade('getCallSiteData',
-                                         { 'targetId': monomorphic.id })
-                .then((Map response) {
-                    print("Monomorphic: $response");
-                    expect(response['type'], equals('_CallSiteData'));
-                    expect(response['function']['id'], equals(monomorphic.id));
-                    expect(response['callSites'], isList);
-                    expect(response['callSites'], hasLength(1));
-                    Map callSite = response['callSites'].single;
-                    expect(callSite['name'], equals('foo'));
-                    // expect(callSite['deoptReasons'], equals(''));
-                    expect(stringifyCacheEntries(callSite),
-                           equals(['A:10'].toSet()));
-                }));
-
-    tests.add(isolate.invokeRpcNoUpgrade('getCallSiteData',
-                                         { 'targetId': polymorphic.id })
-                .then((Map response) {
-                    print("Polymorphic: $response");
-                    expect(response['type'], equals('_CallSiteData'));
-                    expect(response['function']['id'], equals(polymorphic.id));
-                    expect(response['callSites'], isList);
-                    expect(response['callSites'], hasLength(1));
-                    Map callSite = response['callSites'].single;
-                    expect(callSite['name'], equals('foo'));
-                    // expect(callSite['deoptReasons'], equals(''));
-                    expect(stringifyCacheEntries(callSite),
-                           equals(['A:10', 'B:20', 'C:30'].toSet()));
-                }));
-
-    tests.add(isolate.invokeRpcNoUpgrade('getCallSiteData',
-                                         { 'targetId': megamorphic.id })
-                .then((Map response) {
-                    print("Megamorphic: $response");
-                    expect(response['type'], equals('_CallSiteData'));
-                    expect(response['function']['id'], equals(megamorphic.id));
-                    expect(response['callSites'], isList);
-                    expect(response['callSites'], hasLength(1));
-                    Map callSite = response['callSites'].single;
-                    expect(callSite['name'], equals('foo'));
-                    // expect(callSite['deoptReasons'], equals(''));
-                    expect(stringifyCacheEntries(callSite),
-                           equals(['A:10', 'B:20', 'C:30', 'D:40',
-                                   'E:50', 'F:60', 'G:70', 'H:80'].toSet()));
-                }));
-
-    return Future.wait(tests);
-  });
-},
-
-];
+    testMonomorphic,
+    testPolymorphic,
+    testMegamorphic,
+    testStaticCall,
+    testConstructorCall,
+    testTopLevelCall,
+    testSuperCall ];
 
 main(args) => runIsolateTests(args, tests, testeeBefore: script);
diff --git a/runtime/observatory/test/debugging_test.dart b/runtime/observatory/test/debugging_test.dart
index 751ec00..c149ff7 100644
--- a/runtime/observatory/test/debugging_test.dart
+++ b/runtime/observatory/test/debugging_test.dart
@@ -72,7 +72,7 @@
           Breakpoint bpt = result;
           expect(bpt.type, equals('Breakpoint'));
           expect(bpt.script.id, equals(script.id));
-          expect(bpt.tokenPos, equals(67));
+          expect(bpt.tokenPos, equals(66));
           expect(isolate.breakpoints.length, equals(1));
           return completer.future;  // Wait for breakpoint events.
       });
@@ -177,7 +177,7 @@
     Breakpoint bpt = result;
     expect(bpt.type, equals('Breakpoint'));
     expect(bpt.script.name, equals('debugging_test.dart'));
-    expect(bpt.tokenPos, equals(29));
+    expect(bpt.tokenPos, equals(28));
     expect(isolate.breakpoints.length, equals(1));
     return completer.future;  // Wait for breakpoint events.
   });
diff --git a/runtime/tests/vm/dart/data_uri_failures_test.dart b/runtime/tests/vm/dart/data_uri_failures_test.dart
new file mode 100644
index 0000000..2df3195
--- /dev/null
+++ b/runtime/tests/vm/dart/data_uri_failures_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'data:text/plain;charset=utf-8,foo%28%29%20%3D%3E%2042%3B';  /// wrongmime: ok
+import 'data:;charset=utf-8,foo%28%29%20%3D%3E%2042%3B';  /// nomime: ok
+import 'data:application/dart;charset=utf-16,foo%28%29%20%3D%3E%2042%3B';  /// utf16: runtime error
+import 'data:application/dart,foo%28%29%20%3D%3E%2042%3B';  /// nocharset: ok
+import 'data:application/dart;charset=utf-8,foo?%9g';  /// badencodeddate: runtime error
+import 'data:application/dart;charset=utf-8;base64,Zm9vKCkgPT4gNDI7';  /// base64: ok
+
+main() {
+}
\ No newline at end of file
diff --git a/runtime/tests/vm/dart/data_uri_import_test.dart b/runtime/tests/vm/dart/data_uri_import_test.dart
new file mode 100644
index 0000000..2430b95
--- /dev/null
+++ b/runtime/tests/vm/dart/data_uri_import_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// foo() => 42;
+import 'data:application/dart;charset=utf-8,foo%28%29%20%3D%3E%2042%3B';
+
+import "package:expect/expect.dart";
+
+main() {
+  Expect.equals(42, foo());
+}
\ No newline at end of file
diff --git a/runtime/tests/vm/dart/data_uri_spawn_test.dart b/runtime/tests/vm/dart/data_uri_spawn_test.dart
new file mode 100644
index 0000000..2db6e14
--- /dev/null
+++ b/runtime/tests/vm/dart/data_uri_spawn_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:isolate";
+import "package:unittest/unittest.dart";
+
+Uri toDartDataUri(String source) {
+  return Uri.parse("data:application/dart;charset=utf-8,"
+                   "${Uri.encodeComponent(source)}");
+}
+
+main() {
+  test('Simple response', () {
+    String source = """
+import "dart:isolate";
+main(List args, SendPort replyPort) {
+  replyPort.send(42);
+}
+""";
+
+    RawReceivePort receivePort;
+    receivePort = new RawReceivePort(expectAsync((int message) {
+      expect(message, equals(42));
+      receivePort.close();
+    }));
+    Isolate.spawnUri(toDartDataUri(source), [], receivePort.sendPort);
+  });
+}
\ No newline at end of file
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 3eaddef..e1d95ce 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -9,16 +9,9 @@
 
 cc/SNPrint_BadArgs: Skip
 
-# These tests are skipped because of the workaround to open issue 8594.
-cc/Debug_StackTraceDump1: Skip
-cc/Debug_StackTraceDump2: Skip
-
 # Flaky on buildbot. Issue 5133 and 10409.
 cc/Sleep: Pass, Fail
 
-[ $arch == x64 ]
-cc/IsolateInterrupt: Skip
-
 [ $mode == debug ]
 # This is a benchmark that is not informative in debug mode.
 cc/CorelibIsolateStartup: Skip
@@ -64,11 +57,20 @@
 # The source positions do not match with dart2js.
 dart/optimized_stacktrace_test: RuntimeError
 
-[ $compiler == dart2js ]
 # Methods can be missing in dart2js stack traces due to inlining.  Also when
 # minifying they can be renamed, which is issue 7953.
 dart/inline_stack_frame_test: RuntimeError # Issue 7953
 
+[ $compiler == dart2js || $compiler == dartanalyzer || $compiler == dart2analyzer ]
+# Data uri's not supported by dart2js or the analyzer.
+dart/data_uri*test: Skip
+
+[ $runtime == vm ]
+dart/data_uri_failures_test/wrongmime: RuntimeError, OK # VM is more restrictive than the browser
+dart/data_uri_failures_test/nomime: RuntimeError, OK
+dart/data_uri_failures_test/nocharset: RuntimeError, OK
+dart/data_uri_failures_test/base64: RuntimeError, OK
+
 [ $compiler == dart2dart ]
 # Skip until we stabilize language tests.
 *: Skip
diff --git a/runtime/vm/allocation.cc b/runtime/vm/allocation.cc
index bd3d5c6..b8f9cb1 100644
--- a/runtime/vm/allocation.cc
+++ b/runtime/vm/allocation.cc
@@ -24,12 +24,6 @@
 }
 
 
-void* ZoneAllocated::operator new(uword size, BaseIsolate* isolate) {
-  ASSERT(isolate != NULL);
-  return Allocate(size, isolate->current_zone());
-}
-
-
 void* ZoneAllocated::operator new(uword size, Zone* zone) {
   ASSERT(zone == Isolate::Current()->current_zone());
   return Allocate(size, zone);
diff --git a/runtime/vm/allocation.h b/runtime/vm/allocation.h
index 787c8db..579ed77 100644
--- a/runtime/vm/allocation.h
+++ b/runtime/vm/allocation.h
@@ -98,11 +98,6 @@
   // Implicitly allocate the object in the current zone.
   void* operator new(uword size);
 
-  // DEPRECATED: Use Zone version.
-  // Implicitly allocate the object in the current zone given the current
-  // isolate.
-  void* operator new(uword size, BaseIsolate* isolate);
-
   // Allocate the object in the given zone, which must be the current zone.
   void* operator new(uword size, Zone* zone);
 
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index 4aac9ec..6cf6ad1 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -1856,7 +1856,7 @@
         try_index_(try_index) {
     ASSERT(try_block_ != NULL);
     ASSERT(context_var != NULL);
-    ASSERT(catch_block_ != NULL || finally_block_ != NULL);
+    ASSERT(catch_block_ != NULL);
   }
 
   SequenceNode* try_block() const { return try_block_; }
diff --git a/runtime/vm/ast_printer.cc b/runtime/vm/ast_printer.cc
index 31490b8..4d89c9b8 100644
--- a/runtime/vm/ast_printer.cc
+++ b/runtime/vm/ast_printer.cc
@@ -5,32 +5,53 @@
 #include "vm/ast_printer.h"
 
 #include "vm/handles.h"
+#include "vm/log.h"
 #include "vm/object.h"
 #include "vm/os.h"
 #include "vm/parser.h"
 
 namespace dart {
 
-AstPrinter::AstPrinter() { }
+AstPrinter::AstPrinter() : indent_(0) { }
 
 
 AstPrinter::~AstPrinter() { }
 
 
 void AstPrinter::VisitGenericAstNode(AstNode* node) {
-  OS::Print("(%s ", node->PrettyName());
+  ISL_Print("(%s ", node->PrettyName());
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitSequenceNode(SequenceNode* node) {
-  OS::Print("(%s (scope \"%p\")", node->PrettyName(), node->scope());
+  indent_++;
+  LocalScope* scope = node->scope();
+  ISL_Print("(%s (scope \"%p\"", node->PrettyName(), scope);
+  if (scope != NULL) {
+    ISL_Print(" (%" Pd "-%" Pd ") loop %d",
+              scope->begin_token_pos(),
+              scope->end_token_pos(),
+              scope->loop_level());
+    if (scope->HasContextLevel()) {
+      ISL_Print(" context %d captures %d",
+                scope->context_level(),
+                scope->num_context_variables());
+    } else {
+      ASSERT(scope->num_context_variables() == 0);
+    }
+  }
+  ISL_Print(")");
   for (int i = 0; i < node->length(); ++i) {
-    OS::Print("\n");
+    ISL_Print("\n");
+    for (intptr_t p = 0; p < indent_; p++) {
+      ISL_Print("  ");
+    }
     node->NodeAt(i)->Visit(this);
   }
-  OS::Print(")");
+  ISL_Print(")");
+  indent_--;
 }
 
 
@@ -60,29 +81,29 @@
       kind = "";
       UNREACHABLE();
   }
-  OS::Print("(%s %s", node->PrettyName(), kind);
+  ISL_Print("(%s %s", node->PrettyName(), kind);
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitGenericLocalNode(AstNode* node,
                                        const LocalVariable& var) {
-  OS::Print("(%s %s%s \"%s\"",
+  ISL_Print("(%s %s%s \"%s\"",
             node->PrettyName(),
             var.is_final() ? "final " : "",
             String::Handle(var.type().Name()).ToCString(),
             var.name().ToCString());
   if (var.HasIndex()) {
     if (var.is_captured()) {
-      OS::Print(" (context %d %d)", var.owner()->context_level(), var.index());
+      ISL_Print(" (context %d %d)", var.owner()->context_level(), var.index());
     } else {
-      OS::Print(" (stack %d)", var.index());
+      ISL_Print(" (stack %d)", var.index());
     }
   }
-  OS::Print(" ");
+  ISL_Print(" ");
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
@@ -97,14 +118,14 @@
 
 
 void AstPrinter::VisitGenericFieldNode(AstNode* node, const Field& field) {
-  OS::Print("(%s %s%s \"%s\" ",
+  ISL_Print("(%s %s%s \"%s\" ",
             node->PrettyName(),
             field.is_final() ? "final " : "",
             String::Handle(AbstractType::Handle(field.type()).Name()).
                 ToCString(),
             String::Handle(field.name()).ToCString());
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
@@ -145,13 +166,13 @@
 
 void AstPrinter::VisitLiteralNode(LiteralNode* node) {
   const Instance& literal = node->literal();
-  OS::Print("(%s \"%s\")", node->PrettyName(), literal.ToCString());
+  ISL_Print("(%s \"%s\")", node->PrettyName(), literal.ToCString());
 }
 
 
 void AstPrinter::VisitTypeNode(TypeNode* node) {
   const AbstractType& type = node->type();
-  OS::Print("(%s \"%s\")",
+  ISL_Print("(%s \"%s\")",
             node->PrettyName(),
             String::Handle(type.Name()).ToCString());
 }
@@ -160,12 +181,12 @@
 void AstPrinter::VisitAssignableNode(AssignableNode* node) {
   const AbstractType& type = node->type();
   const String& dst_name = node->dst_name();
-  OS::Print("(%s (type \"%s\") (of \"%s\") ",
+  ISL_Print("(%s (type \"%s\") (of \"%s\") ",
             node->PrettyName(),
             String::Handle(type.Name()).ToCString(),
             dst_name.ToCString());
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
@@ -180,38 +201,38 @@
 
 
 void AstPrinter::VisitPrimaryNode(PrimaryNode* node) {
-  OS::Print("*****%s***** \"%s\")",
+  ISL_Print("*****%s***** \"%s\")",
             node->PrettyName(),
             node->primary().ToCString());
 }
 
 
 void AstPrinter::VisitComparisonNode(ComparisonNode* node) {
-  OS::Print("(%s %s ", node->PrettyName(), node->TokenName());
+  ISL_Print("(%s %s ", node->PrettyName(), node->TokenName());
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitBinaryOpNode(BinaryOpNode* node) {
-  OS::Print("(%s %s ", node->PrettyName(), node->TokenName());
+  ISL_Print("(%s %s ", node->PrettyName(), node->TokenName());
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitBinaryOpWithMask32Node(BinaryOpWithMask32Node* node) {
-  OS::Print("(%s %s ", node->PrettyName(), node->TokenName());
+  ISL_Print("(%s %s ", node->PrettyName(), node->TokenName());
   node->VisitChildren(this);
-  OS::Print(" & \"0x%" Px64 "", node->mask32());
-  OS::Print("\")");
+  ISL_Print(" & \"0x%" Px64 "", node->mask32());
+  ISL_Print("\")");
 }
 
 
 void AstPrinter::VisitUnaryOpNode(UnaryOpNode* node) {
-  OS::Print("(%s %s ", node->PrettyName(), node->TokenName());
+  ISL_Print("(%s %s ", node->PrettyName(), node->TokenName());
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
@@ -226,16 +247,16 @@
 
 
 void AstPrinter::VisitCaseNode(CaseNode* node) {
-  OS::Print("(%s (", node->PrettyName());
+  ISL_Print("(%s (", node->PrettyName());
   for (int i = 0; i < node->case_expressions()->length(); i++) {
     node->case_expressions()->NodeAt(i)->Visit(this);
   }
   if (node->contains_default()) {
-    OS::Print(" default");
+    ISL_Print(" default");
   }
-  OS::Print(")");
+  ISL_Print(")");
   node->statements()->Visit(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
@@ -252,17 +273,17 @@
 void AstPrinter::VisitForNode(ForNode* node) {
   // Complicated because the condition is optional and so we clearly want to
   // indicate the subparts.
-  OS::Print("(%s (init ", node->PrettyName());
+  ISL_Print("(%s (init ", node->PrettyName());
   node->initializer()->Visit(this);
   if (node->condition() != NULL) {
-    OS::Print(") (cond ");
+    ISL_Print(") (cond ");
     node->condition()->Visit(this);
   }
-  OS::Print(") (update ");
+  ISL_Print(") (update ");
   node->increment()->Visit(this);
-  OS::Print(") ");
+  ISL_Print(") ");
   node->body()->Visit(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
@@ -272,7 +293,7 @@
 
 
 void AstPrinter::VisitJumpNode(JumpNode* node) {
-  OS::Print("(%s %s %s (scope \"%p\"))",
+  ISL_Print("(%s %s %s (scope \"%p\"))",
             node->PrettyName(),
             node->TokenName(),
             node->label()->name().ToCString(),
@@ -281,25 +302,25 @@
 
 
 void AstPrinter::VisitInstanceCallNode(InstanceCallNode* node) {
-  OS::Print("(%s \"%s\" ",
+  ISL_Print("(%s \"%s\" ",
             node->PrettyName(),
             node->function_name().ToCString());
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitStaticCallNode(StaticCallNode* node) {
   const char* function_fullname = node->function().ToFullyQualifiedCString();
-  OS::Print("(%s \"%s\" ", node->PrettyName(), function_fullname);
+  ISL_Print("(%s \"%s\" ", node->PrettyName(), function_fullname);
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitClosureNode(ClosureNode* node) {
   const char* function_fullname = node->function().ToFullyQualifiedCString();
-  OS::Print("(%s \"%s\")", node->PrettyName(), function_fullname);
+  ISL_Print("(%s \"%s\")", node->PrettyName(), function_fullname);
 }
 
 
@@ -311,39 +332,39 @@
 void AstPrinter::VisitConstructorCallNode(ConstructorCallNode* node) {
   const char* kind = node->constructor().IsFactory() ? "factory " : "";
   const char* constructor_name = node->constructor().ToFullyQualifiedCString();
-  OS::Print("(%s %s \"%s\" ", node->PrettyName(), kind, constructor_name);
+  ISL_Print("(%s %s \"%s\" ", node->PrettyName(), kind, constructor_name);
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitInstanceGetterNode(InstanceGetterNode* node) {
-  OS::Print("(%s \"%s\" ",
+  ISL_Print("(%s \"%s\" ",
             node->PrettyName(),
             node->field_name().ToCString());
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitInstanceSetterNode(InstanceSetterNode* node) {
-  OS::Print("(%s \"%s\" ",
+  ISL_Print("(%s \"%s\" ",
             node->PrettyName(),
             node->field_name().ToCString());
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitInitStaticFieldNode(InitStaticFieldNode* node) {
-  OS::Print("(%s \"%s\")", node->PrettyName(),
+  ISL_Print("(%s \"%s\")", node->PrettyName(),
             String::Handle(node->field().name()).ToCString());
 }
 
 
 void AstPrinter::VisitStaticGetterNode(StaticGetterNode* node) {
   String& class_name = String::Handle(node->cls().Name());
-  OS::Print("(%s \"%s.%s\")",
+  ISL_Print("(%s \"%s.%s\")",
             node->PrettyName(),
             class_name.ToCString(),
             node->field_name().ToCString());
@@ -352,31 +373,31 @@
 
 void AstPrinter::VisitStaticSetterNode(StaticSetterNode* node) {
   String& class_name = String::Handle(node->cls().Name());
-  OS::Print("(%s \"%s.%s\" ",
+  ISL_Print("(%s \"%s.%s\" ",
             node->PrettyName(),
             class_name.ToCString(),
             node->field_name().ToCString());
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitLoadIndexedNode(LoadIndexedNode* node) {
-  OS::Print("(%s%s ", node->PrettyName(), node->IsSuperLoad() ? " super" : "");
+  ISL_Print("(%s%s ", node->PrettyName(), node->IsSuperLoad() ? " super" : "");
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitStoreIndexedNode(StoreIndexedNode* node) {
-  OS::Print("(%s%s ", node->PrettyName(), node->IsSuperStore() ? " super" : "");
+  ISL_Print("(%s%s ", node->PrettyName(), node->IsSuperStore() ? " super" : "");
   node->VisitChildren(this);
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
 void AstPrinter::VisitNativeBodyNode(NativeBodyNode* node) {
-  OS::Print("(%s \"%s\" (%" Pd " args))",
+  ISL_Print("(%s \"%s\" (%" Pd " args))",
             node->PrettyName(),
             node->native_c_function_name().ToCString(),
             NativeArguments::ParameterCountForResolution(node->function()));
@@ -389,17 +410,15 @@
 
 
 void AstPrinter::VisitTryCatchNode(TryCatchNode* node) {
-  OS::Print("(%s ", node->PrettyName());
+  ISL_Print("(%s ", node->PrettyName());
   node->try_block()->Visit(this);
-  if (node->catch_block() != NULL) {
-    node->catch_block()->Visit(this);
-  }
+  node->catch_block()->Visit(this);
   if (node->finally_block() != NULL) {
-    OS::Print("(finally ");
+    ISL_Print("(finally ");
     node->finally_block()->Visit(this);
-    OS::Print(")");
+    ISL_Print(")");
   }
-  OS::Print(")");
+  ISL_Print(")");
 }
 
 
@@ -417,13 +436,13 @@
   ASSERT(node != NULL);
   AstPrinter ast_printer;
   node->Visit(&ast_printer);
-  OS::Print("\n");
+  ISL_Print("\n");
 }
 
 
 static void IndentN(int count) {
   for (int i = 0; i < count; i++) {
-    OS::Print(" ");
+    ISL_Print(" ");
   }
 }
 
@@ -434,22 +453,22 @@
   ASSERT(scope != NULL);
   ASSERT(var != NULL);
   IndentN(indent);
-  OS::Print("(%s%s '%s'",
+  ISL_Print("(%s%s '%s'",
             var->is_final() ? "final " : "",
             String::Handle(var->type().Name()).ToCString(),
             var->name().ToCString());
   if (var->owner() != scope) {
-    OS::Print(" alias");
+    ISL_Print(" alias");
   }
   if (var->HasIndex()) {
-    OS::Print(" @%d", var->index());
+    ISL_Print(" @%d", var->index());
     if (var->is_captured()) {
-      OS::Print(" ctx %d", var->owner()->context_level());
+      ISL_Print(" ctx %d", var->owner()->context_level());
     }
   } else if (var->owner()->function_level() != 0) {
-    OS::Print(" lev %d", var->owner()->function_level());
+    ISL_Print(" lev %d", var->owner()->function_level());
   }
-  OS::Print(" valid %" Pd "-%" Pd ")\n",
+  ISL_Print(" valid %" Pd "-%" Pd ")\n",
             var->token_pos(),
             scope->end_token_pos());
 }
@@ -466,16 +485,16 @@
   const LocalScope* child = scope->child();
   while (child != NULL) {
     IndentN(indent);
-    OS::Print("{scope %p ", child);
+    ISL_Print("{scope %p ", child);
     if (child->HasContextLevel()) {
-      OS::Print("ctx %d numctxvar %d ",
+      ISL_Print("ctx %d numctxvar %d ",
                 child->context_level(),
                 child->num_context_variables());
     }
-    OS::Print("llev %d\n", child->loop_level());
+    ISL_Print("llev %d\n", child->loop_level());
     PrintLocalScope(child, 0, indent + kScopeIndent);
     IndentN(indent);
-    OS::Print("}\n");
+    ISL_Print("}\n");
     child = child->sibling();
   }
 }
@@ -491,13 +510,13 @@
   const LocalScope* scope = node_sequence->scope();
   ASSERT(scope != NULL);
   const char* function_name = function.ToFullyQualifiedCString();
-  OS::Print("Scope for function '%s'\n{scope %p ", function_name, scope);
+  ISL_Print("Scope for function '%s'\n{scope %p ", function_name, scope);
   if (scope->HasContextLevel()) {
-    OS::Print("ctx %d numctxvar %d ",
+    ISL_Print("ctx %d numctxvar %d ",
               scope->context_level(),
               scope->num_context_variables());
   }
-  OS::Print("llev %d\n", scope->loop_level());
+  ISL_Print("llev %d\n", scope->loop_level());
   const int num_fixed_params = function.num_fixed_parameters();
   const int num_params = num_fixed_params + function.NumOptionalParameters();
   // Parameters must be listed first and must all appear in the top scope.
@@ -508,7 +527,7 @@
     LocalVariable* param = scope->VariableAt(pos);
     ASSERT(param->owner() == scope);  // No aliases should precede parameters.
     IndentN(indent);
-    OS::Print("(param %s%s '%s'",
+    ISL_Print("(param %s%s '%s'",
               param->is_final() ? "final " : "",
               String::Handle(param->type().Name()).ToCString(),
               param->name().ToCString());
@@ -516,22 +535,22 @@
     if (pos >= num_fixed_params && pos < num_params) {
       const Object& default_parameter_value = Object::Handle(
           default_parameter_values.At(pos - num_fixed_params));
-      OS::Print(" =%s", default_parameter_value.ToCString());
+      ISL_Print(" =%s", default_parameter_value.ToCString());
     }
     if (param->HasIndex()) {
-      OS::Print(" @%d", param->index());
+      ISL_Print(" @%d", param->index());
       if (param->is_captured()) {
-        OS::Print(" ctx %d", param->owner()->context_level());
+        ISL_Print(" ctx %d", param->owner()->context_level());
       }
     }
-    OS::Print(" valid %" Pd "-%" Pd ")\n",
+    ISL_Print(" valid %" Pd "-%" Pd ")\n",
               param->token_pos(),
               scope->end_token_pos());
     pos++;
   }
   // Visit remaining non-parameter variables and children scopes.
   PrintLocalScope(scope, pos, indent);
-  OS::Print("}\n");
+  ISL_Print("}\n");
 }
 
 
@@ -542,9 +561,9 @@
   AstPrinter ast_printer;
   const char* function_name =
       parsed_function.function().ToFullyQualifiedCString();
-  OS::Print("Ast for function '%s' {\n", function_name);
+  ISL_Print("Ast for function '%s' {\n", function_name);
   node_sequence->Visit(&ast_printer);
-  OS::Print("}\n");
+  ISL_Print("}\n");
 }
 
 }  // namespace dart
diff --git a/runtime/vm/ast_printer.h b/runtime/vm/ast_printer.h
index 6823723..7c43ef6 100644
--- a/runtime/vm/ast_printer.h
+++ b/runtime/vm/ast_printer.h
@@ -42,6 +42,8 @@
   void VisitGenericLocalNode(AstNode* node, const LocalVariable& local);
   void VisitGenericFieldNode(AstNode* node, const Field& field);
 
+  intptr_t indent_;
+
   DISALLOW_COPY_AND_ASSIGN(AstPrinter);
 };
 
diff --git a/runtime/vm/base_isolate.h b/runtime/vm/base_isolate.h
index 5abe170..067c708 100644
--- a/runtime/vm/base_isolate.h
+++ b/runtime/vm/base_isolate.h
@@ -5,6 +5,7 @@
 #ifndef VM_BASE_ISOLATE_H_
 #define VM_BASE_ISOLATE_H_
 
+#include "platform/assert.h"
 #include "vm/globals.h"
 
 namespace dart {
@@ -64,25 +65,25 @@
 #endif
   }
 
-  int32_t no_gc_scope_depth() const {
+  int32_t no_safepoint_scope_depth() const {
 #if defined(DEBUG)
-    return no_gc_scope_depth_;
+    return no_safepoint_scope_depth_;
 #else
     return 0;
 #endif
   }
 
-  void IncrementNoGCScopeDepth() {
+  void IncrementNoSafepointScopeDepth() {
 #if defined(DEBUG)
-    ASSERT(no_gc_scope_depth_ < INT_MAX);
-    no_gc_scope_depth_ += 1;
+    ASSERT(no_safepoint_scope_depth_ < INT_MAX);
+    no_safepoint_scope_depth_ += 1;
 #endif
   }
 
-  void DecrementNoGCScopeDepth() {
+  void DecrementNoSafepointScopeDepth() {
 #if defined(DEBUG)
-    ASSERT(no_gc_scope_depth_ > 0);
-    no_gc_scope_depth_ -= 1;
+    ASSERT(no_safepoint_scope_depth_ > 0);
+    no_safepoint_scope_depth_ -= 1;
 #endif
   }
 
@@ -111,7 +112,7 @@
 #if defined(DEBUG)
         top_handle_scope_(NULL),
         no_handle_scope_depth_(0),
-        no_gc_scope_depth_(0),
+        no_safepoint_scope_depth_(0),
 #endif
         no_callback_scope_depth_(0)
   {}
@@ -125,7 +126,7 @@
 #if defined(DEBUG)
   HandleScope* top_handle_scope_;
   int32_t no_handle_scope_depth_;
-  int32_t no_gc_scope_depth_;
+  int32_t no_safepoint_scope_depth_;
 #endif
   int32_t no_callback_scope_depth_;
 
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 5f67706..7527d48 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -534,7 +534,8 @@
     intptr_t buffer_len = writer.BytesWritten();
 
     // Read object back from the snapshot.
-    SnapshotReader reader(buffer, buffer_len, Snapshot::kMessage, isolate);
+    SnapshotReader reader(buffer, buffer_len, Snapshot::kMessage, isolate,
+                          zone.GetZone());
     reader.ReadObject();
   }
   timer.Stop();
@@ -557,7 +558,8 @@
     intptr_t buffer_len = writer.BytesWritten();
 
     // Read object back from the snapshot.
-    SnapshotReader reader(buffer, buffer_len, Snapshot::kMessage, isolate);
+    SnapshotReader reader(buffer, buffer_len, Snapshot::kMessage, isolate,
+                          zone.GetZone());
     reader.ReadObject();
   }
   timer.Stop();
@@ -582,7 +584,8 @@
     intptr_t buffer_len = writer.BytesWritten();
 
     // Read object back from the snapshot.
-    SnapshotReader reader(buffer, buffer_len, Snapshot::kMessage, isolate);
+    SnapshotReader reader(buffer, buffer_len, Snapshot::kMessage, isolate,
+                          zone.GetZone());
     reader.ReadObject();
     free(buffer);
   }
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 11307ab..c33cd26 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -360,7 +360,6 @@
   V(LinkedHashMap_toArray, 1)                                                  \
   V(LinkedHashMap_getModMark, 2)                                               \
   V(LinkedHashMap_useInternal, 0)                                              \
-  V(LinkedHashMap_useCompact, 0)                                               \
   V(WeakProperty_new, 2)                                                       \
   V(WeakProperty_getKey, 1)                                                    \
   V(WeakProperty_getValue, 1)                                                  \
diff --git a/runtime/vm/cha.cc b/runtime/vm/cha.cc
index fbb9142..065931c 100644
--- a/runtime/vm/cha.cc
+++ b/runtime/vm/cha.cc
@@ -18,7 +18,7 @@
       return;
     }
   }
-  leaf_classes_.Add(&Class::ZoneHandle(isolate_, cls.raw()));
+  leaf_classes_.Add(&Class::ZoneHandle(thread_->zone(), cls.raw()));
 }
 
 
@@ -36,7 +36,7 @@
     return true;
   }
   const GrowableObjectArray& direct_subclasses =
-      GrowableObjectArray::Handle(isolate_, cls.direct_subclasses());
+      GrowableObjectArray::Handle(thread_->zone(), cls.direct_subclasses());
   bool result =
       !direct_subclasses.IsNull() && (direct_subclasses.Length() > 0);
   if (!result) {
@@ -47,8 +47,8 @@
 
 
 bool CHA::HasSubclasses(intptr_t cid) {
-  const ClassTable& class_table = *isolate_->class_table();
-  Class& cls = Class::Handle(isolate_, class_table.At(cid));
+  const ClassTable& class_table = *thread_->isolate()->class_table();
+  Class& cls = Class::Handle(thread_->zone(), class_table.At(cid));
   return HasSubclasses(cls);
 }
 
@@ -72,7 +72,7 @@
 
 bool CHA::HasOverride(const Class& cls, const String& function_name) {
   const GrowableObjectArray& cls_direct_subclasses =
-      GrowableObjectArray::Handle(isolate_, cls.direct_subclasses());
+      GrowableObjectArray::Handle(thread_->zone(), cls.direct_subclasses());
   // Subclasses of Object are not tracked by CHA. Safely assume that overrides
   // exist.
   if (cls.IsObjectClass()) {
@@ -83,7 +83,7 @@
     AddToLeafClasses(cls);
     return false;
   }
-  Class& direct_subclass = Class::Handle(isolate_);
+  Class& direct_subclass = Class::Handle(thread_->zone());
   for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) {
     direct_subclass ^= cls_direct_subclasses.At(i);
     // Unfinalized classes are treated as non-existent for CHA purposes,
diff --git a/runtime/vm/cha.h b/runtime/vm/cha.h
index 2100820..9be0caa 100644
--- a/runtime/vm/cha.h
+++ b/runtime/vm/cha.h
@@ -7,6 +7,7 @@
 
 #include "vm/allocation.h"
 #include "vm/growable_array.h"
+#include "vm/thread.h"
 
 namespace dart {
 
@@ -17,17 +18,17 @@
 
 class CHA : public StackResource {
  public:
-  explicit CHA(Isolate* isolate)
-      : StackResource(isolate),
-        isolate_(isolate),
-        leaf_classes_(isolate, 1),
-        previous_(isolate->cha()) {
-    isolate->set_cha(this);
+  explicit CHA(Thread* thread)
+      : StackResource(thread->isolate()),
+        thread_(thread),
+        leaf_classes_(thread->zone(), 1),
+        previous_(thread->cha()) {
+    thread->set_cha(this);
   }
 
   ~CHA() {
-    ASSERT(isolate_->cha() == this);
-    isolate_->set_cha(previous_);
+    ASSERT(thread_->cha() == this);
+    thread_->set_cha(previous_);
   }
 
   // Returns true if the class has subclasses.
@@ -53,7 +54,7 @@
  private:
   void AddToLeafClasses(const Class& cls);
 
-  Isolate* isolate_;
+  Thread* thread_;
   GrowableArray<Class*> leaf_classes_;
   CHA* previous_;
 };
diff --git a/runtime/vm/cha_test.cc b/runtime/vm/cha_test.cc
index e2b3dc6..3926daa 100644
--- a/runtime/vm/cha_test.cc
+++ b/runtime/vm/cha_test.cc
@@ -80,7 +80,7 @@
       Function::Handle(class_d.LookupDynamicFunction(function_bar_name));
   EXPECT(!class_d_bar.IsNull());
 
-  CHA cha(Isolate::Current());
+  CHA cha(Thread::Current());
 
   EXPECT(cha.HasSubclasses(kInstanceCid));
   EXPECT(!cha.HasSubclasses(kSmiCid));
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 63a80ca..1be6b66 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -631,16 +631,16 @@
 
 DEFINE_RUNTIME_ENTRY(Throw, 1) {
   const Instance& exception =
-      Instance::CheckedHandle(isolate, arguments.ArgAt(0));
+      Instance::CheckedHandle(zone, arguments.ArgAt(0));
   Exceptions::Throw(isolate, exception);
 }
 
 
 DEFINE_RUNTIME_ENTRY(ReThrow, 2) {
   const Instance& exception =
-      Instance::CheckedHandle(isolate, arguments.ArgAt(0));
+      Instance::CheckedHandle(zone, arguments.ArgAt(0));
   const Instance& stacktrace =
-      Instance::CheckedHandle(isolate, arguments.ArgAt(1));
+      Instance::CheckedHandle(zone, arguments.ArgAt(1));
   Exceptions::ReThrow(isolate, exception, stacktrace);
 }
 
@@ -658,7 +658,7 @@
       caller_code.GetStaticCallTargetFunctionAt(caller_frame->pc()));
   if (!target_function.HasCode()) {
     const Error& error =
-        Error::Handle(Compiler::CompileFunction(isolate, target_function));
+        Error::Handle(Compiler::CompileFunction(thread, target_function));
     if (!error.IsNull()) {
       Exceptions::PropagateError(error);
     }
@@ -930,7 +930,7 @@
   ASSERT(ic_data.NumberOfChecks() == 1);
   const Function& target = Function::Handle(ic_data.GetTargetAt(0));
   if (!target.HasCode()) {
-    const Error& error = Error::Handle(Compiler::CompileFunction(isolate,
+    const Error& error = Error::Handle(Compiler::CompileFunction(thread,
                                                                  target));
     if (!error.IsNull()) {
       Exceptions::PropagateError(error);
@@ -963,7 +963,7 @@
   ASSERT(ic_data.NumberOfChecks() > 0);
   const Function& target = Function::Handle(ic_data.GetTargetAt(0));
   if (!target.HasCode()) {
-    const Error& error = Error::Handle(Compiler::CompileFunction(isolate,
+    const Error& error = Error::Handle(Compiler::CompileFunction(thread,
                                                                  target));
     if (!error.IsNull()) {
       Exceptions::PropagateError(error);
@@ -1224,12 +1224,6 @@
       }
     }
   }
-  if ((interrupt_bits & Isolate::kVmStatusInterrupt) != 0) {
-    Dart_IsolateInterruptCallback callback = isolate->VmStatsCallback();
-    if (callback) {
-      (*callback)();
-    }
-  }
 
   if ((stack_overflow_flags & Isolate::kOsrRequest) != 0) {
     ASSERT(FLAG_use_osr);
@@ -1262,7 +1256,7 @@
     // it cannot have been removed from the function.
     ASSERT(!original_code.IsNull());
     const Error& error = Error::Handle(Compiler::CompileOptimizedFunction(
-        isolate, function, osr_id));
+        thread, function, osr_id));
     if (!error.IsNull()) {
       Exceptions::PropagateError(error);
     }
@@ -1303,7 +1297,7 @@
 // The requesting function can be already optimized (reoptimization).
 // Returns the Code object where to continue execution.
 DEFINE_RUNTIME_ENTRY(OptimizeInvokedFunction, 1) {
-  const Function& function = Function::CheckedHandle(isolate,
+  const Function& function = Function::CheckedHandle(zone,
                                                      arguments.ArgAt(0));
   ASSERT(!function.IsNull());
   ASSERT(function.HasCode());
@@ -1313,7 +1307,7 @@
     // prevent recursive triggering of function optimization.
     function.set_usage_counter(0);
     const Error& error = Error::Handle(
-        isolate, Compiler::CompileOptimizedFunction(isolate, function));
+        isolate, Compiler::CompileOptimizedFunction(thread, function));
     if (!error.IsNull()) {
       Exceptions::PropagateError(error);
     }
@@ -1349,7 +1343,7 @@
   ASSERT(!target_code.IsNull());
   if (!target_function.HasCode()) {
     const Error& error = Error::Handle(
-        isolate, Compiler::CompileFunction(isolate, target_function));
+        isolate, Compiler::CompileFunction(thread, target_function));
     if (!error.IsNull()) {
       Exceptions::PropagateError(error);
     }
@@ -1399,7 +1393,7 @@
   const uword target =
       CodePatcher::GetStaticCallTargetAt(frame->pc(), caller_code);
   const Code& stub = Code::Handle(isolate, Code::LookupCode(target));
-  Class& alloc_class = Class::ZoneHandle(isolate);
+  Class& alloc_class = Class::ZoneHandle(zone);
   alloc_class ^= stub.owner();
   Code& alloc_stub = Code::Handle(isolate, alloc_class.allocation_stub());
   if (alloc_stub.IsNull()) {
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 168bd37..77eb89f 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -73,10 +73,11 @@
 // separate helpers functions & `optimizing` args.
 class CompilationPipeline : public ZoneAllocated {
  public:
-  static CompilationPipeline* New(Isolate* isolate, const Function& function);
+  static CompilationPipeline* New(Zone* zone, const Function& function);
 
   virtual void ParseFunction(ParsedFunction* parsed_function) = 0;
   virtual FlowGraph* BuildFlowGraph(
+      Zone* zone,
       ParsedFunction* parsed_function,
       const ZoneGrowableArray<const ICData*>& ic_data_array,
       intptr_t osr_id) = 0;
@@ -93,6 +94,7 @@
   }
 
   virtual FlowGraph* BuildFlowGraph(
+      Zone* zone,
       ParsedFunction* parsed_function,
       const ZoneGrowableArray<const ICData*>& ic_data_array,
       intptr_t osr_id) {
@@ -111,9 +113,7 @@
 
 class IrregexpCompilationPipeline : public CompilationPipeline {
  public:
-  explicit IrregexpCompilationPipeline(Isolate* isolate)
-    : backtrack_goto_(NULL),
-      isolate_(isolate) { }
+  IrregexpCompilationPipeline() : backtrack_goto_(NULL) { }
 
   virtual void ParseFunction(ParsedFunction* parsed_function) {
     RegExpParser::ParseFunction(parsed_function);
@@ -121,6 +121,7 @@
   }
 
   virtual FlowGraph* BuildFlowGraph(
+      Zone* zone,
       ParsedFunction* parsed_function,
       const ZoneGrowableArray<const ICData*>& ic_data_array,
       intptr_t osr_id) {
@@ -140,26 +141,25 @@
                              NULL,  // NULL = not inlining.
                              osr_id);
 
-    return new(isolate_) FlowGraph(*parsed_function,
-                                   result.graph_entry,
-                                   result.num_blocks);
+    return new(zone) FlowGraph(*parsed_function,
+                               result.graph_entry,
+                               result.num_blocks);
   }
 
   virtual void FinalizeCompilation() {
-    backtrack_goto_->ComputeOffsetTable(isolate_);
+    backtrack_goto_->ComputeOffsetTable();
   }
 
  private:
   IndirectGotoInstr* backtrack_goto_;
-  Isolate* isolate_;
 };
 
-CompilationPipeline* CompilationPipeline::New(Isolate* isolate,
+CompilationPipeline* CompilationPipeline::New(Zone* zone,
                                               const Function& function) {
   if (function.IsIrregexpFunction()) {
-    return new(isolate) IrregexpCompilationPipeline(isolate);
+    return new(zone) IrregexpCompilationPipeline();
   } else {
-    return new(isolate) DartCompilationPipeline();
+    return new(zone) DartCompilationPipeline();
   }
 }
 
@@ -169,7 +169,7 @@
 DEFINE_RUNTIME_ENTRY(CompileFunction, 1) {
   const Function& function = Function::CheckedHandle(arguments.ArgAt(0));
   ASSERT(!function.HasCode());
-  const Error& error = Error::Handle(Compiler::CompileFunction(isolate,
+  const Error& error = Error::Handle(Compiler::CompileFunction(thread,
                                                                function));
   if (!error.IsNull()) {
     Exceptions::PropagateError(error);
@@ -178,7 +178,7 @@
 
 
 RawError* Compiler::Compile(const Library& library, const Script& script) {
-  Isolate* isolate = Isolate::Current();
+  Isolate* volatile isolate = Isolate::Current();
   StackZone zone(isolate);
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
@@ -279,7 +279,7 @@
     }
   }
 
-  Isolate* isolate = Isolate::Current();
+  Isolate* volatile isolate = Isolate::Current();
   // We remember all the classes that are being compiled in these lists. This
   // also allows us to reset the marked_for_parsing state in case we see an
   // error.
@@ -374,7 +374,9 @@
   }
   TimerScope timer(FLAG_compiler_stats, &CompilerStats::codegen_timer);
   bool is_compiled = false;
-  Isolate* isolate = Isolate::Current();
+  Thread* volatile thread = Thread::Current();
+  Zone* volatile zone = thread->zone();
+  Isolate* volatile isolate = thread->isolate();
   HANDLESCOPE(isolate);
 
   // We may reattempt compilation if the function needs to be assembled using
@@ -395,7 +397,7 @@
 
       // Class hierarchy analysis is registered with the isolate in the
       // constructor and unregisters itself upon destruction.
-      CHA cha(isolate);
+      CHA cha(thread);
 
       // TimerScope needs an isolate to be properly terminated in case of a
       // LongJump.
@@ -404,7 +406,7 @@
                          &CompilerStats::graphbuilder_timer,
                          isolate);
         ZoneGrowableArray<const ICData*>* ic_data_array =
-            new(isolate) ZoneGrowableArray<const ICData*>();
+            new(zone) ZoneGrowableArray<const ICData*>();
         if (optimized) {
           ASSERT(function.HasCode());
           // Extract type feedback before the graph is built, as the graph
@@ -422,7 +424,8 @@
           }
         }
 
-        flow_graph = pipeline->BuildFlowGraph(parsed_function,
+        flow_graph = pipeline->BuildFlowGraph(zone,
+                                              parsed_function,
                                               *ic_data_array,
                                               osr_id);
       }
@@ -742,9 +745,9 @@
 
           // Register code with the classes it depends on because of CHA.
           for (intptr_t i = 0;
-               i < isolate->cha()->leaf_classes().length();
+               i < thread->cha()->leaf_classes().length();
                ++i) {
-            isolate->cha()->leaf_classes()[i]->RegisterCHACode(code);
+            thread->cha()->leaf_classes()[i]->RegisterCHACode(code);
           }
 
           for (intptr_t i = 0;
@@ -961,10 +964,10 @@
                                        const Function& function,
                                        bool optimized,
                                        intptr_t osr_id) {
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
+  Thread* volatile thread = Thread::Current();
+  Isolate* volatile isolate = thread->isolate();
   StackZone stack_zone(isolate);
-  Zone* zone = stack_zone.GetZone();
+  Zone* volatile zone = stack_zone.GetZone();
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     TIMERSCOPE(isolate, time_compilation);
@@ -1040,19 +1043,21 @@
 }
 
 
-RawError* Compiler::CompileFunction(Isolate* isolate,
+RawError* Compiler::CompileFunction(Thread* thread,
                                     const Function& function) {
-  VMTagScope tagScope(isolate, VMTag::kCompileUnoptimizedTagId);
-  CompilationPipeline* pipeline = CompilationPipeline::New(isolate, function);
+  VMTagScope tagScope(thread->isolate(), VMTag::kCompileUnoptimizedTagId);
+  CompilationPipeline* pipeline =
+      CompilationPipeline::New(thread->zone(), function);
   return CompileFunctionHelper(pipeline, function, false, Isolate::kNoDeoptId);
 }
 
 
-RawError* Compiler::CompileOptimizedFunction(Isolate* isolate,
+RawError* Compiler::CompileOptimizedFunction(Thread* thread,
                                              const Function& function,
                                              intptr_t osr_id) {
-  VMTagScope tagScope(isolate, VMTag::kCompileOptimizedTagId);
-  CompilationPipeline* pipeline = CompilationPipeline::New(isolate, function);
+  VMTagScope tagScope(thread->isolate(), VMTag::kCompileOptimizedTagId);
+  CompilationPipeline* pipeline =
+      CompilationPipeline::New(thread->zone(), function);
   return CompileFunctionHelper(pipeline, function, true, osr_id);
 }
 
@@ -1060,7 +1065,7 @@
 // This is only used from unit tests.
 RawError* Compiler::CompileParsedFunction(
     ParsedFunction* parsed_function) {
-  Isolate* isolate = Isolate::Current();
+  Isolate* volatile isolate = Isolate::Current();
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     // Non-optimized code generator.
@@ -1086,10 +1091,11 @@
 
 
 RawError* Compiler::CompileAllFunctions(const Class& cls) {
-  Isolate* isolate = Isolate::Current();
-  Error& error = Error::Handle(isolate);
-  Array& functions = Array::Handle(isolate, cls.functions());
-  Function& func = Function::Handle(isolate);
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  Error& error = Error::Handle(zone);
+  Array& functions = Array::Handle(zone, cls.functions());
+  Function& func = Function::Handle(zone);
   // Class dynamic lives in the vm isolate. Its array fields cannot be set to
   // an empty array.
   if (functions.IsNull()) {
@@ -1103,7 +1109,7 @@
     if (!func.HasCode() &&
         !func.is_abstract() &&
         !func.IsRedirectingFactory()) {
-      error = CompileFunction(isolate, func);
+      error = CompileFunction(thread, func);
       if (!error.IsNull()) {
         return error.raw();
       }
@@ -1114,12 +1120,12 @@
   // more closures can be added to the end of the array. Compile all the
   // closures until we have reached the end of the "worklist".
   GrowableObjectArray& closures =
-      GrowableObjectArray::Handle(isolate, cls.closures());
+      GrowableObjectArray::Handle(zone, cls.closures());
   if (!closures.IsNull()) {
     for (int i = 0; i < closures.Length(); i++) {
       func ^= closures.At(i);
       if (!func.HasCode()) {
-        error = CompileFunction(isolate, func);
+        error = CompileFunction(thread, func);
         if (!error.IsNull()) {
           return error.raw();
         }
@@ -1136,7 +1142,7 @@
   // The VM sets the field's value to transiton_sentinel prior to
   // evaluating the initializer value.
   ASSERT(field.value() == Object::transition_sentinel().raw());
-  Isolate* isolate = Isolate::Current();
+  Isolate* volatile isolate = Isolate::Current();
   StackZone zone(isolate);
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
@@ -1169,8 +1175,8 @@
 
 
 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) {
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
+  Thread* volatile thread = Thread::Current();
+  Isolate* volatile isolate = thread->isolate();
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     if (FLAG_trace_compiler) {
diff --git a/runtime/vm/compiler.h b/runtime/vm/compiler.h
index 48af3cb..f9cc682 100644
--- a/runtime/vm/compiler.h
+++ b/runtime/vm/compiler.h
@@ -39,13 +39,13 @@
   // Generates code for given function and sets its code field.
   //
   // Returns Error::null() if there is no compilation error.
-  static RawError* CompileFunction(Isolate* isolate, const Function& function);
+  static RawError* CompileFunction(Thread* thread, const Function& function);
 
   // Generates optimized code for function.
   //
   // Returns Error::null() if there is no compilation error.
   static RawError* CompileOptimizedFunction(
-      Isolate* isolate,
+      Thread* thread,
       const Function& function,
       intptr_t osr_id = Isolate::kNoDeoptId);
 
diff --git a/runtime/vm/constant_propagator.cc b/runtime/vm/constant_propagator.cc
index f0ef1c9..890f540 100644
--- a/runtime/vm/constant_propagator.cc
+++ b/runtime/vm/constant_propagator.cc
@@ -296,7 +296,7 @@
 void ConstantPropagator::VisitPhi(PhiInstr* instr) {
   // Compute the join over all the reachable predecessor values.
   JoinEntryInstr* block = instr->block();
-  Object& value = Object::ZoneHandle(I, Unknown());
+  Object& value = Object::ZoneHandle(Z, Unknown());
   for (intptr_t pred_idx = 0; pred_idx < instr->InputCount(); ++pred_idx) {
     if (reachable_->Contains(
             block->PredecessorAt(pred_idx)->preorder_number())) {
@@ -601,7 +601,7 @@
     ASSERT(ch_code >= 0);
     if (ch_code < Symbols::kMaxOneCharCodeSymbol) {
       RawString** table = Symbols::PredefinedAddress();
-      SetValue(instr, String::ZoneHandle(I, table[ch_code]));
+      SetValue(instr, String::ZoneHandle(Z, table[ch_code]));
     } else {
       SetValue(instr, non_constant_);
     }
@@ -617,7 +617,7 @@
     const String& str = String::Cast(o);
     const intptr_t result =
         (str.Length() == 1) ? static_cast<intptr_t>(str.CharAt(0)) : -1;
-    SetValue(instr, Smi::ZoneHandle(I, Smi::New(result)));
+    SetValue(instr, Smi::ZoneHandle(Z, Smi::New(result)));
   }
 }
 
@@ -780,12 +780,12 @@
 void ConstantPropagator::VisitLoadClassId(LoadClassIdInstr* instr) {
   intptr_t cid = instr->object()->Type()->ToCid();
   if (cid != kDynamicCid) {
-    SetValue(instr, Smi::ZoneHandle(I, Smi::New(cid)));
+    SetValue(instr, Smi::ZoneHandle(Z, Smi::New(cid)));
     return;
   }
   const Object& object = instr->object()->definition()->constant_value();
   if (IsConstant(object)) {
-    SetValue(instr, Smi::ZoneHandle(I, Smi::New(object.GetClassId())));
+    SetValue(instr, Smi::ZoneHandle(Z, Smi::New(object.GetClassId())));
     return;
   }
   SetValue(instr, non_constant_);
@@ -801,7 +801,7 @@
     if (num_elements->BindsToConstant() &&
         num_elements->BoundConstant().IsSmi()) {
       intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value();
-      const Object& result = Smi::ZoneHandle(I, Smi::New(length));
+      const Object& result = Smi::ZoneHandle(Z, Smi::New(length));
       SetValue(instr, result);
       return;
     }
@@ -812,17 +812,17 @@
         instance->definition()->OriginalDefinition()->AsConstant();
     if (constant != NULL) {
       if (constant->value().IsString()) {
-        SetValue(instr, Smi::ZoneHandle(I,
+        SetValue(instr, Smi::ZoneHandle(Z,
             Smi::New(String::Cast(constant->value()).Length())));
         return;
       }
       if (constant->value().IsArray()) {
-        SetValue(instr, Smi::ZoneHandle(I,
+        SetValue(instr, Smi::ZoneHandle(Z,
             Smi::New(Array::Cast(constant->value()).Length())));
         return;
       }
       if (constant->value().IsTypedData()) {
-        SetValue(instr, Smi::ZoneHandle(I,
+        SetValue(instr, Smi::ZoneHandle(Z,
             Smi::New(TypedData::Cast(constant->value()).Length())));
         return;
       }
@@ -842,7 +842,7 @@
   if (IsConstant(object)) {
     if (instr->type().IsTypeParameter()) {
       if (object.IsNull()) {
-        SetValue(instr, Type::ZoneHandle(I, Type::DynamicType()));
+        SetValue(instr, Type::ZoneHandle(Z, Type::DynamicType()));
         return;
       }
       // We could try to instantiate the type parameter and return it if no
@@ -905,7 +905,7 @@
       const Integer& result =
           Integer::Handle(I, binary_op->Evaluate(left_int, right_int));
       if (!result.IsNull()) {
-        SetValue(binary_op, Integer::ZoneHandle(I, result.raw()));
+        SetValue(binary_op, Integer::ZoneHandle(Z, result.raw()));
         return;
       }
     }
@@ -964,7 +964,7 @@
     const Integer& result =
         Integer::Handle(I, unary_op->Evaluate(value_int));
     if (!result.IsNull()) {
-      SetValue(unary_op, Integer::ZoneHandle(I, result.raw()));
+      SetValue(unary_op, Integer::ZoneHandle(Z, result.raw()));
       return;
     }
   }
@@ -1475,8 +1475,8 @@
         // Drop the comparison, which does not have side effects
         JoinEntryInstr* join = if_true->AsJoinEntry();
         if (join->phis() == NULL) {
-          GotoInstr* jump = new(I) GotoInstr(if_true->AsJoinEntry());
-          jump->InheritDeoptTarget(I, branch);
+          GotoInstr* jump = new(Z) GotoInstr(if_true->AsJoinEntry());
+          jump->InheritDeoptTarget(Z, branch);
 
           Instruction* previous = branch->previous();
           branch->set_previous(NULL);
@@ -1619,17 +1619,17 @@
         ASSERT(reachable_->Contains(if_false->preorder_number()));
         ASSERT(if_false->parallel_move() == NULL);
         ASSERT(if_false->loop_info() == NULL);
-        join = new(I) JoinEntryInstr(if_false->block_id(),
+        join = new(Z) JoinEntryInstr(if_false->block_id(),
                                      if_false->try_index());
-        join->InheritDeoptTarget(I, if_false);
+        join->InheritDeoptTarget(Z, if_false);
         if_false->UnuseAllInputs();
         next = if_false->next();
       } else if (!reachable_->Contains(if_false->preorder_number())) {
         ASSERT(if_true->parallel_move() == NULL);
         ASSERT(if_true->loop_info() == NULL);
-        join = new(I) JoinEntryInstr(if_true->block_id(),
+        join = new(Z) JoinEntryInstr(if_true->block_id(),
                                      if_true->try_index());
-        join->InheritDeoptTarget(I, if_true);
+        join->InheritDeoptTarget(Z, if_true);
         if_true->UnuseAllInputs();
         next = if_true->next();
       }
@@ -1639,8 +1639,8 @@
         // Drop the comparison, which does not have side effects as long
         // as it is a strict compare (the only one we can determine is
         // constant with the current analysis).
-        GotoInstr* jump = new(I) GotoInstr(join);
-        jump->InheritDeoptTarget(I, branch);
+        GotoInstr* jump = new(Z) GotoInstr(join);
+        jump->InheritDeoptTarget(Z, branch);
 
         Instruction* previous = branch->previous();
         branch->set_previous(NULL);
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 81e31cf..15a1a4f 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -231,7 +231,7 @@
 // Register aliases.
 const Register TMP = IP;  // Used as scratch register by assembler.
 const Register TMP2 = kNoRegister;  // There is no second assembler temporary.
-const Register CTX = R9;  // Caches current context in generated code.
+const Register CTX = R9;  // Location of current context at method entry.
 const Register PP = R10;  // Caches object pool pointer in generated code.
 const Register SPREG = SP;  // Stack pointer register.
 const Register FPREG = FP;  // Frame pointer register.
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index b85ec5b..61d9431 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -109,7 +109,7 @@
 // Register aliases.
 const Register TMP = R16;  // Used as scratch register by assembler.
 const Register TMP2 = R17;
-const Register CTX = R28;  // Caches current context in generated code.
+const Register CTX = R28;  // Location of current context at method entry.
 const Register PP = R27;  // Caches object pool pointer in generated code.
 const Register kNoPP = kNoRegister;
 const Register FPREG = FP;  // Frame pointer register.
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 175f5ae..d609b8a 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -62,7 +62,7 @@
 // Register aliases.
 const Register TMP = kNoRegister;  // No scratch register used by assembler.
 const Register TMP2 = kNoRegister;  // No second assembler scratch register.
-const Register CTX = ESI;  // Caches current context in generated code.
+const Register CTX = EDI;  // Location of current context at method entry.
 const Register PP = kNoRegister;  // No object pool pointer.
 const Register SPREG = ESP;  // Stack pointer register.
 const Register FPREG = EBP;  // Frame pointer register.
diff --git a/runtime/vm/constants_mips.h b/runtime/vm/constants_mips.h
index e48eefe..067d69c 100644
--- a/runtime/vm/constants_mips.h
+++ b/runtime/vm/constants_mips.h
@@ -178,7 +178,7 @@
 // Register aliases.
 const Register TMP = AT;  // Used as scratch register by assembler.
 const Register TMP2 = kNoRegister;  // No second assembler scratch register.
-const Register CTX = S6;  // Caches current context in generated code.
+const Register CTX = S6;  // Location of current context at method entry.
 const Register PP = S7;  // Caches object pool pointer in generated code.
 const Register SPREG = SP;  // Stack pointer register.
 const Register FPREG = FP;  // Frame pointer register.
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 593e8eb..d42687e 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -86,7 +86,7 @@
 // Register aliases.
 const Register TMP = R11;  // Used as scratch register by the assembler.
 const Register TMP2 = kNoRegister;  // No second assembler scratch register.
-const Register CTX = R14;  // Caches current context in generated code.
+const Register CTX = R14;  // Location of current context at method entry.
 // Caches object pool pointer in generated code.
 const Register PP = R15;
 const Register SPREG = RSP;  // Stack pointer register.
diff --git a/runtime/vm/coverage.cc b/runtime/vm/coverage.cc
index 69eadca..d756fd9 100644
--- a/runtime/vm/coverage.cc
+++ b/runtime/vm/coverage.cc
@@ -53,9 +53,12 @@
 
 
 void CodeCoverage::CompileAndAdd(const Function& function,
-                                 const JSONArray& hits_arr,
-                                 const GrowableArray<intptr_t>& pos_to_line) {
-  Isolate* isolate = Isolate::Current();
+                                 const JSONArray& hits_or_sites,
+                                 const GrowableArray<intptr_t>& pos_to_line,
+                                 bool as_call_sites) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
   if (!function.HasCode()) {
     // If the function should not be compiled or if the compilation failed,
     // then just skip this method.
@@ -71,7 +74,7 @@
       return;
     }
     const Error& err = Error::Handle(
-        isolate, Compiler::CompileFunction(isolate, function));
+        zone, Compiler::CompileFunction(thread, function));
     if (!err.IsNull()) {
       return;
     }
@@ -80,7 +83,7 @@
 
   // Print the hit counts for all IC datas.
   ZoneGrowableArray<const ICData*>* ic_data_array =
-      new(isolate) ZoneGrowableArray<const ICData*>();
+      new(zone) ZoneGrowableArray<const ICData*>();
   function.RestoreICDataMap(ic_data_array);
   const Code& code = Code::Handle(function.unoptimized_code());
   const PcDescriptors& descriptors = PcDescriptors::Handle(
@@ -113,19 +116,23 @@
       if (last_line == line) {
         last_count += ic_data->AggregateCount();
       } else {
-        if (last_line != -1) {
-          hits_arr.AddValue(last_line);
-          hits_arr.AddValue(last_count);
+        if ((last_line != -1) && !as_call_sites) {
+          hits_or_sites.AddValue(last_line);
+          hits_or_sites.AddValue(last_count);
         }
         last_count = ic_data->AggregateCount();
         last_line = line;
       }
+      if (as_call_sites) {
+        bool is_static_call = iter.Kind() == RawPcDescriptors::kUnoptStaticCall;
+        ic_data->PrintToJSONArray(hits_or_sites, token_pos, is_static_call);
+      }
     }
   }
   // Write last hit value if needed.
-  if (last_line != -1) {
-    hits_arr.AddValue(last_line);
-    hits_arr.AddValue(last_count);
+  if ((last_line != -1) && !as_call_sites) {
+    hits_or_sites.AddValue(last_line);
+    hits_or_sites.AddValue(last_count);
   }
 }
 
@@ -133,7 +140,8 @@
 void CodeCoverage::PrintClass(const Library& lib,
                               const Class& cls,
                               const JSONArray& jsarr,
-                              CoverageFilter* filter) {
+                              CoverageFilter* filter,
+                              bool as_call_sites) {
   Isolate* isolate = Isolate::Current();
   if (cls.EnsureIsFinalized(isolate) != Error::null()) {
     // Only classes that have been finalized do have a meaningful list of
@@ -161,7 +169,7 @@
     JSONObject jsobj(&jsarr);
     jsobj.AddProperty("source", saved_url.ToCString());
     jsobj.AddProperty("script", script);
-    JSONArray hits_arr(&jsobj, "hits");
+    JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");
 
     // We stay within this loop while we are seeing functions from the same
     // source URI.
@@ -177,10 +185,10 @@
         i++;
         continue;
       }
-      CompileAndAdd(function, hits_arr, pos_to_line);
+      CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
       if (function.HasImplicitClosureFunction()) {
         function = function.ImplicitClosureFunction();
-        CompileAndAdd(function, hits_arr, pos_to_line);
+        CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
       }
       i++;
     }
@@ -206,7 +214,7 @@
       JSONObject jsobj(&jsarr);
       jsobj.AddProperty("source", saved_url.ToCString());
       jsobj.AddProperty("script", script);
-      JSONArray hits_arr(&jsobj, "hits");
+      JSONArray hits_or_sites(&jsobj, as_call_sites ? "callSites" : "hits");
 
       // We stay within this loop while we are seeing functions from the same
       // source URI.
@@ -218,7 +226,7 @@
           pos_to_line.Clear();
           break;
         }
-        CompileAndAdd(function, hits_arr, pos_to_line);
+        CompileAndAdd(function, hits_or_sites, pos_to_line, as_call_sites);
         i++;
       }
     }
@@ -239,7 +247,7 @@
   }
 
   JSONStream stream;
-  PrintJSON(isolate, &stream, NULL);
+  PrintJSON(isolate, &stream, NULL, false);
 
   const char* format = "%s/dart-cov-%" Pd "-%" Pd ".json";
   intptr_t pid = OS::ProcessId();
@@ -260,7 +268,8 @@
 
 void CodeCoverage::PrintJSON(Isolate* isolate,
                              JSONStream* stream,
-                             CoverageFilter* filter) {
+                             CoverageFilter* filter,
+                             bool as_call_sites) {
   CoverageFilterAll default_filter;
   if (filter == NULL) {
     filter = &default_filter;
@@ -279,7 +288,7 @@
       while (it.HasNext()) {
         cls = it.GetNextClass();
         ASSERT(!cls.IsNull());
-        PrintClass(lib, cls, jsarr, filter);
+        PrintClass(lib, cls, jsarr, filter, as_call_sites);
       }
     }
   }
diff --git a/runtime/vm/coverage.h b/runtime/vm/coverage.h
index cdeb0a6..496ff65 100644
--- a/runtime/vm/coverage.h
+++ b/runtime/vm/coverage.h
@@ -37,16 +37,19 @@
   static void Write(Isolate* isolate);
   static void PrintJSON(Isolate* isolate,
                         JSONStream* stream,
-                        CoverageFilter* filter);
+                        CoverageFilter* filter,
+                        bool as_call_sites);
 
  private:
   static void PrintClass(const Library& lib,
                          const Class& cls,
                          const JSONArray& arr,
-                         CoverageFilter* filter);
+                         CoverageFilter* filter,
+                         bool as_call_sites);
   static void CompileAndAdd(const Function& function,
-                            const JSONArray& hits_arr,
-                            const GrowableArray<intptr_t>& pos_to_line);
+                            const JSONArray& hits_or_sites,
+                            const GrowableArray<intptr_t>& pos_to_line,
+                            bool as_call_sites);
 };
 
 }  // namespace dart
diff --git a/runtime/vm/coverage_test.cc b/runtime/vm/coverage_test.cc
index c4c62e1..2301d3a 100644
--- a/runtime/vm/coverage_test.cc
+++ b/runtime/vm/coverage_test.cc
@@ -45,7 +45,7 @@
   ASSERT(!lib.IsNull());
 
   JSONStream js;
-  CodeCoverage::PrintJSON(isolate, &js, NULL);
+  CodeCoverage::PrintJSON(isolate, &js, NULL, false);
 
   char buf[1024];
   OS::SNPrint(buf, sizeof(buf),
@@ -78,7 +78,7 @@
   ASSERT(!lib.IsNull());
 
   JSONStream js;
-  CodeCoverage::PrintJSON(isolate, &js, NULL);
+  CodeCoverage::PrintJSON(isolate, &js, NULL, false);
 
   char buf[1024];
   // Coverage data is printed per class, i.e., there should be two sections
@@ -128,7 +128,7 @@
 
   JSONStream js;
   FunctionCoverageFilter filter(func);
-  CodeCoverage::PrintJSON(isolate, &js, &filter);
+  CodeCoverage::PrintJSON(isolate, &js, &filter, false);
   // Only expect coverage data for Foo.yetAnother() on line 6.
   char buf[1024];
   OS::SNPrint(buf, sizeof(buf),
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 041eba1..ffae666 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -92,6 +92,7 @@
   Isolate::SetEntropySourceCallback(entropy_source);
   OS::InitOnce();
   VirtualMemory::InitOnce();
+  Thread::InitOnce();
   Isolate::InitOnce();
   PortMap::InitOnce();
   FreeListElement::InitOnce();
@@ -158,6 +159,8 @@
 
 
 const char* Dart::Cleanup() {
+  // Shutdown the service isolate before shutting down the thread pool.
+  ServiceIsolate::Shutdown();
 #if 0
   // Ideally we should shutdown the VM isolate here, but the thread pool
   // shutdown does not seem to ensure that all the threads have stopped
@@ -238,7 +241,7 @@
       OS::Print("Size of isolate snapshot = %" Pd "\n", snapshot->length());
     }
     SnapshotReader reader(snapshot->content(), snapshot->length(),
-                          Snapshot::kFull, isolate);
+                          Snapshot::kFull, isolate, zone.GetZone());
     const Error& error = Error::Handle(reader.ReadFullSnapshot());
     if (!error.IsNull()) {
       return error.raw();
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index c087c0e..6dd2be2 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -472,7 +472,7 @@
 bool Api::StringGetPeerHelper(NativeArguments* arguments,
                               int arg_index,
                               void** peer) {
-  NoGCScope no_gc_scope;
+  NoSafepointScope no_safepoint_scope;
   RawObject* raw_obj = arguments->NativeArgAt(arg_index);
   if (!raw_obj->IsHeapObject()) {
     return false;
@@ -502,7 +502,7 @@
 
 
 bool Api::GetNativeReceiver(NativeArguments* arguments, intptr_t* value) {
-  NoGCScope no_gc_scope;
+  NoSafepointScope no_safepoint_scope;
   RawObject* raw_obj = arguments->NativeArg0();
   if (raw_obj->IsHeapObject()) {
     intptr_t cid = raw_obj->GetClassId();
@@ -525,7 +525,7 @@
 bool Api::GetNativeBooleanArgument(NativeArguments* arguments,
                                    int arg_index,
                                    bool* value) {
-  NoGCScope no_gc_scope;
+  NoSafepointScope no_safepoint_scope;
   RawObject* raw_obj = arguments->NativeArgAt(arg_index);
   if (raw_obj->IsHeapObject()) {
       intptr_t cid = raw_obj->GetClassId();
@@ -545,7 +545,7 @@
 bool Api::GetNativeIntegerArgument(NativeArguments* arguments,
                                    int arg_index,
                                    int64_t* value) {
-  NoGCScope no_gc_scope;
+  NoSafepointScope no_safepoint_scope;
   RawObject* raw_obj = arguments->NativeArgAt(arg_index);
   if (raw_obj->IsHeapObject()) {
     intptr_t cid = raw_obj->GetClassId();
@@ -563,7 +563,7 @@
 bool Api::GetNativeDoubleArgument(NativeArguments* arguments,
                                   int arg_index,
                                   double* value) {
-  NoGCScope no_gc_scope;
+  NoSafepointScope no_safepoint_scope;
   RawObject* raw_obj = arguments->NativeArgAt(arg_index);
   if (raw_obj->IsHeapObject()) {
     intptr_t cid = raw_obj->GetClassId();
@@ -587,7 +587,7 @@
                                     int arg_index,
                                     int num_fields,
                                     intptr_t* field_values) {
-  NoGCScope no_gc_scope;
+  NoSafepointScope no_safepoint_scope;
   RawObject* raw_obj = arguments->NativeArgAt(arg_index);
   if (raw_obj->IsHeapObject()) {
     intptr_t cid = raw_obj->GetClassId();
@@ -793,10 +793,10 @@
   const Error* error;
   {
     // We need to preserve the error object across the destruction of zones
-    // when the ApiScopes are unwound.  By using NoGCScope, we can ensure
+    // when the ApiScopes are unwound.  By using NoSafepointScope, we can ensure
     // that GC won't touch the raw error object before creating a valid
     // handle for it in the surviving zone.
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     RawError* raw_error = Api::UnwrapErrorHandle(isolate, handle).raw();
     state->UnwindScopes(isolate->top_exit_frame_info());
     error = &Error::Handle(isolate, raw_error);
@@ -839,7 +839,7 @@
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   {
-    NoGCScope ngc;
+    NoSafepointScope no_safepoint_scope;
     if (Api::UnwrapHandle(obj1) == Api::UnwrapHandle(obj2)) {
       return true;
     }
@@ -1156,7 +1156,7 @@
   }
 
   void VisitHandle(uword addr) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     FinalizablePersistentHandle* handle =
         reinterpret_cast<FinalizablePersistentHandle*>(addr);
     RawObject* raw_obj = handle->raw();
@@ -1713,15 +1713,17 @@
 
 DART_EXPORT Dart_Handle Dart_ObjectEquals(Dart_Handle obj1, Dart_Handle obj2,
                                           bool* value) {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
+  Zone* zone = thread->zone();
   DARTSCOPE(isolate);
   CHECK_CALLBACK_STATE(isolate);
   const Instance& expected =
-      Instance::CheckedHandle(isolate, Api::UnwrapHandle(obj1));
+      Instance::CheckedHandle(zone, Api::UnwrapHandle(obj1));
   const Instance& actual =
-      Instance::CheckedHandle(isolate, Api::UnwrapHandle(obj2));
+      Instance::CheckedHandle(zone, Api::UnwrapHandle(obj2));
   const Object& result =
-      Object::Handle(isolate, DartLibraryCalls::Equals(expected, actual));
+      Object::Handle(zone, DartLibraryCalls::Equals(expected, actual));
   if (result.IsBool()) {
     *value = Bool::Cast(result).value();
     return Api::Success();
@@ -2452,7 +2454,7 @@
     *peer = str.GetPeer();
     ASSERT(*peer != NULL);
   } else {
-    NoGCScope no_gc_scope;
+    NoSafepointScope no_safepoint_scope;
     *peer = isolate->heap()->GetPeer(str.raw());
   }
   *char_size = str.CharSize();
@@ -2711,7 +2713,7 @@
   ASSERT(state != NULL);
   const Instance* saved_exception;
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     RawInstance* raw_exception = exception.raw();
     state->UnwindScopes(isolate->top_exit_frame_info());
     saved_exception = &Instance::Handle(raw_exception);
@@ -2749,7 +2751,7 @@
                              uint8_t* native_array,
                              intptr_t length) {
   ASSERT(array.ElementSizeInBytes() == 1);
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   memmove(native_array,
           reinterpret_cast<uint8_t*>(array.DataAddr(offset)),
           length);
@@ -2892,7 +2894,7 @@
     const TypedData& array = TypedData::Cast(obj);
     if (array.ElementSizeInBytes() == 1) {
       if (Utils::RangeCheck(offset, length, array.Length())) {
-        NoGCScope no_gc;
+        NoSafepointScope no_safepoint;
         memmove(reinterpret_cast<uint8_t*>(array.DataAddr(offset)),
                 native_array,
                 length);
@@ -3469,7 +3471,7 @@
     ASSERT(!obj.IsNull());
     length = obj.Length();
     size_in_bytes = length * TypedData::ElementSizeInBytes(class_id);
-    isolate->IncrementNoGCScopeDepth();
+    isolate->IncrementNoSafepointScopeDepth();
     START_NO_CALLBACK_SCOPE(isolate);
     data_tmp = obj.DataAddr(0);
   } else {
@@ -3483,7 +3485,7 @@
     val ^= TypedDataView::OffsetInBytes(view_obj);
     intptr_t offset_in_bytes = val.Value();
     const Instance& obj = Instance::Handle(TypedDataView::Data(view_obj));
-    isolate->IncrementNoGCScopeDepth();
+    isolate->IncrementNoSafepointScopeDepth();
     START_NO_CALLBACK_SCOPE(isolate);
     if (TypedData::IsTypedData(obj)) {
       const TypedData& data_obj = TypedData::Cast(obj);
@@ -3525,7 +3527,7 @@
     RETURN_TYPE_ERROR(isolate, object, 'TypedData');
   }
   if (!RawObject::IsExternalTypedDataClassId(class_id)) {
-    isolate->DecrementNoGCScopeDepth();
+    isolate->DecrementNoSafepointScopeDepth();
     END_NO_CALLBACK_SCOPE(isolate);
   }
   if (FLAG_verify_acquired_data) {
@@ -4409,7 +4411,7 @@
   ASSERT(state != NULL);
   const Instance* saved_exception;
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     RawInstance* raw_exception =
         Api::UnwrapInstanceHandle(isolate, exception).raw();
     state->UnwindScopes(isolate->top_exit_frame_info());
@@ -4448,7 +4450,7 @@
   const Instance* saved_exception;
   const Stacktrace* saved_stacktrace;
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     RawInstance* raw_exception =
         Api::UnwrapInstanceHandle(isolate, exception).raw();
     RawStacktrace* raw_stacktrace =
@@ -5007,6 +5009,7 @@
   Isolate* isolate = Isolate::Current();
   DARTSCOPE(isolate);
   TIMERSCOPE(isolate, time_script_loading);
+  StackZone zone(isolate);
   if (buffer == NULL) {
     RETURN_NULL_ERROR(buffer);
   }
@@ -5034,7 +5037,8 @@
   SnapshotReader reader(snapshot->content(),
                         snapshot->length(),
                         snapshot->kind(),
-                        isolate);
+                        isolate,
+                        zone.GetZone());
   const Object& tmp = Object::Handle(isolate, reader.ReadScriptSnapshot());
   if (tmp.IsError()) {
     return Api::NewHandle(isolate, tmp.raw());
@@ -5466,7 +5470,7 @@
     return Api::NewError(msg, CURRENT_FUNC);
   }
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     RawObject* raw_obj = obj.raw();
     *peer = isolate->heap()->GetPeer(raw_obj);
   }
@@ -5486,7 +5490,7 @@
     return Api::NewError(msg, CURRENT_FUNC);
   }
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     RawObject* raw_obj = obj.raw();
     isolate->heap()->SetPeer(raw_obj, peer);
   }
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index d8361e0..fe7c5ea 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -112,7 +112,7 @@
   Dart_StringToCString(script_url, &cstr);
   EXPECT_STREQ("test-lib", cstr);
   EXPECT_EQ(2, line_number);
-  EXPECT_EQ(13, column_number);
+  EXPECT_EQ(10, column_number);
 
   result = Dart_GetActivationFrame(stacktrace, 2, &frame);
   EXPECT_VALID(result);
@@ -124,7 +124,7 @@
   Dart_StringToCString(script_url, &cstr);
   EXPECT_STREQ("test-lib", cstr);
   EXPECT_EQ(3, line_number);
-  EXPECT_EQ(18, column_number);
+  EXPECT_EQ(15, column_number);
 
   // Out-of-bounds frames.
   result = Dart_GetActivationFrame(stacktrace, frame_count, &frame);
@@ -190,7 +190,7 @@
     Dart_StringToCString(script_url, &cstr);
     EXPECT_STREQ("test-lib", cstr);
     EXPECT_EQ(1, line_number);
-    EXPECT_EQ(43, column_number);
+    EXPECT_EQ(40, column_number);
   }
 
   // Bottom frame positioned at testMain().
@@ -204,7 +204,7 @@
   Dart_StringToCString(script_url, &cstr);
   EXPECT_STREQ("test-lib", cstr);
   EXPECT_EQ(2, line_number);
-  EXPECT_EQ(18, column_number);
+  EXPECT_EQ(15, column_number);
 
   // Out-of-bounds frames.
   result = Dart_GetActivationFrame(stacktrace, frame_count, &frame);
@@ -327,7 +327,7 @@
   Dart_StringToCString(script_url, &cstr);
   EXPECT_STREQ("test-lib", cstr);
   EXPECT_EQ(2, line_number);
-  EXPECT_EQ(32, column_number);
+  EXPECT_EQ(20, column_number);
 
   // Middle frames positioned at the recursive call.
   for (intptr_t frame_index = 2;
@@ -343,7 +343,7 @@
     Dart_StringToCString(script_url, &cstr);
     EXPECT_STREQ("test-lib", cstr);
     EXPECT_EQ(2, line_number);
-    EXPECT_EQ(40, column_number);
+    EXPECT_EQ(37, column_number);
   }
 
   // Bottom frame positioned at testMain().
@@ -357,7 +357,7 @@
   Dart_StringToCString(script_url, &cstr);
   EXPECT_STREQ("test-lib", cstr);
   EXPECT_EQ(3, line_number);
-  EXPECT_EQ(18, column_number);
+  EXPECT_EQ(15, column_number);
 
   // Out-of-bounds frames.
   result = Dart_GetActivationFrame(stacktrace, frame_count, &frame);
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index b14ded6..fd1c9de 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -79,10 +79,12 @@
   // Get the entrypoint corresponding to the function specified, this
   // will result in a compilation of the function if it is not already
   // compiled.
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
   if (!function.HasCode()) {
     const Error& error = Error::Handle(
-        isolate, Compiler::CompileFunction(isolate, function));
+        zone, Compiler::CompileFunction(thread, function));
     if (!error.IsNull()) {
       return error.raw();
     }
@@ -90,7 +92,7 @@
   // Now Call the invoke stub which will invoke the dart function.
   invokestub entrypoint = reinterpret_cast<invokestub>(
       isolate->stub_code()->InvokeDartCodeEntryPoint());
-  const Code& code = Code::Handle(isolate, function.CurrentCode());
+  const Code& code = Code::Handle(zone, function.CurrentCode());
   ASSERT(!code.IsNull());
   ASSERT(Isolate::Current()->no_callback_scope_depth() == 0);
   ScopedIsolateStackLimits stack_limit(isolate);
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 1834063..3ffa06b 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -898,7 +898,7 @@
 
 
 void DebuggerStackTrace::AddActivation(ActivationFrame* frame) {
-  if (FLAG_show_invisible_frames || frame->function().is_debuggable()) {
+  if (FLAG_show_invisible_frames || frame->function().is_visible()) {
     trace_.Add(frame);
   }
 }
@@ -1317,7 +1317,7 @@
     // pre-allocated trace (such as a stack overflow) or (b) because a stack has
     // fewer frames that the pre-allocated trace (such as memory exhaustion with
     // a shallow stack).
-    if (!function.IsNull() && function.is_debuggable()) {
+    if (!function.IsNull() && function.is_visible()) {
       code = ex_trace.CodeAtFrame(i);
       ASSERT(function.raw() == code.function());
       uword pc = code.EntryPoint() + Smi::Value(ex_trace.PcOffsetAtFrame(i));
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index 1ee1773..e8df088 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -253,7 +253,7 @@
   const char* func_name_chars_from_func_handle;
   Dart_StringToCString(Dart_FunctionName(func),
                        &func_name_chars_from_func_handle);
-  EXPECT_STREQ(func_name_chars, func_name_chars_from_func_handle);
+  EXPECT_SUBSTRING(func_name_chars_from_func_handle, func_name_chars);
 
   if (!Dart_IsNull(expected_locals)) {
     Dart_Handle locals = Dart_GetLocalVariables(frame);
@@ -1572,7 +1572,7 @@
   Dart_ListSetAt(frame0_locals, 7, Dart_NewInteger(99));
 
   // Frame 1 corresponding to "Test.local1_to_func1".
-  Dart_Handle frame1_locals = Dart_NewList(14);
+  Dart_Handle frame1_locals = Dart_NewList(12);
   Dart_ListSetAt(frame1_locals, 0, NewString("i"));
   Dart_ListSetAt(frame1_locals, 1, Dart_NewInteger(11));
   Dart_ListSetAt(frame1_locals, 2, NewString("j"));
@@ -1585,8 +1585,6 @@
   Dart_ListSetAt(frame1_locals, 9, Dart_NewInteger(55));
   Dart_ListSetAt(frame1_locals, 10, NewString("func"));
   Dart_ListSetAt(frame1_locals, 11, Dart_Null());
-  Dart_ListSetAt(frame1_locals, 12, NewString("n"));
-  Dart_ListSetAt(frame1_locals, 13, Dart_Null());
 
   // Frame 2 corresponding to "Test.func1".
   Dart_Handle frame2_locals = Dart_NewList(18);
@@ -1740,7 +1738,7 @@
   Dart_ListSetAt(frame1_locals, 3, Dart_Null());
 
   // Frame 2 corresponding to "Test.local1_to_func1".
-  Dart_Handle frame2_locals = Dart_NewList(16);
+  Dart_Handle frame2_locals = Dart_NewList(14);
   Dart_ListSetAt(frame2_locals, 0, NewString("i"));
   Dart_ListSetAt(frame2_locals, 1, Dart_NewInteger(11));
   Dart_ListSetAt(frame2_locals, 2, NewString("j"));
@@ -1755,8 +1753,6 @@
   Dart_ListSetAt(frame2_locals, 11, Dart_Null());
   Dart_ListSetAt(frame2_locals, 12, NewString("func"));
   Dart_ListSetAt(frame2_locals, 13, Dart_Null());
-  Dart_ListSetAt(frame2_locals, 14, NewString("n"));
-  Dart_ListSetAt(frame2_locals, 15, Dart_Null());
 
   // Frame 3 corresponding to "Test.func1".
   Dart_Handle frame3_locals = Dart_NewList(18);
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 45dfd81..26b0066 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -10,6 +10,7 @@
 #include "vm/locations.h"
 #include "vm/parser.h"
 #include "vm/stack_frame.h"
+#include "vm/thread.h"
 
 namespace dart {
 
@@ -38,7 +39,7 @@
       num_args_(0),
       deopt_reason_(ICData::kDeoptUnknown),
       deopt_flags_(0),
-      isolate_(Isolate::Current()),
+      thread_(Thread::Current()),
       deferred_slots_(NULL),
       deferred_objects_count_(0),
       deferred_objects_(NULL) {
@@ -338,8 +339,8 @@
 RawArray* DeoptContext::DestFrameAsArray() {
   ASSERT(dest_frame_ != NULL && dest_frame_is_allocated_);
   const Array& dest_array =
-      Array::Handle(isolate(), Array::New(dest_frame_size_));
-  PassiveObject& obj = PassiveObject::Handle(isolate());
+      Array::Handle(zone(), Array::New(dest_frame_size_));
+  PassiveObject& obj = PassiveObject::Handle(zone());
   for (intptr_t i = 0; i < dest_frame_size_; i++) {
     obj = reinterpret_cast<RawObject*>(dest_frame_[i]);
     dest_array.SetAt(i, obj);
@@ -371,12 +372,12 @@
   virtual DeoptInstr::Kind kind() const { return kRetAddress; }
 
   virtual const char* ArgumentsToCString() const {
-    return Isolate::Current()->current_zone()->PrintToString(
+    return Thread::Current()->zone()->PrintToString(
         "%" Pd ", %" Pd "", object_table_index_, deopt_id_);
   }
 
   void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
-    Code& code = Code::Handle(deopt_context->isolate());
+    Code& code = Code::Handle(deopt_context->zone());
     code ^= deopt_context->ObjectAt(object_table_index_);
     ASSERT(!code.IsNull());
     uword continue_at_pc = code.GetPcForDeoptId(deopt_id_,
@@ -433,13 +434,13 @@
   virtual DeoptInstr::Kind kind() const { return kConstant; }
 
   virtual const char* ArgumentsToCString() const {
-    return Isolate::Current()->current_zone()->PrintToString(
+    return Thread::Current()->zone()->PrintToString(
         "%" Pd "", object_table_index_);
   }
 
   void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     const PassiveObject& obj = PassiveObject::Handle(
-        deopt_context->isolate(), deopt_context->ObjectAt(object_table_index_));
+        deopt_context->zone(), deopt_context->ObjectAt(object_table_index_));
     *reinterpret_cast<RawObject**>(dest_addr) = obj.raw();
   }
 
@@ -522,7 +523,7 @@
   virtual DeoptInstr::Kind kind() const { return kMintPair; }
 
   virtual const char* ArgumentsToCString() const {
-    return Isolate::Current()->current_zone()->PrintToString(
+    return Thread::Current()->zone()->PrintToString(
         "%s,%s",
         lo_.ToCString(),
         hi_.ToCString());
@@ -635,12 +636,12 @@
   virtual DeoptInstr::Kind kind() const { return kPcMarker; }
 
   virtual const char* ArgumentsToCString() const {
-    return Isolate::Current()->current_zone()->PrintToString(
+    return Thread::Current()->zone()->PrintToString(
         "%" Pd "", object_table_index_);
   }
 
   void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
-    Code& code = Code::Handle(deopt_context->isolate());
+    Code& code = Code::Handle(deopt_context->zone());
     code ^= deopt_context->ObjectAt(object_table_index_);
     if (code.IsNull()) {
       // Callee's PC marker is not used (pc of Deoptimize stub). Set to 0.
@@ -648,7 +649,7 @@
       return;
     }
     const Function& function =
-        Function::Handle(deopt_context->isolate(), code.function());
+        Function::Handle(deopt_context->zone(), code.function());
     ASSERT(function.HasCode());
     const intptr_t pc_marker =
         code.EntryPoint() + Assembler::EntryPointToPcMarkerOffset();
@@ -689,12 +690,12 @@
   virtual DeoptInstr::Kind kind() const { return kPp; }
 
   virtual const char* ArgumentsToCString() const {
-    return Isolate::Current()->current_zone()->PrintToString(
+    return Thread::Current()->zone()->PrintToString(
         "%" Pd "", object_table_index_);
   }
 
   void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
-    Code& code = Code::Handle(deopt_context->isolate());
+    Code& code = Code::Handle(deopt_context->zone());
     code ^= deopt_context->ObjectAt(object_table_index_);
     ASSERT(!code.IsNull());
     const intptr_t pp = reinterpret_cast<intptr_t>(code.ObjectPool());
@@ -786,7 +787,7 @@
   virtual DeoptInstr::Kind kind() const { return kSuffix; }
 
   virtual const char* ArgumentsToCString() const {
-    return Isolate::Current()->current_zone()->PrintToString(
+    return Thread::Current()->zone()->PrintToString(
         "%" Pd ":%" Pd, info_number_, suffix_length_);
   }
 
@@ -825,7 +826,7 @@
   virtual DeoptInstr::Kind kind() const { return kMaterializedObjectRef; }
 
   virtual const char* ArgumentsToCString() const {
-    return Isolate::Current()->current_zone()->PrintToString(
+    return Thread::Current()->zone()->PrintToString(
         "#%" Pd "", index_);
   }
 
@@ -856,7 +857,7 @@
   virtual DeoptInstr::Kind kind() const { return kMaterializeObject; }
 
   virtual const char* ArgumentsToCString() const {
-    return Isolate::Current()->current_zone()->PrintToString(
+    return Thread::Current()->zone()->PrintToString(
         "%" Pd "", field_count_);
   }
 
@@ -1023,13 +1024,13 @@
 };
 
 
-DeoptInfoBuilder::DeoptInfoBuilder(Isolate* isolate, const intptr_t num_args)
-    : isolate_(isolate),
+DeoptInfoBuilder::DeoptInfoBuilder(Zone* zone, const intptr_t num_args)
+    : zone_(zone),
       instructions_(),
       object_table_(GrowableObjectArray::Handle(
           GrowableObjectArray::New(Heap::kOld))),
       num_args_(num_args),
-      trie_root_(new(isolate) TrieNode()),
+      trie_root_(new(zone) TrieNode()),
       current_info_number_(0),
       frame_start_(-1),
       materializations_() {
@@ -1094,7 +1095,7 @@
   const intptr_t object_table_index = FindOrAddObjectInTable(code);
   ASSERT(dest_index == FrameSize());
   instructions_.Add(
-      new(isolate()) DeoptRetAddressInstr(object_table_index, deopt_id));
+      new(zone()) DeoptRetAddressInstr(object_table_index, deopt_id));
 }
 
 
@@ -1102,7 +1103,7 @@
                                    intptr_t dest_index) {
   intptr_t object_table_index = FindOrAddObjectInTable(code);
   ASSERT(dest_index == FrameSize());
-  instructions_.Add(new(isolate()) DeoptPcMarkerInstr(object_table_index));
+  instructions_.Add(new(zone()) DeoptPcMarkerInstr(object_table_index));
 }
 
 
@@ -1110,7 +1111,7 @@
                              intptr_t dest_index) {
   intptr_t object_table_index = FindOrAddObjectInTable(code);
   ASSERT(dest_index == FrameSize());
-  instructions_.Add(new(isolate()) DeoptPpInstr(object_table_index));
+  instructions_.Add(new(zone()) DeoptPpInstr(object_table_index));
 }
 
 
@@ -1120,55 +1121,55 @@
   DeoptInstr* deopt_instr = NULL;
   if (source_loc.IsConstant()) {
     intptr_t object_table_index = FindOrAddObjectInTable(source_loc.constant());
-    deopt_instr = new(isolate()) DeoptConstantInstr(object_table_index);
+    deopt_instr = new(zone()) DeoptConstantInstr(object_table_index);
   } else if (source_loc.IsInvalid() &&
              value->definition()->IsMaterializeObject()) {
     const intptr_t index = FindMaterialization(
         value->definition()->AsMaterializeObject());
     ASSERT(index >= 0);
-    deopt_instr = new(isolate()) DeoptMaterializedObjectRefInstr(index);
+    deopt_instr = new(zone()) DeoptMaterializedObjectRefInstr(index);
   } else {
     ASSERT(!source_loc.IsInvalid());
     switch (value->definition()->representation()) {
       case kTagged:
-        deopt_instr = new(isolate()) DeoptWordInstr(
+        deopt_instr = new(zone()) DeoptWordInstr(
           ToCpuRegisterSource(source_loc));
         break;
       case kUnboxedMint: {
         if (source_loc.IsPairLocation()) {
           PairLocation* pair = source_loc.AsPairLocation();
-          deopt_instr = new(isolate()) DeoptMintPairInstr(
+          deopt_instr = new(zone()) DeoptMintPairInstr(
               ToCpuRegisterSource(pair->At(0)),
               ToCpuRegisterSource(pair->At(1)));
         } else {
           ASSERT(!source_loc.IsPairLocation());
-          deopt_instr = new(isolate()) DeoptMintInstr(
+          deopt_instr = new(zone()) DeoptMintInstr(
               ToCpuRegisterSource(source_loc));
         }
         break;
       }
       case kUnboxedInt32:
-        deopt_instr = new(isolate()) DeoptInt32Instr(
+        deopt_instr = new(zone()) DeoptInt32Instr(
             ToCpuRegisterSource(source_loc));
         break;
       case kUnboxedUint32:
-        deopt_instr = new(isolate()) DeoptUint32Instr(
+        deopt_instr = new(zone()) DeoptUint32Instr(
             ToCpuRegisterSource(source_loc));
         break;
       case kUnboxedDouble:
-        deopt_instr = new(isolate()) DeoptDoubleInstr(
+        deopt_instr = new(zone()) DeoptDoubleInstr(
             ToFpuRegisterSource(source_loc, Location::kDoubleStackSlot));
         break;
       case kUnboxedFloat32x4:
-        deopt_instr = new(isolate()) DeoptFloat32x4Instr(
+        deopt_instr = new(zone()) DeoptFloat32x4Instr(
             ToFpuRegisterSource(source_loc, Location::kQuadStackSlot));
         break;
       case kUnboxedFloat64x2:
-        deopt_instr = new(isolate()) DeoptFloat64x2Instr(
+        deopt_instr = new(zone()) DeoptFloat64x2Instr(
             ToFpuRegisterSource(source_loc, Location::kQuadStackSlot));
         break;
       case kUnboxedInt32x4:
-        deopt_instr = new(isolate()) DeoptInt32x4Instr(
+        deopt_instr = new(zone()) DeoptInt32x4Instr(
             ToFpuRegisterSource(source_loc, Location::kQuadStackSlot));
         break;
       default:
@@ -1184,26 +1185,26 @@
 
 void DeoptInfoBuilder::AddCallerFp(intptr_t dest_index) {
   ASSERT(dest_index == FrameSize());
-  instructions_.Add(new(isolate()) DeoptCallerFpInstr());
+  instructions_.Add(new(zone()) DeoptCallerFpInstr());
 }
 
 
 void DeoptInfoBuilder::AddCallerPp(intptr_t dest_index) {
   ASSERT(dest_index == FrameSize());
-  instructions_.Add(new(isolate()) DeoptCallerPpInstr());
+  instructions_.Add(new(zone()) DeoptCallerPpInstr());
 }
 
 
 void DeoptInfoBuilder::AddCallerPc(intptr_t dest_index) {
   ASSERT(dest_index == FrameSize());
-  instructions_.Add(new(isolate()) DeoptCallerPcInstr());
+  instructions_.Add(new(zone()) DeoptCallerPcInstr());
 }
 
 
 void DeoptInfoBuilder::AddConstant(const Object& obj, intptr_t dest_index) {
   ASSERT(dest_index == FrameSize());
   intptr_t object_table_index = FindOrAddObjectInTable(obj);
-  instructions_.Add(new(isolate()) DeoptConstantInstr(object_table_index));
+  instructions_.Add(new(zone()) DeoptConstantInstr(object_table_index));
 }
 
 
@@ -1225,7 +1226,7 @@
   }
 
   instructions_.Add(
-      new(isolate()) DeoptMaterializeObjectInstr(non_null_fields));
+      new(zone()) DeoptMaterializeObjectInstr(non_null_fields));
 
   for (intptr_t i = 0; i < mat->InputCount(); i++) {
     MaterializeObjectInstr* nested_mat = mat->InputAt(i)->definition()->
@@ -1293,7 +1294,7 @@
   // than one instruction, we replace it with a single suffix instruction.
   if (suffix_length > 1) length -= (suffix_length - 1);
   const DeoptInfo& deopt_info =
-      DeoptInfo::Handle(isolate(), DeoptInfo::New(length));
+      DeoptInfo::Handle(zone(), DeoptInfo::New(length));
 
   // Write the unshared instructions and build their sub-tree.
   TrieNode* node = NULL;
@@ -1302,14 +1303,14 @@
     DeoptInstr* instr = instructions_[i];
     deopt_info.SetAt(i, instr->kind(), instr->source_index());
     TrieNode* child = node;
-    node = new(isolate()) TrieNode(instr, current_info_number_);
+    node = new(zone()) TrieNode(instr, current_info_number_);
     node->AddChild(child);
   }
 
   if (suffix_length > 1) {
     suffix->AddChild(node);
     DeoptInstr* instr =
-        new(isolate()) DeoptSuffixInstr(suffix->info_number(), suffix_length);
+        new(zone()) DeoptSuffixInstr(suffix->info_number(), suffix_length);
     deopt_info.SetAt(length - 1, instr->kind(), instr->source_index());
   } else {
     trie_root_->AddChild(node);
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 683750b..6154e06 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -12,6 +12,7 @@
 #include "vm/growable_array.h"
 #include "vm/locations.h"
 #include "vm/object.h"
+#include "vm/thread.h"
 
 namespace dart {
 
@@ -84,7 +85,7 @@
     dest_frame_ = dest_frame;
   }
 
-  Isolate* isolate() const { return isolate_; }
+  Zone* zone() const { return thread_->zone(); }
 
   intptr_t source_frame_size() const { return source_frame_size_; }
   intptr_t dest_frame_size() const { return dest_frame_size_; }
@@ -196,7 +197,7 @@
   ICData::DeoptReasonId deopt_reason_;
   uint32_t deopt_flags_;
   intptr_t caller_fp_;
-  Isolate* isolate_;
+  Thread* thread_;
 
   DeferredSlot* deferred_slots_;
 
@@ -247,7 +248,7 @@
   virtual const char* ToCString() const {
     const char* args = ArgumentsToCString();
     if (args != NULL) {
-      return Isolate::Current()->current_zone()->PrintToString(
+      return Thread::Current()->zone()->PrintToString(
           "%s(%s)", KindToCString(kind()), args);
     } else {
       return KindToCString(kind());
@@ -362,7 +363,7 @@
     if (is_register()) {
       return Name(reg());
     } else {
-      return Isolate::Current()->current_zone()->PrintToString(
+      return Thread::Current()->zone()->PrintToString(
           "s%" Pd "", raw_index());
     }
   }
@@ -401,7 +402,7 @@
 // the heap and reset the builder's internal state for the next DeoptInfo.
 class DeoptInfoBuilder : public ValueObject {
  public:
-  DeoptInfoBuilder(Isolate* isolate, const intptr_t num_args);
+  DeoptInfoBuilder(Zone* zone, const intptr_t num_args);
 
   // 'object_table' holds all objects referred to by DeoptInstr in
   // all DeoptInfo instances for a single Code object.
@@ -462,9 +463,9 @@
 
   void AddConstant(const Object& obj, intptr_t dest_index);
 
-  Isolate* isolate() const { return isolate_; }
+  Zone* zone() const { return zone_; }
 
-  Isolate* isolate_;
+  Zone* zone_;
 
   GrowableArray<DeoptInstr*> instructions_;
   const GrowableObjectArray& object_table_;
diff --git a/runtime/vm/disassembler.cc b/runtime/vm/disassembler.cc
index ac8356e..80e1ff6 100644
--- a/runtime/vm/disassembler.cc
+++ b/runtime/vm/disassembler.cc
@@ -104,7 +104,7 @@
 
 bool Disassembler::CanFindOldObject(uword addr) {
   FindAddrVisitor visitor(addr);
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   return Isolate::Current()->heap()->FindOldObject(&visitor) != Object::null();
 }
 
diff --git a/runtime/vm/disassembler_ia32.cc b/runtime/vm/disassembler_ia32.cc
index cd917d4..b933302 100644
--- a/runtime/vm/disassembler_ia32.cc
+++ b/runtime/vm/disassembler_ia32.cc
@@ -497,7 +497,7 @@
       reinterpret_cast<RawObject*>(addr)->IsOldObject() &&
       !Isolate::Current()->heap()->CodeContains(addr) &&
       Disassembler::CanFindOldObject(addr)) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     const Object& obj = Object::Handle(reinterpret_cast<RawObject*>(addr));
     if (obj.IsArray()) {
       const Array& arr = Array::Cast(obj);
diff --git a/runtime/vm/disassembler_x64.cc b/runtime/vm/disassembler_x64.cc
index 8279d4b..be31deb 100644
--- a/runtime/vm/disassembler_x64.cc
+++ b/runtime/vm/disassembler_x64.cc
@@ -813,7 +813,7 @@
       reinterpret_cast<RawObject*>(addr)->IsOldObject() &&
       !Isolate::Current()->heap()->CodeContains(addr) &&
       Disassembler::CanFindOldObject(addr)) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     const Object& obj = Object::Handle(reinterpret_cast<RawObject*>(addr));
     if (obj.IsArray()) {
       const Array& arr = Array::Cast(obj);
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index f3cbb88..1ef229f 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -202,7 +202,7 @@
                                    const Object& stacktrace_object) {
   // The no_gc StackResource is unwound through the tear down of
   // stack resources below.
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   RawObject* raw_exception = exception_object.raw();
   RawObject* raw_stacktrace = stacktrace_object.raw();
 
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index fbef3fe..8327146 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -100,7 +100,7 @@
   if (constant == NULL) {
     // Otherwise, allocate and add it to the pool.
     constant = new(zone()) ConstantInstr(
-        Object::ZoneHandle(isolate(), object.raw()));
+        Object::ZoneHandle(zone(), object.raw()));
     constant->set_ssa_temp_index(alloc_ssa_temp_index());
 
     AddToInitialDefinitions(constant);
@@ -136,7 +136,9 @@
   }
   instr->InsertAfter(prev);
   ASSERT(instr->env() == NULL);
-  if (env != NULL) env->DeepCopyTo(isolate(), instr);
+  if (env != NULL) {
+    env->DeepCopyTo(zone(), instr);
+  }
 }
 
 
@@ -149,7 +151,9 @@
     AllocateSSAIndexes(instr->AsDefinition());
   }
   ASSERT(instr->env() == NULL);
-  if (env != NULL) env->DeepCopyTo(isolate(), instr);
+  if (env != NULL) {
+    env->DeepCopyTo(zone(), instr);
+  }
   return prev->AppendInstruction(instr);
 }
 
@@ -884,12 +888,12 @@
 void FlowGraph::AttachEnvironment(Instruction* instr,
                                   GrowableArray<Definition*>* env) {
   Environment* deopt_env =
-      Environment::From(isolate(),
+      Environment::From(zone(),
                         *env,
                         num_non_copied_params_,
                         parsed_function_);
   if (instr->IsClosureCall()) {
-    deopt_env = deopt_env->DeepCopy(isolate(),
+    deopt_env = deopt_env->DeepCopy(zone(),
                                     deopt_env->Length() - instr->InputCount());
   }
   instr->SetEnvironment(deopt_env);
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index f5cf662..d962f90 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -230,7 +230,7 @@
   // have to keep deoptimization environment at gotos for LICM purposes.
   void CopyDeoptTarget(Instruction* to, Instruction* from) {
     if (is_licm_allowed()) {
-      to->InheritDeoptTarget(isolate(), from);
+      to->InheritDeoptTarget(zone(), from);
     }
   }
 
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index fdbe56a..db4b32e 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -43,8 +43,8 @@
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
 
-// Quick access to the locally defined isolate() method.
-#define I (isolate())
+// Quick access to the locally defined zone() method.
+#define Z (zone())
 
 // TODO(srdjan): Allow compiler to add constants as they are encountered in
 // the compilation.
@@ -125,7 +125,7 @@
   if (label != label_) return NULL;
   if (break_target_ == NULL) {
     break_target_ =
-        new(owner()->isolate()) JoinEntryInstr(owner()->AllocateBlockId(),
+        new(owner()->zone()) JoinEntryInstr(owner()->AllocateBlockId(),
                                                owner()->try_index());
   }
   return break_target_;
@@ -183,7 +183,7 @@
   if (label != this->label()) return NULL;
   if (continue_target_ == NULL) {
     continue_target_ =
-        new(owner()->isolate()) JoinEntryInstr(owner()->AllocateBlockId(),
+        new(owner()->zone()) JoinEntryInstr(owner()->AllocateBlockId(),
                                                try_index());
   }
   return continue_target_;
@@ -227,7 +227,7 @@
     if (label != case_labels_[i]) continue;
     if (case_targets_[i] == NULL) {
       case_targets_[i] =
-          new(owner()->isolate()) JoinEntryInstr(owner()->AllocateBlockId(),
+          new(owner()->zone()) JoinEntryInstr(owner()->AllocateBlockId(),
                                                  try_index());
     }
     return case_targets_[i];
@@ -260,8 +260,8 @@
         nesting_stack_(NULL),
         osr_id_(osr_id),
         jump_count_(0),
-        await_joins_(new(I) ZoneGrowableArray<JoinEntryInstr*>()),
-        await_levels_(new(I) ZoneGrowableArray<intptr_t>()) { }
+        await_joins_(new(Z) ZoneGrowableArray<JoinEntryInstr*>()),
+        await_levels_(new(Z) ZoneGrowableArray<intptr_t>()) { }
 
 
 void FlowGraphBuilder::AddCatchEntry(CatchBlockEntryInstr* entry) {
@@ -294,7 +294,7 @@
     }
     Instruction* instr = block;
     if (block->env() != NULL) {
-      call_->env()->DeepCopyToOuter(callee_graph->isolate(), block);
+      call_->env()->DeepCopyToOuter(callee_graph->zone(), block);
     }
     for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
       instr = it.Current();
@@ -302,7 +302,7 @@
       // optimizations need deoptimization info for non-deoptable instructions,
       // eg, LICM on GOTOs.
       if (instr->env() != NULL) {
-        call_->env()->DeepCopyToOuter(callee_graph->isolate(), instr);
+        call_->env()->DeepCopyToOuter(callee_graph->zone(), instr);
       }
     }
     if (instr->IsGoto()) {
@@ -360,7 +360,7 @@
     intptr_t join_id = caller_graph_->max_block_id() + 1;
     caller_graph_->set_max_block_id(join_id);
     JoinEntryInstr* join =
-        new(I) JoinEntryInstr(join_id, try_index);
+        new(Z) JoinEntryInstr(join_id, try_index);
 
     // The dominator set of the join is the intersection of the dominator
     // sets of all the predecessors.  If we keep the dominator sets ordered
@@ -378,8 +378,8 @@
     GrowableArray<BlockEntryInstr*> join_dominators;
     for (intptr_t i = 0; i < num_exits; ++i) {
       // Add the control-flow edge.
-      GotoInstr* goto_instr = new(I) GotoInstr(join);
-      goto_instr->InheritDeoptTarget(isolate(), ReturnAt(i));
+      GotoInstr* goto_instr = new(Z) GotoInstr(join);
+      goto_instr->InheritDeoptTarget(zone(), ReturnAt(i));
       LastInstructionAt(i)->LinkTo(goto_instr);
       ExitBlockAt(i)->set_last_instruction(LastInstructionAt(i)->next());
       join->predecessors_.Add(ExitBlockAt(i));
@@ -424,7 +424,7 @@
     // If the call has uses, create a phi of the returns.
     if (call_->HasUses()) {
       // Add a phi of the return values.
-      PhiInstr* phi = new(I) PhiInstr(join, num_exits);
+      PhiInstr* phi = new(Z) PhiInstr(join, num_exits);
       phi->set_ssa_temp_index(caller_graph_->alloc_ssa_temp_index());
       phi->mark_alive();
       for (intptr_t i = 0; i < num_exits; ++i) {
@@ -464,7 +464,7 @@
     // goes to the rest of the caller graph. It is removed as unreachable code
     // by the constant propagation.
     TargetEntryInstr* false_block =
-        new(I) TargetEntryInstr(caller_graph_->allocate_block_id(),
+        new(Z) TargetEntryInstr(caller_graph_->allocate_block_id(),
                                 call_block->try_index());
     false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL);
     false_block->LinkTo(call_->next());
@@ -472,13 +472,13 @@
 
     ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True());
     BranchInstr* branch =
-        new(I) BranchInstr(
-            new(I) StrictCompareInstr(call_block->start_pos(),
+        new(Z) BranchInstr(
+            new(Z) StrictCompareInstr(call_block->start_pos(),
                                       Token::kEQ_STRICT,
-                                      new(I) Value(true_const),
-                                      new(I) Value(true_const),
+                                      new(Z) Value(true_const),
+                                      new(Z) Value(true_const),
                                       false));  // No number check.
-    branch->InheritDeoptTarget(isolate(), call_);
+    branch->InheritDeoptTarget(zone(), call_);
     *branch->true_successor_address() = callee_entry;
     *branch->false_successor_address() = false_block;
 
@@ -584,7 +584,7 @@
     exit()->LinkTo(definition);
   }
   exit_ = definition;
-  return new(I) Value(definition);
+  return new(Z) Value(definition);
 }
 
 
@@ -618,7 +618,7 @@
 
 void EffectGraphVisitor::AddReturnExit(intptr_t token_pos, Value* value) {
   ASSERT(is_open());
-  ReturnInstr* return_instr = new(I) ReturnInstr(token_pos, value);
+  ReturnInstr* return_instr = new(Z) ReturnInstr(token_pos, value);
   AddInstruction(return_instr);
   InlineExitCollector* exit_collector = owner()->exit_collector();
   if (exit_collector != NULL) {
@@ -631,7 +631,7 @@
 void EffectGraphVisitor::Goto(JoinEntryInstr* join) {
   ASSERT(is_open());
   if (is_empty()) {
-    entry_ = new(I) GotoInstr(join);
+    entry_ = new(Z) GotoInstr(join);
   } else {
     exit()->Goto(join);
   }
@@ -681,7 +681,7 @@
     exit_ = true_exit;
   } else {
     JoinEntryInstr* join =
-        new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
+        new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
     true_exit->Goto(join);
     false_exit->Goto(join);
     exit_ = join;
@@ -712,9 +712,9 @@
     Append(test_fragment);
   } else {
     JoinEntryInstr* join =
-        new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
+        new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
     CheckStackOverflowInstr* check =
-        new(I) CheckStackOverflowInstr(token_pos, owner()->loop_depth());
+        new(Z) CheckStackOverflowInstr(token_pos, owner()->loop_depth());
     join->LinkTo(check);
     if (!test_preamble_fragment.is_empty()) {
       check->LinkTo(test_preamble_fragment.entry());
@@ -734,7 +734,7 @@
 
 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) {
   owner_->add_args_pushed(1);
-  PushArgumentInstr* result = new(I) PushArgumentInstr(value);
+  PushArgumentInstr* result = new(Z) PushArgumentInstr(value);
   AddInstruction(result);
   return result;
 }
@@ -743,7 +743,7 @@
 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local,
                                                Value* value) {
   ASSERT(!local.is_captured());
-  return new(I) StoreLocalInstr(local, value);
+  return new(Z) StoreLocalInstr(local, value);
 }
 
 
@@ -767,13 +767,13 @@
     ASSERT(delta >= 0);
     Value* context = Bind(BuildCurrentContext());
     while (delta-- > 0) {
-      context = Bind(new(I) LoadFieldInstr(
-          context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()),
+      context = Bind(new(Z) LoadFieldInstr(
+          context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
           Scanner::kNoSourcePos));
     }
-    Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var));
+    Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
     StoreInstanceFieldInstr* store =
-        new(I) StoreInstanceFieldInstr(Context::variable_offset(local.index()),
+        new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()),
                                        context,
                                        tmp_val,
                                        kEmitStoreBarrier,
@@ -781,30 +781,30 @@
     Do(store);
     return ExitTempLocalScope(tmp_var);
   } else {
-    return new(I) StoreLocalInstr(local, value);
+    return new(Z) StoreLocalInstr(local, value);
   }
 }
 
 
 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) {
   if (local.IsConst()) {
-    return new(I) ConstantInstr(*local.ConstValue());
+    return new(Z) ConstantInstr(*local.ConstValue());
   } else if (local.is_captured()) {
     intptr_t delta =
         owner()->context_level() - local.owner()->context_level();
     ASSERT(delta >= 0);
     Value* context = Bind(BuildCurrentContext());
     while (delta-- > 0) {
-      context = Bind(new(I) LoadFieldInstr(
-          context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()),
+      context = Bind(new(Z) LoadFieldInstr(
+          context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
           Scanner::kNoSourcePos));
     }
-    return new(I) LoadFieldInstr(context,
+    return new(Z) LoadFieldInstr(context,
                               Context::variable_offset(local.index()),
                               local.type(),
                               Scanner::kNoSourcePos);
   } else {
-    return new(I) LoadLocalInstr(local);
+    return new(Z) LoadLocalInstr(local);
   }
 }
 
@@ -824,13 +824,13 @@
 
 
 Definition* EffectGraphVisitor::BuildStoreContext(Value* value) {
-  return new(I) StoreLocalInstr(
+  return new(Z) StoreLocalInstr(
       *owner()->parsed_function().current_context_var(), value);
 }
 
 
 Definition* EffectGraphVisitor::BuildCurrentContext() {
-  return new(I) LoadLocalInstr(
+  return new(Z) LoadLocalInstr(
       *owner()->parsed_function().current_context_var());
 }
 
@@ -841,7 +841,7 @@
   ASSERT(!branches.is_empty());
   for (intptr_t i = 0; i < branches.length(); i++) {
     TargetEntryInstr* target =
-        new(I) TargetEntryInstr(owner()->AllocateBlockId(),
+        new(Z) TargetEntryInstr(owner()->AllocateBlockId(),
                                 owner()->try_index());
     *(branches[i]) = target;
     target->Goto(join);
@@ -865,14 +865,14 @@
 
   if (branches.length() == 1) {
     TargetEntryInstr* target =
-        new(I) TargetEntryInstr(owner()->AllocateBlockId(),
+        new(Z) TargetEntryInstr(owner()->AllocateBlockId(),
                                 owner()->try_index());
     *(branches[0]) = target;
     return target;
   }
 
   JoinEntryInstr* join =
-      new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
+      new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
   ConnectBranchesTo(branches, join);
   return join;
 }
@@ -891,16 +891,16 @@
 void TestGraphVisitor::ReturnValue(Value* value) {
   if (Isolate::Current()->TypeChecksEnabled() ||
       Isolate::Current()->AssertsEnabled()) {
-    value = Bind(new(I) AssertBooleanInstr(condition_token_pos(), value));
+    value = Bind(new(Z) AssertBooleanInstr(condition_token_pos(), value));
   }
-  Value* constant_true = Bind(new(I) ConstantInstr(Bool::True()));
+  Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
   StrictCompareInstr* comp =
-      new(I) StrictCompareInstr(condition_token_pos(),
+      new(Z) StrictCompareInstr(condition_token_pos(),
                                 Token::kEQ_STRICT,
                                 value,
                                 constant_true,
                                 false);  // No number check.
-  BranchInstr* branch = new(I) BranchInstr(comp);
+  BranchInstr* branch = new(Z) BranchInstr(comp);
   AddInstruction(branch);
   CloseFragment();
 
@@ -913,18 +913,18 @@
   BranchInstr* branch;
   if (Token::IsStrictEqualityOperator(comp->kind())) {
     ASSERT(comp->IsStrictCompare());
-    branch = new(I) BranchInstr(comp);
+    branch = new(Z) BranchInstr(comp);
   } else if (Token::IsEqualityOperator(comp->kind()) &&
              (comp->left()->BindsToConstantNull() ||
               comp->right()->BindsToConstantNull())) {
-    branch = new(I) BranchInstr(new(I) StrictCompareInstr(
+    branch = new(Z) BranchInstr(new(Z) StrictCompareInstr(
         comp->token_pos(),
         (comp->kind() == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
         comp->left(),
         comp->right(),
         false));  // No number check.
   } else {
-    branch = new(I) BranchInstr(comp);
+    branch = new(Z) BranchInstr(comp);
     branch->set_is_checked(Isolate::Current()->TypeChecksEnabled());
   }
   AddInstruction(branch);
@@ -936,14 +936,14 @@
 
 void TestGraphVisitor::MergeBranchWithNegate(BooleanNegateInstr* neg) {
   ASSERT(!Isolate::Current()->TypeChecksEnabled());
-  Value* constant_true = Bind(new(I) ConstantInstr(Bool::True()));
+  Value* constant_true = Bind(new(Z) ConstantInstr(Bool::True()));
   StrictCompareInstr* comp =
-      new(I) StrictCompareInstr(condition_token_pos(),
+      new(Z) StrictCompareInstr(condition_token_pos(),
                              Token::kNE_STRICT,
                              neg->value(),
                              constant_true,
                              false);  // No number check.
-  BranchInstr* branch = new(I) BranchInstr(comp);
+  BranchInstr* branch = new(Z) BranchInstr(comp);
   AddInstruction(branch);
   CloseFragment();
   true_successor_addresses_.Add(branch->true_successor_address());
@@ -1042,7 +1042,7 @@
   // statements for which there is no associated source position.
   const Function& function = owner()->function();
   if ((node->token_pos() != Scanner::kNoSourcePos) && !function.is_native()) {
-    AddInstruction(new(I) DebugStepCheckInstr(node->token_pos(),
+    AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(),
                                               RawPcDescriptors::kRuntimeCall));
   }
 
@@ -1058,7 +1058,7 @@
     // However, factories may create an instance of the wrong type.
     if (!is_implicit_dynamic_getter && !function.IsGenerativeConstructor()) {
       const AbstractType& dst_type =
-          AbstractType::ZoneHandle(I, function.result_type());
+          AbstractType::ZoneHandle(Z, function.result_type());
       return_value = BuildAssignableValue(node->value()->token_pos(),
                                           return_value,
                                           dst_type,
@@ -1084,12 +1084,12 @@
         node->scope()->LookupVariable(Symbols::AsyncCompleter(), false);
     ASSERT(rcv_var != NULL && rcv_var->is_captured());
     ZoneGrowableArray<PushArgumentInstr*>* arguments =
-        new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+        new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
     Value* rcv_value = Bind(BuildLoadLocal(*rcv_var));
     arguments->Add(PushArgument(rcv_value));
     Value* returned_value = Bind(BuildLoadExprTemp());
     arguments->Add(PushArgument(returned_value));
-    InstanceCallInstr* call = new(I) InstanceCallInstr(
+    InstanceCallInstr* call = new(Z) InstanceCallInstr(
         Scanner::kNoSourcePos,
         Symbols::CompleterComplete(),
         Token::kILLEGAL,
@@ -1115,7 +1115,7 @@
       function.IsSyncGenClosure() ||
       function.IsAsyncGenClosure()) &&
       (node->return_type() == ReturnNode::kContinuationTarget)) {
-    JoinEntryInstr* const join = new(I) JoinEntryInstr(
+    JoinEntryInstr* const join = new(Z) JoinEntryInstr(
         owner()->AllocateBlockId(), owner()->try_index());
     owner()->await_joins()->Add(join);
     exit_ = join;
@@ -1125,7 +1125,7 @@
 
 // <Expression> ::= Literal { literal: Instance }
 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
-  ReturnDefinition(new(I) ConstantInstr(node->literal()));
+  ReturnDefinition(new(Z) ConstantInstr(node->literal()));
 }
 
 
@@ -1142,13 +1142,13 @@
   // Type may be malbounded, but not malformed.
   ASSERT(type.IsFinalized() && !type.IsMalformed());
   if (type.IsInstantiated()) {
-    ReturnDefinition(new(I) ConstantInstr(type));
+    ReturnDefinition(new(Z) ConstantInstr(type));
   } else {
     const Class& instantiator_class = Class::ZoneHandle(
-        I, owner()->function().Owner());
+        Z, owner()->function().Owner());
     Value* instantiator_value = BuildInstantiatorTypeArguments(
         node->token_pos(), instantiator_class, NULL);
-    ReturnDefinition(new(I) InstantiateTypeInstr(
+    ReturnDefinition(new(Z) InstantiateTypeInstr(
         node->token_pos(), type, instantiator_class, instantiator_value));
   }
 }
@@ -1213,7 +1213,7 @@
                        node->type(),
                        node->dst_name())) {
     // Drop the value and 0 additional temporaries.
-    checked_value = new(I) DropTempsInstr(0, for_value.value());
+    checked_value = new(Z) DropTempsInstr(0, for_value.value());
   } else {
     checked_value = BuildAssertAssignable(node->expr()->token_pos(),
                                           for_value.value(),
@@ -1251,7 +1251,7 @@
       ValueGraphVisitor for_right(owner());
       node->right()->Visit(&for_right);
       Value* right_value = for_right.value();
-      for_right.Do(new(I) AssertBooleanInstr(node->right()->token_pos(),
+      for_right.Do(new(Z) AssertBooleanInstr(node->right()->token_pos(),
                                              right_value));
       if (node->kind() == Token::kAND) {
         Join(for_left, for_right, empty);
@@ -1280,12 +1280,12 @@
   PushArgumentInstr* push_right = PushArgument(for_right_value.value());
 
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
   arguments->Add(push_left);
   arguments->Add(push_right);
-  const String& name = String::ZoneHandle(I, Symbols::New(node->TokenName()));
+  const String& name = String::ZoneHandle(Z, Symbols::New(node->TokenName()));
   const intptr_t kNumArgsChecked = 2;
-  InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(),
+  InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(),
                                                      name,
                                                      node->kind(),
                                                      arguments,
@@ -1315,12 +1315,12 @@
     if (Isolate::Current()->TypeChecksEnabled() ||
         Isolate::Current()->AssertsEnabled()) {
       right_value =
-          for_right.Bind(new(I) AssertBooleanInstr(node->right()->token_pos(),
+          for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(),
                                                    right_value));
     }
-    Value* constant_true = for_right.Bind(new(I) ConstantInstr(Bool::True()));
+    Value* constant_true = for_right.Bind(new(Z) ConstantInstr(Bool::True()));
     Value* compare =
-        for_right.Bind(new(I) StrictCompareInstr(node->token_pos(),
+        for_right.Bind(new(Z) StrictCompareInstr(node->token_pos(),
                                                  Token::kEQ_STRICT,
                                                  right_value,
                                                  constant_true,
@@ -1330,13 +1330,13 @@
     if (node->kind() == Token::kAND) {
       ValueGraphVisitor for_false(owner());
       Value* constant_false =
-          for_false.Bind(new(I) ConstantInstr(Bool::False()));
+          for_false.Bind(new(Z) ConstantInstr(Bool::False()));
       for_false.Do(BuildStoreExprTemp(constant_false));
       Join(for_test, for_right, for_false);
     } else {
       ASSERT(node->kind() == Token::kOR);
       ValueGraphVisitor for_true(owner());
-      Value* constant_true = for_true.Bind(new(I) ConstantInstr(Bool::True()));
+      Value* constant_true = for_true.Bind(new(Z) ConstantInstr(Bool::True()));
       for_true.Do(BuildStoreExprTemp(constant_true));
       Join(for_test, for_true, for_right);
     }
@@ -1352,7 +1352,7 @@
     return Library::PrivateCoreLibName(Symbols::_leftShiftWithMask32());
   }
   UNIMPLEMENTED();
-  return String::ZoneHandle(Isolate::Current(), String::null());
+  return String::ZoneHandle(Thread::Current()->zone(), String::null());
 }
 
 
@@ -1373,18 +1373,18 @@
   Append(for_right_value);
   PushArgumentInstr* push_right = PushArgument(for_right_value.value());
 
-  Value* mask_value = Bind(new(I) ConstantInstr(
-      Integer::ZoneHandle(I, Integer::New(node->mask32(), Heap::kOld))));
+  Value* mask_value = Bind(new(Z) ConstantInstr(
+      Integer::ZoneHandle(Z, Integer::New(node->mask32(), Heap::kOld))));
   PushArgumentInstr* push_mask = PushArgument(mask_value);
 
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(3);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(3);
   arguments->Add(push_left);
   arguments->Add(push_right);
   // Call to special method 'BinaryOpAndMaskName(node)'.
   arguments->Add(push_mask);
   const intptr_t kNumArgsChecked = 2;
-  InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(),
+  InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(),
                                                      BinaryOpAndMaskName(node),
                                                      Token::kILLEGAL,
                                                      arguments,
@@ -1400,7 +1400,7 @@
     PushArgumentInstr** push_instantiator_result,
     PushArgumentInstr** push_instantiator_type_arguments_result) {
   const Class& instantiator_class = Class::Handle(
-      I, owner()->function().Owner());
+      Z, owner()->function().Owner());
   // Since called only when type tested against is not instantiated.
   ASSERT(instantiator_class.NumTypeParameters() > 0);
   Value* instantiator_type_arguments = NULL;
@@ -1430,7 +1430,7 @@
   Value* instantiator = NULL;
   Value* instantiator_type_arguments = NULL;
   const Class& instantiator_class = Class::Handle(
-      I, owner()->function().Owner());
+      Z, owner()->function().Owner());
   // Since called only when type tested against is not instantiated.
   ASSERT(instantiator_class.NumTypeParameters() > 0);
   instantiator = BuildInstantiator(instantiator_class);
@@ -1452,7 +1452,7 @@
 
 
 Value* EffectGraphVisitor::BuildNullValue() {
-  return Bind(new(I) ConstantInstr(Object::ZoneHandle(I, Object::null())));
+  return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null())));
 }
 
 
@@ -1475,7 +1475,7 @@
   }
 
   const intptr_t deopt_id = Isolate::Current()->GetNextDeoptId();
-  return new(I) AssertAssignableInstr(token_pos,
+  return new(Z) AssertAssignableInstr(token_pos,
                                       value,
                                       instantiator,
                                       instantiator_type_arguments,
@@ -1517,15 +1517,15 @@
   ASSERT(delta >= 0);
   Value* context = Bind(BuildCurrentContext());
   while (delta-- > 0) {
-    context = Bind(new(I) LoadFieldInstr(
-        context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()),
+    context = Bind(new(Z) LoadFieldInstr(
+        context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
         Scanner::kNoSourcePos));
   }
   LocalVariable* temp_context_var = EnterTempLocalScope(context);
 
-  Value* context_val = Bind(new(I) LoadLocalInstr(*temp_context_var));
-  Value* store_val = Bind(new(I) LoadLocalInstr(*temp_iterator_var));
-  StoreInstanceFieldInstr* store = new(I) StoreInstanceFieldInstr(
+  Value* context_val = Bind(new(Z) LoadLocalInstr(*temp_context_var));
+  Value* store_val = Bind(new(Z) LoadLocalInstr(*temp_iterator_var));
+  StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
       Context::variable_offset(iterator_param->index()),
       context_val,
       store_val,
@@ -1582,24 +1582,24 @@
   ASSERT(delta >= 0);
   Value* context = Bind(BuildCurrentContext());
   while (delta-- > 0) {
-    context = Bind(new(I) LoadFieldInstr(
-        context, Context::parent_offset(), Type::ZoneHandle(I, Type::null()),
+    context = Bind(new(Z) LoadFieldInstr(
+        context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()),
         Scanner::kNoSourcePos));
   }
   LocalVariable* temp_context_var = EnterTempLocalScope(context);
 
-  Value* context_val = Bind(new(I) LoadLocalInstr(*temp_context_var));
-  Value* store_val = Bind(new(I) LoadLocalInstr(*temp_result_var));
-  StoreInstanceFieldInstr* store = new(I) StoreInstanceFieldInstr(
+  Value* context_val = Bind(new(Z) LoadLocalInstr(*temp_context_var));
+  Value* store_val = Bind(new(Z) LoadLocalInstr(*temp_result_var));
+  StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
       Context::variable_offset(continuation_result->index()),
       context_val,
       store_val,
       kEmitStoreBarrier,
       Scanner::kNoSourcePos);
   Do(store);
-  context_val = Bind(new(I) LoadLocalInstr(*temp_context_var));
-  store_val = Bind(new(I) LoadLocalInstr(*temp_error_var));
-  StoreInstanceFieldInstr* store2 = new(I) StoreInstanceFieldInstr(
+  context_val = Bind(new(Z) LoadLocalInstr(*temp_context_var));
+  store_val = Bind(new(Z) LoadLocalInstr(*temp_error_var));
+  StoreInstanceFieldInstr* store2 = new(Z) StoreInstanceFieldInstr(
       Context::variable_offset(continuation_error->index()),
       context_val,
       store_val,
@@ -1607,9 +1607,9 @@
       Scanner::kNoSourcePos);
   Do(store2);
 
-  context_val = Bind(new(I) LoadLocalInstr(*temp_context_var));
-  store_val = Bind(new(I) LoadLocalInstr(*temp_stack_trace_var));
-  StoreInstanceFieldInstr* store3 = new(I) StoreInstanceFieldInstr(
+  context_val = Bind(new(Z) LoadLocalInstr(*temp_context_var));
+  store_val = Bind(new(Z) LoadLocalInstr(*temp_stack_trace_var));
+  StoreInstanceFieldInstr* store3 = new(Z) StoreInstanceFieldInstr(
       Context::variable_offset(continuation_stack_trace->index()),
       context_val,
       store_val,
@@ -1669,13 +1669,13 @@
   ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
   const bool negate_result = (node->kind() == Token::kISNOT);
   // All objects are instances of type T if Object type is a subtype of type T.
-  const Type& object_type = Type::Handle(I, Type::ObjectType());
+  const Type& object_type = Type::Handle(Z, Type::ObjectType());
   if (type.IsInstantiated() && object_type.IsSubtypeOf(type, NULL)) {
     // Must evaluate left side.
     EffectGraphVisitor for_left_value(owner());
     node->left()->Visit(&for_left_value);
     Append(for_left_value);
-    ReturnDefinition(new(I) ConstantInstr(Bool::Get(!negate_result)));
+    ReturnDefinition(new(Z) ConstantInstr(Bool::Get(!negate_result)));
     return;
   }
   ValueGraphVisitor for_left_value(owner());
@@ -1693,19 +1693,19 @@
                                 &push_type_args);
   }
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(5);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(5);
   arguments->Add(push_left);
   arguments->Add(push_instantiator);
   arguments->Add(push_type_args);
   ASSERT(!node->right()->AsTypeNode()->type().IsNull());
   Value* type_arg = Bind(
-      new(I) ConstantInstr(node->right()->AsTypeNode()->type()));
+      new(Z) ConstantInstr(node->right()->AsTypeNode()->type()));
   arguments->Add(PushArgument(type_arg));
   const Bool& negate = Bool::Get(node->kind() == Token::kISNOT);
-  Value* negate_arg = Bind(new(I) ConstantInstr(negate));
+  Value* negate_arg = Bind(new(Z) ConstantInstr(negate));
   arguments->Add(PushArgument(negate_arg));
   const intptr_t kNumArgsChecked = 1;
-  InstanceCallInstr* call = new(I) InstanceCallInstr(
+  InstanceCallInstr* call = new(Z) InstanceCallInstr(
       node->token_pos(),
       Library::PrivateCoreLibName(Symbols::_instanceOf()),
       node->kind(),
@@ -1726,7 +1726,7 @@
   node->left()->Visit(&for_value);
   Append(for_value);
   const String& dst_name = String::ZoneHandle(
-      I, Symbols::New(Exceptions::kCastErrorDstName));
+      Z, Symbols::New(Exceptions::kCastErrorDstName));
   if (CanSkipTypeCheck(node->token_pos(),
                        for_value.value(),
                        type,
@@ -1751,14 +1751,14 @@
                                 &push_type_args);
   }
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(4);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(4);
   arguments->Add(push_left);
   arguments->Add(push_instantiator);
   arguments->Add(push_type_args);
-  Value* type_arg = Bind(new(I) ConstantInstr(type));
+  Value* type_arg = Bind(new(Z) ConstantInstr(type));
   arguments->Add(PushArgument(type_arg));
   const intptr_t kNumArgsChecked = 1;
-  InstanceCallInstr* call = new(I) InstanceCallInstr(
+  InstanceCallInstr* call = new(Z) InstanceCallInstr(
       node->token_pos(),
       Library::PrivateCoreLibName(Symbols::_as()),
       node->kind(),
@@ -1780,7 +1780,7 @@
   ValueGraphVisitor for_right_value(owner());
   right->Visit(&for_right_value);
   Append(for_right_value);
-  StrictCompareInstr* comp = new(I) StrictCompareInstr(token_pos,
+  StrictCompareInstr* comp = new(Z) StrictCompareInstr(token_pos,
                                                     kind,
                                                     for_left_value.value(),
                                                     for_right_value.value(),
@@ -1825,7 +1825,7 @@
     }
 
     ZoneGrowableArray<PushArgumentInstr*>* arguments =
-        new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+        new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
 
     ValueGraphVisitor for_left_value(owner());
     node->left()->Visit(&for_left_value);
@@ -1839,7 +1839,7 @@
     PushArgumentInstr* push_right = PushArgument(for_right_value.value());
     arguments->Add(push_right);
 
-    Definition* result = new(I) InstanceCallInstr(
+    Definition* result = new(Z) InstanceCallInstr(
         node->token_pos(),
         Symbols::EqualOperator(),
         Token::kEQ,  // Result is negated later for kNE.
@@ -1851,17 +1851,17 @@
       if (Isolate::Current()->TypeChecksEnabled() ||
           Isolate::Current()->AssertsEnabled()) {
         Value* value = Bind(result);
-        result = new(I) AssertBooleanInstr(node->token_pos(), value);
+        result = new(Z) AssertBooleanInstr(node->token_pos(), value);
       }
       Value* value = Bind(result);
-      result = new(I) BooleanNegateInstr(value);
+      result = new(Z) BooleanNegateInstr(value);
     }
     ReturnDefinition(result);
     return;
   }
 
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
 
   ValueGraphVisitor for_left_value(owner());
   node->left()->Visit(&for_left_value);
@@ -1876,9 +1876,9 @@
   arguments->Add(push_right);
 
   ASSERT(Token::IsRelationalOperator(node->kind()));
-  InstanceCallInstr* comp = new(I) InstanceCallInstr(
+  InstanceCallInstr* comp = new(Z) InstanceCallInstr(
       node->token_pos(),
-      String::ZoneHandle(I, Symbols::New(node->TokenName())),
+      String::ZoneHandle(Z, Symbols::New(node->TokenName())),
       node->kind(),
       arguments,
       Object::null_array(),
@@ -1898,9 +1898,9 @@
     if (Isolate::Current()->TypeChecksEnabled() ||
         Isolate::Current()->AssertsEnabled()) {
       value =
-          Bind(new(I) AssertBooleanInstr(node->operand()->token_pos(), value));
+          Bind(new(Z) AssertBooleanInstr(node->operand()->token_pos(), value));
     }
-    BooleanNegateInstr* negate = new(I) BooleanNegateInstr(value);
+    BooleanNegateInstr* negate = new(Z) BooleanNegateInstr(value);
     ReturnDefinition(negate);
     return;
   }
@@ -1910,11 +1910,11 @@
   Append(for_value);
   PushArgumentInstr* push_value = PushArgument(for_value.value());
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
   arguments->Add(push_value);
-  InstanceCallInstr* call = new(I) InstanceCallInstr(
+  InstanceCallInstr* call = new(Z) InstanceCallInstr(
       node->token_pos(),
-      String::ZoneHandle(I, Symbols::New(node->TokenName())),
+      String::ZoneHandle(Z, Symbols::New(node->TokenName())),
       node->kind(),
       arguments,
       Object::null_array(),
@@ -2015,7 +2015,7 @@
   // Compute the start of the statements fragment.
   JoinEntryInstr* statement_start = NULL;
   if (node->label() == NULL) {
-    statement_start = new(I) JoinEntryInstr(owner()->AllocateBlockId(),
+    statement_start = new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
                                             owner()->try_index());
   } else {
     // The case nodes are nested inside a SequenceNode that is the body of a
@@ -2067,7 +2067,7 @@
       exit_instruction = statement_exit;
     } else {
       if (statement_exit != NULL) {
-        JoinEntryInstr* join = new(I) JoinEntryInstr(owner()->AllocateBlockId(),
+        JoinEntryInstr* join = new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
                                                      owner()->try_index());
         statement_exit->Goto(join);
         next_target->Goto(join);
@@ -2151,7 +2151,7 @@
 
   // Tie do-while loop (test is after the body).
   JoinEntryInstr* body_entry_join =
-      new(I) JoinEntryInstr(owner()->AllocateBlockId(),
+      new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
                             owner()->try_index());
   Goto(body_entry_join);
   Instruction* body_exit = AppendFragment(body_entry_join, for_body);
@@ -2159,10 +2159,10 @@
   JoinEntryInstr* join = nested_loop.continue_target();
   if ((body_exit != NULL) || (join != NULL)) {
     if (join == NULL) {
-      join = new(I) JoinEntryInstr(owner()->AllocateBlockId(),
+      join = new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
                                    owner()->try_index());
     }
-    CheckStackOverflowInstr* check = new(I) CheckStackOverflowInstr(
+    CheckStackOverflowInstr* check = new(Z) CheckStackOverflowInstr(
         node->token_pos(), owner()->loop_depth());
     join->LinkTo(check);
     check->LinkTo(for_test.entry());
@@ -2212,7 +2212,7 @@
   JoinEntryInstr* continue_join = nested_loop.continue_target();
   if ((continue_join != NULL) || for_body.is_open()) {
     JoinEntryInstr* loop_entry =
-        new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
+        new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
     if (continue_join != NULL) {
       if (for_body.is_open()) for_body.Goto(continue_join);
       Instruction* current = AppendFragment(continue_join, for_increment);
@@ -2224,7 +2224,7 @@
     Goto(loop_entry);
     exit_ = loop_entry;
     AddInstruction(
-        new(I) CheckStackOverflowInstr(node->token_pos(),
+        new(Z) CheckStackOverflowInstr(node->token_pos(),
                                        owner()->loop_depth()));
   }
 
@@ -2332,8 +2332,8 @@
   // state.
   ASSERT(jump_count == owner()->await_joins()->length());
   // Store the counter in :await_jump_var.
-  Value* jump_val = Bind(new (I) ConstantInstr(
-      Smi::ZoneHandle(I, Smi::New(jump_count))));
+  Value* jump_val = Bind(new(Z) ConstantInstr(
+      Smi::ZoneHandle(Z, Smi::New(jump_count))));
   Do(BuildStoreLocal(*jump_var, jump_val));
   // Save the current context for resuming.
   BuildSaveContext(*ctx_var);
@@ -2351,7 +2351,7 @@
 
 
 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) {
-  Do(new(I) PushTempInstr(value));
+  Do(new(Z) PushTempInstr(value));
   owner()->AllocateTemp();
 
   ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1));
@@ -2359,8 +2359,8 @@
   char name[64];
   OS::SNPrint(name, 64, ":tmp_local%" Pd, index);
   LocalVariable*  var =
-      new(I) LocalVariable(0,
-                           String::ZoneHandle(I, Symbols::New(name)),
+      new(Z) LocalVariable(0,
+                           String::ZoneHandle(Z, Symbols::New(name)),
                            *value->Type()->ToAbstractType());
   var->set_index(index);
   return var;
@@ -2368,10 +2368,10 @@
 
 
 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) {
-    Value* tmp = Bind(new(I) LoadLocalInstr(*var));
+    Value* tmp = Bind(new(Z) LoadLocalInstr(*var));
     owner()->DeallocateTemps(1);
     ASSERT(GetCurrentTempLocalIndex() == var->index());
-    return new(I) DropTempsInstr(1, tmp);
+    return new(Z) DropTempsInstr(1, tmp);
 }
 
 
@@ -2383,7 +2383,7 @@
     Append(for_value);
     Value* temp_val = for_value.value();
     node->TempAt(i)->set_index(GetCurrentTempLocalIndex());
-    Do(new(I) PushTempInstr(temp_val));
+    Do(new(Z) PushTempInstr(temp_val));
     owner()->AllocateTemp();
   }
 }
@@ -2402,7 +2402,7 @@
   intptr_t num_temps = node->num_temps();
   if (num_temps > 0) {
     owner()->DeallocateTemps(num_temps);
-    Do(new(I) DropTempsInstr(num_temps, NULL));
+    Do(new(Z) DropTempsInstr(num_temps, NULL));
   }
 }
 
@@ -2425,7 +2425,7 @@
   intptr_t num_temps = node->num_temps();
   if (num_temps > 0) {
     owner()->DeallocateTemps(num_temps);
-    ReturnDefinition(new(I) DropTempsInstr(num_temps, result_value));
+    ReturnDefinition(new(Z) DropTempsInstr(num_temps, result_value));
   } else {
     ReturnValue(result_value);
   }
@@ -2434,12 +2434,12 @@
 
 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
   const TypeArguments& type_args =
-      TypeArguments::ZoneHandle(I, node->type().arguments());
+      TypeArguments::ZoneHandle(Z, node->type().arguments());
   Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(),
                                                        type_args);
   Value* num_elements =
-      Bind(new(I) ConstantInstr(Smi::ZoneHandle(I, Smi::New(node->length()))));
-  CreateArrayInstr* create = new(I) CreateArrayInstr(node->token_pos(),
+      Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length()))));
+  CreateArrayInstr* create = new(Z) CreateArrayInstr(node->token_pos(),
                                                      element_type,
                                                      num_elements);
   Value* array_val = Bind(create);
@@ -2448,9 +2448,9 @@
     const intptr_t class_id = kArrayCid;
     const intptr_t deopt_id = Isolate::kNoDeoptId;
     for (int i = 0; i < node->length(); ++i) {
-      Value* array = Bind(new(I) LoadLocalInstr(*tmp_var));
+      Value* array = Bind(new(Z) LoadLocalInstr(*tmp_var));
       Value* index =
-          Bind(new(I) ConstantInstr(Smi::ZoneHandle(I, Smi::New(i))));
+          Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i))));
       ValueGraphVisitor for_value(owner());
       node->ElementAt(i)->Visit(&for_value);
       Append(for_value);
@@ -2460,7 +2460,7 @@
               ? kNoStoreBarrier
               : kEmitStoreBarrier;
       const intptr_t index_scale = Instance::ElementSizeFor(class_id);
-      StoreIndexedInstr* store = new(I) StoreIndexedInstr(
+      StoreIndexedInstr* store = new(Z) StoreIndexedInstr(
           array, index, for_value.value(), emit_store_barrier,
           index_scale, class_id, deopt_id, node->token_pos());
       Do(store);
@@ -2476,7 +2476,7 @@
   ArrayNode* arguments = node->value();
   if (arguments->length() == 1) {
     ZoneGrowableArray<PushArgumentInstr*>* values =
-        new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
+        new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
     arguments->ElementAt(0)->Visit(&for_argument);
     Append(for_argument);
     PushArgumentInstr* push_arg = PushArgument(for_argument.value());
@@ -2487,14 +2487,14 @@
         Class::Handle(Library::LookupCoreClass(Symbols::StringBase()));
     ASSERT(!cls.IsNull());
     const Function& function = Function::ZoneHandle(
-        isolate(),
+        Z,
         Resolver::ResolveStatic(
             cls,
             Library::PrivateCoreLibName(Symbols::InterpolateSingle()),
             kNumberOfArguments,
             kNoArgumentNames));
     StaticCallInstr* call =
-        new(I) StaticCallInstr(node->token_pos(),
+        new(Z) StaticCallInstr(node->token_pos(),
                                function,
                                kNoArgumentNames,
                                values,
@@ -2505,7 +2505,7 @@
   arguments->Visit(&for_argument);
   Append(for_argument);
   StringInterpolateInstr* instr =
-      new(I) StringInterpolateInstr(for_argument.value(), node->token_pos());
+      new(Z) StringInterpolateInstr(for_argument.value(), node->token_pos());
   ReturnDefinition(instr);
 }
 
@@ -2515,8 +2515,8 @@
 
   if (function.IsImplicitStaticClosureFunction()) {
     const Instance& closure =
-        Instance::ZoneHandle(I, function.ImplicitStaticClosure());
-    ReturnDefinition(new(I) ConstantInstr(closure));
+        Instance::ZoneHandle(Z, function.ImplicitStaticClosure());
+    ReturnDefinition(new(Z) ConstantInstr(closure));
     return;
   }
   const bool is_implicit = function.IsImplicitInstanceClosureFunction();
@@ -2526,11 +2526,11 @@
   if (function.context_scope() == ContextScope::null()) {
     ASSERT(!is_implicit);
     const ContextScope& context_scope = ContextScope::ZoneHandle(
-        I, node->scope()->PreserveOuterScope(owner()->context_level()));
+        Z, node->scope()->PreserveOuterScope(owner()->context_level()));
     ASSERT(!function.HasCode());
     ASSERT(function.context_scope() == ContextScope::null());
     function.set_context_scope(context_scope);
-    const Class& cls = Class::Handle(I, owner()->function().Owner());
+    const Class& cls = Class::Handle(Z, owner()->function().Owner());
     // The closure is now properly setup, add it to the lookup table.
     // It is possible that the compiler creates more than one function
     // object for the same closure, e.g. when inlining nodes from
@@ -2542,7 +2542,7 @@
     // parent, and one with a closurized parent function.
 
     const Function& found_func = Function::Handle(
-        I, cls.LookupClosureFunction(function.token_pos()));
+        Z, cls.LookupClosureFunction(function.token_pos()));
 
     if (found_func.IsNull() ||
         (found_func.token_pos() != function.token_pos()) ||
@@ -2552,12 +2552,12 @@
     }
   }
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
   ASSERT(function.context_scope() != ContextScope::null());
 
   // The function type of a closure may have type arguments. In that case,
   // pass the type arguments of the instantiator.
-  const Class& cls = Class::ZoneHandle(I, function.signature_class());
+  const Class& cls = Class::ZoneHandle(Z, function.signature_class());
   ASSERT(!cls.IsNull());
   const bool requires_type_arguments = cls.NumTypeArguments() > 0;
   Value* type_arguments = NULL;
@@ -2566,13 +2566,13 @@
            Closure::type_arguments_offset());
     ASSERT(cls.instance_size() == Closure::InstanceSize());
     const Class& instantiator_class = Class::Handle(
-        I, owner()->function().Owner());
+        Z, owner()->function().Owner());
     type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
                                                     instantiator_class,
                                                     NULL);
     arguments->Add(PushArgument(type_arguments));
   }
-  AllocateObjectInstr* alloc = new(I) AllocateObjectInstr(node->token_pos(),
+  AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(),
                                                           cls,
                                                           arguments);
   alloc->set_closure_function(function);
@@ -2580,10 +2580,10 @@
   Value* closure_val = Bind(alloc);
   { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val);
     // Store function.
-    Value* closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var));
+    Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var));
     Value* func_val =
-        Bind(new(I) ConstantInstr(Function::ZoneHandle(I, function.raw())));
-    Do(new(I) StoreInstanceFieldInstr(Closure::function_offset(),
+        Bind(new(Z) ConstantInstr(Function::ZoneHandle(Z, function.raw())));
+    Do(new(Z) StoreInstanceFieldInstr(Closure::function_offset(),
                                       closure_tmp_val,
                                       func_val,
                                       kEmitStoreBarrier,
@@ -2592,24 +2592,24 @@
       // Create new context containing the receiver.
       const intptr_t kNumContextVariables = 1;  // The receiver.
       Value* allocated_context =
-          Bind(new(I) AllocateContextInstr(node->token_pos(),
+          Bind(new(Z) AllocateContextInstr(node->token_pos(),
                                            kNumContextVariables));
       { LocalVariable* context_tmp_var = EnterTempLocalScope(allocated_context);
         // Store receiver in context.
-        Value* context_tmp_val = Bind(new(I) LoadLocalInstr(*context_tmp_var));
+        Value* context_tmp_val = Bind(new(Z) LoadLocalInstr(*context_tmp_var));
         ValueGraphVisitor for_receiver(owner());
         node->receiver()->Visit(&for_receiver);
         Append(for_receiver);
         Value* receiver = for_receiver.value();
-        Do(new(I) StoreInstanceFieldInstr(Context::variable_offset(0),
+        Do(new(Z) StoreInstanceFieldInstr(Context::variable_offset(0),
                                           context_tmp_val,
                                           receiver,
                                           kEmitStoreBarrier,
                                           node->token_pos()));
         // Store new context in closure.
-        closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var));
-        context_tmp_val = Bind(new(I) LoadLocalInstr(*context_tmp_var));
-        Do(new(I) StoreInstanceFieldInstr(Closure::context_offset(),
+        closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var));
+        context_tmp_val = Bind(new(Z) LoadLocalInstr(*context_tmp_var));
+        Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(),
                                           closure_tmp_val,
                                           context_tmp_val,
                                           kEmitStoreBarrier,
@@ -2618,9 +2618,9 @@
       }
     } else {
       // Store current context in closure.
-      closure_tmp_val = Bind(new(I) LoadLocalInstr(*closure_tmp_var));
+      closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var));
       Value* context = Bind(BuildCurrentContext());
-      Do(new(I) StoreInstanceFieldInstr(Closure::context_offset(),
+      Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(),
                                         closure_tmp_val,
                                         context,
                                         kEmitStoreBarrier,
@@ -2650,12 +2650,12 @@
   Append(for_receiver);
   PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(
           node->arguments()->length() + 1);
   arguments->Add(push_receiver);
 
   BuildPushArguments(*node->arguments(), arguments);
-  InstanceCallInstr* call = new(I) InstanceCallInstr(
+  InstanceCallInstr* call = new(Z) InstanceCallInstr(
       node->token_pos(),
       node->function_name(),
       Token::kILLEGAL,
@@ -2701,10 +2701,10 @@
 //                               arguments: <ArgumentList> }
 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
   BuildPushArguments(*node->arguments(), arguments);
   StaticCallInstr* call =
-      new(I) StaticCallInstr(node->token_pos(),
+      new(Z) StaticCallInstr(node->token_pos(),
                              node->function(),
                              node->arguments()->names(),
                              arguments,
@@ -2729,26 +2729,26 @@
   LocalVariable* tmp_var = EnterTempLocalScope(for_closure.value());
 
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
-  Value* closure_val = Bind(new(I) LoadLocalInstr(*tmp_var));
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
+  Value* closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
   PushArgumentInstr* push_closure = PushArgument(closure_val);
   arguments->Add(push_closure);
   BuildPushArguments(*node->arguments(), arguments);
 
-  closure_val = Bind(new(I) LoadLocalInstr(*tmp_var));
-  LoadFieldInstr* function_load = new(I) LoadFieldInstr(
+  closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
+  LoadFieldInstr* function_load = new(Z) LoadFieldInstr(
       closure_val,
       Closure::function_offset(),
-      AbstractType::ZoneHandle(I, AbstractType::null()),
+      AbstractType::ZoneHandle(Z, AbstractType::null()),
       node->token_pos());
   function_load->set_is_immutable(true);
   Value* function_val = Bind(function_load);
 
   Definition* closure_call =
-      new(I) ClosureCallInstr(function_val, node, arguments);
+      new(Z) ClosureCallInstr(function_val, node, arguments);
   if (result_needed) {
     Value* result = Bind(closure_call);
-    Do(new(I) StoreLocalInstr(*tmp_var, result));
+    Do(new(Z) StoreLocalInstr(*tmp_var, result));
   } else {
     Do(closure_call);
   }
@@ -2767,24 +2767,24 @@
 
 
 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) {
-  Value* field = Bind(new(I) ConstantInstr(node->field()));
-  AddInstruction(new(I) InitStaticFieldInstr(field, node->field()));
+  Value* field = Bind(new(Z) ConstantInstr(node->field()));
+  AddInstruction(new(Z) InitStaticFieldInstr(field, node->field()));
 }
 
 
 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
   Value* context = Bind(BuildCurrentContext());
-  Value* clone = Bind(new(I) CloneContextInstr(node->token_pos(), context));
+  Value* clone = Bind(new(Z) CloneContextInstr(node->token_pos(), context));
   Do(BuildStoreContext(clone));
 }
 
 
 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) {
-  const Class& cls = Class::ZoneHandle(I, node->constructor().Owner());
+  const Class& cls = Class::ZoneHandle(Z, node->constructor().Owner());
   const bool cls_is_parameterized = cls.NumTypeArguments() > 0;
 
   ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(
           cls_is_parameterized ? 1 : 0);
   if (cls_is_parameterized) {
     Value* type_args = BuildInstantiatedTypeArguments(node->token_pos(),
@@ -2792,9 +2792,9 @@
     allocate_arguments->Add(PushArgument(type_args));
   }
 
-  Definition* allocation = new(I) AllocateObjectInstr(
+  Definition* allocation = new(Z) AllocateObjectInstr(
       node->token_pos(),
-      Class::ZoneHandle(I, node->constructor().Owner()),
+      Class::ZoneHandle(Z, node->constructor().Owner()),
       allocate_arguments);
 
   return Bind(allocation);
@@ -2804,17 +2804,17 @@
 void EffectGraphVisitor::BuildConstructorCall(
     ConstructorCallNode* node,
     PushArgumentInstr* push_alloc_value) {
-  Value* ctor_arg = Bind(new(I) ConstantInstr(
-      Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseAll))));
+  Value* ctor_arg = Bind(new(Z) ConstantInstr(
+      Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll))));
   PushArgumentInstr* push_ctor_arg = PushArgument(ctor_arg);
 
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
   arguments->Add(push_alloc_value);
   arguments->Add(push_ctor_arg);
 
   BuildPushArguments(*node->arguments(), arguments);
-  Do(new(I) StaticCallInstr(node->token_pos(),
+  Do(new(Z) StaticCallInstr(node->token_pos(),
                             node->constructor(),
                             node->arguments()->names(),
                             arguments,
@@ -2849,7 +2849,7 @@
 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
   if (node->constructor().IsFactory()) {
     ZoneGrowableArray<PushArgumentInstr*>* arguments =
-        new(I) ZoneGrowableArray<PushArgumentInstr*>();
+        new(Z) ZoneGrowableArray<PushArgumentInstr*>();
     PushArgumentInstr* push_type_arguments = PushArgument(
         BuildInstantiatedTypeArguments(node->token_pos(),
                                        node->type_arguments()));
@@ -2857,7 +2857,7 @@
     ASSERT(arguments->length() == 1);
     BuildPushArguments(*node->arguments(), arguments);
     StaticCallInstr* call =
-        new(I) StaticCallInstr(node->token_pos(),
+        new(Z) StaticCallInstr(node->token_pos(),
                                node->constructor(),
                                node->arguments()->names(),
                                arguments,
@@ -2888,7 +2888,7 @@
 
 Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) {
   ASSERT(instantiator_class.NumTypeParameters() > 0);
-  Function& outer_function = Function::Handle(I, owner()->function().raw());
+  Function& outer_function = Function::Handle(Z, owner()->function().raw());
   while (outer_function.IsLocalFunction()) {
     outer_function = outer_function.parent_function();
   }
@@ -2912,19 +2912,19 @@
   if (instantiator_class.NumTypeParameters() == 0) {
     // The type arguments are compile time constants.
     TypeArguments& type_arguments =
-        TypeArguments::ZoneHandle(I, TypeArguments::null());
+        TypeArguments::ZoneHandle(Z, TypeArguments::null());
     // Type is temporary. Only its type arguments are preserved.
     Type& type = Type::Handle(
-        I,
+        Z,
         Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew));
     type ^= ClassFinalizer::FinalizeType(
         instantiator_class, type, ClassFinalizer::kFinalize);
     ASSERT(!type.IsMalformedOrMalbounded());
     type_arguments = type.arguments();
     type_arguments = type_arguments.Canonicalize();
-    return Bind(new(I) ConstantInstr(type_arguments));
+    return Bind(new(Z) ConstantInstr(type_arguments));
   }
-  Function& outer_function = Function::Handle(I, owner()->function().raw());
+  Function& outer_function = Function::Handle(Z, owner()->function().raw());
   while (outer_function.IsLocalFunction()) {
     outer_function = outer_function.parent_function();
   }
@@ -2947,10 +2947,10 @@
       instantiator_class.type_arguments_field_offset();
   ASSERT(type_arguments_field_offset != Class::kNoTypeArguments);
 
-  return Bind(new(I) LoadFieldInstr(
+  return Bind(new(Z) LoadFieldInstr(
       instantiator,
       type_arguments_field_offset,
-      Type::ZoneHandle(I, Type::null()),  // Not an instance, no type.
+      Type::ZoneHandle(Z, Type::null()),  // Not an instance, no type.
       Scanner::kNoSourcePos));
 }
 
@@ -2959,11 +2959,11 @@
     intptr_t token_pos,
     const TypeArguments& type_arguments) {
   if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
-    return Bind(new(I) ConstantInstr(type_arguments));
+    return Bind(new(Z) ConstantInstr(type_arguments));
   }
   // The type arguments are uninstantiated.
   const Class& instantiator_class = Class::ZoneHandle(
-      I, owner()->function().Owner());
+      Z, owner()->function().Owner());
   Value* instantiator_value =
       BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
   const bool use_instantiator_type_args =
@@ -2972,7 +2972,7 @@
   if (use_instantiator_type_args) {
     return instantiator_value;
   } else {
-    return Bind(new(I) InstantiateTypeArgumentsInstr(token_pos,
+    return Bind(new(Z) InstantiateTypeArgumentsInstr(token_pos,
                                                   type_arguments,
                                                   instantiator_class,
                                                   instantiator_value));
@@ -2996,7 +2996,7 @@
 
   Value* allocate = BuildObjectAllocation(node);
   { LocalVariable* tmp_var = EnterTempLocalScope(allocate);
-    Value* allocated_tmp = Bind(new(I) LoadLocalInstr(*tmp_var));
+    Value* allocated_tmp = Bind(new(Z) LoadLocalInstr(*tmp_var));
     PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp);
     BuildConstructorCall(node, push_allocated_value);
     ReturnDefinition(ExitTempLocalScope(tmp_var));
@@ -3010,11 +3010,11 @@
   Append(for_receiver);
   PushArgumentInstr* push_receiver = PushArgument(for_receiver.value());
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
   arguments->Add(push_receiver);
   const String& name =
-      String::ZoneHandle(I, Field::GetterSymbol(node->field_name()));
-  InstanceCallInstr* call = new(I) InstanceCallInstr(
+      String::ZoneHandle(Z, Field::GetterSymbol(node->field_name()));
+  InstanceCallInstr* call = new(Z) InstanceCallInstr(
       node->token_pos(),
       name,
       Token::kGET,
@@ -3050,11 +3050,11 @@
 
 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
   BuildInstanceSetterArguments(node, arguments, kResultNotNeeded);
   const String& name =
-      String::ZoneHandle(I, Field::SetterSymbol(node->field_name()));
-  InstanceCallInstr* call = new(I) InstanceCallInstr(node->token_pos(),
+      String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
+  InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(),
                                                      name,
                                                      Token::kSET,
                                                      arguments,
@@ -3067,11 +3067,11 @@
 
 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
   BuildInstanceSetterArguments(node, arguments, kResultNeeded);
   const String& name =
-      String::ZoneHandle(I, Field::SetterSymbol(node->field_name()));
-  Do(new(I) InstanceCallInstr(node->token_pos(),
+      String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
+  Do(new(Z) InstanceCallInstr(node->token_pos(),
                               name,
                               Token::kSET,
                               arguments,
@@ -3084,17 +3084,17 @@
 
 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
   const String& getter_name =
-      String::ZoneHandle(I, Field::GetterSymbol(node->field_name()));
+      String::ZoneHandle(Z, Field::GetterSymbol(node->field_name()));
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>();
-  Function& getter_function = Function::ZoneHandle(I, Function::null());
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>();
+  Function& getter_function = Function::ZoneHandle(Z, Function::null());
   if (node->is_super_getter()) {
     // Statically resolved instance getter, i.e. "super getter".
     ASSERT(node->receiver() != NULL);
     getter_function = Resolver::ResolveDynamicAnyArgs(node->cls(), getter_name);
     if (getter_function.IsNull()) {
       // Resolve and call noSuchMethod.
-      ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos());
+      ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
       arguments->Add(node->receiver());
       StaticCallInstr* call =
           BuildStaticNoSuchMethodCall(node->cls(),
@@ -3144,7 +3144,7 @@
     }
   }
   ASSERT(!getter_function.IsNull());
-  StaticCallInstr* call = new(I) StaticCallInstr(
+  StaticCallInstr* call = new(Z) StaticCallInstr(
       node->token_pos(),
       getter_function,
       Object::null_array(),  // No names
@@ -3157,15 +3157,15 @@
 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node,
                                            bool result_is_needed) {
   const String& setter_name =
-      String::ZoneHandle(I, Field::SetterSymbol(node->field_name()));
+      String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
   // A super setter is an instance setter whose setter function is
   // resolved at compile time (in the caller instance getter's super class).
   // Unlike a static getter, a super getter has a receiver parameter.
   const bool is_super_setter = (node->receiver() != NULL);
   Function& setter_function =
-      Function::ZoneHandle(I, is_super_setter
+      Function::ZoneHandle(Z, is_super_setter
           ? Resolver::ResolveDynamicAnyArgs(node->cls(), setter_name)
           : node->cls().LookupStaticFunction(setter_name));
   StaticCallInstr* call;
@@ -3173,7 +3173,7 @@
     if (is_super_setter) {
       ASSERT(node->receiver() != NULL);
       // Resolve and call noSuchMethod.
-      ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos());
+      ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
       arguments->Add(node->receiver());
       arguments->Add(node->value());
       call = BuildStaticNoSuchMethodCall(
@@ -3185,7 +3185,7 @@
           true);  // Super invocation.
     } else {
       // Throw a NoSuchMethodError.
-      ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos());
+      ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
       arguments->Add(node->value());
       call = BuildThrowNoSuchMethodError(
           node->token_pos(),
@@ -3217,7 +3217,7 @@
     }
     arguments->Add(PushArgument(value));
 
-    call = new(I) StaticCallInstr(node->token_pos(),
+    call = new(Z) StaticCallInstr(node->token_pos(),
                                   setter_function,
                                   Object::null_array(),  // No names.
                                   arguments,
@@ -3264,7 +3264,7 @@
 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope) {
   LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(),
                                                       true);  // Test only.
-  return new(I) LoadLocalInstr(*receiver_var);
+  return new(Z) LoadLocalInstr(*receiver_var);
 }
 
 
@@ -3278,11 +3278,11 @@
         LocalVariable* other_var =
             node->scope()->LookupVariable(Symbols::Other(),
                                           true);  // Test only.
-        Value* other = Bind(new(I) LoadLocalInstr(*other_var));
+        Value* other = Bind(new(Z) LoadLocalInstr(*other_var));
         // Receiver is not a number because numbers override equality.
         const bool kNoNumberCheck = false;
         StrictCompareInstr* compare =
-            new(I) StrictCompareInstr(node->token_pos(),
+            new(Z) StrictCompareInstr(node->token_pos(),
                                       Token::kEQ_STRICT,
                                       receiver,
                                       other,
@@ -3296,10 +3296,10 @@
         // avoid hoisting them since we can't hoist the preceding class-check.
         // This is because of externalization of strings that affects their
         // class-id.
-        LoadFieldInstr* load = new(I) LoadFieldInstr(
+        LoadFieldInstr* load = new(Z) LoadFieldInstr(
             receiver,
             String::length_offset(),
-            Type::ZoneHandle(I, Type::SmiType()),
+            Type::ZoneHandle(Z, Type::SmiType()),
             node->token_pos());
         load->set_result_cid(kSmiCid);
         load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
@@ -3307,11 +3307,11 @@
           return ReturnDefinition(load);
         }
         ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty);
-        Value* zero_val = Bind(new(I) ConstantInstr(
-            Smi::ZoneHandle(I, Smi::New(0))));
+        Value* zero_val = Bind(new(Z) ConstantInstr(
+            Smi::ZoneHandle(Z, Smi::New(0))));
         Value* load_val = Bind(load);
         StrictCompareInstr* compare =
-            new(I) StrictCompareInstr(node->token_pos(),
+            new(Z) StrictCompareInstr(node->token_pos(),
                                    Token::kEQ_STRICT,
                                    load_val,
                                    zero_val,
@@ -3323,10 +3323,10 @@
       case MethodRecognizer::kImmutableArrayLength:
       case MethodRecognizer::kTypedDataLength: {
         Value* receiver = Bind(BuildLoadThisVar(node->scope()));
-        LoadFieldInstr* load = new(I) LoadFieldInstr(
+        LoadFieldInstr* load = new(Z) LoadFieldInstr(
             receiver,
             OffsetForLengthGetter(kind),
-            Type::ZoneHandle(I, Type::SmiType()),
+            Type::ZoneHandle(Z, Type::SmiType()),
             node->token_pos());
         load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength);
         load->set_result_cid(kSmiCid);
@@ -3336,23 +3336,23 @@
       case MethodRecognizer::kClassIDgetID: {
         LocalVariable* value_var =
             node->scope()->LookupVariable(Symbols::Value(), true);
-        Value* value = Bind(new(I) LoadLocalInstr(*value_var));
-        LoadClassIdInstr* load = new(I) LoadClassIdInstr(value);
+        Value* value = Bind(new(Z) LoadLocalInstr(*value_var));
+        LoadClassIdInstr* load = new(Z) LoadClassIdInstr(value);
         return ReturnDefinition(load);
       }
       case MethodRecognizer::kGrowableArrayCapacity: {
         Value* receiver = Bind(BuildLoadThisVar(node->scope()));
-        LoadFieldInstr* data_load = new(I) LoadFieldInstr(
+        LoadFieldInstr* data_load = new(Z) LoadFieldInstr(
             receiver,
             Array::data_offset(),
-            Type::ZoneHandle(I, Type::DynamicType()),
+            Type::ZoneHandle(Z, Type::DynamicType()),
             node->token_pos());
         data_load->set_result_cid(kArrayCid);
         Value* data = Bind(data_load);
-        LoadFieldInstr* length_load = new(I) LoadFieldInstr(
+        LoadFieldInstr* length_load = new(Z) LoadFieldInstr(
             data,
             Array::length_offset(),
-            Type::ZoneHandle(I, Type::SmiType()),
+            Type::ZoneHandle(Z, Type::SmiType()),
             node->token_pos());
         length_load->set_result_cid(kSmiCid);
         length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength);
@@ -3362,20 +3362,20 @@
         LocalVariable* type_args_parameter =
             node->scope()->LookupVariable(Symbols::TypeArgumentsParameter(),
                                           true);
-        Value* element_type = Bind(new(I) LoadLocalInstr(*type_args_parameter));
+        Value* element_type = Bind(new(Z) LoadLocalInstr(*type_args_parameter));
         LocalVariable* length_parameter =
             node->scope()->LookupVariable(Symbols::Length(), true);
-        Value* length = Bind(new(I) LoadLocalInstr(*length_parameter));
+        Value* length = Bind(new(Z) LoadLocalInstr(*length_parameter));
         CreateArrayInstr* create_array =
             new CreateArrayInstr(node->token_pos(), element_type, length);
         return ReturnDefinition(create_array);
       }
       case MethodRecognizer::kBigint_getDigits: {
         Value* receiver = Bind(BuildLoadThisVar(node->scope()));
-        LoadFieldInstr* load = new(I) LoadFieldInstr(
+        LoadFieldInstr* load = new(Z) LoadFieldInstr(
             receiver,
             Bigint::digits_offset(),
-            Type::ZoneHandle(I, Type::DynamicType()),
+            Type::ZoneHandle(Z, Type::DynamicType()),
             node->token_pos());
         load->set_result_cid(kTypedDataUint32ArrayCid);
         load->set_recognized_kind(kind);
@@ -3383,10 +3383,10 @@
       }
       case MethodRecognizer::kBigint_getUsed: {
         Value* receiver = Bind(BuildLoadThisVar(node->scope()));
-        LoadFieldInstr* load = new(I) LoadFieldInstr(
+        LoadFieldInstr* load = new(Z) LoadFieldInstr(
             receiver,
             Bigint::used_offset(),
-            Type::ZoneHandle(I, Type::SmiType()),
+            Type::ZoneHandle(Z, Type::SmiType()),
             node->token_pos());
         load->set_result_cid(kSmiCid);
         load->set_recognized_kind(kind);
@@ -3394,10 +3394,10 @@
       }
       case MethodRecognizer::kBigint_getNeg: {
         Value* receiver = Bind(BuildLoadThisVar(node->scope()));
-        LoadFieldInstr* load = new(I) LoadFieldInstr(
+        LoadFieldInstr* load = new(Z) LoadFieldInstr(
             receiver,
             Bigint::neg_offset(),
-            Type::ZoneHandle(I, Type::BoolType()),
+            Type::ZoneHandle(Z, Type::BoolType()),
             node->token_pos());
         load->set_result_cid(kBoolCid);
         load->set_recognized_kind(kind);
@@ -3408,7 +3408,7 @@
     }
   }
   InlineBailout("EffectGraphVisitor::VisitNativeBodyNode");
-  NativeCallInstr* native_call = new(I) NativeCallInstr(node);
+  NativeCallInstr* native_call = new(Z) NativeCallInstr(node);
   ReturnDefinition(native_call);
 }
 
@@ -3436,11 +3436,14 @@
 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
   // If the right hand side is an expression that does not contain
   // a safe point for the debugger to stop, add an explicit stub
-  // call.
-  if (node->value()->IsLiteralNode() ||
+  // call. Exception: don't do this when assigning to internal variables,
+  // or for generated code that has no source position.
+  if ((node->value()->IsLiteralNode() ||
       node->value()->IsLoadLocalNode() ||
-      node->value()->IsClosureNode()) {
-    AddInstruction(new(I) DebugStepCheckInstr(
+      node->value()->IsClosureNode()) &&
+      !node->local().IsInternal() &&
+      (node->token_pos() != Scanner::kNoSourcePos)) {
+    AddInstruction(new(Z) DebugStepCheckInstr(
         node->token_pos(), RawPcDescriptors::kRuntimeCall));
   }
 
@@ -3464,10 +3467,10 @@
   ValueGraphVisitor for_instance(owner());
   node->instance()->Visit(&for_instance);
   Append(for_instance);
-  LoadFieldInstr* load = new(I) LoadFieldInstr(
+  LoadFieldInstr* load = new(Z) LoadFieldInstr(
       for_instance.value(),
       &node->field(),
-      AbstractType::ZoneHandle(I, node->field().type()),
+      AbstractType::ZoneHandle(Z, node->field().type()),
       node->token_pos());
   if (node->field().guarded_cid() != kIllegalCid) {
     if (!node->field().is_nullable() ||
@@ -3491,8 +3494,8 @@
   Value* store_value = for_value.value();
   if (Isolate::Current()->TypeChecksEnabled()) {
     const AbstractType& type =
-        AbstractType::ZoneHandle(I, node->field().type());
-    const String& dst_name = String::ZoneHandle(I, node->field().name());
+        AbstractType::ZoneHandle(Z, node->field().type());
+    const String& dst_name = String::ZoneHandle(Z, node->field().name());
     store_value = BuildAssignableValue(node->value()->token_pos(),
                                        store_value,
                                        type,
@@ -3501,21 +3504,21 @@
 
   store_value = Bind(BuildStoreExprTemp(store_value));
   GuardFieldClassInstr* guard_field_class =
-      new(I) GuardFieldClassInstr(store_value,
+      new(Z) GuardFieldClassInstr(store_value,
                                node->field(),
-                               I->GetNextDeoptId());
+                               isolate()->GetNextDeoptId());
   AddInstruction(guard_field_class);
 
   store_value = Bind(BuildLoadExprTemp());
   GuardFieldLengthInstr* guard_field_length =
-      new(I) GuardFieldLengthInstr(store_value,
+      new(Z) GuardFieldLengthInstr(store_value,
                                    node->field(),
-                                   I->GetNextDeoptId());
+                                   isolate()->GetNextDeoptId());
   AddInstruction(guard_field_length);
 
   store_value = Bind(BuildLoadExprTemp());
   StoreInstanceFieldInstr* store =
-      new(I) StoreInstanceFieldInstr(node->field(),
+      new(Z) StoreInstanceFieldInstr(node->field(),
                                      for_instance.value(),
                                      store_value,
                                      kEmitStoreBarrier,
@@ -3531,11 +3534,11 @@
     ASSERT(node->field().value() != Object::sentinel().raw());
     ASSERT(node->field().value() != Object::transition_sentinel().raw());
     Definition* result =
-        new(I) ConstantInstr(Instance::ZoneHandle(I, node->field().value()));
+        new(Z) ConstantInstr(Instance::ZoneHandle(Z, node->field().value()));
     return ReturnDefinition(result);
   }
-  Value* field_value = Bind(new(I) ConstantInstr(node->field()));
-  LoadStaticFieldInstr* load = new(I) LoadStaticFieldInstr(field_value);
+  Value* field_value = Bind(new(Z) ConstantInstr(node->field()));
+  LoadStaticFieldInstr* load = new(Z) LoadStaticFieldInstr(field_value);
   ReturnDefinition(load);
 }
 
@@ -3552,7 +3555,7 @@
     store_value = for_value.value();
   }
   StoreStaticFieldInstr* store =
-      new(I) StoreStaticFieldInstr(node->field(), store_value);
+      new(Z) StoreStaticFieldInstr(node->field(), store_value);
 
   if (result_is_needed) {
     Do(store);
@@ -3578,12 +3581,12 @@
   if (node->IsSuperLoad()) {
     // Resolve the load indexed operator in the super class.
     super_function = &Function::ZoneHandle(
-          I, Resolver::ResolveDynamicAnyArgs(node->super_class(),
+          Z, Resolver::ResolveDynamicAnyArgs(node->super_class(),
                                              Symbols::IndexToken()));
     if (super_function->IsNull()) {
       // Could not resolve super operator. Generate call noSuchMethod() of the
       // super class instead.
-      ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos());
+      ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
       arguments->Add(node->array());
       arguments->Add(node->index_expr());
       StaticCallInstr* call =
@@ -3598,7 +3601,7 @@
     }
   }
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
   ValueGraphVisitor for_array(owner());
   node->array()->Visit(&for_array);
   Append(for_array);
@@ -3611,7 +3614,7 @@
 
   if (super_function != NULL) {
     // Generate static call to super operator.
-    StaticCallInstr* load = new(I) StaticCallInstr(node->token_pos(),
+    StaticCallInstr* load = new(Z) StaticCallInstr(node->token_pos(),
                                                    *super_function,
                                                    Object::null_array(),
                                                    arguments,
@@ -3620,7 +3623,7 @@
   } else {
     // Generate dynamic call to index operator.
     const intptr_t checked_argument_count = 1;
-    InstanceCallInstr* load = new(I) InstanceCallInstr(
+    InstanceCallInstr* load = new(Z) InstanceCallInstr(
         node->token_pos(),
         Symbols::IndexToken(),
         Token::kINDEX,
@@ -3640,12 +3643,12 @@
   if (node->IsSuperStore()) {
     // Resolve the store indexed operator in the super class.
     super_function = &Function::ZoneHandle(
-        I, Resolver::ResolveDynamicAnyArgs(node->super_class(),
+        Z, Resolver::ResolveDynamicAnyArgs(node->super_class(),
                                            Symbols::AssignIndexToken()));
     if (super_function->IsNull()) {
       // Could not resolve super operator. Generate call noSuchMethod() of the
       // super class instead.
-      ArgumentListNode* arguments = new(I) ArgumentListNode(node->token_pos());
+      ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos());
       arguments->Add(node->array());
       arguments->Add(node->index_expr());
       arguments->Add(node->value());
@@ -3667,7 +3670,7 @@
   }
 
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(3);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(3);
   ValueGraphVisitor for_array(owner());
   node->array()->Visit(&for_array);
   Append(for_array);
@@ -3693,7 +3696,7 @@
     // Generate static call to super operator []=.
 
     StaticCallInstr* store =
-        new(I) StaticCallInstr(node->token_pos(),
+        new(Z) StaticCallInstr(node->token_pos(),
                                *super_function,
                                Object::null_array(),
                                arguments,
@@ -3708,9 +3711,9 @@
     // Generate dynamic call to operator []=.
     const intptr_t checked_argument_count = 3;
     const String& name =
-        String::ZoneHandle(I, Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
+        String::ZoneHandle(Z, Symbols::New(Token::Str(Token::kASSIGN_INDEX)));
     InstanceCallInstr* store =
-        new(I) InstanceCallInstr(node->token_pos(),
+        new(Z) InstanceCallInstr(node->token_pos(),
                                  name,
                                  Token::kASSIGN_INDEX,
                                  arguments,
@@ -3749,10 +3752,10 @@
     Value* context = Bind(BuildCurrentContext());
     while (n-- > 0) {
       context = Bind(
-          new(I) LoadFieldInstr(context,
+          new(Z) LoadFieldInstr(context,
                                 Context::parent_offset(),
                                 // Not an instance, no type.
-                                Type::ZoneHandle(I, Type::null()),
+                                Type::ZoneHandle(Z, Type::null()),
                                 Scanner::kNoSourcePos));
     }
     Do(BuildStoreContext(context));
@@ -3779,16 +3782,16 @@
     // Allocate and chain a new context (Except don't chain when at the function
     // entry if the function does not capture any variables from outer scopes).
     Value* allocated_context =
-        Bind(new(I) AllocateContextInstr(node->token_pos(),
+        Bind(new(Z) AllocateContextInstr(node->token_pos(),
                                          num_context_variables));
     { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context);
       if (!is_top_level_sequence || HasContextScope()) {
         ASSERT(is_top_level_sequence ||
                (nested_block.ContextLevel() ==
                 nested_block.outer()->ContextLevel() + 1));
-        Value* tmp_val = Bind(new(I) LoadLocalInstr(*tmp_var));
+        Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var));
         Value* parent_context = Bind(BuildCurrentContext());
-        Do(new(I) StoreInstanceFieldInstr(Context::parent_offset(),
+        Do(new(Z) StoreInstanceFieldInstr(Context::parent_offset(),
                                           tmp_val,
                                           parent_context,
                                           kEmitStoreBarrier,
@@ -3810,10 +3813,10 @@
         if (parameter.is_captured()) {
           // Create a temporary local describing the original position.
           const String& temp_name = Symbols::TempParam();
-          LocalVariable* temp_local = new(I) LocalVariable(
+          LocalVariable* temp_local = new(Z) LocalVariable(
               0,  // Token index.
               temp_name,
-              Type::ZoneHandle(I, Type::DynamicType()));  // Type.
+              Type::ZoneHandle(Z, Type::DynamicType()));  // Type.
           temp_local->set_index(param_frame_index);
 
           // Mark this local as captured parameter so that the optimizer
@@ -3828,8 +3831,8 @@
           // Write NULL to the source location to detect buggy accesses and
           // allow GC of passed value if it gets overwritten by a new value in
           // the function.
-          Value* null_constant = Bind(new(I) ConstantInstr(
-              Object::ZoneHandle(I, Object::null())));
+          Value* null_constant = Bind(new(Z) ConstantInstr(
+              Object::ZoneHandle(Z, Object::null())));
           Do(BuildStoreLocal(*temp_local, null_constant));
         }
       }
@@ -3844,7 +3847,7 @@
     if (!function.IsImplicitGetterFunction() &&
         !function.IsImplicitSetterFunction()) {
       CheckStackOverflowInstr* check =
-          new(I) CheckStackOverflowInstr(function.token_pos(), 0);
+          new(Z) CheckStackOverflowInstr(function.token_pos(), 0);
       // If we are inlining don't actually attach the stack check. We must still
       // create the stack check in order to allocate a deopt id.
       if (!owner()->IsInlining()) {
@@ -3890,7 +3893,7 @@
       (function.IsAsyncClosure() ||
           function.IsSyncGenClosure() ||
           function.IsAsyncGenClosure())) {
-    JoinEntryInstr* preamble_end = new(I) JoinEntryInstr(
+    JoinEntryInstr* preamble_end = new(Z) JoinEntryInstr(
         owner()->AllocateBlockId(), owner()->try_index());
     ASSERT(exit() != NULL);
     exit()->Goto(preamble_end);
@@ -3930,19 +3933,19 @@
     exit_ = NULL;
 
     LoadLocalNode* load_jump_count =
-        new(I) LoadLocalNode(Scanner::kNoSourcePos, jump_var);
+        new(Z) LoadLocalNode(Scanner::kNoSourcePos, jump_var);
     ComparisonNode* check_jump_count;
     const intptr_t num_await_states = owner()->await_joins()->length();
 
     LocalVariable* old_context = top_scope->LookupVariable(
         Symbols::AwaitContextVar(), false);
     for (intptr_t i = 0; i < num_await_states; i++) {
-      check_jump_count = new(I) ComparisonNode(
+      check_jump_count = new(Z) ComparisonNode(
           Scanner::kNoSourcePos,
           Token::kEQ,
           load_jump_count,
-          new(I) LiteralNode(
-              Scanner::kNoSourcePos, Smi::ZoneHandle(I, Smi::New(i))));
+          new(Z) LiteralNode(
+              Scanner::kNoSourcePos, Smi::ZoneHandle(Z, Smi::New(i))));
       TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos);
       check_jump_count->Visit(&for_test);
       EffectGraphVisitor for_true(owner());
@@ -4033,14 +4036,14 @@
 
   if (for_try.is_open()) {
     JoinEntryInstr* after_try =
-        new(I) JoinEntryInstr(owner()->AllocateBlockId(),
+        new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
                               original_handler_index);
     for_try.Goto(after_try);
     for_try.exit_ = after_try;
   }
 
   JoinEntryInstr* try_entry =
-      new(I) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index);
+      new(Z) JoinEntryInstr(owner()->AllocateBlockId(), try_handler_index);
 
   Goto(try_entry);
   AppendFragment(try_entry, for_try);
@@ -4073,7 +4076,7 @@
   ASSERT(!catch_block->stacktrace_var().is_captured());
 
   CatchBlockEntryInstr* catch_entry =
-      new(I) CatchBlockEntryInstr(owner()->AllocateBlockId(),
+      new(Z) CatchBlockEntryInstr(owner()->AllocateBlockId(),
                                   catch_handler_index,
                                   catch_block->handler_types(),
                                   try_handler_index,
@@ -4084,7 +4087,7 @@
   AppendFragment(catch_entry, for_catch);
 
   if (for_catch.is_open()) {
-    JoinEntryInstr* join = new(I) JoinEntryInstr(owner()->AllocateBlockId(),
+    JoinEntryInstr* join = new(Z) JoinEntryInstr(owner()->AllocateBlockId(),
                                                  original_handler_index);
     for_catch.Goto(join);
     if (is_open()) Goto(join);
@@ -4108,15 +4111,15 @@
           for_finally.BuildLoadLocal(catch_block->rethrow_stacktrace_var()));
       for_finally.PushArgument(stacktrace);
       for_finally.AddInstruction(
-          new(I) ReThrowInstr(catch_block->token_pos(), catch_handler_index));
+          new(Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index));
       for_finally.CloseFragment();
     }
     ASSERT(!for_finally.is_open());
 
-    const Array& types = Array::ZoneHandle(I, Array::New(1, Heap::kOld));
-    types.SetAt(0, Type::Handle(I, Type::DynamicType()));
+    const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
+    types.SetAt(0, Type::Handle(Z, Type::DynamicType()));
     CatchBlockEntryInstr* finally_entry =
-        new(I) CatchBlockEntryInstr(owner()->AllocateBlockId(),
+        new(Z) CatchBlockEntryInstr(owner()->AllocateBlockId(),
                                     original_handler_index,
                                     types,
                                     catch_handler_index,
@@ -4156,14 +4159,14 @@
                                          *method_arguments,
                                          temp,
                                          is_super_invocation);
-  const Function& no_such_method_func = Function::ZoneHandle(I,
+  const Function& no_such_method_func = Function::ZoneHandle(Z,
       Resolver::ResolveDynamicAnyArgs(target_class, Symbols::NoSuchMethod()));
   // We are guaranteed to find noSuchMethod of class Object.
   ASSERT(!no_such_method_func.IsNull());
   ZoneGrowableArray<PushArgumentInstr*>* push_arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
   BuildPushArguments(*args, push_arguments);
-  return new(I) StaticCallInstr(args_pos,
+  return new(Z) StaticCallInstr(args_pos,
                                 no_such_method_func,
                                 Object::null_array(),
                                 push_arguments,
@@ -4178,65 +4181,65 @@
     ArgumentListNode* function_arguments,
     int invocation_type) {
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>();
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>();
   // Object receiver, actually a class literal of the unresolved method's owner.
   Type& type = Type::ZoneHandle(
-      I,
+      Z,
       Type::New(function_class,
-                TypeArguments::Handle(I, TypeArguments::null()),
+                TypeArguments::Handle(Z, TypeArguments::null()),
                 token_pos,
                 Heap::kOld));
   type ^= ClassFinalizer::FinalizeType(
       function_class, type, ClassFinalizer::kCanonicalize);
-  Value* receiver_value = Bind(new(I) ConstantInstr(type));
+  Value* receiver_value = Bind(new(Z) ConstantInstr(type));
   arguments->Add(PushArgument(receiver_value));
   // String memberName.
   const String& member_name =
-      String::ZoneHandle(I, Symbols::New(function_name));
-  Value* member_name_value = Bind(new(I) ConstantInstr(member_name));
+      String::ZoneHandle(Z, Symbols::New(function_name));
+  Value* member_name_value = Bind(new(Z) ConstantInstr(member_name));
   arguments->Add(PushArgument(member_name_value));
   // Smi invocation_type.
-  Value* invocation_type_value = Bind(new(I) ConstantInstr(
-      Smi::ZoneHandle(I, Smi::New(invocation_type))));
+  Value* invocation_type_value = Bind(new(Z) ConstantInstr(
+      Smi::ZoneHandle(Z, Smi::New(invocation_type))));
   arguments->Add(PushArgument(invocation_type_value));
   // List arguments.
   if (function_arguments == NULL) {
     Value* arguments_value = Bind(
-        new(I) ConstantInstr(Array::ZoneHandle(I, Array::null())));
+        new(Z) ConstantInstr(Array::ZoneHandle(Z, Array::null())));
     arguments->Add(PushArgument(arguments_value));
   } else {
     ValueGraphVisitor array_val(owner());
     ArrayNode* array =
-        new(I) ArrayNode(token_pos, Type::ZoneHandle(I, Type::ArrayType()),
+        new(Z) ArrayNode(token_pos, Type::ZoneHandle(Z, Type::ArrayType()),
                       function_arguments->nodes());
     array->Visit(&array_val);
     Append(array_val);
     arguments->Add(PushArgument(array_val.value()));
   }
   // List argumentNames.
-  ConstantInstr* cinstr = new(I) ConstantInstr(
-      (function_arguments == NULL) ? Array::ZoneHandle(I, Array::null())
+  ConstantInstr* cinstr = new(Z) ConstantInstr(
+      (function_arguments == NULL) ? Array::ZoneHandle(Z, Array::null())
                                    : function_arguments->names());
   Value* argument_names_value = Bind(cinstr);
   arguments->Add(PushArgument(argument_names_value));
 
   // List existingArgumentNames.
   Value* existing_argument_names_value =
-      Bind(new(I) ConstantInstr(Array::ZoneHandle(I, Array::null())));
+      Bind(new(Z) ConstantInstr(Array::ZoneHandle(Z, Array::null())));
   arguments->Add(PushArgument(existing_argument_names_value));
   // Resolve and call NoSuchMethodError._throwNew.
-  const Library& core_lib = Library::Handle(I, Library::CoreLibrary());
+  const Library& core_lib = Library::Handle(Z, Library::CoreLibrary());
   const Class& cls = Class::Handle(
-      I, core_lib.LookupClass(Symbols::NoSuchMethodError()));
+      Z, core_lib.LookupClass(Symbols::NoSuchMethodError()));
   ASSERT(!cls.IsNull());
   const Function& func = Function::ZoneHandle(
-      I,
+      Z,
       Resolver::ResolveStatic(cls,
                               Library::PrivateCoreLibName(Symbols::ThrowNew()),
                               arguments->length(),
                               Object::null_array()));
   ASSERT(!func.IsNull());
-  return new(I) StaticCallInstr(token_pos,
+  return new(Z) StaticCallInstr(token_pos,
                                 func,
                                 Object::null_array(),  // No names.
                                 arguments,
@@ -4248,7 +4251,7 @@
   if (node->exception()->IsLiteralNode() ||
       node->exception()->IsLoadLocalNode() ||
       node->exception()->IsClosureNode()) {
-    AddInstruction(new(I) DebugStepCheckInstr(
+    AddInstruction(new(Z) DebugStepCheckInstr(
         node->token_pos(), RawPcDescriptors::kRuntimeCall));
   }
   ValueGraphVisitor for_exception(owner());
@@ -4257,13 +4260,13 @@
   PushArgument(for_exception.value());
   Instruction* instr = NULL;
   if (node->stacktrace() == NULL) {
-    instr = new(I) ThrowInstr(node->token_pos());
+    instr = new(Z) ThrowInstr(node->token_pos());
   } else {
     ValueGraphVisitor for_stack_trace(owner());
     node->stacktrace()->Visit(&for_stack_trace);
     Append(for_stack_trace);
     PushArgument(for_stack_trace.value());
-    instr = new(I) ReThrowInstr(node->token_pos(), owner()->catch_try_index());
+    instr = new(Z) ReThrowInstr(node->token_pos(), owner()->catch_try_index());
   }
   AddInstruction(instr);
 }
@@ -4280,8 +4283,8 @@
 // so that the fragment is not closed in the middle of an expression.
 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) {
   BuildThrowNode(node);
-  ReturnDefinition(new(I) ConstantInstr(
-      Instance::ZoneHandle(I, Instance::null())));
+  ReturnDefinition(new(Z) ConstantInstr(
+      Instance::ZoneHandle(Z, Instance::null())));
 }
 
 
@@ -4301,7 +4304,7 @@
   // that follows the inlined code. See issue 22822.
 
   JoinEntryInstr* finally_entry =
-      new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
+      new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
   EffectGraphVisitor for_finally_block(owner());
   node->finally_block()->Visit(&for_finally_block);
 
@@ -4311,7 +4314,7 @@
 
   if (for_finally_block.is_open()) {
     JoinEntryInstr* after_finally =
-        new(I) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
+        new(Z) JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index());
     for_finally_block.Goto(after_finally);
     for_finally_block.exit_ = after_finally;
   }
@@ -4331,10 +4334,10 @@
     AstPrinter::PrintFunctionScope(parsed_function());
   }
   TargetEntryInstr* normal_entry =
-      new(I) TargetEntryInstr(AllocateBlockId(),
+      new(Z) TargetEntryInstr(AllocateBlockId(),
                               CatchClauseNode::kInvalidTryIndex);
   graph_entry_ =
-      new(I) GraphEntryInstr(parsed_function(), normal_entry, osr_id_);
+      new(Z) GraphEntryInstr(parsed_function(), normal_entry, osr_id_);
   EffectGraphVisitor for_effect(this);
   parsed_function().node_sequence()->Visit(&for_effect);
   AppendFragment(normal_entry, for_effect);
@@ -4349,15 +4352,14 @@
   }
 
   FlowGraph* graph =
-      new(I) FlowGraph(parsed_function(), graph_entry_, last_used_block_id_);
+      new(Z) FlowGraph(parsed_function(), graph_entry_, last_used_block_id_);
   return graph;
 }
 
 
 void FlowGraphBuilder::PruneUnreachable() {
   ASSERT(osr_id_ != Isolate::kNoDeoptId);
-  Zone* zone = parsed_function().zone();
-  BitVector* block_marks = new(zone) BitVector(zone, last_used_block_id_ + 1);
+  BitVector* block_marks = new(Z) BitVector(Z, last_used_block_id_ + 1);
   bool found = graph_entry_->PruneUnreachable(this, graph_entry_, NULL, osr_id_,
                                               block_marks);
   ASSERT(found);
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 9e8812d..1ecd7f5 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -131,6 +131,7 @@
                           intptr_t try_index);
 
   Isolate* isolate() const { return caller_graph_->isolate(); }
+  Zone* zone() const { return caller_graph_->zone(); }
 
   FlowGraph* caller_graph_;
   Definition* call_;
@@ -230,6 +231,7 @@
   static uword FindDoubleConstant(double value);
 
   Isolate* isolate() const { return parsed_function().isolate(); }
+  Zone* zone() const { return parsed_function().zone(); }
 
  private:
   friend class NestedStatement;  // Explicit access to nesting_stack_.
@@ -480,6 +482,7 @@
                       JoinEntryInstr* target);
 
   Isolate* isolate() const { return owner()->isolate(); }
+  Zone* zone() const { return owner()->zone(); }
 
  private:
   friend class TempLocalScope;  // For ReturnDefinition.
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index d41a3b4..146b2ec 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -55,9 +55,6 @@
 DECLARE_FLAG(bool, use_osr);
 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
 
-// Quick access to the locally defined isolate() method.
-#define I (isolate())
-
 // Assign locations to incoming arguments, i.e., values pushed above spill slots
 // with PushArgument.  Recursively allocates from outermost to innermost
 // environment.
@@ -96,6 +93,7 @@
     const GrowableArray<const Function*>& inline_id_to_function,
     const GrowableArray<intptr_t>& caller_inline_id)
       : isolate_(Isolate::Current()),
+        zone_(Thread::Current()->zone()),
         assembler_(assembler),
         parsed_function_(parsed_function),
         flow_graph_(*flow_graph),
@@ -137,17 +135,17 @@
          parsed_function.function().raw());
   if (!is_optimizing) {
     const intptr_t len = isolate()->deopt_id();
-    deopt_id_to_ic_data_ = new(isolate()) ZoneGrowableArray<const ICData*>(len);
+    deopt_id_to_ic_data_ = new(zone()) ZoneGrowableArray<const ICData*>(len);
     deopt_id_to_ic_data_->SetLength(len);
     for (intptr_t i = 0; i < len; i++) {
       (*deopt_id_to_ic_data_)[i] = NULL;
     }
-    const Array& old_saved_icdata = Array::Handle(isolate(),
+    const Array& old_saved_icdata = Array::Handle(zone(),
         flow_graph->function().ic_data_array());
     const intptr_t saved_len =
         old_saved_icdata.IsNull() ? 0 : old_saved_icdata.Length();
     for (intptr_t i = 0; i < saved_len; i++) {
-      ICData& icd = ICData::ZoneHandle(isolate());
+      ICData& icd = ICData::ZoneHandle(zone());
       icd ^= old_saved_icdata.At(i);
       (*deopt_id_to_ic_data_)[icd.deopt_id()] = &icd;
     }
@@ -389,6 +387,12 @@
       continue;
     }
 
+#if defined(DEBUG)
+    if (!is_optimizing()) {
+      FrameStateClear();
+    }
+#endif
+
     LoopInfoComment(assembler(), *entry, *loop_headers);
 
     entry->set_offset(assembler()->CodeSize());
@@ -426,7 +430,17 @@
         pending_deoptimization_env_ = NULL;
         EmitInstructionEpilogue(instr);
       }
+
+#if defined(DEBUG)
+      if (!is_optimizing()) {
+        FrameStateUpdateWith(instr);
+      }
+#endif
     }
+
+#if defined(DEBUG)
+    ASSERT(is_optimizing() || FrameStateIsSafeToCall());
+#endif
   }
 
   if (inline_id_to_function_.length() > max_inlining_id + 1) {
@@ -750,7 +764,7 @@
     return NULL;
   }
 
-  Environment* env = instruction->env()->DeepCopy(isolate());
+  Environment* env = instruction->env()->DeepCopy(zone());
   // 1. Iterate the registers in the order they will be spilled to compute
   //    the slots they will be spilled to.
   intptr_t next_slot = StackSize() + env->CountArgsPushed();
@@ -838,7 +852,7 @@
   const Function& function = parsed_function().function();
   const intptr_t incoming_arg_count =
       function.HasOptionalParameters() ? 0 : function.num_fixed_parameters();
-  DeoptInfoBuilder builder(isolate(), incoming_arg_count);
+  DeoptInfoBuilder builder(zone(), incoming_arg_count);
 
   intptr_t deopt_info_table_size = DeoptTable::SizeFor(deopt_infos_.length());
   if (deopt_info_table_size == 0) {
@@ -912,7 +926,7 @@
 void FlowGraphCompiler::TryIntrinsify() {
   // Intrinsification skips arguments checks, therefore disable if in checked
   // mode.
-  if (FLAG_intrinsify && !I->TypeChecksEnabled()) {
+  if (FLAG_intrinsify && !isolate()->TypeChecksEnabled()) {
     if (parsed_function().function().kind() == RawFunction::kImplicitGetter) {
       // An implicit getter must have a specific AST structure.
       const SequenceNode& sequence_node = *parsed_function().node_sequence();
@@ -1139,7 +1153,7 @@
 void FlowGraphCompiler::AllocateRegistersLocally(Instruction* instr) {
   ASSERT(!is_optimizing());
 
-  instr->InitializeLocationSummary(I->current_zone(),
+  instr->InitializeLocationSummary(zone(),
                                    false);  // Not optimizing.
   LocationSummary* locs = instr->locs();
 
@@ -1520,7 +1534,7 @@
     ASSERT(res->NumArgsTested() == num_args_tested);
     return res;
   }
-  const ICData& ic_data = ICData::ZoneHandle(isolate(), ICData::New(
+  const ICData& ic_data = ICData::ZoneHandle(zone(), ICData::New(
       parsed_function().function(), target_name,
       arguments_descriptor, deopt_id, num_args_tested));
   (*deopt_id_to_ic_data_)[deopt_id] = &ic_data;
@@ -1541,8 +1555,8 @@
     ASSERT(res->NumArgsTested() == num_args_tested);
     return res;
   }
-  const ICData& ic_data = ICData::ZoneHandle(isolate(), ICData::New(
-      parsed_function().function(), String::Handle(isolate(), target.name()),
+  const ICData& ic_data = ICData::ZoneHandle(zone(), ICData::New(
+      parsed_function().function(), String::Handle(zone(), target.name()),
       arguments_descriptor, deopt_id, num_args_tested));
   ic_data.AddTarget(target);
   (*deopt_id_to_ic_data_)[deopt_id] = &ic_data;
@@ -1598,4 +1612,78 @@
 }
 
 
+#if defined(DEBUG)
+void FlowGraphCompiler::FrameStateUpdateWith(Instruction* instr) {
+  ASSERT(!is_optimizing());
+
+  switch (instr->tag()) {
+    case Instruction::kPushArgument:
+    case Instruction::kPushTemp:
+      // Do nothing.
+      break;
+
+    case Instruction::kDropTemps:
+      FrameStatePop(instr->locs()->input_count() +
+          instr->AsDropTemps()->num_temps());
+      break;
+
+    default:
+      FrameStatePop(instr->locs()->input_count());
+      break;
+  }
+
+  ASSERT(!instr->locs()->can_call() || FrameStateIsSafeToCall());
+
+  FrameStatePop(instr->ArgumentCount());
+  Definition* defn = instr->AsDefinition();
+  if ((defn != NULL) && defn->HasTemp()) {
+    FrameStatePush(defn);
+  }
+}
+
+
+void FlowGraphCompiler::FrameStatePush(Definition* defn) {
+  Representation rep = defn->representation();
+  if ((rep == kUnboxedDouble) ||
+      (rep == kUnboxedFloat64x2) ||
+      (rep == kUnboxedFloat32x4)) {
+    // LoadField instruction lies about its representation in the unoptimized
+    // code because Definition::representation() can't depend on the type of
+    // compilation but MakeLocationSummary and EmitNativeCode can.
+    ASSERT(defn->IsLoadField() && defn->AsLoadField()->IsUnboxedLoad());
+    ASSERT(defn->locs()->out(0).IsRegister());
+    rep = kTagged;
+  }
+  ASSERT(!is_optimizing());
+  ASSERT((rep == kTagged) || (rep == kUntagged));
+  ASSERT(rep != kUntagged || flow_graph_.IsIrregexpFunction());
+  frame_state_.Add(rep);
+}
+
+
+void FlowGraphCompiler::FrameStatePop(intptr_t count) {
+  ASSERT(!is_optimizing());
+  frame_state_.TruncateTo(Utils::Maximum(static_cast<intptr_t>(0),
+      frame_state_.length() - count));
+}
+
+
+bool FlowGraphCompiler::FrameStateIsSafeToCall() {
+  ASSERT(!is_optimizing());
+  for (intptr_t i = 0; i < frame_state_.length(); i++) {
+    if (frame_state_[i] != kTagged) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+void FlowGraphCompiler::FrameStateClear() {
+  ASSERT(!is_optimizing());
+  frame_state_.TruncateTo(0);
+}
+#endif
+
+
 }  // namespace dart
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 60bffbd..31b6176 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -521,6 +521,7 @@
   }
 
   Isolate* isolate() const { return isolate_; }
+  Zone* zone() const { return zone_; }
 
   void AddStubCallTarget(const Code& code);
 
@@ -644,12 +645,25 @@
     return stackmap_table_builder_;
   }
 
+#if defined(DEBUG)
+  void FrameStateUpdateWith(Instruction* instr);
+  void FrameStatePush(Definition* defn);
+  void FrameStatePop(intptr_t count);
+  bool FrameStateIsSafeToCall();
+  void FrameStateClear();
+#endif
+
   Isolate* isolate_;
+  Zone* zone_;
   Assembler* assembler_;
   const ParsedFunction& parsed_function_;
   const FlowGraph& flow_graph_;
   const GrowableArray<BlockEntryInstr*>& block_order_;
 
+#if defined(DEBUG)
+  GrowableArray<Representation> frame_state_;
+#endif
+
   // Compiler specific per-block state.  Indexed by postorder block number
   // for convenience.  This is not the block's index in the block order,
   // which is reverse postorder.
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index b1bb19a..8f93df9 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -1102,7 +1102,7 @@
           __ StoreToOffset(kWord, CTX, FP, (slot_base - i) * kWordSize);
         } else {
           const Context& empty_context = Context::ZoneHandle(
-              isolate(), isolate()->object_store()->empty_context());
+              zone(), isolate()->object_store()->empty_context());
           __ LoadObject(R1, empty_context);
           __ StoreToOffset(kWord, R1, FP, (slot_base - i) * kWordSize);
         }
@@ -1196,49 +1196,29 @@
   counter.SetAt(0, Smi::Handle(Smi::New(0)));
   __ Comment("Edge counter");
   __ LoadObject(R0, counter);
-#if defined(DEBUG)
   intptr_t increment_start = assembler_->CodeSize();
+#if defined(DEBUG)
   bool old_use_far_branches = assembler_->use_far_branches();
   assembler_->set_use_far_branches(true);
 #endif  // DEBUG
   __ ldr(IP, FieldAddress(R0, Array::element_offset(0)));
   __ add(IP, IP, Operand(Smi::RawValue(1)));
   __ StoreIntoSmiField(FieldAddress(R0, Array::element_offset(0)), IP);
+  int32_t size = assembler_->CodeSize() - increment_start;
+  if (isolate()->edge_counter_increment_size() == -1) {
+    isolate()->set_edge_counter_increment_size(size);
+  } else {
+    ASSERT(size == isolate()->edge_counter_increment_size());
+  }
 #if defined(DEBUG)
   assembler_->set_use_far_branches(old_use_far_branches);
-  // If the assertion below fails, update EdgeCounterIncrementSizeInBytes.
-  intptr_t expected = EdgeCounterIncrementSizeInBytes();
-  intptr_t actual = assembler_->CodeSize() - increment_start;
-  if (actual != expected) {
-    FATAL2("Edge counter increment length: %" Pd ", expected %" Pd "\n",
-           actual,
-           expected);
-  }
 #endif  // DEBUG
 }
 
 
 int32_t FlowGraphCompiler::EdgeCounterIncrementSizeInBytes() {
-  // Used by CodePatcher; so must be constant across all code in an isolate.
-  int32_t size = 3 * Instr::kInstrSize;
-#if defined(DEBUG)
-  if (TargetCPUFeatures::arm_version() == ARMv7) {
-    size += 35 * Instr::kInstrSize;
-  } else {
-    // To update this number for e.g. ARMv6, run a SIMARM build with
-    // --sim_use_armv6 on any Dart program.
-    size += 51 * Instr::kInstrSize;
-  }
-#endif  // DEBUG
-  if (VerifiedMemory::enabled()) {
-    if (TargetCPUFeatures::arm_version() == ARMv7) {
-      size += 20 * Instr::kInstrSize;
-    } else {
-      // To update this number for e.g. ARMv6, run a SIMARM build with
-      // --sim_use_armv6 --verified_mem on any Dart program.
-      size += 28 * Instr::kInstrSize;
-    }
-  }
+  const int32_t size = Isolate::Current()->edge_counter_increment_size();
+  ASSERT(size != -1);
   return size;
 }
 
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index cee93b7..1e1bb66 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -1106,7 +1106,7 @@
           __ StoreToOffset(CTX, FP, (slot_base - i) * kWordSize, PP);
         } else {
           const Context& empty_context = Context::ZoneHandle(
-              isolate(), isolate()->object_store()->empty_context());
+              zone(), isolate()->object_store()->empty_context());
           __ LoadObject(R1, empty_context, PP);
           __ StoreToOffset(R1, FP, (slot_base - i) * kWordSize, PP);
         }
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 4170d94..b6a6b94 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -1233,32 +1233,20 @@
   counter.SetAt(0, Smi::Handle(Smi::New(0)));
   __ Comment("Edge counter");
   __ LoadObject(EAX, counter);
-#if defined(DEBUG)
   intptr_t increment_start = assembler_->CodeSize();
-#endif  // DEBUG
   __ IncrementSmiField(FieldAddress(EAX, Array::element_offset(0)), 1);
-#if defined(DEBUG)
-  // If the assertion below fails, update EdgeCounterIncrementSizeInBytes.
-  intptr_t expected = EdgeCounterIncrementSizeInBytes();
-  intptr_t actual = assembler_->CodeSize() - increment_start;
-  if (actual != expected) {
-    FATAL2("Edge counter increment length: %" Pd ", expected %" Pd "\n",
-           actual,
-           expected);
+  int32_t size = assembler_->CodeSize() - increment_start;
+  if (isolate()->edge_counter_increment_size() == -1) {
+    isolate()->set_edge_counter_increment_size(size);
+  } else {
+    ASSERT(size == isolate()->edge_counter_increment_size());
   }
-#endif  // DEBUG
 }
 
 
 int32_t FlowGraphCompiler::EdgeCounterIncrementSizeInBytes() {
-  // Used by CodePatcher; so must be constant across all code in an isolate.
-  int32_t size = 4;
-#if defined(DEBUG)
-  size += 19;  // VerifySmi
-#endif  // DEBUG
-  if (VerifiedMemory::enabled()) {
-    size += 50;
-  }
+  const int32_t size = Isolate::Current()->edge_counter_increment_size();
+  ASSERT(size != -1);
   return size;
 }
 
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 8127636..1f09dc0 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -1130,7 +1130,7 @@
           __ sw(CTX, Address(FP, (slot_base - i) * kWordSize));
         } else {
           const Context& empty_context = Context::ZoneHandle(
-              isolate(), isolate()->object_store()->empty_context());
+              zone(), isolate()->object_store()->empty_context());
           __ LoadObject(V1, empty_context);
           __ sw(V1, Address(FP, (slot_base - i) * kWordSize));
         }
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index b10a119..c24d2ef 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -1122,7 +1122,7 @@
           __ movq(Address(RBP, (slot_base - i) * kWordSize), CTX);
         } else {
           const Context& empty_context = Context::ZoneHandle(
-              isolate(), isolate()->object_store()->empty_context());
+              zone(), isolate()->object_store()->empty_context());
           __ StoreObject(
               Address(RBP, (slot_base - i) * kWordSize), empty_context, PP);
         }
@@ -1240,32 +1240,20 @@
   counter.SetAt(0, Smi::Handle(Smi::New(0)));
   __ Comment("Edge counter");
   __ LoadObject(RAX, counter, PP);
-#if defined(DEBUG)
   intptr_t increment_start = assembler_->CodeSize();
-#endif  // DEBUG
   __ IncrementSmiField(FieldAddress(RAX, Array::element_offset(0)), 1);
-#if defined(DEBUG)
-  // If the assertion below fails, update EdgeCounterIncrementSizeInBytes.
-  intptr_t expected = EdgeCounterIncrementSizeInBytes();
-  intptr_t actual = assembler_->CodeSize() - increment_start;
-  if (actual != expected) {
-    FATAL2("Edge counter increment length: %" Pd ", expected %" Pd "\n",
-           actual,
-           expected);
+  int32_t size = assembler_->CodeSize() - increment_start;
+  if (isolate()->edge_counter_increment_size() == -1) {
+    isolate()->set_edge_counter_increment_size(size);
+  } else {
+    ASSERT(size == isolate()->edge_counter_increment_size());
   }
-#endif  // DEBUG
 }
 
 
 int32_t FlowGraphCompiler::EdgeCounterIncrementSizeInBytes() {
-  // Used by CodePatcher; so must be constant across all code in an isolate.
-  int32_t size = 5;
-#if defined(DEBUG)
-  size += 36;  // VerifySmi
-#endif  // DEBUG
-  if (VerifiedMemory::enabled()) {
-    size += 72;
-  }
+  const int32_t size = Isolate::Current()->edge_counter_increment_size();
+  ASSERT(size != -1);
   return size;
 }
 
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index b18a838..de8fabd 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -993,7 +993,7 @@
         LoadFieldInstr* context_load = new(Z) LoadFieldInstr(
             new Value((*arguments)[0]->definition()),
             Closure::context_offset(),
-            AbstractType::ZoneHandle(isolate(), AbstractType::null()),
+            AbstractType::ZoneHandle(zone(), AbstractType::null()),
             call_data->call->token_pos());
         context_load->set_is_immutable(true);
         context_load->set_ssa_temp_index(
@@ -1331,7 +1331,7 @@
         inlined_entries_[i]->AsGraphEntry()->UnuseAllInputs();
 
         JoinEntryInstr* new_join =
-            BranchSimplifier::ToJoinEntry(isolate(), old_target);
+            BranchSimplifier::ToJoinEntry(zone(), old_target);
         old_target->ReplaceAsPredecessorWith(new_join);
         for (intptr_t j = 0; j < old_target->dominated_blocks().length(); ++j) {
           BlockEntryInstr* block = old_target->dominated_blocks()[j];
@@ -1341,9 +1341,9 @@
         TargetEntryInstr* new_target =
             new TargetEntryInstr(owner_->caller_graph()->allocate_block_id(),
                                  old_target->try_index());
-        new_target->InheritDeoptTarget(isolate(), new_join);
+        new_target->InheritDeoptTarget(zone(), new_join);
         GotoInstr* new_goto = new(Z) GotoInstr(new_join);
-        new_goto->InheritDeoptTarget(isolate(), new_join);
+        new_goto->InheritDeoptTarget(zone(), new_join);
         new_target->LinkTo(new_goto);
         new_target->set_last_instruction(new_goto);
         new_join->predecessors_.Add(new_target);
@@ -1407,7 +1407,7 @@
   ASSERT(arguments.length() > 0);
   Value* actual = arguments[0];
   RedefinitionInstr* redefinition = new(Z)
-      RedefinitionInstr(actual->Copy(isolate()));
+      RedefinitionInstr(actual->Copy(Z));
   redefinition->set_ssa_temp_index(
       owner_->caller_graph()->alloc_ssa_temp_index());
   redefinition->UpdateType(CompileType::FromCid(receiver_cid));
@@ -1436,7 +1436,7 @@
       LoadFieldInstr* context_load = new(Z) LoadFieldInstr(
           new Value(redefinition),
           Closure::context_offset(),
-          AbstractType::ZoneHandle(isolate(), AbstractType::null()),
+          AbstractType::ZoneHandle(zone(), AbstractType::null()),
           call_data.call->token_pos());
       context_load->set_is_immutable(true);
       context_load->set_ssa_temp_index(
@@ -1522,7 +1522,7 @@
       new(Z) TargetEntryInstr(
           owner_->caller_graph()->allocate_block_id(),
           call_->GetBlock()->try_index());
-  entry->InheritDeoptTarget(isolate(), call_);
+  entry->InheritDeoptTarget(zone(), call_);
 
   // This function uses a cursor (a pointer to the 'current' instruction) to
   // build the graph.  The next instruction will be inserted after the
@@ -1552,7 +1552,7 @@
           new(Z) Value(cid_redefinition),
           inlined_variants_[i].cid,
           call_->deopt_id());
-      check_class_id->InheritDeoptTarget(isolate(), call_);
+      check_class_id->InheritDeoptTarget(zone(), call_);
       cursor = AppendInstruction(cursor, check_class_id);
 
       // The next instruction is the first instruction of the inlined body.
@@ -1585,7 +1585,7 @@
         JoinEntryInstr* join = callee_entry->AsJoinEntry();
         ASSERT(join->dominator() != NULL);
         GotoInstr* goto_join = new GotoInstr(join);
-        goto_join->InheritDeoptTarget(isolate(), join);
+        goto_join->InheritDeoptTarget(zone(), join);
         cursor->LinkTo(goto_join);
         current_block->set_last_instruction(goto_join);
       } else {
@@ -1608,7 +1608,7 @@
                                  new Value(cid_constant),
                                  false);  // No number check.
       BranchInstr* branch = new BranchInstr(compare);
-      branch->InheritDeoptTarget(isolate(), call_);
+      branch->InheritDeoptTarget(zone(), call_);
       AppendInstruction(AppendInstruction(cursor, cid_constant), branch);
       current_block->set_last_instruction(branch);
       cursor = NULL;
@@ -1640,9 +1640,9 @@
         true_target =
             new TargetEntryInstr(owner_->caller_graph()->allocate_block_id(),
                                  call_->GetBlock()->try_index());
-        true_target->InheritDeoptTarget(isolate(), join);
+        true_target->InheritDeoptTarget(zone(), join);
         GotoInstr* goto_join = new GotoInstr(join);
-        goto_join->InheritDeoptTarget(isolate(), join);
+        goto_join->InheritDeoptTarget(zone(), join);
         true_target->LinkTo(goto_join);
         true_target->set_last_instruction(goto_join);
       }
@@ -1654,7 +1654,7 @@
       TargetEntryInstr* false_target =
           new TargetEntryInstr(owner_->caller_graph()->allocate_block_id(),
                                call_->GetBlock()->try_index());
-      false_target->InheritDeoptTarget(isolate(), call_);
+      false_target->InheritDeoptTarget(zone(), call_);
       *branch->false_successor_address() = false_target;
       current_block->AddDominatedBlock(false_target);
       cursor = current_block = false_target;
@@ -1689,7 +1689,7 @@
                                          true);  // With checks.
     fallback_call->set_ssa_temp_index(
         owner_->caller_graph()->alloc_ssa_temp_index());
-    fallback_call->InheritDeoptTarget(isolate(), call_);
+    fallback_call->InheritDeoptTarget(zone(), call_);
     ReturnInstr* fallback_return =
         new ReturnInstr(call_->instance_call()->token_pos(),
                         new Value(fallback_call));
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 17e5c08..04bb036 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -1199,7 +1199,7 @@
 
   *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(),
                                    call->GetBlock()->try_index());
-  (*entry)->InheritDeoptTarget(I, call);
+  (*entry)->InheritDeoptTarget(Z, call);
   Instruction* cursor = *entry;
   if (I->TypeChecksEnabled()) {
     // Only type check for the value. A type check for the index is not
@@ -1681,7 +1681,7 @@
   Definition* index = call->ArgumentAt(1);
   *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(),
                                    call->GetBlock()->try_index());
-  (*entry)->InheritDeoptTarget(I, call);
+  (*entry)->InheritDeoptTarget(Z, call);
   Instruction* cursor = *entry;
 
   array_cid = PrepareInlineIndexedOp(call,
@@ -2272,8 +2272,8 @@
     const String& name = (kind == RawFunction::kMethodExtractor)
         ? String::Handle(Z, Field::NameFromGetter(call->function_name()))
         : call->function_name();
-    return isolate()->cha()->HasOverride(Class::Handle(Z, function.Owner()),
-                                         name);
+    return thread()->cha()->HasOverride(Class::Handle(Z, function.Owner()),
+                                        name);
   }
   return true;
 }
@@ -2738,7 +2738,7 @@
 
   *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(),
                                    call->GetBlock()->try_index());
-  (*entry)->InheritDeoptTarget(I, call);
+  (*entry)->InheritDeoptTarget(Z, call);
 
   *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry);
 
@@ -2760,7 +2760,7 @@
 
   *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(),
                                    call->GetBlock()->try_index());
-  (*entry)->InheritDeoptTarget(I, call);
+  (*entry)->InheritDeoptTarget(Z, call);
 
   *last = PrepareInlineStringIndexOp(call, cid, str, index, *entry);
 
@@ -2784,7 +2784,7 @@
 
   *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(),
                                    call->GetBlock()->try_index());
-  (*entry)->InheritDeoptTarget(I, call);
+  (*entry)->InheritDeoptTarget(Z, call);
   // Arguments are checked. No need for class check.
   BinaryDoubleOpInstr* double_bin_op =
       new(Z) BinaryDoubleOpInstr(op_kind,
@@ -3554,7 +3554,7 @@
   Definition* index = call->ArgumentAt(1);
   *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(),
                                    call->GetBlock()->try_index());
-  (*entry)->InheritDeoptTarget(I, call);
+  (*entry)->InheritDeoptTarget(Z, call);
   Instruction* cursor = *entry;
 
   array_cid = PrepareInlineByteArrayBaseOp(call,
@@ -3607,7 +3607,7 @@
   Definition* index = call->ArgumentAt(1);
   *entry = new(Z) TargetEntryInstr(flow_graph()->allocate_block_id(),
                                    call->GetBlock()->try_index());
-  (*entry)->InheritDeoptTarget(I, call);
+  (*entry)->InheritDeoptTarget(Z, call);
   Instruction* cursor = *entry;
 
   array_cid = PrepareInlineByteArrayBaseOp(call,
@@ -3939,9 +3939,9 @@
   // Signature classes have different type checking rules.
   if (type_class.IsSignatureClass()) return false;
   // Could be an interface check?
-  if (isolate()->cha()->IsImplemented(type_class)) return false;
+  if (thread()->cha()->IsImplemented(type_class)) return false;
   // Check if there are subclasses.
-  if (isolate()->cha()->HasSubclasses(type_class)) return false;
+  if (thread()->cha()->HasSubclasses(type_class)) return false;
   const intptr_t num_type_args = type_class.NumTypeArguments();
   if (num_type_args > 0) {
     // Only raw types can be directly compared, thus disregarding type
@@ -4877,7 +4877,7 @@
         Definition* old = (*idefs)[j];
         ConstantInstr* orig = cdefs[j]->AsConstant();
         ConstantInstr* copy =
-            new(flow_graph->isolate()) ConstantInstr(orig->value());
+            new(flow_graph->zone()) ConstantInstr(orig->value());
         copy->set_ssa_temp_index(flow_graph->alloc_ssa_temp_index());
         old->ReplaceUsesWith(copy);
         (*idefs)[j] = copy;
@@ -5628,7 +5628,7 @@
  public:
   // Record a move from the place with id |from| to the place with id |to| at
   // the given block.
-  void CreateOutgoingMove(Isolate* isolate,
+  void CreateOutgoingMove(Zone* zone,
                           BlockEntryInstr* block, intptr_t from, intptr_t to) {
     const intptr_t block_num = block->preorder_number();
     while (moves_.length() <= block_num) {
@@ -5636,7 +5636,7 @@
     }
 
     if (moves_[block_num] == NULL) {
-      moves_[block_num] = new(isolate) ZoneGrowableArray<Move>(5);
+      moves_[block_num] = new(zone) ZoneGrowableArray<Move>(5);
     }
 
     moves_[block_num]->Add(Move(from, to));
@@ -6204,7 +6204,6 @@
     DirectChainedHashMap<PointerKeyValueTrait<Place> >* map,
     ZoneGrowableArray<Place*>* places) {
   Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
   PhiPlaceMoves* phi_moves = new(zone) PhiPlaceMoves();
 
@@ -6234,7 +6233,7 @@
                       result->id());
           }
         }
-        phi_moves->CreateOutgoingMove(isolate,
+        phi_moves->CreateOutgoingMove(zone,
                                       block->PredecessorAt(j),
                                       result->id(),
                                       place->id());
@@ -7694,14 +7693,14 @@
 }
 
 
-JoinEntryInstr* BranchSimplifier::ToJoinEntry(Isolate* isolate,
+JoinEntryInstr* BranchSimplifier::ToJoinEntry(Zone* zone,
                                               TargetEntryInstr* target) {
   // Convert a target block into a join block.  Branches will be duplicated
   // so the former true and false targets become joins of the control flows
   // from all the duplicated branches.
   JoinEntryInstr* join =
-      new(isolate) JoinEntryInstr(target->block_id(), target->try_index());
-  join->InheritDeoptTarget(isolate, target);
+      new(zone) JoinEntryInstr(target->block_id(), target->try_index());
+  join->InheritDeoptTarget(zone, target);
   join->LinkTo(target->next());
   join->set_last_instruction(target->last_instruction());
   target->UnuseAllInputs();
@@ -7709,14 +7708,14 @@
 }
 
 
-BranchInstr* BranchSimplifier::CloneBranch(Isolate* isolate,
+BranchInstr* BranchSimplifier::CloneBranch(Zone* zone,
                                            BranchInstr* branch,
                                            Value* new_left,
                                            Value* new_right) {
   ComparisonInstr* comparison = branch->comparison();
   ComparisonInstr* new_comparison =
       comparison->CopyWithNewOperands(new_left, new_right);
-  BranchInstr* new_branch = new(isolate) BranchInstr(new_comparison);
+  BranchInstr* new_branch = new(zone) BranchInstr(new_comparison);
   new_branch->set_is_checked(branch->is_checked());
   return new_branch;
 }
@@ -7734,7 +7733,7 @@
 
   // Begin with a worklist of join blocks ending in branches.  They are
   // candidates for the pattern below.
-  Isolate* isolate = flow_graph->isolate();
+  Zone* zone = flow_graph->zone();
   const GrowableArray<BlockEntryInstr*>& postorder = flow_graph->postorder();
   GrowableArray<BlockEntryInstr*> worklist(postorder.length());
   for (BlockIterator it(postorder); !it.Done(); it.Advance()) {
@@ -7765,9 +7764,9 @@
       BranchInstr* branch = block->last_instruction()->AsBranch();
       ASSERT(branch != NULL);
       JoinEntryInstr* join_true =
-          ToJoinEntry(isolate, branch->true_successor());
+          ToJoinEntry(zone, branch->true_successor());
       JoinEntryInstr* join_false =
-          ToJoinEntry(isolate, branch->false_successor());
+          ToJoinEntry(zone, branch->false_successor());
 
       ComparisonInstr* comparison = branch->comparison();
       PhiInstr* phi = comparison->left()->definition()->AsPhi();
@@ -7781,15 +7780,15 @@
 
         // Replace the goto in each predecessor with a rewritten branch,
         // rewritten to use the corresponding phi input instead of the phi.
-        Value* new_left = phi->InputAt(i)->Copy(isolate);
-        Value* new_right = new(isolate) Value(constant);
+        Value* new_left = phi->InputAt(i)->Copy(zone);
+        Value* new_right = new(zone) Value(constant);
         BranchInstr* new_branch =
-            CloneBranch(isolate, branch, new_left, new_right);
+            CloneBranch(zone, branch, new_left, new_right);
         if (branch->env() == NULL) {
-          new_branch->InheritDeoptTarget(isolate, old_goto);
+          new_branch->InheritDeoptTarget(zone, old_goto);
         } else {
           // Take the environment from the branch if it has one.
-          new_branch->InheritDeoptTarget(isolate, branch);
+          new_branch->InheritDeoptTarget(zone, branch);
           // InheritDeoptTarget gave the new branch's comparison the same
           // deopt id that it gave the new branch.  The id should be the
           // deopt id of the original comparison.
@@ -7822,22 +7821,22 @@
         // Connect the branch to the true and false joins, via empty target
         // blocks.
         TargetEntryInstr* true_target =
-            new(isolate) TargetEntryInstr(flow_graph->max_block_id() + 1,
+            new(zone) TargetEntryInstr(flow_graph->max_block_id() + 1,
                                           block->try_index());
-        true_target->InheritDeoptTarget(isolate, join_true);
+        true_target->InheritDeoptTarget(zone, join_true);
         TargetEntryInstr* false_target =
-            new(isolate) TargetEntryInstr(flow_graph->max_block_id() + 2,
+            new(zone) TargetEntryInstr(flow_graph->max_block_id() + 2,
                                           block->try_index());
-        false_target->InheritDeoptTarget(isolate, join_false);
+        false_target->InheritDeoptTarget(zone, join_false);
         flow_graph->set_max_block_id(flow_graph->max_block_id() + 2);
         *new_branch->true_successor_address() = true_target;
         *new_branch->false_successor_address() = false_target;
-        GotoInstr* goto_true = new(isolate) GotoInstr(join_true);
-        goto_true->InheritDeoptTarget(isolate, join_true);
+        GotoInstr* goto_true = new(zone) GotoInstr(join_true);
+        goto_true->InheritDeoptTarget(zone, join_true);
         true_target->LinkTo(goto_true);
         true_target->set_last_instruction(goto_true);
-        GotoInstr* goto_false = new(isolate) GotoInstr(join_false);
-        goto_false->InheritDeoptTarget(isolate, join_false);
+        GotoInstr* goto_false = new(zone) GotoInstr(join_false);
+        goto_false->InheritDeoptTarget(zone, join_false);
         false_target->LinkTo(goto_false);
         false_target->set_last_instruction(goto_false);
       }
@@ -7881,7 +7880,7 @@
 
 
 void IfConverter::Simplify(FlowGraph* flow_graph) {
-  Isolate* isolate = flow_graph->isolate();
+  Zone* zone = flow_graph->zone();
   bool changed = false;
 
   const GrowableArray<BlockEntryInstr*>& postorder = flow_graph->postorder();
@@ -7936,12 +7935,12 @@
 
           ComparisonInstr* new_comparison =
               comparison->CopyWithNewOperands(
-                  comparison->left()->Copy(isolate),
-                  comparison->right()->Copy(isolate));
-          IfThenElseInstr* if_then_else = new(isolate) IfThenElseInstr(
+                  comparison->left()->Copy(zone),
+                  comparison->right()->Copy(zone));
+          IfThenElseInstr* if_then_else = new(zone) IfThenElseInstr(
               new_comparison,
-              if_true->Copy(isolate),
-              if_false->Copy(isolate));
+              if_true->Copy(zone),
+              if_false->Copy(zone));
           flow_graph->InsertBefore(branch,
                                    if_then_else,
                                    NULL,
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 44a72a1..ba3c4d8 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -253,6 +253,7 @@
                                        Representation rep, intptr_t cid);
   bool TryStringLengthOneEquality(InstanceCallInstr* call, Token::Kind op_kind);
 
+  Thread* thread() const { return flow_graph_->thread(); }
   Isolate* isolate() const { return flow_graph_->isolate(); }
   Zone* zone() const { return flow_graph_->zone(); }
 
@@ -324,7 +325,7 @@
   // Replace a target entry instruction with a join entry instruction.  Does
   // not update the original target's predecessors to point to the new block
   // and does not replace the target in already computed block order lists.
-  static JoinEntryInstr* ToJoinEntry(Isolate* isolate,
+  static JoinEntryInstr* ToJoinEntry(Zone* zone,
                                      TargetEntryInstr* target);
 
  private:
@@ -334,7 +335,7 @@
 
   // Duplicate a branch while replacing its comparison's left and right
   // inputs.
-  static BranchInstr* CloneBranch(Isolate* isolate,
+  static BranchInstr* CloneBranch(Zone* zone,
                                   BranchInstr* branch,
                                   Value* new_left,
                                   Value* new_right);
diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc
index 0a0ef94..59d2cd3 100644
--- a/runtime/vm/flow_graph_range_analysis.cc
+++ b/runtime/vm/flow_graph_range_analysis.cc
@@ -16,8 +16,9 @@
     "Print integer IR selection optimization pass.");
 DECLARE_FLAG(bool, trace_constant_propagation);
 
-// Quick access to the locally defined isolate() method.
+// Quick access to the locally defined isolate() and zone() methods.
 #define I (isolate())
+#define Z (zone())
 
 void RangeAnalysis::Analyze() {
   CollectValues();
@@ -344,21 +345,21 @@
 Range* RangeAnalysis::ConstraintSmiRange(Token::Kind op, Definition* boundary) {
   switch (op) {
     case Token::kEQ:
-      return new(I) Range(RangeBoundary::FromDefinition(boundary),
+      return new(Z) Range(RangeBoundary::FromDefinition(boundary),
                           RangeBoundary::FromDefinition(boundary));
     case Token::kNE:
-      return new(I) Range(Range::Full(RangeBoundary::kRangeBoundarySmi));
+      return new(Z) Range(Range::Full(RangeBoundary::kRangeBoundarySmi));
     case Token::kLT:
-      return new(I) Range(RangeBoundary::MinSmi(),
+      return new(Z) Range(RangeBoundary::MinSmi(),
                           RangeBoundary::FromDefinition(boundary, -1));
     case Token::kGT:
-      return new(I) Range(RangeBoundary::FromDefinition(boundary, 1),
+      return new(Z) Range(RangeBoundary::FromDefinition(boundary, 1),
                           RangeBoundary::MaxSmi());
     case Token::kLTE:
-      return new(I) Range(RangeBoundary::MinSmi(),
+      return new(Z) Range(RangeBoundary::MinSmi(),
                           RangeBoundary::FromDefinition(boundary));
     case Token::kGTE:
-      return new(I) Range(RangeBoundary::FromDefinition(boundary),
+      return new(Z) Range(RangeBoundary::FromDefinition(boundary),
                           RangeBoundary::MaxSmi());
     default:
       UNREACHABLE();
@@ -385,7 +386,7 @@
     constraint = constraint->next()->AsConstraint();
   }
 
-  constraint = new(I) ConstraintInstr(
+  constraint = new(Z) ConstraintInstr(
       use->CopyWithType(), constraint_range);
 
   flow_graph_->InsertAfter(after, constraint, NULL, FlowGraph::kValue);
@@ -469,13 +470,13 @@
   Range* constraint_range = NULL;
   if (use_index == CheckArrayBoundInstr::kIndexPos) {
     Definition* length = check->length()->definition();
-    constraint_range = new(I) Range(
+    constraint_range = new(Z) Range(
         RangeBoundary::FromConstant(0),
         RangeBoundary::FromDefinition(length, -1));
   } else {
     ASSERT(use_index == CheckArrayBoundInstr::kLengthPos);
     Definition* index = check->index()->definition();
-    constraint_range = new(I) Range(
+    constraint_range = new(Z) Range(
         RangeBoundary::FromDefinition(index, 1),
         RangeBoundary::MaxSmi());
   }
@@ -1653,14 +1654,11 @@
 
 
 IntegerInstructionSelector::IntegerInstructionSelector(FlowGraph* flow_graph)
-    : flow_graph_(flow_graph),
-      isolate_(NULL) {
+    : flow_graph_(flow_graph) {
   ASSERT(flow_graph_ != NULL);
-  isolate_ = flow_graph_->isolate();
-  ASSERT(isolate_ != NULL);
-  Zone* zone = flow_graph_->zone();
+  zone_ = flow_graph_->zone();
   selected_uint32_defs_ =
-      new(zone) BitVector(zone, flow_graph_->current_ssa_temp_index());
+      new(zone_) BitVector(zone_, flow_graph_->current_ssa_temp_index());
 }
 
 
@@ -1853,28 +1851,28 @@
     Value* left = op->left()->CopyWithType();
     Value* right = op->right()->CopyWithType();
     intptr_t deopt_id = op->DeoptimizationTarget();
-    return new(I) BinaryUint32OpInstr(op_kind, left, right, deopt_id);
+    return new(Z) BinaryUint32OpInstr(op_kind, left, right, deopt_id);
   } else if (def->IsBoxInt64()) {
     Value* value = def->AsBoxInt64()->value()->CopyWithType();
-    return new(I) BoxUint32Instr(value);
+    return new(Z) BoxUint32Instr(value);
   } else if (def->IsUnboxInt64()) {
     UnboxInstr* unbox = def->AsUnboxInt64();
     Value* value = unbox->value()->CopyWithType();
     intptr_t deopt_id = unbox->DeoptimizationTarget();
-    return new(I) UnboxUint32Instr(value, deopt_id);
+    return new(Z) UnboxUint32Instr(value, deopt_id);
   } else if (def->IsUnaryMintOp()) {
     UnaryMintOpInstr* op = def->AsUnaryMintOp();
     Token::Kind op_kind = op->op_kind();
     Value* value = op->value()->CopyWithType();
     intptr_t deopt_id = op->DeoptimizationTarget();
-    return new(I) UnaryUint32OpInstr(op_kind, value, deopt_id);
+    return new(Z) UnaryUint32OpInstr(op_kind, value, deopt_id);
   } else if (def->IsShiftMintOp()) {
     ShiftMintOpInstr* op = def->AsShiftMintOp();
     Token::Kind op_kind = op->op_kind();
     Value* left = op->left()->CopyWithType();
     Value* right = op->right()->CopyWithType();
     intptr_t deopt_id = op->DeoptimizationTarget();
-    return new(I) ShiftUint32OpInstr(op_kind, left, right, deopt_id);
+    return new(Z) ShiftUint32OpInstr(op_kind, left, right, deopt_id);
   }
   UNREACHABLE();
   return NULL;
diff --git a/runtime/vm/flow_graph_range_analysis.h b/runtime/vm/flow_graph_range_analysis.h
index 5ee9f2f..691fff5 100644
--- a/runtime/vm/flow_graph_range_analysis.h
+++ b/runtime/vm/flow_graph_range_analysis.h
@@ -601,7 +601,7 @@
 
   Range* ConstraintSmiRange(Token::Kind op, Definition* boundary);
 
-  Isolate* isolate() const { return flow_graph_->isolate(); }
+  Zone* zone() const { return flow_graph_->zone(); }
 
   FlowGraph* flow_graph_;
 
@@ -651,13 +651,13 @@
   Definition* ConstructReplacementFor(Definition* def);
   void ReplaceInstructions();
 
-  Isolate* isolate() const { return isolate_; }
+  Zone* zone() const { return zone_; }
 
   GrowableArray<Definition*> potential_uint32_defs_;
   BitVector* selected_uint32_defs_;
 
   FlowGraph* flow_graph_;
-  Isolate* isolate_;
+  Zone* zone_;
 };
 
 
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index b17c86a..2b7001f 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -410,13 +410,13 @@
   Instruction* check_clone = NULL;
   if (check->IsCheckSmi()) {
     check_clone =
-        new CheckSmiInstr(assert->value()->Copy(isolate()),
+        new CheckSmiInstr(assert->value()->Copy(zone()),
                           assert->env()->deopt_id(),
                           check->token_pos());
   } else {
     ASSERT(check->IsCheckClass());
     check_clone =
-        new CheckClassInstr(assert->value()->Copy(isolate()),
+        new CheckClassInstr(assert->value()->Copy(zone()),
                             assert->env()->deopt_id(),
                             check->AsCheckClass()->unary_checks(),
                             check->token_pos());
@@ -424,7 +424,7 @@
   ASSERT(check_clone != NULL);
   ASSERT(assert->deopt_id() == assert->env()->deopt_id());
   check_clone->InsertBefore(assert);
-  assert->env()->DeepCopyTo(isolate(), check_clone);
+  assert->env()->DeepCopyTo(zone(), check_clone);
 
   (*asserts_)[defn->ssa_temp_index()] = kStrengthenedAssertMarker;
 }
@@ -538,7 +538,7 @@
     } else if (type_->HasResolvedTypeClass()) {
       if (FLAG_use_cha) {
         const Class& type_class = Class::Handle(type_->type_class());
-        CHA* cha = Isolate::Current()->cha();
+        CHA* cha = Thread::Current()->cha();
         // Don't infer a cid from an abstract type for signature classes since
         // there can be multiple compatible classes with different cids.
         if (!type_class.IsSignatureClass() &&
@@ -772,7 +772,7 @@
     intptr_t cid = kDynamicCid;
     if (FLAG_use_cha && type.HasResolvedTypeClass()) {
       const Class& type_class = Class::Handle(type.type_class());
-      if (!Isolate::Current()->cha()->HasSubclasses(type_class.id())) {
+      if (!Thread::Current()->cha()->HasSubclasses(type_class.id())) {
         cid = type_class.id();
       }
     }
diff --git a/runtime/vm/flow_graph_type_propagator.h b/runtime/vm/flow_graph_type_propagator.h
index b324052..2e09ef3 100644
--- a/runtime/vm/flow_graph_type_propagator.h
+++ b/runtime/vm/flow_graph_type_propagator.h
@@ -52,7 +52,7 @@
   void StrengthenAsserts(BlockEntryInstr* block);
   void StrengthenAssertWith(Instruction* check);
 
-  Isolate* isolate() const { return flow_graph_->isolate(); }
+  Zone* zone() const { return flow_graph_->zone(); }
 
   FlowGraph* flow_graph_;
 
diff --git a/runtime/vm/growable_array.h b/runtime/vm/growable_array.h
index d18391d..81a946b 100644
--- a/runtime/vm/growable_array.h
+++ b/runtime/vm/growable_array.h
@@ -146,9 +146,9 @@
 template<typename T>
 class GrowableArray : public BaseGrowableArray<T, ValueObject> {
  public:
-  GrowableArray(Isolate* isolate, intptr_t initial_capacity)
+  GrowableArray(Zone* zone, intptr_t initial_capacity)
       : BaseGrowableArray<T, ValueObject>(
-          initial_capacity, ASSERT_NOTNULL(isolate->current_zone())) {}
+          initial_capacity, ASSERT_NOTNULL(zone)) {}
   explicit GrowableArray(intptr_t initial_capacity)
       : BaseGrowableArray<T, ValueObject>(
           initial_capacity,
@@ -162,9 +162,9 @@
 template<typename T>
 class ZoneGrowableArray : public BaseGrowableArray<T, ZoneAllocated> {
  public:
-  ZoneGrowableArray(Isolate* isolate, intptr_t initial_capacity)
+  ZoneGrowableArray(Zone* zone, intptr_t initial_capacity)
       : BaseGrowableArray<T, ZoneAllocated>(
-          initial_capacity, ASSERT_NOTNULL(isolate->current_zone())) {}
+          initial_capacity, ASSERT_NOTNULL(zone)) {}
   explicit ZoneGrowableArray(intptr_t initial_capacity)
       : BaseGrowableArray<T, ZoneAllocated>(
           initial_capacity,
diff --git a/runtime/vm/hash_table_test.cc b/runtime/vm/hash_table_test.cc
index 0aab291..b646b32 100644
--- a/runtime/vm/hash_table_test.cc
+++ b/runtime/vm/hash_table_test.cc
@@ -139,7 +139,7 @@
   EXPECT(b_value.Equals("BBB"));
   {
     // When the key is already present, there should be no allocation.
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     b_value ^= table.InsertNewOrGetValue("b", a_value);
     EXPECT(b_value.Equals("BBB"));
   }
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 4b31be8..a8f35f4 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -76,7 +76,7 @@
 
 
 uword Heap::AllocateNew(intptr_t size) {
-  ASSERT(isolate()->no_gc_scope_depth() == 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() == 0);
   uword addr = new_space_->TryAllocate(size);
   if (addr == 0) {
     CollectGarbage(kNew);
@@ -90,7 +90,7 @@
 
 
 uword Heap::AllocateOld(intptr_t size, HeapPage::PageType type) {
-  ASSERT(isolate()->no_gc_scope_depth() == 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() == 0);
   uword addr = old_space_->TryAllocate(size, type);
   if (addr != 0) {
     return addr;
@@ -151,7 +151,7 @@
 
 
 uword Heap::AllocatePretenured(intptr_t size) {
-  ASSERT(isolate()->no_gc_scope_depth() == 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() == 0);
   uword addr = old_space_->TryAllocateDataBump(size, PageSpace::kControlGrowth);
   if (addr != 0) return addr;
   return AllocateOld(size, HeapPage::kData);
@@ -159,7 +159,7 @@
 
 
 void Heap::AllocateExternal(intptr_t size, Space space) {
-  ASSERT(isolate()->no_gc_scope_depth() == 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() == 0);
   if (space == kNew) {
     new_space_->AllocateExternal(size);
     if (new_space_->ExternalInWords() > (FLAG_new_gen_ext_limit * MBInWords)) {
@@ -268,7 +268,7 @@
 
 
 RawObject* Heap::FindObject(FindObjectVisitor* visitor) const {
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   RawObject* raw_obj = FindNewObject(visitor);
   if (raw_obj != Object::null()) {
     return raw_obj;
@@ -716,13 +716,13 @@
 
 
 #if defined(DEBUG)
-NoGCScope::NoGCScope() : StackResource(Isolate::Current()) {
-  isolate()->IncrementNoGCScopeDepth();
+NoSafepointScope::NoSafepointScope() : StackResource(Isolate::Current()) {
+  isolate()->IncrementNoSafepointScopeDepth();
 }
 
 
-NoGCScope::~NoGCScope() {
-  isolate()->DecrementNoGCScopeDepth();
+NoSafepointScope::~NoSafepointScope() {
+  isolate()->DecrementNoSafepointScopeDepth();
 }
 #endif  // defined(DEBUG)
 
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index ddd24f3..f1085f7 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -125,7 +125,8 @@
   // point.
   // The 'visitor' function should return false if the object is not found,
   // traversal through the heap space continues.
-  // Returns null object if nothing is found. Must be called within a NoGCScope.
+  // Returns null object if nothing is found. Must be called within a
+  // NoSafepointScope.
   RawInstructions* FindObjectInCodeSpace(FindObjectVisitor* visitor) const;
   RawObject* FindOldObject(FindObjectVisitor* visitor) const;
   RawObject* FindNewObject(FindObjectVisitor* visitor) const;
@@ -335,20 +336,22 @@
 };
 
 
+// Within a NoSafepointScope, the thread must not reach any safepoint. Used
+// around code that manipulates raw object pointers directly without handles.
 #if defined(DEBUG)
-class NoGCScope : public StackResource {
+class NoSafepointScope : public StackResource {
  public:
-  NoGCScope();
-  ~NoGCScope();
+  NoSafepointScope();
+  ~NoSafepointScope();
  private:
-  DISALLOW_COPY_AND_ASSIGN(NoGCScope);
+  DISALLOW_COPY_AND_ASSIGN(NoSafepointScope);
 };
 #else  // defined(DEBUG)
-class NoGCScope : public ValueObject {
+class NoSafepointScope : public ValueObject {
  public:
-  NoGCScope() {}
+  NoSafepointScope() {}
  private:
-  DISALLOW_COPY_AND_ASSIGN(NoGCScope);
+  DISALLOW_COPY_AND_ASSIGN(NoSafepointScope);
 };
 #endif  // defined(DEBUG)
 
diff --git a/runtime/vm/heap_test.cc b/runtime/vm/heap_test.cc
index b9ea5ad..32ec871 100644
--- a/runtime/vm/heap_test.cc
+++ b/runtime/vm/heap_test.cc
@@ -213,7 +213,7 @@
  public:
   FindOnly(Isolate* isolate, RawObject* target)
       : FindObjectVisitor(isolate), target_(target) {
-    ASSERT(isolate->no_gc_scope_depth() != 0);
+    ASSERT(isolate->no_safepoint_scope_depth() != 0);
   }
   virtual ~FindOnly() { }
 
@@ -240,13 +240,13 @@
   for (size_t space = 0; space < ARRAY_SIZE(spaces); ++space) {
     const String& obj = String::Handle(String::New("x", spaces[space]));
     {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
       FindOnly find_only(isolate, obj.raw());
       EXPECT(obj.raw() == heap->FindObject(&find_only));
     }
   }
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     FindNothing find_nothing;
     EXPECT(Object::null() == heap->FindObject(&find_nothing));
   }
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 858c441..840b45e 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -769,7 +769,7 @@
                                           Definition* result) {
   ASSERT(call->env() != NULL);
   deopt_id_ = Isolate::ToDeoptAfter(call->deopt_id_);
-  call->env()->DeepCopyAfterTo(flow_graph->isolate(),
+  call->env()->DeepCopyAfterTo(flow_graph->zone(),
                                this,
                                call->ArgumentCount(),
                                flow_graph->constant_dead(),
@@ -779,17 +779,17 @@
 }
 
 
-void Instruction::InheritDeoptTarget(Isolate* isolate, Instruction* other) {
+void Instruction::InheritDeoptTarget(Zone* zone, Instruction* other) {
   ASSERT(other->env() != NULL);
   CopyDeoptIdFrom(*other);
-  other->env()->DeepCopyTo(isolate, this);
+  other->env()->DeepCopyTo(zone, this);
   env()->set_deopt_id(deopt_id_);
 }
 
 
-void BranchInstr::InheritDeoptTarget(Isolate* isolate, Instruction* other) {
+void BranchInstr::InheritDeoptTarget(Zone* zone, Instruction* other) {
   ASSERT(env() == NULL);
-  Instruction::InheritDeoptTarget(isolate, other);
+  Instruction::InheritDeoptTarget(zone, other);
   comparison()->SetDeoptId(*this);
 }
 
@@ -2123,7 +2123,7 @@
 
     const Object& val = value()->BoundConstant();
     if (val.IsSmi()) {
-      const Double& double_val = Double::ZoneHandle(flow_graph->isolate(),
+      const Double& double_val = Double::ZoneHandle(flow_graph->zone(),
           Double::NewCanonical(Smi::Cast(val).AsDoubleValue()));
       uc = new UnboxedConstantInstr(double_val, kUnboxedDouble);
     } else if (val.IsDouble()) {
@@ -2391,7 +2391,7 @@
 
 
 Instruction* BranchInstr::Canonicalize(FlowGraph* flow_graph) {
-  Isolate* isolate = flow_graph->isolate();
+  Zone* zone = flow_graph->zone();
   // Only handle strict-compares.
   if (comparison()->IsStrictCompare()) {
     bool negated = false;
@@ -2452,8 +2452,8 @@
           comparison()->token_pos(),
           negate ? Token::NegateComparison(comparison()->kind())
                  : comparison()->kind(),
-          bit_and->left()->Copy(isolate),
-          bit_and->right()->Copy(isolate));
+          bit_and->left()->Copy(zone),
+          bit_and->right()->Copy(zone));
       ASSERT(!CanDeoptimize());
       RemoveEnvironment();
       flow_graph->CopyDeoptTarget(this, bit_and);
@@ -2694,7 +2694,7 @@
 }
 
 
-void IndirectGotoInstr::ComputeOffsetTable(Isolate* isolate) {
+void IndirectGotoInstr::ComputeOffsetTable() {
   if (GetBlock()->offset() < 0) {
     // Don't generate a table when contained in an unreachable block.
     return;
@@ -2924,23 +2924,23 @@
 
 
 void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  Isolate* isolate = compiler->isolate();
+  Zone* zone = compiler->zone();
   const ICData* call_ic_data = NULL;
   if (!FLAG_propagate_ic_data || !compiler->is_optimizing()) {
     const Array& arguments_descriptor =
-        Array::Handle(isolate, ArgumentsDescriptor::New(ArgumentCount(),
+        Array::Handle(zone, ArgumentsDescriptor::New(ArgumentCount(),
                                                         argument_names()));
     call_ic_data = compiler->GetOrAddInstanceCallICData(
         deopt_id(), function_name(), arguments_descriptor,
         checked_argument_count());
   } else {
-    call_ic_data = &ICData::ZoneHandle(isolate, ic_data()->raw());
+    call_ic_data = &ICData::ZoneHandle(zone, ic_data()->raw());
   }
   if (compiler->is_optimizing()) {
     ASSERT(HasICData());
     if (ic_data()->NumberOfUsedChecks() > 0) {
       const ICData& unary_ic_data =
-          ICData::ZoneHandle(isolate, ic_data()->AsUnaryClassChecks());
+          ICData::ZoneHandle(zone, ic_data()->AsUnaryClassChecks());
       compiler->GenerateInstanceCall(deopt_id(),
                                      token_pos(),
                                      ArgumentCount(),
@@ -2963,8 +2963,8 @@
       // We have a dedicated inline cache stub for this operation, add an
       // an initial Smi/Smi check with count 0.
       ASSERT(call_ic_data->NumArgsTested() == 2);
-      const String& name = String::Handle(isolate, call_ic_data->target_name());
-      const Class& smi_class = Class::Handle(isolate, Smi::Class());
+      const String& name = String::Handle(zone, call_ic_data->target_name());
+      const Class& smi_class = Class::Handle(zone, Smi::Class());
       const Function& smi_op_target =
           Function::Handle(Resolver::ResolveDynamicAnyArgs(smi_class, name));
       if (call_ic_data->NumberOfChecks() == 0) {
@@ -2977,7 +2977,7 @@
         is_smi_two_args_op = true;
       } else if (call_ic_data->NumberOfChecks() == 1) {
         GrowableArray<intptr_t> class_ids(2);
-        Function& target = Function::Handle(isolate);
+        Function& target = Function::Handle(zone);
         call_ic_data->GetCheckAt(0, &class_ids, &target);
         if ((target.raw() == smi_op_target.raw()) &&
             (class_ids[0] == kSmiCid) && (class_ids[1] == kSmiCid)) {
@@ -2997,7 +2997,7 @@
                  (ArgumentCount() == 1));
       ASSERT(Token::IsBinaryArithmeticOperator(token_kind()) ==
                  (ArgumentCount() == 2));
-      StubCode* stub_code = isolate->stub_code();
+      StubCode* stub_code = compiler->isolate()->stub_code();
       ExternalLabel target_label((ArgumentCount() == 1) ?
           stub_code->UnaryRangeCollectingInlineCacheEntryPoint() :
           stub_code->BinaryRangeCollectingInlineCacheEntryPoint());
@@ -3096,37 +3096,37 @@
 }
 
 
-Environment* Environment::From(Isolate* isolate,
+Environment* Environment::From(Zone* zone,
                                const GrowableArray<Definition*>& definitions,
                                intptr_t fixed_parameter_count,
                                const ParsedFunction& parsed_function) {
   Environment* env =
-      new(isolate) Environment(definitions.length(),
+      new(zone) Environment(definitions.length(),
                                fixed_parameter_count,
                                Isolate::kNoDeoptId,
                                parsed_function,
                                NULL);
   for (intptr_t i = 0; i < definitions.length(); ++i) {
-    env->values_.Add(new(isolate) Value(definitions[i]));
+    env->values_.Add(new(zone) Value(definitions[i]));
   }
   return env;
 }
 
 
-Environment* Environment::DeepCopy(Isolate* isolate, intptr_t length) const {
+Environment* Environment::DeepCopy(Zone* zone, intptr_t length) const {
   ASSERT(length <= values_.length());
-  Environment* copy = new(isolate) Environment(
+  Environment* copy = new(zone) Environment(
       length,
       fixed_parameter_count_,
       deopt_id_,
       parsed_function_,
-      (outer_ == NULL) ? NULL : outer_->DeepCopy(isolate));
+      (outer_ == NULL) ? NULL : outer_->DeepCopy(zone));
   if (locations_ != NULL) {
-    Location* new_locations = isolate->current_zone()->Alloc<Location>(length);
+    Location* new_locations = zone->Alloc<Location>(length);
     copy->set_locations(new_locations);
   }
   for (intptr_t i = 0; i < length; ++i) {
-    copy->values_.Add(values_[i]->Copy(isolate));
+    copy->values_.Add(values_[i]->Copy(zone));
     if (locations_ != NULL) {
       copy->locations_[i] = locations_[i].Copy();
     }
@@ -3136,12 +3136,12 @@
 
 
 // Copies the environment and updates the environment use lists.
-void Environment::DeepCopyTo(Isolate* isolate, Instruction* instr) const {
+void Environment::DeepCopyTo(Zone* zone, Instruction* instr) const {
   for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) {
     it.CurrentValue()->RemoveFromUseList();
   }
 
-  Environment* copy = DeepCopy(isolate);
+  Environment* copy = DeepCopy(zone);
   instr->SetEnvironment(copy);
   for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) {
     Value* value = it.CurrentValue();
@@ -3150,7 +3150,7 @@
 }
 
 
-void Environment::DeepCopyAfterTo(Isolate* isolate,
+void Environment::DeepCopyAfterTo(Zone* zone,
                                   Instruction* instr,
                                   intptr_t argc,
                                   Definition* dead,
@@ -3159,11 +3159,11 @@
     it.CurrentValue()->RemoveFromUseList();
   }
 
-  Environment* copy = DeepCopy(isolate, values_.length() - argc);
+  Environment* copy = DeepCopy(zone, values_.length() - argc);
   for (intptr_t i = 0; i < argc; i++) {
-    copy->values_.Add(new(isolate) Value(dead));
+    copy->values_.Add(new(zone) Value(dead));
   }
-  copy->values_.Add(new(isolate) Value(result));
+  copy->values_.Add(new(zone) Value(result));
 
   instr->SetEnvironment(copy);
   for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) {
@@ -3175,12 +3175,12 @@
 
 // Copies the environment as outer on an inlined instruction and updates the
 // environment use lists.
-void Environment::DeepCopyToOuter(Isolate* isolate, Instruction* instr) const {
+void Environment::DeepCopyToOuter(Zone* zone, Instruction* instr) const {
   // Create a deep copy removing caller arguments from the environment.
   ASSERT(this != NULL);
   ASSERT(instr->env()->outer() == NULL);
   intptr_t argument_count = instr->env()->fixed_parameter_count();
-  Environment* copy = DeepCopy(isolate, values_.length() - argument_count);
+  Environment* copy = DeepCopy(zone, values_.length() - argument_count);
   instr->env()->outer_ = copy;
   intptr_t use_index = instr->env()->Length();  // Start index after inner.
   for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) {
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 1e31675..b8bf6dd 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -317,7 +317,7 @@
   inline void BindTo(Definition* definition);
   inline void BindToEnvironment(Definition* definition);
 
-  Value* Copy(Isolate* isolate) { return new(isolate) Value(definition_); }
+  Value* Copy(Zone* zone) { return new(zone) Value(definition_); }
 
   // This function must only be used when the new Value is dominated by
   // the original Value.
@@ -841,7 +841,7 @@
     return false;
   }
 
-  virtual void InheritDeoptTarget(Isolate* isolate, Instruction* other);
+  virtual void InheritDeoptTarget(Zone* zone, Instruction* other);
 
   bool NeedsEnvironment() const {
     return CanDeoptimize() || CanBecomeDeoptimizationTarget();
@@ -2235,7 +2235,7 @@
   virtual void PrintTo(BufferFormatter* f) const;
 
   Value* offset() const { return inputs_[0]; }
-  void ComputeOffsetTable(Isolate* isolate);
+  void ComputeOffsetTable();
 
  private:
   GrowableArray<TargetEntryInstr*> successors_;
@@ -2385,7 +2385,7 @@
     return constant_target_;
   }
 
-  virtual void InheritDeoptTarget(Isolate* isolate, Instruction* other);
+  virtual void InheritDeoptTarget(Zone* zone, Instruction* other);
 
   virtual bool MayThrow() const {
     return comparison()->MayThrow();
@@ -7920,7 +7920,7 @@
   };
 
   // Construct an environment by constructing uses from an array of definitions.
-  static Environment* From(Isolate* isolate,
+  static Environment* From(Zone* zone,
                            const GrowableArray<Definition*>& definitions,
                            intptr_t fixed_parameter_count,
                            const ParsedFunction& parsed_function);
@@ -7981,14 +7981,14 @@
 
   const Code& code() const { return parsed_function_.code(); }
 
-  Environment* DeepCopy(Isolate* isolate) const {
-    return DeepCopy(isolate, Length());
+  Environment* DeepCopy(Zone* zone) const {
+    return DeepCopy(zone, Length());
   }
 
-  void DeepCopyTo(Isolate* isolate, Instruction* instr) const;
-  void DeepCopyToOuter(Isolate* isolate, Instruction* instr) const;
+  void DeepCopyTo(Zone* zone, Instruction* instr) const;
+  void DeepCopyToOuter(Zone* zone, Instruction* instr) const;
 
-  void DeepCopyAfterTo(Isolate* isolate,
+  void DeepCopyAfterTo(Zone* zone,
                        Instruction* instr,
                        intptr_t argc,
                        Definition* dead,
@@ -8000,7 +8000,7 @@
   // Deep copy an environment.  The 'length' parameter may be less than the
   // environment's length in order to drop values (e.g., passed arguments)
   // from the copy.
-  Environment* DeepCopy(Isolate* isolate, intptr_t length) const;
+  Environment* DeepCopy(Zone* zone, intptr_t length) const;
 
  private:
   friend class ShallowIterator;
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 56850d63..d2df9ee 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -155,7 +155,7 @@
   }
 
   if (FLAG_print_flow_graph && FlowGraphPrinter::ShouldPrint(function)) {
-    OS::Print("Intrinsic graph before\n");
+    ISL_Print("Intrinsic graph before\n");
     FlowGraphPrinter printer(*graph);
     printer.PrintBlocks();
   }
@@ -165,7 +165,7 @@
   allocator.AllocateRegisters();
 
   if (FLAG_print_flow_graph && FlowGraphPrinter::ShouldPrint(function)) {
-    OS::Print("Intrinsic graph after\n");
+    ISL_Print("Intrinsic graph after\n");
     FlowGraphPrinter printer(*graph);
     printer.PrintBlocks();
   }
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 50d4d13..bd4ee51 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -810,17 +810,13 @@
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
 
-  // Preserve CTX to free ESI.
-  __ pushl(CTX);
-  ASSERT(CTX == ESI);
-
-  __ movl(EDI, Address(ESP, 6 * kWordSize));  // digits
-  __ movl(EAX, Address(ESP, 5 * kWordSize));  // used is Smi
+  __ movl(EDI, Address(ESP, 5 * kWordSize));  // digits
+  __ movl(EAX, Address(ESP, 4 * kWordSize));  // used is Smi
   __ SmiUntag(EAX);  // used > 0.
-  __ movl(ESI, Address(ESP, 4 * kWordSize));  // a_digits
-  __ movl(ECX, Address(ESP, 3 * kWordSize));  // a_used is Smi
+  __ movl(ESI, Address(ESP, 3 * kWordSize));  // a_digits
+  __ movl(ECX, Address(ESP, 2 * kWordSize));  // a_used is Smi
   __ SmiUntag(ECX);  // a_used > 0.
-  __ movl(EBX, Address(ESP, 2 * kWordSize));  // r_digits
+  __ movl(EBX, Address(ESP, 1 * kWordSize));  // r_digits
 
   // Precompute 'used - a_used' now so that carry flag is not lost later.
   __ subl(EAX, ECX);
@@ -858,8 +854,6 @@
   __ adcl(EAX, Immediate(0));
   __ movl(FieldAddress(EBX, EDX, TIMES_4, TypedData::data_offset()), EAX);
 
-  // Restore CTX and return.
-  __ popl(CTX);
   // Returning Object::null() is not required, since this method is private.
   __ ret();
 }
@@ -870,17 +864,13 @@
   //                     Uint32List a_digits, int a_used,
   //                     Uint32List r_digits)
 
-  // Preserve CTX to free ESI.
-  __ pushl(CTX);
-  ASSERT(CTX == ESI);
-
-  __ movl(EDI, Address(ESP, 6 * kWordSize));  // digits
-  __ movl(EAX, Address(ESP, 5 * kWordSize));  // used is Smi
+  __ movl(EDI, Address(ESP, 5 * kWordSize));  // digits
+  __ movl(EAX, Address(ESP, 4 * kWordSize));  // used is Smi
   __ SmiUntag(EAX);  // used > 0.
-  __ movl(ESI, Address(ESP, 4 * kWordSize));  // a_digits
-  __ movl(ECX, Address(ESP, 3 * kWordSize));  // a_used is Smi
+  __ movl(ESI, Address(ESP, 3 * kWordSize));  // a_digits
+  __ movl(ECX, Address(ESP, 2 * kWordSize));  // a_used is Smi
   __ SmiUntag(ECX);  // a_used > 0.
-  __ movl(EBX, Address(ESP, 2 * kWordSize));  // r_digits
+  __ movl(EBX, Address(ESP, 1 * kWordSize));  // r_digits
 
   // Precompute 'used - a_used' now so that carry flag is not lost later.
   __ subl(EAX, ECX);
@@ -914,8 +904,6 @@
   __ j(NOT_ZERO, &carry_loop, Assembler::kNearJump);
 
   __ Bind(&done);
-  // Restore CTX and return.
-  __ popl(CTX);
   // Returning Object::null() is not required, since this method is private.
   __ ret();
 }
@@ -962,18 +950,14 @@
   __ SmiUntag(EDX);
   __ j(ZERO, &no_op, Assembler::kNearJump);
 
-  // Preserve CTX to free ESI.
-  __ pushl(CTX);
-  ASSERT(CTX == ESI);
-
   // EDI = mip = &m_digits[i >> 1]
-  __ movl(EDI, Address(ESP, 6 * kWordSize));  // m_digits
-  __ movl(EAX, Address(ESP, 5 * kWordSize));  // i is Smi
+  __ movl(EDI, Address(ESP, 5 * kWordSize));  // m_digits
+  __ movl(EAX, Address(ESP, 4 * kWordSize));  // i is Smi
   __ leal(EDI, FieldAddress(EDI, EAX, TIMES_2, TypedData::data_offset()));
 
   // ESI = ajp = &a_digits[j >> 1]
-  __ movl(ESI, Address(ESP, 4 * kWordSize));  // a_digits
-  __ movl(EAX, Address(ESP, 3 * kWordSize));  // j is Smi
+  __ movl(ESI, Address(ESP, 3 * kWordSize));  // a_digits
+  __ movl(EAX, Address(ESP, 2 * kWordSize));  // j is Smi
   __ leal(ESI, FieldAddress(ESI, EAX, TIMES_2, TypedData::data_offset()));
 
   // Save n
@@ -1032,8 +1016,6 @@
 
   __ Bind(&done);
   __ Drop(1);  // n
-  // Restore CTX and return.
-  __ popl(CTX);
 
   __ Bind(&no_op);
   __ movl(EAX, Immediate(Smi::RawValue(1)));  // One digit processed.
@@ -1080,12 +1062,8 @@
   __ j(EQUAL, &x_zero, Assembler::kNearJump);
   __ addl(EDI, Immediate(Bigint::kBytesPerDigit));
 
-  // Preserve CTX to free ESI.
-  __ pushl(CTX);
-  ASSERT(CTX == ESI);
-
   // ESI = ajp = &a_digits[i]
-  __ movl(ESI, Address(ESP, 3 * kWordSize));  // a_digits
+  __ movl(ESI, Address(ESP, 2 * kWordSize));  // a_digits
   __ leal(ESI, FieldAddress(ESI, EAX, TIMES_4, TypedData::data_offset()));
 
   // EDX:EAX = t = x*x + *ajp
@@ -1099,8 +1077,8 @@
   __ addl(ESI, Immediate(Bigint::kBytesPerDigit));
 
   // int n = used - i - 1
-  __ movl(EAX, Address(ESP, 2 * kWordSize));  // used is Smi
-  __ subl(EAX, Address(ESP, 4 * kWordSize));  // i is Smi
+  __ movl(EAX, Address(ESP, 1 * kWordSize));  // used is Smi
+  __ subl(EAX, Address(ESP, 3 * kWordSize));  // i is Smi
   __ SmiUntag(EAX);
   __ decl(EAX);
   __ pushl(EAX);  // Save n on stack.
@@ -1165,9 +1143,7 @@
   __ movl(Address(ESI, 0), EAX);
   __ movl(Address(ESI, Bigint::kBytesPerDigit), EDX);
 
-  // Restore CTX and return.
   __ Drop(3);
-  __ popl(CTX);
   __ Bind(&x_zero);
   __ movl(EAX, Immediate(Smi::RawValue(1)));  // One digit processed.
   __ ret();
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index d2a5f54..806c712 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -357,7 +357,8 @@
   }
 
   // Parse the message.
-  SnapshotReader reader(message->data(), message->len(), Snapshot::kMessage, I);
+  SnapshotReader reader(message->data(), message->len(), Snapshot::kMessage,
+                        I, zone.GetZone());
   const Object& msg_obj = Object::Handle(I, reader.ReadObject());
   if (msg_obj.IsError()) {
     // An error occurred while reading the message.
@@ -535,7 +536,8 @@
   object##_handle_(NULL),
 
 Isolate::Isolate()
-    : vm_tag_(0),
+  :   mutator_thread_(new Thread(this)),
+      vm_tag_(0),
       store_buffer_(),
       message_notify_callback_(NULL),
       name_(NULL),
@@ -576,13 +578,13 @@
       gc_epilogue_callback_(NULL),
       defer_finalization_count_(0),
       deopt_context_(NULL),
+      edge_counter_increment_size_(-1),
       is_service_isolate_(false),
       log_(new class Log()),
       stacktrace_(NULL),
       stack_frame_index_(-1),
       last_allocationprofile_accumulator_reset_timestamp_(0),
       last_allocationprofile_gc_timestamp_(0),
-      cha_(NULL),
       object_id_ring_(NULL),
       trace_buffer_(NULL),
       profiler_data_(NULL),
@@ -601,7 +603,8 @@
 }
 
 Isolate::Isolate(Isolate* original)
-    : vm_tag_(0),
+  :   mutator_thread_(new Thread(this)),
+      vm_tag_(0),
       store_buffer_(true),
       class_table_(original->class_table()),
       message_notify_callback_(NULL),
@@ -645,7 +648,6 @@
       stack_frame_index_(-1),
       last_allocationprofile_accumulator_reset_timestamp_(0),
       last_allocationprofile_gc_timestamp_(0),
-      cha_(NULL),
       object_id_ring_(NULL),
       trace_buffer_(NULL),
       profiler_data_(NULL),
@@ -680,9 +682,17 @@
   delete spawn_state_;
   delete log_;
   log_ = NULL;
+  delete mutator_thread_;
 }
 
 
+#if defined(DEBUG)
+bool Isolate::IsIsolateOf(Thread* thread) {
+  return this == thread->isolate();
+}
+#endif  // DEBUG
+
+
 void Isolate::SetCurrent(Isolate* current) {
   Isolate* old_current = Current();
   if (old_current != NULL) {
@@ -690,8 +700,8 @@
     old_current->set_thread_state(NULL);
     Profiler::EndExecution(old_current);
   }
-  OSThread::SetThreadLocal(isolate_key, reinterpret_cast<uword>(current));
   if (current != NULL) {
+    Thread::SetCurrent(current->mutator_thread());
     ASSERT(current->thread_state() == NULL);
     InterruptableThreadState* thread_state =
         ThreadInterrupter::GetCurrentThreadState();
@@ -702,21 +712,13 @@
     Profiler::BeginExecution(current);
     current->set_thread_state(thread_state);
     current->set_vm_tag(VMTag::kVMTagId);
+  } else {
+    Thread::SetCurrent(NULL);
   }
 }
 
 
-// The single thread local key which stores all the thread local data
-// for a thread. Since an Isolate is the central repository for
-// storing all isolate specific information a single thread local key
-// is sufficient.
-ThreadLocalKey Isolate::isolate_key = OSThread::kUnsetThreadLocalKey;
-
-
 void Isolate::InitOnce() {
-  ASSERT(isolate_key == OSThread::kUnsetThreadLocalKey);
-  isolate_key = OSThread::CreateThreadLocal();
-  ASSERT(isolate_key != OSThread::kUnsetThreadLocalKey);
   create_callback_ = NULL;
   isolates_list_monitor_ = new Monitor();
   ASSERT(isolates_list_monitor_ != NULL);
@@ -1221,8 +1223,8 @@
     const Array& args = Array::Handle(Array::New(7));
     args.SetAt(0, SendPort::Handle(SendPort::New(state->parent_port())));
     args.SetAt(1, Instance::Handle(func.ImplicitStaticClosure()));
-    args.SetAt(2, Instance::Handle(state->BuildArgs()));
-    args.SetAt(3, Instance::Handle(state->BuildMessage()));
+    args.SetAt(2, Instance::Handle(state->BuildArgs(zone.GetZone())));
+    args.SetAt(3, Instance::Handle(state->BuildMessage(zone.GetZone())));
     args.SetAt(4, is_spawn_uri ? Bool::True() : Bool::False());
     args.SetAt(5, ReceivePort::Handle(
         ReceivePort::New(isolate->main_port(), true /* control port */)));
@@ -1446,7 +1448,6 @@
 Dart_FileWriteCallback Isolate::file_write_callback_ = NULL;
 Dart_FileCloseCallback Isolate::file_close_callback_ = NULL;
 Dart_EntropySource Isolate::entropy_source_callback_ = NULL;
-Dart_IsolateInterruptCallback Isolate::vmstats_callback_ = NULL;
 
 Monitor* Isolate::isolates_list_monitor_ = NULL;
 Isolate* Isolate::isolates_list_head_ = NULL;
@@ -1796,12 +1797,13 @@
 
 
 static RawInstance* DeserializeObject(Isolate* isolate,
+                                      Zone* zone,
                                       uint8_t* obj_data,
                                       intptr_t obj_len) {
   if (obj_data == NULL) {
     return Instance::null();
   }
-  SnapshotReader reader(obj_data, obj_len, Snapshot::kMessage, isolate);
+  SnapshotReader reader(obj_data, obj_len, Snapshot::kMessage, isolate, zone);
   const Object& obj = Object::Handle(isolate, reader.ReadObject());
   ASSERT(!obj.IsError());
   Instance& instance = Instance::Handle(isolate);
@@ -1960,13 +1962,14 @@
 }
 
 
-RawInstance* IsolateSpawnState::BuildArgs() {
-  return DeserializeObject(isolate_, serialized_args_, serialized_args_len_);
+RawInstance* IsolateSpawnState::BuildArgs(Zone* zone) {
+  return DeserializeObject(isolate_, zone,
+                           serialized_args_, serialized_args_len_);
 }
 
 
-RawInstance* IsolateSpawnState::BuildMessage() {
-  return DeserializeObject(isolate_,
+RawInstance* IsolateSpawnState::BuildMessage(Zone* zone) {
+  return DeserializeObject(isolate_, zone,
                            serialized_message_, serialized_message_len_);
 }
 
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 5953fb2..54c92fe 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -16,6 +16,7 @@
 #include "vm/random.h"
 #include "vm/store_buffer.h"
 #include "vm/tags.h"
+#include "vm/thread.h"
 #include "vm/os_thread.h"
 #include "vm/trace_buffer.h"
 #include "vm/timer.h"
@@ -118,9 +119,9 @@
   ~Isolate();
 
   static inline Isolate* Current() {
-    return reinterpret_cast<Isolate*>(OSThread::GetThreadLocal(isolate_key));
+    Thread* thread = Thread::Current();
+    return thread == NULL ? NULL : thread->isolate();
   }
-
   static void SetCurrent(Isolate* isolate);
 
   static void InitOnce();
@@ -154,9 +155,6 @@
     return OFFSET_OF(Isolate, class_table_);
   }
 
-  CHA* cha() const { return cha_; }
-  void set_cha(CHA* value) { cha_ = value; }
-
   MegamorphicCacheTable* megamorphic_cache_table() {
     return &megamorphic_cache_table_;
   }
@@ -168,7 +166,19 @@
     message_notify_callback_ = value;
   }
 
+  // A thread that operates on this isolate and may execute Dart code.
+  // No other threads operating on this isolate may execute Dart code.
+  // TODO(koda): Remove after caching current thread in generated code.
+  Thread* mutator_thread() {
+    DEBUG_ASSERT(IsIsolateOf(mutator_thread_));
+    return mutator_thread_;
+  }
+#if defined(DEBUG)
+  bool IsIsolateOf(Thread* thread);
+#endif  // DEBUG
+
   const char* name() const { return name_; }
+  // TODO(koda): Move to Thread.
   class Log* Log() const;
 
   int64_t start_time() const { return start_time_; }
@@ -304,13 +314,11 @@
     kApiInterrupt = 0x1,      // An interrupt from Dart_InterruptIsolate.
     kMessageInterrupt = 0x2,  // An interrupt to process an out of band message.
     kStoreBufferInterrupt = 0x4,  // An interrupt to process the store buffer.
-    kVmStatusInterrupt = 0x8,     // An interrupt to process a status request.
 
     kInterruptsMask =
         kApiInterrupt |
         kMessageInterrupt |
-        kStoreBufferInterrupt |
-        kVmStatusInterrupt,
+        kStoreBufferInterrupt,
   };
 
   void ScheduleInterrupts(uword interrupt_bits);
@@ -457,13 +465,6 @@
     return interrupt_callback_;
   }
 
-  static void SetVmStatsCallback(Dart_IsolateInterruptCallback cb) {
-    vmstats_callback_ = cb;
-  }
-  static Dart_IsolateInterruptCallback VmStatsCallback() {
-    return vmstats_callback_;
-  }
-
   static void SetUnhandledExceptionCallback(
       Dart_IsolateUnhandledExceptionCallback cb) {
     unhandled_exception_callback_ = cb;
@@ -529,6 +530,15 @@
     deopt_context_ = value;
   }
 
+  int32_t edge_counter_increment_size() const {
+    return edge_counter_increment_size_;
+  }
+  void set_edge_counter_increment_size(int32_t size) {
+    ASSERT(edge_counter_increment_size_ == -1);
+    ASSERT(size >= 0);
+    edge_counter_increment_size_ = size;
+  }
+
   void UpdateLastAllocationProfileAccumulatorResetTimestamp() {
     last_allocationprofile_accumulator_reset_timestamp_ =
         OS::GetCurrentTimeMillis();
@@ -670,11 +680,9 @@
     user_tag_ = tag;
   }
 
-
   template<class T> T* AllocateReusableHandle();
 
-  static ThreadLocalKey isolate_key;
-
+  Thread* mutator_thread_;
   uword vm_tag_;
   StoreBuffer store_buffer_;
   ClassTable class_table_;
@@ -718,6 +726,7 @@
   Dart_GcEpilogueCallback gc_epilogue_callback_;
   intptr_t defer_finalization_count_;
   DeoptContext* deopt_context_;
+  int32_t edge_counter_increment_size_;
 
   // Log.
   bool is_service_isolate_;
@@ -731,8 +740,6 @@
   int64_t last_allocationprofile_accumulator_reset_timestamp_;
   int64_t last_allocationprofile_gc_timestamp_;
 
-  CHA* cha_;
-
   // Ring buffer of objects assigned an id.
   ObjectIdRing* object_id_ring_;
 
@@ -801,6 +808,7 @@
 #undef REUSABLE_FRIEND_DECLARATION
 
   friend class ServiceIsolate;
+  friend class Thread;
 
   DISALLOW_COPY_AND_ASSIGN(Isolate);
 };
@@ -906,8 +914,8 @@
   bool paused() const { return paused_; }
 
   RawObject* ResolveFunction();
-  RawInstance* BuildArgs();
-  RawInstance* BuildMessage();
+  RawInstance* BuildArgs(Zone* zone);
+  RawInstance* BuildMessage(Zone* zone);
   void Cleanup();
 
  private:
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 565d8b7..3291b0f 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -68,6 +68,7 @@
                                      cls,
                                      0));  // No token position.
   function.set_is_debuggable(false);
+  function.set_is_visible(false);
   miss_handler_code_ = code.raw();
   miss_handler_function_ = function.raw();
   function.AttachCode(code);
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index b445008..3db849c 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -39,6 +39,8 @@
 
 #define DEFINE_NATIVE_ENTRY(name, argument_count)                              \
   static RawObject* DN_Helper##name(Isolate* isolate,                          \
+                                    Thread* thread,                            \
+                                    Zone* zone,                                \
                                     NativeArguments* arguments);               \
   void NATIVE_ENTRY_FUNCTION(name)(Dart_NativeArguments args) {                \
     CHECK_STACK_ALIGNMENT;                                                     \
@@ -49,14 +51,23 @@
     ASSERT(arguments->NativeArgCount() == argument_count);                     \
     TRACE_NATIVE_CALL("%s", ""#name);                                          \
     {                                                                          \
-      StackZone zone(arguments->isolate());                                    \
+      Isolate* isolate = arguments->isolate();                                 \
+      /* TODO(koda): Pivot from Isolate to Thread in NativeArguments. */       \
+      Thread* thread = isolate->mutator_thread();                              \
+      ASSERT(thread == Thread::Current());                                     \
+      StackZone zone(isolate);                                                 \
       SET_NATIVE_RETVAL(arguments,                                             \
-                        DN_Helper##name(arguments->isolate(), arguments));     \
+                        DN_Helper##name(isolate,                               \
+                                        thread,                                \
+                                        zone.GetZone(),                        \
+                                        arguments));                           \
       DEOPTIMIZE_ALOT;                                                         \
     }                                                                          \
     VERIFY_ON_TRANSITION;                                                      \
   }                                                                            \
   static RawObject* DN_Helper##name(Isolate* isolate,                          \
+                                    Thread* thread,                            \
+                                    Zone* zone,                                \
                                     NativeArguments* arguments)
 
 
@@ -64,7 +75,7 @@
 // type name = value.
 #define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)                        \
   const Instance& __##name##_instance__ =                                      \
-      Instance::CheckedHandle(isolate, value);                                 \
+      Instance::CheckedHandle(zone, value);                                    \
   if (!__##name##_instance__.Is##type()) {                                     \
     const Array& __args__ = Array::Handle(Array::New(1));                      \
     __args__.SetAt(0, __##name##_instance__);                                  \
@@ -77,7 +88,7 @@
 // type name = value.
 #define GET_NATIVE_ARGUMENT(type, name, value)                                 \
   const Instance& __##name##_instance__ =                                      \
-      Instance::CheckedHandle(isolate, value);                                 \
+      Instance::CheckedHandle(zone, value);                                    \
   type& name = type::Handle(isolate);                                          \
   if (!__##name##_instance__.IsNull()) {                                       \
     if (!__##name##_instance__.Is##type()) {                                   \
diff --git a/runtime/vm/native_entry_test.cc b/runtime/vm/native_entry_test.cc
index 875bb30..6d48368 100644
--- a/runtime/vm/native_entry_test.cc
+++ b/runtime/vm/native_entry_test.cc
@@ -56,11 +56,12 @@
 // Arg0-4: 5 smis or null.
 // Result: a smi representing the sum of all non-null arguments.
 void TestNonNullSmiSum(Dart_NativeArguments args) {
-  Isolate* isolate = Isolate::Current();
+  Isolate* isolate = Isolate::Current();  // Used by GET_NATIVE_ARGUMENT.
   int64_t result = 0;
   int arg_count = Dart_GetNativeArgumentCount(args);
   // Test the lower level macro GET_NATIVE_ARGUMENT.
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+  Zone* zone = Thread::Current()->zone();  // Used by GET_NATIVE_ARGUMENT.
   for (int i = 0; i < arg_count; i++) {
     Dart_Handle arg = Dart_GetNativeArgument(args, i);
     GET_NATIVE_ARGUMENT(Integer, argument, arguments->NativeArgAt(i));
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index dd85273..103a394 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -387,7 +387,7 @@
   // Should only be run by the vm isolate.
   ASSERT(isolate == Dart::vm_isolate());
 
-  // TODO(iposva): NoGCScope needs to be added here.
+  // TODO(iposva): NoSafepointScope needs to be added here.
   ASSERT(class_class() == null_);
   // Initialize the static vtable values.
   {
@@ -850,7 +850,7 @@
 void Object::MakeUnusedSpaceTraversable(const Object& obj,
                                         intptr_t original_size,
                                         intptr_t used_size) {
-  ASSERT(Isolate::Current()->no_gc_scope_depth() > 0);
+  ASSERT(Isolate::Current()->no_safepoint_scope_depth() > 0);
   ASSERT(!obj.IsNull());
   ASSERT(original_size >= used_size);
   if (original_size > used_size) {
@@ -1680,7 +1680,7 @@
   } else {
     isolate->class_table()->UpdateAllocatedOld(cls_id, size);
   }
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   InitializeObject(address, cls_id, size);
   RawObject* raw_obj = reinterpret_cast<RawObject*>(address + kHeapObjectTag);
   ASSERT(cls_id == RawObject::ClassIdTag::decode(raw_obj->ptr()->tags_));
@@ -1729,7 +1729,7 @@
   const Class& cls = Class::Handle(orig.clazz());
   intptr_t size = orig.raw()->Size();
   RawObject* raw_clone = Object::Allocate(cls.id(), size, space);
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   // TODO(koda): This will trip when we start allocating black.
   // Revisit code below at that point, to account for the new write barrier.
   ASSERT(!raw_clone->IsMarked());
@@ -1851,7 +1851,7 @@
     RawObject* raw = Object::Allocate(Class::kClassId,
                                       Class::InstanceSize(),
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   FakeObject fake;
@@ -2589,6 +2589,7 @@
   }
   invocation.set_result_type(Type::Handle(Type::DynamicType()));
   invocation.set_is_debuggable(false);
+  invocation.set_is_visible(false);
   invocation.set_is_reflectable(false);
   invocation.set_saved_args_desc(args_desc);
 
@@ -2950,7 +2951,7 @@
     RawObject* raw = Object::Allocate(Class::kClassId,
                                       Class::InstanceSize(),
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   FakeInstance fake;
@@ -3889,7 +3890,7 @@
   }
   if (name.IsSymbol()) {
     // Quick Symbol compare.
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     for (intptr_t i = 0; i < len; i++) {
       function ^= funcs.At(i);
       if (function.name() == name.raw()) {
@@ -4776,7 +4777,7 @@
     RawObject* raw = Object::Allocate(TypeArguments::kClassId,
                                       TypeArguments::InstanceSize(len),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     // Length must be set before we start storing into the array.
     result.SetLength(len);
@@ -6090,7 +6091,7 @@
 
 
 bool Function::IsImplicitStaticClosureFunction(RawFunction* func) {
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   uint32_t kind_tag = func->ptr()->kind_tag_;
   if (KindBits::decode(kind_tag) != RawFunction::kClosureFunction) {
     return false;
@@ -6136,6 +6137,7 @@
   result.set_is_external(is_external);
   result.set_is_native(is_native);
   result.set_is_reflectable(true);  // Will be computed later.
+  result.set_is_visible(true);  // Will be computed later.
   result.set_is_debuggable(true);  // Will be computed later.
   result.set_is_intrinsic(false);
   result.set_is_redirecting(false);
@@ -6237,6 +6239,7 @@
                     0));
   ASSERT(!script.IsNull());
   result.set_is_debuggable(false);
+  result.set_is_visible(false);
   result.set_eval_script(script);
   return result.raw();
 }
@@ -6267,6 +6270,11 @@
   // Set closure function's end token to this end token.
   closure_function.set_end_token_pos(end_token_pos());
 
+  // The closurized method stub just calls into the original method and should
+  // therefore be skipped by the debugger and in stack traces.
+  closure_function.set_is_debuggable(false);
+  closure_function.set_is_visible(false);
+
   // Set closure function's formal parameters to this formal parameters,
   // removing the receiver if this is an instance method and adding the closure
   // object as first parameter.
@@ -6657,8 +6665,8 @@
 
 void Function::RestoreICDataMap(
     ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data) const {
-  Isolate* isolate = Isolate::Current();
-  const Array& saved_icd = Array::Handle(isolate, ic_data_array());
+  Zone* zone = Thread::Current()->zone();
+  const Array& saved_icd = Array::Handle(zone, ic_data_array());
   if (saved_icd.Length() == 0) {
     deopt_id_to_ic_data->Clear();
     return;
@@ -6671,7 +6679,7 @@
     (*deopt_id_to_ic_data)[i] = NULL;
   }
   for (intptr_t i = 0; i < saved_icd.Length(); i++) {
-    ICData& icd = ICData::ZoneHandle(isolate);
+    ICData& icd = ICData::ZoneHandle(zone);
     icd ^= saved_icd.At(i);
     (*deopt_id_to_ic_data)[icd.deopt_id()] = &icd;
   }
@@ -6851,46 +6859,6 @@
 }
 
 
-RawGrowableObjectArray* Function::CollectICsWithSourcePositions() const {
-  ZoneGrowableArray<const ICData*>* ic_data_array =
-      new ZoneGrowableArray<const ICData*>();
-  RestoreICDataMap(ic_data_array);
-  const Code& code = Code::Handle(unoptimized_code());
-  const PcDescriptors& descriptors = PcDescriptors::Handle(
-      code.pc_descriptors());
-
-  const intptr_t begin_pos = token_pos();
-  const intptr_t end_pos = end_token_pos();
-
-  const Script& script = Script::Handle(this->script());
-  const GrowableObjectArray& result =
-      GrowableObjectArray::Handle(GrowableObjectArray::New());
-
-  PcDescriptors::Iterator iter(descriptors,
-      RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
-  while (iter.MoveNext()) {
-    const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
-    if (!ic_data->IsNull()) {
-      const intptr_t token_pos = iter.TokenPos();
-      // Filter out descriptors that do not map to tokens in the source code.
-      if ((token_pos < begin_pos) || (token_pos > end_pos)) {
-        continue;
-      }
-
-      intptr_t line = -1;
-      intptr_t column = -1;
-      script.GetTokenLocation(token_pos, &line, &column);
-
-      result.Add(*ic_data);
-      result.Add(Smi::Handle(Smi::New(line)));
-      result.Add(Smi::Handle(Smi::New(column)));
-    }
-  }
-
-  return result.raw();
-}
-
-
 void ClosureData::set_context_scope(const ContextScope& value) const {
   StorePointer(&raw_ptr()->context_scope_, value.raw());
 }
@@ -7979,7 +7947,7 @@
   result.SetPrivateKey(private_key);
   const Array& token_objects = Array::Handle(data.MakeTokenObjectsArray());
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result.SetStream(stream);
     result.SetTokenObjects(token_objects);
   }
@@ -10522,7 +10490,7 @@
     RawObject* raw = Object::Allocate(Instructions::kClassId,
                                       aligned_size,
                                       Heap::kCode);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_size(size);
   }
@@ -10575,7 +10543,7 @@
     RawObject* raw = Object::Allocate(PcDescriptors::kClassId,
                                       size,
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(num_descriptors);
     result.SetRecordSizeInBytes(rec_size);
@@ -10606,7 +10574,7 @@
   const int addr_width = (kBitsPerWord / 4) + 2;
   // "*" in a printf format specifier tells it to read the field width from
   // the printf argument list.
-  OS::Print("%-*s\tkind    \tdeopt-id\ttok-ix\ttry-ix\n",
+  ISL_Print("%-*s\tkind    \tdeopt-id\ttok-ix\ttry-ix\n",
             addr_width, "pc");
 }
 
@@ -10738,7 +10706,7 @@
   int byte_index = bit_index >> kBitsPerByteLog2;
   int bit_remainder = bit_index & (kBitsPerByte - 1);
   uint8_t byte_mask = 1U << bit_remainder;
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   uint8_t* byte_addr = UnsafeMutableNonPointer(&raw_ptr()->data()[byte_index]);
   if (value) {
     *byte_addr |= byte_mask;
@@ -10770,7 +10738,7 @@
     RawObject* raw = Object::Allocate(Stackmap::kClassId,
                                       Stackmap::InstanceSize(length),
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(length);
   }
@@ -10994,7 +10962,7 @@
     RawObject* raw = Object::Allocate(LocalVarDescriptors::kClassId,
                                       size,
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_variables);
   }
@@ -11018,7 +10986,7 @@
                                        bool needs_stacktrace,
                                        bool has_catch_all) const {
   ASSERT((try_index >= 0) && (try_index < num_entries()));
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   RawExceptionHandlers::HandlerInfo* info =
       UnsafeMutableNonPointer(&raw_ptr()->data()[try_index]);
   info->outer_try_index = outer_try_index;
@@ -11099,7 +11067,7 @@
     RawObject* raw = Object::Allocate(ExceptionHandlers::kClassId,
                                       size,
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(&result.raw_ptr()->num_entries_, num_handlers);
   }
@@ -11126,8 +11094,8 @@
   for (intptr_t i = 0; i < num_entries(); i++) {
     GetHandlerInfo(i, &info);
     handled_types = GetHandledTypes(i);
-    ASSERT(!handled_types.IsNull());
-    const intptr_t num_types = handled_types.Length();
+    const intptr_t num_types =
+        handled_types.IsNull() ? 0 : handled_types.Length();
     len += OS::SNPrint(NULL, 0, kFormat,
                        i,
                        info.handler_pc_offset,
@@ -11146,7 +11114,8 @@
   for (intptr_t i = 0; i < num_entries(); i++) {
     GetHandlerInfo(i, &info);
     handled_types = GetHandledTypes(i);
-    const intptr_t num_types = handled_types.Length();
+    const intptr_t num_types =
+        handled_types.IsNull() ? 0 : handled_types.Length();
     num_chars += OS::SNPrint((buffer + num_chars),
                              (len - num_chars),
                              kFormat,
@@ -11177,13 +11146,13 @@
 
 
 intptr_t DeoptInfo::FromIndex(intptr_t index) const {
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   return *(EntryAddr(index, kFromIndex));
 }
 
 
 intptr_t DeoptInfo::Instruction(intptr_t index) const {
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   return *(EntryAddr(index, kInstruction));
 }
 
@@ -11303,7 +11272,7 @@
     RawObject* raw = Object::Allocate(DeoptInfo::kClassId,
                                       size,
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(num_commands);
   }
@@ -11321,7 +11290,7 @@
 void DeoptInfo::SetAt(intptr_t index,
                       intptr_t instr_kind,
                       intptr_t from_index) const {
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   *(EntryAddr(index, kInstruction)) = instr_kind;
   *(EntryAddr(index, kFromIndex)) = from_index;
 }
@@ -11672,7 +11641,7 @@
 intptr_t ICData::GetReceiverClassIdAt(intptr_t index) const {
   ASSERT(index < NumberOfChecks());
   const intptr_t data_pos = index * TestEntryLength();
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   RawArray* raw_data = ic_data();
   return Smi::Value(Smi::RawCast(raw_data->ptr()->data()[data_pos]));
 }
@@ -11682,7 +11651,7 @@
   const intptr_t data_pos = index * TestEntryLength() + NumArgsTested();
   ASSERT(Object::Handle(Array::Handle(ic_data()).At(data_pos)).IsFunction());
 
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   RawArray* raw_data = ic_data();
   return reinterpret_cast<RawFunction*>(raw_data->ptr()->data()[data_pos]);
 }
@@ -11882,7 +11851,7 @@
     RawObject* raw = Object::Allocate(ICData::kClassId,
                                       ICData::InstanceSize(),
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_owner(owner);
@@ -11906,27 +11875,38 @@
 }
 
 
-void ICData::PrintToJSONArray(JSONArray* jsarray,
-                              intptr_t line,
-                              intptr_t column) const {
+void ICData::PrintToJSONArray(const JSONArray& jsarray,
+                              intptr_t token_pos,
+                              bool is_static_call) const {
   Isolate* isolate = Isolate::Current();
   Class& cls = Class::Handle();
+  Function& func = Function::Handle();
 
-  JSONObject jsobj(jsarray);
+  JSONObject jsobj(&jsarray);
   jsobj.AddProperty("name", String::Handle(target_name()).ToCString());
-  jsobj.AddProperty("line", line);
-  jsobj.AddProperty("column", column);
+  jsobj.AddProperty("tokenPos", token_pos);
   // TODO(rmacnak): Figure out how to stringify DeoptReasons().
   // jsobj.AddProperty("deoptReasons", ...);
 
   JSONArray cache_entries(&jsobj, "cacheEntries");
   for (intptr_t i = 0; i < NumberOfChecks(); i++) {
-    intptr_t cid = GetReceiverClassIdAt(i);
-    cls ^= isolate->class_table()->At(cid);
+    func = GetTargetAt(i);
+    if (is_static_call) {
+      cls ^= func.Owner();
+    } else {
+      intptr_t cid = GetReceiverClassIdAt(i);
+      cls ^= isolate->class_table()->At(cid);
+    }
     intptr_t count = GetCountAt(i);
     JSONObject cache_entry(&cache_entries);
-    cache_entry.AddProperty("receiverClass", cls);
+    if (cls.IsTopLevel()) {
+      cache_entry.AddProperty("receiverContainer",
+                              Library::Handle(cls.library()));
+    } else {
+      cache_entry.AddProperty("receiverContainer", cls);
+    }
     cache_entry.AddProperty("count", count);
+    cache_entry.AddProperty("target", func);
   }
 }
 
@@ -12156,7 +12136,7 @@
 
 
 intptr_t Code::BinarySearchInSCallTable(uword pc) const {
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   const Array& table = Array::Handle(raw_ptr()->static_calls_target_table_);
   RawObject* key = reinterpret_cast<RawObject*>(Smi::New(pc - EntryPoint()));
   intptr_t imin = 0;
@@ -12288,7 +12268,7 @@
   {
     uword size = Code::InstanceSize(pointer_offsets_length);
     RawObject* raw = Object::Allocate(Code::kClassId, size, Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_pointer_offsets_length(pointer_offsets_length);
     result.set_is_optimized(false);
@@ -12333,7 +12313,7 @@
                            optimized);
 
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     const ZoneGrowableArray<intptr_t>& pointer_offsets =
         assembler->GetPointerOffsets();
     ASSERT(pointer_offsets.length() == pointer_offset_count);
@@ -12402,7 +12382,7 @@
 
 RawCode* Code::LookupCodeInIsolate(Isolate* isolate, uword pc) {
   ASSERT((isolate == Isolate::Current()) || (isolate == Dart::vm_isolate()));
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   FindRawCodeVisitor visitor(pc);
   RawInstructions* instr;
   if (isolate->heap() == NULL) {
@@ -12670,7 +12650,7 @@
     uint32_t pc_offset, Array* maps, Stackmap* map) const {
   // This code is used during iterating frames during a GC and hence it
   // should not in turn start a GC.
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   if (stackmaps() == Array::null()) {
     // No stack maps are present in the code object which means this
     // frame relies on tagged pointers.
@@ -12792,7 +12772,7 @@
     RawObject* raw = Object::Allocate(Context::kClassId,
                                       Context::InstanceSize(num_variables),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_num_variables(num_variables);
   }
@@ -12896,7 +12876,7 @@
     RawObject* raw = Object::Allocate(ContextScope::kClassId,
                                       size,
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_num_variables(num_variables);
   }
@@ -13061,7 +13041,7 @@
   { RawObject* raw = Object::Allocate(MegamorphicCache::kClassId,
                                       MegamorphicCache::InstanceSize(),
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   const intptr_t capacity = kInitialCapacity;
@@ -13148,7 +13128,7 @@
     RawObject* raw = Object::Allocate(SubtypeTestCache::kClassId,
                                       SubtypeTestCache::InstanceSize(),
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   const Array& cache = Array::Handle(Array::New(kTestEntryLength));
@@ -13163,7 +13143,7 @@
 
 
 intptr_t SubtypeTestCache::NumberOfChecks() const {
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   // Do not count the sentinel;
   return (Smi::Value(cache()->ptr()->length_) / kTestEntryLength) - 1;
 }
@@ -13249,7 +13229,7 @@
     RawObject* raw = Object::Allocate(ApiError::kClassId,
                                       ApiError::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_message(message);
@@ -13303,7 +13283,7 @@
     RawObject* raw = Object::Allocate(LanguageError::kClassId,
                                       LanguageError::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_previous_error(prev_error);
@@ -13325,7 +13305,7 @@
   va_start(args, format);
   RawLanguageError* result = LanguageError::NewFormattedV(
       prev_error, script, token_pos, kind, space, format, args);
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   va_end(args);
   return result;
 }
@@ -13340,7 +13320,7 @@
     RawObject* raw = Object::Allocate(LanguageError::kClassId,
                                       LanguageError::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_formatted_message(formatted_message);
@@ -13428,7 +13408,7 @@
     RawObject* raw = Object::Allocate(UnhandledException::kClassId,
                                       UnhandledException::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_exception(exception);
@@ -13444,7 +13424,7 @@
     RawObject* raw = Object::Allocate(UnhandledException::kClassId,
                                       UnhandledException::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_exception(Object::null_instance());
@@ -13524,7 +13504,7 @@
     RawObject* raw = Object::Allocate(UnwindError::kClassId,
                                       UnwindError::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_message(message);
@@ -13590,7 +13570,7 @@
   }
 
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     // Raw bits compare.
     const intptr_t instance_size = Class::Handle(this->clazz()).instance_size();
     ASSERT(instance_size != 0);
@@ -13817,7 +13797,7 @@
 
 
 intptr_t* Instance::NativeFieldsDataAddr() const {
-  ASSERT(Isolate::Current()->no_gc_scope_depth() > 0);
+  ASSERT(Isolate::Current()->no_safepoint_scope_depth() > 0);
   RawTypedData* native_fields =
       reinterpret_cast<RawTypedData*>(*NativeFieldsAddr());
   if (native_fields == TypedData::null()) {
@@ -13966,7 +13946,7 @@
     return "unknown_constant";
   } else if (raw() == Object::non_constant().raw()) {
     return "non_constant";
-  } else if (Isolate::Current()->no_gc_scope_depth() > 0) {
+  } else if (Isolate::Current()->no_safepoint_scope_depth() > 0) {
     // Can occur when running disassembler.
     return "Instance";
   } else {
@@ -16372,7 +16352,7 @@
     RawObject* raw = Object::Allocate(Mint::kClassId,
                                       Mint::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_value(val);
@@ -16522,7 +16502,7 @@
     RawObject* raw = Object::Allocate(Double::kClassId,
                                       Double::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_value(d);
@@ -16726,7 +16706,7 @@
     RawObject* raw = Object::Allocate(Bigint::kClassId,
                                       Bigint::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.SetNeg(false);
@@ -16748,7 +16728,7 @@
     RawObject* raw = Object::Allocate(Bigint::kClassId,
                                       Bigint::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   // Clamp the digits array.
@@ -17405,7 +17385,7 @@
     return;
   }
   if (str.IsOneByteString()) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     uint8_t* str_addr = OneByteString::CharAddr(str, begin_index);
     for (intptr_t i = 0; i < len; i++) {
       Add(*str_addr);
@@ -17683,7 +17663,7 @@
   if (type == Utf8::kLatin1) {
     const String& strobj = String::Handle(OneByteString::New(len, space));
     if (len > 0) {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
       Utf8::DecodeToLatin1(utf8_array, array_len,
                            OneByteString::CharAddr(strobj, 0), len);
     }
@@ -17691,7 +17671,7 @@
   }
   ASSERT((type == Utf8::kBMP) || (type == Utf8::kSupplementary));
   const String& strobj = String::Handle(TwoByteString::New(len, space));
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   Utf8::DecodeToUTF16(utf8_array, array_len,
                       TwoByteString::CharAddr(strobj, 0), len);
   return strobj.raw();
@@ -17786,7 +17766,7 @@
   ASSERT(len >= 0);
   ASSERT(len <= (dst.Length() - dst_offset));
   if (dst.IsOneByteString()) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     if (len > 0) {
       memmove(OneByteString::CharAddr(dst, dst_offset),
               characters,
@@ -17807,14 +17787,14 @@
   ASSERT(array_len >= 0);
   ASSERT(array_len <= (dst.Length() - dst_offset));
   if (dst.IsOneByteString()) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     for (intptr_t i = 0; i < array_len; ++i) {
       ASSERT(Utf::IsLatin1(utf16_array[i]));
       *OneByteString::CharAddr(dst, i + dst_offset) = utf16_array[i];
     }
   } else {
     ASSERT(dst.IsTwoByteString());
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     if (array_len > 0) {
       memmove(TwoByteString::CharAddr(dst, dst_offset),
               utf16_array,
@@ -17836,14 +17816,14 @@
     intptr_t char_size = src.CharSize();
     if (char_size == kOneByteChar) {
       if (src.IsOneByteString()) {
-        NoGCScope no_gc;
+        NoSafepointScope no_safepoint;
         String::Copy(dst,
                      dst_offset,
                      OneByteString::CharAddr(src, src_offset),
                      len);
       } else {
         ASSERT(src.IsExternalOneByteString());
-        NoGCScope no_gc;
+        NoSafepointScope no_safepoint;
         String::Copy(dst,
                      dst_offset,
                      ExternalOneByteString::CharAddr(src, src_offset),
@@ -17852,14 +17832,14 @@
     } else {
       ASSERT(char_size == kTwoByteChar);
       if (src.IsTwoByteString()) {
-        NoGCScope no_gc;
+        NoSafepointScope no_safepoint;
         String::Copy(dst,
                      dst_offset,
                      TwoByteString::CharAddr(src, src_offset),
                      len);
       } else {
         ASSERT(src.IsExternalTwoByteString());
-        NoGCScope no_gc;
+        NoSafepointScope no_safepoint;
         String::Copy(dst,
                      dst_offset,
                      ExternalTwoByteString::CharAddr(src, src_offset),
@@ -18041,7 +18021,7 @@
   va_list args;
   va_start(args, format);
   RawString* result = NewFormattedV(format, args);
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   va_end(args);
   return result;
 }
@@ -18168,7 +18148,7 @@
     }
     Zone* zone = Isolate::Current()->current_zone();
     uint8_t* result = zone->Alloc<uint8_t>(len + 1);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     const uint8_t* original_str = OneByteString::CharAddr(*this, 0);
     for (intptr_t i = 0; i < len; i++) {
       if (original_str[i] <= Utf8::kMaxOneByteChar) {
@@ -18252,7 +18232,7 @@
   void* external_data;
   Dart_WeakPersistentHandleFinalizer finalizer;
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     ASSERT(array != NULL);
     intptr_t str_length = this->Length();
     ASSERT(length >= (str_length * this->CharSize()));
@@ -18333,7 +18313,7 @@
       external_data = ext_data;
       finalizer = ExternalTwoByteString::Finalize;
     }
-  }  // NoGCScope
+  }  // NoSafepointScope
   AddFinalizer(result, external_data, finalizer);
   return this->raw();
 }
@@ -18383,7 +18363,7 @@
   ASSERT(start <= end);
   ASSERT(end <= str.Length());
   intptr_t length = end - start;
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   const uint8_t* startChar;
   if (str.IsOneByteString()) {
     startChar = OneByteString::CharAddr(str, start);
@@ -18481,7 +18461,7 @@
   if (str1.raw() == str2.raw()) {
     return true;  // Both handles point to the same raw instance.
   }
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   intptr_t str1_class_id = str1.raw()->GetClassId();
   intptr_t str2_class_id = str2.raw()->GetClassId();
   switch (str1_class_id) {
@@ -18605,7 +18585,7 @@
     RawObject* raw = Object::Allocate(OneByteString::kClassId,
                                       OneByteString::InstanceSize(len),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     RawOneByteString* result = reinterpret_cast<RawOneByteString*>(raw);
     result->StoreSmi(&(result->ptr()->length_), Smi::New(len));
     result->StoreSmi(&(result->ptr()->hash_), Smi::New(0));
@@ -18619,7 +18599,7 @@
                                      Heap::Space space) {
   const String& result = String::Handle(OneByteString::New(len, space));
   if (len > 0) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     memmove(CharAddr(result, 0), characters, len);
   }
   return OneByteString::raw(result);
@@ -18630,7 +18610,7 @@
                                      intptr_t len,
                                      Heap::Space space) {
   const String& result = String::Handle(OneByteString::New(len, space));
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   for (intptr_t i = 0; i < len; ++i) {
     ASSERT(Utf::IsLatin1(characters[i]));
     *CharAddr(result, i) = characters[i];
@@ -18643,7 +18623,7 @@
                                      intptr_t len,
                                      Heap::Space space) {
   const String& result = String::Handle(OneByteString::New(len, space));
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   for (intptr_t i = 0; i < len; ++i) {
     ASSERT(Utf::IsLatin1(characters[i]));
     *CharAddr(result, i) = characters[i];
@@ -18668,7 +18648,7 @@
   const String& result = String::Handle(OneByteString::New(other_len, space));
   ASSERT(other_one_byte_string.IsOneByteString());
   if (other_len > 0) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     memmove(OneByteString::CharAddr(result, 0),
             OneByteString::CharAddr(other_one_byte_string, other_start_index),
             other_len);
@@ -18684,7 +18664,7 @@
   const String& result = String::Handle(OneByteString::New(other_len, space));
   ASSERT(other_typed_data.ElementSizeInBytes() == 1);
   if (other_len > 0) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     memmove(OneByteString::CharAddr(result, 0),
             other_typed_data.DataAddr(other_start_index),
             other_len);
@@ -18700,7 +18680,7 @@
   const String& result = String::Handle(OneByteString::New(other_len, space));
   ASSERT(other_typed_data.ElementSizeInBytes() == 1);
   if (other_len > 0) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     memmove(OneByteString::CharAddr(result, 0),
             other_typed_data.DataAddr(other_start_index),
             other_len);
@@ -18750,7 +18730,7 @@
   ASSERT(!str.IsNull());
   intptr_t len = str.Length();
   const String& result = String::Handle(OneByteString::New(len, space));
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   for (intptr_t i = 0; i < len; ++i) {
     int32_t ch = mapping(str.CharAt(i));
     ASSERT(Utf::IsLatin1(ch));
@@ -18772,7 +18752,7 @@
   }
   ASSERT(begin_index < str.Length());
   RawOneByteString* result = OneByteString::New(length, space);
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   if (length > 0) {
     uint8_t* dest = &result->ptr()->data()[0];
     const uint8_t* src =  &raw_ptr(str)->data()[begin_index];
@@ -18846,7 +18826,7 @@
     RawObject* raw = Object::Allocate(TwoByteString::kClassId,
                                       TwoByteString::InstanceSize(len),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
     result.SetHash(0);
@@ -18861,7 +18841,7 @@
   ASSERT(array_len > 0);
   const String& result = String::Handle(TwoByteString::New(array_len, space));
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     memmove(CharAddr(result, 0), utf16_array, (array_len * 2));
   }
   return TwoByteString::raw(result);
@@ -18875,7 +18855,7 @@
   ASSERT((array_len > 0) && (utf16_len >= array_len));
   const String& result = String::Handle(TwoByteString::New(utf16_len, space));
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     intptr_t j = 0;
     for (intptr_t i = 0; i < array_len; ++i) {
       if (Utf::IsSupplementary(utf32_array[i])) {
@@ -18908,7 +18888,7 @@
                                      Heap::Space space) {
   const String& result = String::Handle(TwoByteString::New(other_len, space));
   if (other_len > 0) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     memmove(TwoByteString::CharAddr(result, 0),
             other_typed_data.DataAddr(other_start_index),
             other_len * sizeof(uint16_t));
@@ -18923,7 +18903,7 @@
                                      Heap::Space space) {
   const String& result = String::Handle(TwoByteString::New(other_len, space));
   if (other_len > 0) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     memmove(TwoByteString::CharAddr(result, 0),
             other_typed_data.DataAddr(other_start_index),
             other_len * sizeof(uint16_t));
@@ -18975,7 +18955,7 @@
   const String& result = String::Handle(TwoByteString::New(len, space));
   String::CodePointIterator it(str);
   intptr_t i = 0;
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   while (it.Next()) {
     int32_t src = it.Current();
     int32_t dst = mapping(src);
@@ -19032,7 +19012,7 @@
     RawObject* raw = Object::Allocate(ExternalOneByteString::kClassId,
                                       ExternalOneByteString::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
     result.SetHash(0);
@@ -19070,7 +19050,7 @@
     RawObject* raw = Object::Allocate(ExternalTwoByteString::kClassId,
                                       ExternalTwoByteString::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
     result.SetHash(0);
@@ -19097,7 +19077,7 @@
     RawObject* raw = Object::Allocate(Bool::kClassId,
                                       Bool::InstanceSize(),
                                       Heap::kOld);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_value(value);
@@ -19174,7 +19154,7 @@
         Object::Allocate(class_id,
                          Array::InstanceSize(len),
                          space));
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     raw->StoreSmi(&(raw->ptr()->length_), Smi::New(len));
     VerifiedMemory::Accept(reinterpret_cast<uword>(raw->ptr()),
                            Array::InstanceSize(len));
@@ -19201,7 +19181,7 @@
 
 
 void Array::MakeImmutable() const {
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   uword tags = raw_ptr()->tags_;
   uword old_tags;
   do {
@@ -19289,7 +19269,7 @@
   array.SetTypeArguments(type_arguments);
   intptr_t capacity_size = Array::InstanceSize(capacity_len);
   intptr_t used_size = Array::InstanceSize(used_len);
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
 
   // If there is any left over space fill it with either an Array object or
   // just a plain object (depending on the amount of left over space) so
@@ -19457,7 +19437,7 @@
     RawObject* raw = Object::Allocate(GrowableObjectArray::kClassId,
                                       GrowableObjectArray::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(0);
     result.SetData(array);
@@ -19560,7 +19540,7 @@
   ASSERT(!IsNull());
   EnumIndexDefaultMap map(data());
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     RawObject* result = map.GetOrNull(key);
     ASSERT(map.Release().raw() == data());
     return result;
@@ -19639,7 +19619,7 @@
     RawObject* raw = Object::Allocate(LinkedHashMap::kClassId,
                                       LinkedHashMap::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetData(data);
     result.SetModified();
@@ -19669,7 +19649,7 @@
     RawObject* raw = Object::Allocate(Float32x4::kClassId,
                                       Float32x4::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_x(v0);
@@ -19688,7 +19668,7 @@
     RawObject* raw = Object::Allocate(Float32x4::kClassId,
                                       Float32x4::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_value(value);
@@ -19774,7 +19754,7 @@
     RawObject* raw = Object::Allocate(Int32x4::kClassId,
                                       Int32x4::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_x(v0);
@@ -19793,7 +19773,7 @@
     RawObject* raw = Object::Allocate(Int32x4::kClassId,
                                       Int32x4::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_value(value);
@@ -19878,7 +19858,7 @@
     RawObject* raw = Object::Allocate(Float64x2::kClassId,
                                       Float64x2::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_x(value0);
@@ -19895,7 +19875,7 @@
     RawObject* raw = Object::Allocate(Float64x2::kClassId,
                                       Float64x2::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_value(value);
@@ -19988,7 +19968,7 @@
   if (len != other_typed_data.LengthInBytes()) {
     return false;
   }
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   return (len == 0) ||
       (memcmp(DataAddr(0), other_typed_data.DataAddr(0), len) == 0);
 }
@@ -20006,7 +19986,7 @@
     RawObject* raw = Object::Allocate(class_id,
                                       TypedData::InstanceSize(lengthInBytes),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
     if (len > 0) {
@@ -20056,7 +20036,7 @@
     RawObject* raw = Object::Allocate(class_id,
                                       ExternalTypedData::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.SetLength(len);
     result.SetData(data);
@@ -20082,7 +20062,7 @@
     RawObject* raw = Object::Allocate(Capability::kClassId,
                                       Capability::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(&result.raw_ptr()->id_, id);
   }
@@ -20112,7 +20092,7 @@
     RawObject* raw = Object::Allocate(ReceivePort::kClassId,
                                       ReceivePort::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.StorePointer(&result.raw_ptr()->send_port_, send_port.raw());
   }
@@ -20148,7 +20128,7 @@
     RawObject* raw = Object::Allocate(SendPort::kClassId,
                                       SendPort::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.StoreNonPointer(&result.raw_ptr()->id_, id);
     result.StoreNonPointer(&result.raw_ptr()->origin_id_, origin_id);
@@ -20189,7 +20169,7 @@
   Instance& result = Instance::Handle();
   {
     RawObject* raw = Object::Allocate(cls.id(), Closure::InstanceSize(), space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   Closure::set_function(result, function);
@@ -20264,7 +20244,7 @@
     RawObject* raw = Object::Allocate(Stacktrace::kClassId,
                                       Stacktrace::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_code_array(code_array);
@@ -20368,7 +20348,7 @@
         OS::SNPrint(chars, truncated_len, "%s", kTruncated);
         frame_strings.Add(chars);
       }
-    } else if (function.is_debuggable() || FLAG_show_invisible_frames) {
+    } else if (function.is_visible() || FLAG_show_invisible_frames) {
       code = CodeAtFrame(i);
       ASSERT(function.raw() == code.function());
       uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i));
@@ -20377,7 +20357,7 @@
         for (InlinedFunctionsIterator it(code, pc);
              !it.Done() && (*frame_index < max_frames); it.Advance()) {
           function = it.function();
-          if (function.is_debuggable() || FLAG_show_invisible_frames) {
+          if (function.is_visible() || FLAG_show_invisible_frames) {
             code = it.code();
             ASSERT(function.raw() == code.function());
             uword pc = it.pc();
@@ -20436,7 +20416,7 @@
     RawObject* raw = Object::Allocate(JSRegExp::kClassId,
                                       JSRegExp::InstanceSize(len),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
     result.set_type(kUnitialized);
     result.set_flags(0);
@@ -20593,7 +20573,7 @@
     RawObject* raw = Object::Allocate(MirrorReference::kClassId,
                                       MirrorReference::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_referent(referent);
@@ -20652,7 +20632,7 @@
     RawObject* raw = Object::Allocate(UserTag::kClassId,
                                       UserTag::InstanceSize(),
                                       space);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     result ^= raw;
   }
   result.set_label(label);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 7981b2b..4ca6980 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -93,10 +93,6 @@
     }                                                                          \
     return *obj;                                                               \
   }                                                                            \
-  /* DEPRECATED: Use Zone version. */                                          \
-  static object& CheckedHandle(Isolate* isolate, RawObject* raw_ptr) {         \
-    return CheckedHandle(isolate->current_zone(), raw_ptr);                    \
-  }                                                                            \
   static object& CheckedHandle(RawObject* raw_ptr) {                           \
     return CheckedHandle(Thread::Current()->zone(), raw_ptr);                  \
   }                                                                            \
@@ -106,10 +102,6 @@
     initializeHandle(obj, raw_ptr);                                            \
     return *obj;                                                               \
   }                                                                            \
-  /* DEPRECATED: Use Zone version. */                                          \
-  static object& ZoneHandle(Isolate* isolate, Raw##object* raw_ptr) {          \
-    return ZoneHandle(isolate->current_zone(), raw_ptr);                       \
-  }                                                                            \
   static object* ReadOnlyHandle() {                                            \
     object* obj = reinterpret_cast<object*>(                                   \
         Dart::AllocateReadOnlyHandle());                                       \
@@ -119,10 +111,6 @@
   static object& ZoneHandle(Zone* zone) {                                      \
     return ZoneHandle(zone, object::null());                                   \
   }                                                                            \
-  /* DEPRECATED: Use Zone version. */                                          \
-  static object& ZoneHandle(Isolate* isolate) {                                \
-    return ZoneHandle(isolate->current_zone(), object::null());                \
-  }                                                                            \
   static object& ZoneHandle() {                                                \
     return ZoneHandle(Thread::Current()->zone(), object::null());              \
   }                                                                            \
@@ -374,19 +362,19 @@
     return Handle(Isolate::Current(), raw_ptr);
   }
 
-  static Object& ZoneHandle(Isolate* isolate, RawObject* raw_ptr) {
+  static Object& ZoneHandle(Zone* zone, RawObject* raw_ptr) {
     Object* obj = reinterpret_cast<Object*>(
-        VMHandles::AllocateZoneHandle(isolate->current_zone()));
+        VMHandles::AllocateZoneHandle(zone));
     initializeHandle(obj, raw_ptr);
     return *obj;
   }
 
   static Object& ZoneHandle() {
-    return ZoneHandle(Isolate::Current(), null_);
+    return ZoneHandle(Thread::Current()->zone(), null_);
   }
 
   static Object& ZoneHandle(RawObject* raw_ptr) {
-    return ZoneHandle(Isolate::Current(), raw_ptr);
+    return ZoneHandle(Thread::Current()->zone(), raw_ptr);
   }
 
   static RawObject* null() { return null_; }
@@ -671,16 +659,16 @@
   }
 
   // Provides non-const access to non-pointer fields within the object. Such
-  // access does not need a write barrier, but it is *not* GC-safe (since the
-  // object might move), hence must be fully contained within a NoGCScope.
+  // access does not need a write barrier, but it is *not* GC-safe, since the
+  // object might move, hence must be fully contained within a NoSafepointScope.
   template<typename FieldType>
   FieldType* UnsafeMutableNonPointer(const FieldType* addr) const {
     // Allow pointers at the end of variable-length data, and disallow pointers
     // within the header word.
     ASSERT(Contains(reinterpret_cast<uword>(addr) - 1) &&
            Contains(reinterpret_cast<uword>(addr) - kWordSize));
-    // At least check that there is a NoGCScope, and hope it's big enough.
-    ASSERT(Isolate::Current()->no_gc_scope_depth() > 0);
+    // At least check that there is a NoSafepointScope and hope it's big enough.
+    ASSERT(Isolate::Current()->no_safepoint_scope_depth() > 0);
     return const_cast<FieldType*>(addr);
   }
 
@@ -833,43 +821,46 @@
   void operator^=(RawObject* value) {
     raw_ = value;
   }
-  static PassiveObject& Handle(Isolate* I, RawObject* raw_ptr) {
+
+  static PassiveObject& Handle(Zone* zone, RawObject* raw_ptr) {
     PassiveObject* obj = reinterpret_cast<PassiveObject*>(
-        VMHandles::AllocateHandle(I->current_zone()));
+        VMHandles::AllocateHandle(zone));
     obj->raw_ = raw_ptr;
     obj->set_vtable(0);
     return *obj;
   }
+  // DEPRECATED - use Zone version.
+  static PassiveObject& Handle(Isolate* I, RawObject* raw_ptr) {
+    return Handle(I->current_zone(), raw_ptr);
+  }
   static PassiveObject& Handle(RawObject* raw_ptr) {
     return Handle(Isolate::Current(), raw_ptr);
   }
   static PassiveObject& Handle() {
     return Handle(Isolate::Current(), Object::null());
   }
-  // DEPRECATED
-  // TODO(koda): Add Zone version.
+  static PassiveObject& Handle(Zone* zone) {
+    return Handle(zone, Object::null());
+  }
+  // DEPRECATED - use Zone version.
   static PassiveObject& Handle(Isolate* I) {
     return Handle(I, Object::null());
   }
-  // DEPRECATED
-  // TODO(koda): Add Zone version.
-  static PassiveObject& ZoneHandle(Isolate* I, RawObject* raw_ptr) {
+  static PassiveObject& ZoneHandle(Zone* zone, RawObject* raw_ptr) {
     PassiveObject* obj = reinterpret_cast<PassiveObject*>(
-        VMHandles::AllocateZoneHandle(I->current_zone()));
+        VMHandles::AllocateZoneHandle(zone));
     obj->raw_ = raw_ptr;
     obj->set_vtable(0);
     return *obj;
   }
   static PassiveObject& ZoneHandle(RawObject* raw_ptr) {
-    return ZoneHandle(Isolate::Current(), raw_ptr);
+    return ZoneHandle(Thread::Current()->zone(), raw_ptr);
   }
   static PassiveObject& ZoneHandle() {
-    return ZoneHandle(Isolate::Current(), Object::null());
+    return ZoneHandle(Thread::Current()->zone(), Object::null());
   }
-  // DEPRECATED
-  // TODO(koda): Add Zone version.
-  static PassiveObject& ZoneHandle(Isolate* I) {
-    return ZoneHandle(I, Object::null());
+  static PassiveObject& ZoneHandle(Zone* zone) {
+    return ZoneHandle(zone, Object::null());
   }
 
  private:
@@ -1811,8 +1802,6 @@
   }
   bool HasCode() const;
 
-  RawGrowableObjectArray* CollectICsWithSourcePositions() const;
-
   static intptr_t instructions_offset() {
     return OFFSET_OF(RawFunction, instructions_);
   }
@@ -2253,9 +2242,12 @@
   // abstract: Skipped during instance-side resolution.
   // reflectable: Enumerated by mirrors, invocable by mirrors. False for private
   //              functions of dart: libraries.
-  // debuggable: Valid location of a break point. True for functions with source
-  //             code; false for synthetic functions such as dispatchers. Also
-  //             used to decide whether to include a frame in stack traces.
+  // debuggable: Valid location of a breakpoint. Synthetic code is not
+  //             debuggable.
+  // visible: Frame is included in stack traces. Synthetic code such as
+  //          dispatchers is not visible. Synthetic code that can trigger
+  //          exceptions such as the outer async functions that create Futures
+  //          is visible.
   // optimizable: Candidate for going through the optimizing compiler. False for
   //              some functions known to be execute infrequently and functions
   //              which have been de-optimized too many times.
@@ -2273,6 +2265,7 @@
   V(Const, is_const)                                                           \
   V(Abstract, is_abstract)                                                     \
   V(Reflectable, is_reflectable)                                               \
+  V(Visible, is_visible)                                                       \
   V(Debuggable, is_debuggable)                                                 \
   V(Optimizable, is_optimizable)                                               \
   V(Inlinable, is_inlinable)                                                   \
@@ -3292,7 +3285,7 @@
                      int64_t deopt_id,
                      int64_t token_pos,  // Or deopt reason.
                      intptr_t try_index) const {  // Or deopt index.
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     RawPcDescriptors::PcDescriptorRec* rec = recAt(index);
     rec->set_pc_offset(pc_offset);
     rec->set_kind(kind);
@@ -3356,23 +3349,23 @@
     }
 
     uword PcOffset() const {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
       return descriptors_.recAt(current_ix_)->pc_offset();
     }
     intptr_t DeoptId() const {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
       return descriptors_.recAt(current_ix_)->deopt_id();
     }
     intptr_t TokenPos() const {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
       return descriptors_.recAt(current_ix_)->token_pos();
     }
     intptr_t TryIndex() const {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
       return descriptors_.recAt(current_ix_)->try_index();
     }
     RawPcDescriptors::Kind Kind() const {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
       return descriptors_.recAt(current_ix_)->kind();
     }
 
@@ -3391,7 +3384,7 @@
 
     // Moves to record that matches kind_mask_.
     void MoveToMatching() {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
       while (next_ix_ < descriptors_.Length()) {
         const RawPcDescriptors::PcDescriptorRec& rec =
             *descriptors_.recAt(next_ix_);
@@ -3896,9 +3889,9 @@
   bool HasRangeFeedback() const;
   RangeFeedback DecodeRangeFeedbackAt(intptr_t idx) const;
 
-  void PrintToJSONArray(JSONArray* jsarray,
-                        intptr_t line,
-                        intptr_t column) const;
+  void PrintToJSONArray(const JSONArray& jsarray,
+                        intptr_t token_pos,
+                        bool is_static_call) const;
 
  private:
   RawArray* ic_data() const {
@@ -4155,7 +4148,7 @@
   static RawCode* FindCode(uword pc, int64_t timestamp);
 
   int32_t GetPointerOffsetAt(int index) const {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     return *PointerOffsetAddrAt(index);
   }
   intptr_t GetTokenIndexOfPC(uword pc) const;
@@ -4266,7 +4259,7 @@
     return &UnsafeMutableNonPointer(raw_ptr()->data())[index];
   }
   void SetPointerOffsetAt(int index, int32_t offset_in_instructions) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     *PointerOffsetAddrAt(index) = offset_in_instructions;
   }
 
@@ -6087,7 +6080,7 @@
   }
 
   static void SetCharAt(const String& str, intptr_t index, uint8_t code_unit) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     *CharAddr(str, index) = code_unit;
   }
   static RawOneByteString* EscapeSpecialCharacters(const String& str);
@@ -6218,7 +6211,7 @@
   }
 
   static void SetCharAt(const String& str, intptr_t index, uint16_t ch) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     *CharAddr(str, index) = ch;
   }
 
@@ -6324,7 +6317,7 @@
 class ExternalOneByteString : public AllStatic {
  public:
   static uint16_t CharAt(const String& str, intptr_t index) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     return *CharAddr(str, index);
   }
 
@@ -6404,7 +6397,7 @@
 class ExternalTwoByteString : public AllStatic {
  public:
   static uint16_t CharAt(const String& str, intptr_t index) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     return *CharAddr(str, index);
   }
 
@@ -6532,7 +6525,7 @@
     return *ObjectAddr(index);
   }
   void SetAt(intptr_t index, const Object& value) const {
-    // TODO(iposva): Add storing NoGCScope.
+    // TODO(iposva): Add storing NoSafepointScope.
     StorePointer(ObjectAddr(index), value.raw());
   }
 
@@ -6664,7 +6657,7 @@
 class GrowableObjectArray : public Instance {
  public:
   intptr_t Capacity() const {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     ASSERT(!IsNull());
     return Smi::Value(DataArray()->length_);
   }
@@ -6684,7 +6677,7 @@
   }
 
   RawObject* At(intptr_t index) const {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     ASSERT(!IsNull());
     ASSERT(index < Length());
     return *ObjectAddr(index);
@@ -6693,7 +6686,7 @@
     ASSERT(!IsNull());
     ASSERT(index < Length());
 
-    // TODO(iposva): Add storing NoGCScope.
+    // TODO(iposva): Add storing NoSafepointScope.
     DataStorePointer(ObjectAddr(index), value.raw());
   }
 
@@ -6942,11 +6935,11 @@
 
 #define TYPED_GETTER_SETTER(name, type)                                        \
   type Get##name(intptr_t byte_offset) const {                                 \
-    NoGCScope no_gc;                                                           \
+    NoSafepointScope no_safepoint;                                             \
     return *reinterpret_cast<type*>(DataAddr(byte_offset));                    \
   }                                                                            \
   void Set##name(intptr_t byte_offset, type value) const {                     \
-    NoGCScope no_gc;                                                           \
+    NoSafepointScope no_safepoint;                                             \
     *reinterpret_cast<type*>(DataAddr(byte_offset)) = value;                   \
   }
   TYPED_GETTER_SETTER(Int8, int8_t)
@@ -7015,7 +7008,7 @@
                              length_in_bytes,
                              dst.LengthInBytes()));
     {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
       if (length_in_bytes > 0) {
         memmove(dst.DataAddr(dst_offset_in_bytes),
                 src.DataAddr(src_offset_in_bytes),
@@ -7036,7 +7029,7 @@
                              length_in_bytes,
                              dst.LengthInBytes()));
     {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
       if (length_in_bytes > 0) {
         uint8_t* dst_data =
             reinterpret_cast<uint8_t*>(dst.DataAddr(dst_offset_in_bytes));
@@ -7766,7 +7759,7 @@
 
 intptr_t Instance::GetNativeField(int index) const {
   ASSERT(IsValidNativeIndex(index));
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   RawTypedData* native_fields =
       reinterpret_cast<RawTypedData*>(*NativeFieldsAddr());
   if (native_fields == TypedData::null()) {
@@ -7778,7 +7771,7 @@
 
 void Instance::GetNativeFields(uint16_t num_fields,
                                intptr_t* field_values) const {
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   ASSERT(num_fields == NumNativeFields());
   ASSERT(field_values != NULL);
   RawTypedData* native_fields =
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc
index f5787e8..50e0792 100644
--- a/runtime/vm/object_graph.cc
+++ b/runtime/vm/object_graph.cc
@@ -171,7 +171,7 @@
 
 
 void ObjectGraph::IterateObjects(ObjectGraph::Visitor* visitor) {
-  NoGCScope no_gc_scope_;
+  NoSafepointScope no_safepoint_scope_;
   Stack stack(isolate());
   isolate()->VisitObjectPointers(&stack, false, false);
   stack.TraverseGraph(visitor);
@@ -181,7 +181,7 @@
 
 void ObjectGraph::IterateObjectsFrom(const Object& root,
                                      ObjectGraph::Visitor* visitor) {
-  NoGCScope no_gc_scope_;
+  NoSafepointScope no_safepoint_scope_;
   Stack stack(isolate());
   RawObject* root_raw = root.raw();
   stack.VisitPointer(&root_raw);
@@ -256,7 +256,7 @@
   // We cannot use a GrowableObjectArray, since we must not trigger GC.
   RetainingPathVisitor(RawObject* obj, const Array& path)
       : obj_(obj), path_(path), length_(0) {
-    ASSERT(Isolate::Current()->no_gc_scope_depth() != 0);
+    ASSERT(Isolate::Current()->no_safepoint_scope_depth() != 0);
   }
 
   intptr_t length() const { return length_; }
@@ -291,7 +291,7 @@
 
 
 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) {
-  NoGCScope no_gc_scope_;
+  NoSafepointScope no_safepoint_scope_;
   // To break the trivial path, the handle 'obj' is temporarily cleared during
   // the search, but restored before returning.
   RawObject* raw = obj->raw();
@@ -313,7 +313,7 @@
                            Object* scratch)
     : ObjectVisitor(isolate), ObjectPointerVisitor(isolate), source_(NULL),
       target_(target), references_(references), scratch_(scratch), length_(0) {
-    ASSERT(Isolate::Current()->no_gc_scope_depth() != 0);
+    ASSERT(Isolate::Current()->no_safepoint_scope_depth() != 0);
   }
 
   intptr_t length() const { return length_; }
@@ -365,7 +365,7 @@
 
 intptr_t ObjectGraph::InboundReferences(Object* obj, const Array& references) {
   Object& scratch = Object::Handle();
-  NoGCScope no_gc_scope_;
+  NoSafepointScope no_safepoint_scope_;
   InboundReferencesVisitor visitor(isolate(), obj->raw(), references, &scratch);
   isolate()->heap()->IterateObjects(&visitor);
   return visitor.length();
diff --git a/runtime/vm/object_graph_test.cc b/runtime/vm/object_graph_test.cc
index 9ccd9f9..66771db 100644
--- a/runtime/vm/object_graph_test.cc
+++ b/runtime/vm/object_graph_test.cc
@@ -59,7 +59,7 @@
   intptr_t d_size = d.raw()->Size();
   {
     // No more allocation; raw pointers ahead.
-    NoGCScope no_gc_scope;
+    NoSafepointScope no_safepoint_scope;
     RawObject* b_raw = b.raw();
     // Clear handles to cut unintended retained paths.
     b = Array::null();
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 6bf6b45..1a349ed 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -3226,13 +3226,13 @@
       "Unhandled exception:\n"
       "MyException\n"
       "#0      baz (test-lib:2:3)\n"
-      "#1      _OtherClass._OtherClass._named (test-lib:7:8)\n"
+      "#1      _OtherClass._OtherClass._named (test-lib:7:5)\n"
       "#2      globalVar= (test-lib:12:7)\n"
       "#3      _bar (test-lib:16:3)\n"
-      "#4      MyClass.field (test-lib:25:9)\n"
+      "#4      MyClass.field (test-lib:25:5)\n"
       "#5      MyClass.foo.fooHelper (test-lib:30:7)\n"
       "#6      MyClass.foo (test-lib:32:14)\n"
-      "#7      MyClass.MyClass.<anonymous closure> (test-lib:21:15)\n"
+      "#7      MyClass.MyClass.<anonymous closure> (test-lib:21:12)\n"
       "#8      MyClass.MyClass (test-lib:21:18)\n"
       "#9      main.<anonymous closure> (test-lib:37:14)\n"
       "#10     main (test-lib:37:24)");
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 25039a2..19da567 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -448,7 +448,7 @@
  private:
   const PageSpace* space_;
   MutexLocker ml_;
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   HeapPage* page_;
 };
 
@@ -471,7 +471,7 @@
  private:
   const PageSpace* space_;
   MutexLocker ml_;
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   HeapPage* page_;
 };
 
@@ -493,7 +493,7 @@
  private:
   const PageSpace* space_;
   MutexLocker ml_;
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   HeapPage* page_;
 };
 
@@ -670,7 +670,7 @@
     // TODO(19445): Use ExclusivePageIterator once HeapMap supports large pages.
     MutexLocker ml(pages_lock_);
     MakeIterable();
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     JSONArray all_pages(&heap_map, "pages");
     for (HeapPage* page = pages_; page != NULL; page = page->next()) {
       JSONObject page_container(&all_pages);
@@ -713,7 +713,7 @@
 void PageSpace::WriteProtectCode(bool read_only) {
   if (FLAG_write_protect_code) {
     MutexLocker ml(pages_lock_);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     // No need to go through all of the data pages first.
     HeapPage* page = exec_pages_;
     while (page != NULL) {
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 4f8be44..0a2b0fb 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -858,8 +858,15 @@
   SequenceNode* node_sequence = NULL;
   Array& default_parameter_values = Array::ZoneHandle(zone, Array::null());
   switch (func.kind()) {
-    case RawFunction::kRegularFunction:
     case RawFunction::kClosureFunction:
+      if (func.IsImplicitClosureFunction()) {
+        parser.SkipFunctionPreamble();
+        node_sequence =
+            parser.ParseImplicitClosure(func, &default_parameter_values);
+        break;
+      }
+      // Fall-through: Handle non-implicit closures.
+    case RawFunction::kRegularFunction:
     case RawFunction::kGetterFunction:
     case RawFunction::kSetterFunction:
     case RawFunction::kConstructor:
@@ -1301,6 +1308,59 @@
 }
 
 
+SequenceNode* Parser::ParseImplicitClosure(const Function& func,
+                                           Array* default_values) {
+  TRACE_PARSER("ParseImplicitClosure");
+
+  intptr_t token_pos = func.token_pos();
+
+  OpenFunctionBlock(func);
+
+  ParamList params;
+
+  params.AddFinalParameter(
+      token_pos,
+      &Symbols::ClosureParameter(),
+      &Type::ZoneHandle(Type::DynamicType()));
+
+  const bool allow_explicit_default_values = true;
+  ParseFormalParameterList(allow_explicit_default_values, false, &params);
+  SetupDefaultsForOptionalParams(&params, default_values);
+
+  // Getters can't be closurized. If supported, they need special
+  // handling of the parameters as in ParseFunc.
+  const Function& parent = Function::ZoneHandle(func.parent_function());
+  ASSERT(!parent.IsGetterFunction());
+
+  // Populate function scope with the formal parameters.
+  LocalScope* scope = current_block_->scope;
+  AddFormalParamsToScope(&params, scope);
+
+  ArgumentListNode* func_args = new ArgumentListNode(token_pos);
+  if (!func.is_static()) {
+    func_args->Add(LoadReceiver(token_pos));
+  }
+  // Skip implicit parameter at 0.
+  for (intptr_t i = 1; i < func.NumParameters(); ++i) {
+    func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i)));
+  }
+
+  if (func.HasOptionalNamedParameters()) {
+    const Array& arg_names =
+        Array::ZoneHandle(Array::New(func.NumOptionalParameters()));
+    for (intptr_t i = 0; i < arg_names.Length(); ++i) {
+      intptr_t index = func.num_fixed_parameters() + i;
+      arg_names.SetAt(i, String::Handle(func.ParameterNameAt(index)));
+    }
+    func_args->set_names(arg_names);
+  }
+  StaticCallNode* call = new StaticCallNode(token_pos, parent, func_args);
+  ReturnNode* return_node = new ReturnNode(token_pos, call);
+  current_block_->statements->Add(return_node);
+  return CloseBlock();
+}
+
+
 SequenceNode* Parser::ParseMethodExtractor(const Function& func) {
   TRACE_PARSER("ParseMethodExtractor");
   ParamList params;
@@ -6795,6 +6855,7 @@
   TRACE_PARSER("CloseAsyncFunction");
   ASSERT(!closure.IsNull());
   ASSERT(closure_body != NULL);
+
   // The block for the async closure body has already been closed. Close the
   // corresponding function block.
   CloseBlock();
@@ -8275,7 +8336,10 @@
       ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
   ExpectToken(Token::kRPAREN);
 
+  // Open a block for the iterator variable and the try-finally
+  // statement that contains the loop.
   OpenBlock();
+  const Block* loop_block = current_block_;
 
   // Build creation of implicit StreamIterator.
   // var :for-in-iter = new StreamIterator(stream_expr).
@@ -8301,6 +8365,33 @@
       new(Z) StoreLocalNode(stream_pos, iterator_var, ctor_call);
   current_block_->statements->Add(iterator_init);
 
+  // We need to ensure that the stream is cancelled after the loop.
+  // Thus, wrap the loop in a try-finally that calls :for-in-iter.close()
+  // in the finally clause. It is harmless to call close() if the stream
+  // is already cancelled (when moveNext() returns false).
+  // Note: even though this is async code, we do not need to set up
+  // the closurized saved_exception_var and saved_stack_trace_var because
+  // there can not be a suspend/resume event before the exception is
+  // rethrown in the catch clause. The catch block of the implicit
+  // try-finally is empty.
+  LocalVariable* context_var = NULL;
+  LocalVariable* exception_var = NULL;
+  LocalVariable* stack_trace_var = NULL;
+  LocalVariable* saved_exception_var = NULL;
+  LocalVariable* saved_stack_trace_var = NULL;
+  SetupExceptionVariables(current_block_->scope,
+                          false,  // Do not create the saved_ vars.
+                          &context_var,
+                          &exception_var,
+                          &stack_trace_var,
+                          &saved_exception_var,
+                          &saved_stack_trace_var);
+  OpenBlock();  // try block.
+  PushTry(current_block_);
+  SetupSavedTryContext(context_var);
+
+  // Build while loop condition.
+  // while (await :for-in-iter.moveNext())
   LocalScope* try_scope;
   int16_t try_index;
   LocalScope* outer_try_scope;
@@ -8308,23 +8399,22 @@
   CheckAsyncOpInTryBlock(&try_scope, &try_index,
                          &outer_try_scope, &outer_try_index);
 
-  // Build while loop condition.
-  // while (await :for-in-iter.moveNext())
   ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_pos);
   AstNode* iterator_moveNext = new(Z) InstanceCallNode(
       stream_pos,
       new(Z) LoadLocalNode(stream_pos, iterator_var),
                            Symbols::MoveNext(),
                            no_args);
-  AstNode* await_moveNext = new (Z) AwaitNode(stream_pos,
-                                              iterator_moveNext,
-                                              try_scope,
-                                              try_index,
-                                              outer_try_scope,
-                                              outer_try_index);
+  AstNode* await_moveNext =
+      new(Z) AwaitNode(stream_pos,
+                       iterator_moveNext,
+                       try_scope,
+                       try_index,
+                       outer_try_scope,
+                       outer_try_index);
   OpenBlock();
   AwaitTransformer at(current_block_->statements, async_temp_scope_);
-  AstNode* transformed_await = at.Transform(await_moveNext);
+  await_moveNext = at.Transform(await_moveNext);
   SequenceNode* await_preamble = CloseBlock();
 
   // Parse the for loop body. Ideally, we would use ParseNestedStatement()
@@ -8332,6 +8422,7 @@
   // variable assignment and potentially a variable declaration in the
   // loop body.
   OpenLoopBlock();
+
   SourceLabel* label =
       SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor);
   current_block_->scope->AddLabel(label);
@@ -8369,6 +8460,7 @@
                                                loop_var_assignment_pos);
     ASSERT(loop_var_assignment != NULL);
   }
+
   current_block_->statements->Add(loop_var_assignment);
 
   // Now parse the for-in loop statement or block.
@@ -8382,14 +8474,97 @@
       current_block_->statements->Add(statement);
     }
   }
-  SequenceNode* for_loop_statement = CloseBlock();
+  SequenceNode* for_loop_block = CloseBlock();
 
   WhileNode* while_node = new (Z) WhileNode(await_for_pos,
                                             label,
-                                            transformed_await,
+                                            await_moveNext,
                                             await_preamble,
-                                            for_loop_statement);
+                                            for_loop_block);
+  // Add the while loop to the try block.
   current_block_->statements->Add(while_node);
+  SequenceNode* try_block = CloseBlock();
+
+  // Create an empty "catch all" block that rethrows the current
+  // exception and stacktrace.
+  try_stack_->enter_catch();
+  SequenceNode* catch_block = new(Z) SequenceNode(await_for_pos, NULL);
+
+  if (outer_try_scope != NULL) {
+    catch_block->Add(AwaitTransformer::RestoreSavedTryContext(
+        Z, outer_try_scope, outer_try_index));
+  }
+
+  // We don't need to copy the current exception and stack trace variables
+  // into :saved_exception_var and :saved_stack_trace_var here because there
+  // is no code in the catch clause that could suspend the function.
+
+  // Rethrow the exception.
+  catch_block->Add(new(Z) ThrowNode(
+      await_for_pos,
+      new(Z) LoadLocalNode(await_for_pos, exception_var),
+      new(Z) LoadLocalNode(await_for_pos, stack_trace_var)));
+
+  TryStack* try_statement = PopTry();
+  ASSERT(try_index == try_statement->try_index());
+
+  // The finally block contains a call to cancel the stream.
+  // :for-in-iter.cancel()
+
+  // Inline the finally block to the exit points in the try block.
+  intptr_t node_index = 0;
+  SequenceNode* finally_clause = NULL;
+  do {
+    OpenBlock();
+    ArgumentListNode* no_args =
+        new(Z) ArgumentListNode(Scanner::kNoSourcePos);
+    current_block_->statements->Add(
+        new(Z) InstanceCallNode(Scanner::kNoSourcePos,
+            new(Z) LoadLocalNode(Scanner::kNoSourcePos, iterator_var),
+            Symbols::Cancel(),
+            no_args));
+    finally_clause = CloseBlock();
+    AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index);
+    if (node_to_inline != NULL) {
+      InlinedFinallyNode* node =
+          new(Z) InlinedFinallyNode(Scanner::kNoSourcePos,
+                                    finally_clause,
+                                    context_var,
+                                    outer_try_index);
+      finally_clause = NULL;
+      AddFinallyBlockToNode(true, node_to_inline, node);
+      node_index++;
+    }
+  } while (finally_clause == NULL);
+
+  // Create the try-statement and add to the current sequence, which is
+  // the block around the loop statement.
+
+  const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType());
+  const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
+  handler_types.SetAt(0, dynamic_type);  // Catch block handles all exceptions.
+
+  CatchClauseNode* catch_clause = new(Z) CatchClauseNode(await_for_pos,
+      catch_block,
+      handler_types,
+      context_var,
+      exception_var,
+      stack_trace_var,
+      exception_var,
+      stack_trace_var,
+      AllocateTryIndex(),
+      true);  // Needs stack trace.
+
+  AstNode* try_catch_node =
+      new(Z) TryCatchNode(await_for_pos,
+                         try_block,
+                         context_var,
+                         catch_clause,
+                         finally_clause,
+                         try_index);
+
+  ASSERT(current_block_ == loop_block);
+  loop_block->statements->Add(try_catch_node);
 
   return CloseBlock();  // Implicit block around while loop.
 }
@@ -10152,15 +10327,18 @@
     if (name.IsNull()) {
       ReportError(left_pos, "expression is not assignable");
     }
-    result = ThrowNoSuchMethodError(
-        original->token_pos(),
-        *target_cls,
-        String::Handle(Z, Field::SetterName(name)),
-        NULL,  // No arguments.
-        InvocationMirror::kStatic,
-        original->IsLoadLocalNode() ?
-            InvocationMirror::kLocalVar : InvocationMirror::kSetter,
-        NULL);  // No existing function.
+    LetNode* let_node = new(Z) LetNode(left_pos);
+    let_node->AddInitializer(rhs);
+    let_node->AddNode(ThrowNoSuchMethodError(
+         original->token_pos(),
+         *target_cls,
+         String::Handle(Z, Field::SetterName(name)),
+         NULL,  // No arguments.
+         InvocationMirror::kStatic,
+         original->IsLoadLocalNode() ?
+         InvocationMirror::kLocalVar : InvocationMirror::kSetter,
+         NULL));  // No existing function.
+    result = let_node;
   } else if (result->IsStoreIndexedNode() ||
              result->IsInstanceSetterNode() ||
              result->IsStaticSetterNode() ||
@@ -10549,16 +10727,17 @@
                                    arguments->NodeAt(1));
     }
   }
-  return new(Z) StaticCallNode(call_pos, func, arguments);
+  return new(Z) StaticCallNode(ident_pos, func, arguments);
 }
 
 
-AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) {
+AstNode* Parser::ParseInstanceCall(AstNode* receiver,
+                                   const String& func_name,
+                                   intptr_t ident_pos) {
   TRACE_PARSER("ParseInstanceCall");
-  const intptr_t call_pos = TokenPos();
   CheckToken(Token::kLPAREN);
   ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst);
-  return new(Z) InstanceCallNode(call_pos, receiver, func_name, arguments);
+  return new(Z) InstanceCallNode(ident_pos, receiver, func_name, arguments);
 }
 
 
@@ -10758,7 +10937,7 @@
           const Class& cls = Class::Cast(left->AsPrimaryNode()->primary());
           selector = ParseStaticCall(cls, *ident, ident_pos);
         } else {
-          selector = ParseInstanceCall(left, *ident);
+          selector = ParseInstanceCall(left, *ident, ident_pos);
         }
       } else {
         // Field access.
@@ -10852,7 +11031,9 @@
                           "from static function",
                           func_name.ToCString());
             }
-            selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name);
+            selector = ParseInstanceCall(LoadReceiver(primary_pos),
+                                         func_name,
+                                         primary_pos);
           }
         } else if (primary_node->primary().IsString()) {
           // Primary is an unresolved name.
@@ -10871,7 +11052,9 @@
                                               NULL);  // No existing function.
           } else {
             // Treat as call to unresolved (instance) method.
-            selector = ParseInstanceCall(LoadReceiver(primary_pos), name);
+            selector = ParseInstanceCall(LoadReceiver(primary_pos),
+                                         name,
+                                         primary_pos);
           }
         } else if (primary_node->primary().IsTypeParameter()) {
           const String& name = String::ZoneHandle(Z,
@@ -10884,7 +11067,9 @@
                         name.ToCString());
           } else {
             // Treat as call to unresolved (instance) method.
-            selector = ParseInstanceCall(LoadReceiver(primary_pos), name);
+            selector = ParseInstanceCall(LoadReceiver(primary_pos),
+                                         name,
+                                         primary_pos);
           }
         } else if (primary_node->primary().IsClass()) {
           const Class& type_class = Class::Cast(primary_node->primary());
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 49eef83..cfb6a76 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -526,6 +526,8 @@
                                             Array* default_values);
   SequenceNode* ParseInvokeFieldDispatcher(const Function& func,
                                            Array* default_values);
+  SequenceNode* ParseImplicitClosure(const Function& func,
+                                     Array* default_values);
 
   void BuildDispatcherScope(const Function& func,
                             const ArgumentsDescriptor& desc,
@@ -699,7 +701,9 @@
   AstNode* ParseStaticCall(const Class& cls,
                            const String& method_name,
                            intptr_t ident_pos);
-  AstNode* ParseInstanceCall(AstNode* receiver, const String& method_name);
+  AstNode* ParseInstanceCall(AstNode* receiver,
+                             const String& method_name,
+                             intptr_t ident_pos);
   AstNode* ParseClosureCall(AstNode* closure);
   AstNode* GenerateStaticFieldLookup(const Field& field,
                                      intptr_t ident_pos);
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index dd3d124..6e3637f 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -63,7 +63,7 @@
     if (array.IsNull() || code.IsNull()) {
       return false;
     }
-    NoGCScope no_gc_scope;
+    NoSafepointScope no_safepoint_scope;
     for (intptr_t i = 0; array.Length(); i++) {
       if (code.raw() == array.At(i)) {
         return true;
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 41d2f9c..0ef0d80a 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -65,151 +65,146 @@
 
 
 intptr_t RawObject::SizeFromClass() const {
-  Isolate* isolate = Isolate::Current();
-  NoHandleScope no_handles(isolate);
-
   // Only reasonable to be called on heap objects.
   ASSERT(IsHeapObject());
 
   intptr_t class_id = GetClassId();
-  ClassTable* class_table = isolate->class_table();
-#if defined(DEBUG)
-  if (!class_table->IsValidIndex(class_id) ||
-      !class_table->HasValidClassAt(class_id)) {
-    FATAL2("Invalid class id: %" Pd " from tags %" Px "\n",
-           class_id, ptr()->tags_);
-  }
-#endif  // DEBUG
-  RawClass* raw_class = class_table->At(class_id);
-  ASSERT(raw_class->ptr()->id_ == class_id);
-
-  // Get the instance size out of the class.
-  intptr_t instance_size =
-      raw_class->ptr()->instance_size_in_words_ << kWordSizeLog2;
-
-  if (instance_size == 0) {
-    switch (class_id) {
-      case kCodeCid: {
-        const RawCode* raw_code = reinterpret_cast<const RawCode*>(this);
-        intptr_t pointer_offsets_length =
-            Code::PtrOffBits::decode(raw_code->ptr()->state_bits_);
-        instance_size = Code::InstanceSize(pointer_offsets_length);
-        break;
-      }
-      case kInstructionsCid: {
-        const RawInstructions* raw_instructions =
-            reinterpret_cast<const RawInstructions*>(this);
-        intptr_t instructions_size = raw_instructions->ptr()->size_;
-        instance_size = Instructions::InstanceSize(instructions_size);
-        break;
-      }
-      case kContextCid: {
-        const RawContext* raw_context =
-            reinterpret_cast<const RawContext*>(this);
-        intptr_t num_variables = raw_context->ptr()->num_variables_;
-        instance_size = Context::InstanceSize(num_variables);
-        break;
-      }
-      case kContextScopeCid: {
-        const RawContextScope* raw_context_scope =
-            reinterpret_cast<const RawContextScope*>(this);
-        intptr_t num_variables = raw_context_scope->ptr()->num_variables_;
-        instance_size = ContextScope::InstanceSize(num_variables);
-        break;
-      }
-      case kOneByteStringCid: {
-        const RawOneByteString* raw_string =
-            reinterpret_cast<const RawOneByteString*>(this);
-        intptr_t string_length = Smi::Value(raw_string->ptr()->length_);
-        instance_size = OneByteString::InstanceSize(string_length);
-        break;
-      }
-      case kTwoByteStringCid: {
-        const RawTwoByteString* raw_string =
-            reinterpret_cast<const RawTwoByteString*>(this);
-        intptr_t string_length = Smi::Value(raw_string->ptr()->length_);
-        instance_size = TwoByteString::InstanceSize(string_length);
-        break;
-      }
-      case kArrayCid:
-      case kImmutableArrayCid: {
-        const RawArray* raw_array = reinterpret_cast<const RawArray*>(this);
-        intptr_t array_length = Smi::Value(raw_array->ptr()->length_);
-        instance_size = Array::InstanceSize(array_length);
-        break;
-      }
+  intptr_t instance_size = 0;
+  switch (class_id) {
+    case kCodeCid: {
+      const RawCode* raw_code = reinterpret_cast<const RawCode*>(this);
+      intptr_t pointer_offsets_length =
+          Code::PtrOffBits::decode(raw_code->ptr()->state_bits_);
+      instance_size = Code::InstanceSize(pointer_offsets_length);
+      break;
+    }
+    case kInstructionsCid: {
+      const RawInstructions* raw_instructions =
+          reinterpret_cast<const RawInstructions*>(this);
+      intptr_t instructions_size = raw_instructions->ptr()->size_;
+      instance_size = Instructions::InstanceSize(instructions_size);
+      break;
+    }
+    case kContextCid: {
+      const RawContext* raw_context =
+          reinterpret_cast<const RawContext*>(this);
+      intptr_t num_variables = raw_context->ptr()->num_variables_;
+      instance_size = Context::InstanceSize(num_variables);
+      break;
+    }
+    case kContextScopeCid: {
+      const RawContextScope* raw_context_scope =
+          reinterpret_cast<const RawContextScope*>(this);
+      intptr_t num_variables = raw_context_scope->ptr()->num_variables_;
+      instance_size = ContextScope::InstanceSize(num_variables);
+      break;
+    }
+    case kOneByteStringCid: {
+      const RawOneByteString* raw_string =
+          reinterpret_cast<const RawOneByteString*>(this);
+      intptr_t string_length = Smi::Value(raw_string->ptr()->length_);
+      instance_size = OneByteString::InstanceSize(string_length);
+      break;
+    }
+    case kTwoByteStringCid: {
+      const RawTwoByteString* raw_string =
+          reinterpret_cast<const RawTwoByteString*>(this);
+      intptr_t string_length = Smi::Value(raw_string->ptr()->length_);
+      instance_size = TwoByteString::InstanceSize(string_length);
+      break;
+    }
+    case kArrayCid:
+    case kImmutableArrayCid: {
+      const RawArray* raw_array = reinterpret_cast<const RawArray*>(this);
+      intptr_t array_length = Smi::Value(raw_array->ptr()->length_);
+      instance_size = Array::InstanceSize(array_length);
+      break;
+    }
 #define SIZE_FROM_CLASS(clazz)                                                 \
-      case kTypedData##clazz##Cid:
-      CLASS_LIST_TYPED_DATA(SIZE_FROM_CLASS) {
-        const RawTypedData* raw_obj =
-            reinterpret_cast<const RawTypedData*>(this);
-        intptr_t cid = raw_obj->GetClassId();
-        intptr_t array_len = Smi::Value(raw_obj->ptr()->length_);
-        intptr_t lengthInBytes = array_len * TypedData::ElementSizeInBytes(cid);
-        instance_size = TypedData::InstanceSize(lengthInBytes);
-        break;
-      }
+    case kTypedData##clazz##Cid:
+    CLASS_LIST_TYPED_DATA(SIZE_FROM_CLASS) {
+      const RawTypedData* raw_obj =
+          reinterpret_cast<const RawTypedData*>(this);
+      intptr_t cid = raw_obj->GetClassId();
+      intptr_t array_len = Smi::Value(raw_obj->ptr()->length_);
+      intptr_t lengthInBytes = array_len * TypedData::ElementSizeInBytes(cid);
+      instance_size = TypedData::InstanceSize(lengthInBytes);
+      break;
+    }
 #undef SIZE_FROM_CLASS
-      case kTypeArgumentsCid: {
-        const RawTypeArguments* raw_array =
-            reinterpret_cast<const RawTypeArguments*>(this);
-        intptr_t array_length = Smi::Value(raw_array->ptr()->length_);
-        instance_size = TypeArguments::InstanceSize(array_length);
-        break;
+    case kTypeArgumentsCid: {
+      const RawTypeArguments* raw_array =
+          reinterpret_cast<const RawTypeArguments*>(this);
+      intptr_t array_length = Smi::Value(raw_array->ptr()->length_);
+      instance_size = TypeArguments::InstanceSize(array_length);
+      break;
+    }
+    case kPcDescriptorsCid: {
+      const RawPcDescriptors* raw_descriptors =
+          reinterpret_cast<const RawPcDescriptors*>(this);
+      const intptr_t num_descriptors = raw_descriptors->ptr()->length_;
+      const intptr_t rec_size_in_bytes =
+          raw_descriptors->ptr()->record_size_in_bytes_;
+      instance_size = PcDescriptors::InstanceSize(num_descriptors,
+                                                  rec_size_in_bytes);
+      break;
+    }
+    case kStackmapCid: {
+      const RawStackmap* map = reinterpret_cast<const RawStackmap*>(this);
+      intptr_t length = map->ptr()->length_;
+      instance_size = Stackmap::InstanceSize(length);
+      break;
+    }
+    case kLocalVarDescriptorsCid: {
+      const RawLocalVarDescriptors* raw_descriptors =
+          reinterpret_cast<const RawLocalVarDescriptors*>(this);
+      intptr_t num_descriptors = raw_descriptors->ptr()->num_entries_;
+      instance_size = LocalVarDescriptors::InstanceSize(num_descriptors);
+      break;
+    }
+    case kExceptionHandlersCid: {
+      const RawExceptionHandlers* raw_handlers =
+          reinterpret_cast<const RawExceptionHandlers*>(this);
+      intptr_t num_handlers = raw_handlers->ptr()->num_entries_;
+      instance_size = ExceptionHandlers::InstanceSize(num_handlers);
+      break;
+    }
+    case kDeoptInfoCid: {
+      const RawDeoptInfo* raw_deopt_info =
+          reinterpret_cast<const RawDeoptInfo*>(this);
+      intptr_t num_entries = Smi::Value(raw_deopt_info->ptr()->length_);
+      instance_size = DeoptInfo::InstanceSize(num_entries);
+      break;
+    }
+    case kJSRegExpCid: {
+      const RawJSRegExp* raw_jsregexp =
+          reinterpret_cast<const RawJSRegExp*>(this);
+      intptr_t data_length = Smi::Value(raw_jsregexp->ptr()->data_length_);
+      instance_size = JSRegExp::InstanceSize(data_length);
+      break;
+    }
+    case kFreeListElement: {
+      uword addr = RawObject::ToAddr(const_cast<RawObject*>(this));
+      FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
+      instance_size = element->Size();
+      break;
+    }
+    default: {
+      // Get the (constant) instance size out of the class object.
+      // TODO(koda): Add Size(ClassTable*) interface to allow caching in loops.
+      Isolate* isolate = Isolate::Current();
+      ClassTable* class_table = isolate->class_table();
+#if defined(DEBUG)
+      if (!class_table->IsValidIndex(class_id) ||
+          !class_table->HasValidClassAt(class_id)) {
+        FATAL2("Invalid class id: %" Pd " from tags %" Px "\n",
+               class_id, ptr()->tags_);
       }
-      case kPcDescriptorsCid: {
-        const RawPcDescriptors* raw_descriptors =
-            reinterpret_cast<const RawPcDescriptors*>(this);
-        const intptr_t num_descriptors = raw_descriptors->ptr()->length_;
-        const intptr_t rec_size_in_bytes =
-            raw_descriptors->ptr()->record_size_in_bytes_;
-        instance_size = PcDescriptors::InstanceSize(num_descriptors,
-                                                    rec_size_in_bytes);
-        break;
-      }
-      case kStackmapCid: {
-        const RawStackmap* map = reinterpret_cast<const RawStackmap*>(this);
-        intptr_t length = map->ptr()->length_;
-        instance_size = Stackmap::InstanceSize(length);
-        break;
-      }
-      case kLocalVarDescriptorsCid: {
-        const RawLocalVarDescriptors* raw_descriptors =
-            reinterpret_cast<const RawLocalVarDescriptors*>(this);
-        intptr_t num_descriptors = raw_descriptors->ptr()->num_entries_;
-        instance_size = LocalVarDescriptors::InstanceSize(num_descriptors);
-        break;
-      }
-      case kExceptionHandlersCid: {
-        const RawExceptionHandlers* raw_handlers =
-            reinterpret_cast<const RawExceptionHandlers*>(this);
-        intptr_t num_handlers = raw_handlers->ptr()->num_entries_;
-        instance_size = ExceptionHandlers::InstanceSize(num_handlers);
-        break;
-      }
-      case kDeoptInfoCid: {
-        const RawDeoptInfo* raw_deopt_info =
-            reinterpret_cast<const RawDeoptInfo*>(this);
-        intptr_t num_entries = Smi::Value(raw_deopt_info->ptr()->length_);
-        instance_size = DeoptInfo::InstanceSize(num_entries);
-        break;
-      }
-      case kJSRegExpCid: {
-        const RawJSRegExp* raw_jsregexp =
-            reinterpret_cast<const RawJSRegExp*>(this);
-        intptr_t data_length = Smi::Value(raw_jsregexp->ptr()->data_length_);
-        instance_size = JSRegExp::InstanceSize(data_length);
-        break;
-      }
-      case kFreeListElement: {
-        uword addr = RawObject::ToAddr(const_cast<RawObject*>(this));
-        FreeListElement* element = reinterpret_cast<FreeListElement*>(addr);
-        instance_size = element->Size();
-        break;
-      }
-      default:
-        UNREACHABLE();
-        break;
+#endif  // DEBUG
+      RawClass* raw_class = class_table->At(class_id);
+      ASSERT(raw_class->ptr()->id_ == class_id);
+      instance_size =
+          raw_class->ptr()->instance_size_in_words_ << kWordSizeLog2;
     }
   }
   ASSERT(instance_size != 0);
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 232ed6f..6a9c490 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -28,7 +28,7 @@
                           Snapshot::Kind kind) {
   ASSERT(reader != NULL);
 
-  Class& cls = Class::ZoneHandle(reader->isolate(), Class::null());
+  Class& cls = Class::ZoneHandle(reader->zone(), Class::null());
   if ((kind == Snapshot::kFull) ||
       (kind == Snapshot::kScript && !RawObject::IsCreatedFromSnapshot(tags))) {
     // Read in the base information.
@@ -139,7 +139,7 @@
 
   // Allocate unresolved class object.
   UnresolvedClass& unresolved_class = UnresolvedClass::ZoneHandle(
-      reader->isolate(), NEW_OBJECT(UnresolvedClass));
+      reader->zone(), NEW_OBJECT(UnresolvedClass));
   reader->AddBackRef(object_id, &unresolved_class, kIsDeserialized);
 
   // Set the object tags.
@@ -206,7 +206,7 @@
   ASSERT(reader != NULL);
 
   // Allocate type object.
-  Type& type = Type::ZoneHandle(reader->isolate(), NEW_OBJECT(Type));
+  Type& type = Type::ZoneHandle(reader->zone(), NEW_OBJECT(Type));
   reader->AddBackRef(object_id, &type, kIsDeserialized);
 
   // Set all non object fields.
@@ -281,7 +281,7 @@
 
   // Allocate type ref object.
   TypeRef& type_ref = TypeRef::ZoneHandle(
-      reader->isolate(), NEW_OBJECT(TypeRef));
+      reader->zone(), NEW_OBJECT(TypeRef));
   reader->AddBackRef(object_id, &type_ref, kIsDeserialized);
 
   // Set the object tags.
@@ -327,7 +327,7 @@
 
   // Allocate type parameter object.
   TypeParameter& type_parameter = TypeParameter::ZoneHandle(
-      reader->isolate(), NEW_OBJECT(TypeParameter));
+      reader->zone(), NEW_OBJECT(TypeParameter));
   reader->AddBackRef(object_id, &type_parameter, kIsDeserialized);
 
   // Set the object tags.
@@ -387,7 +387,7 @@
 
   // Allocate bounded type object.
   BoundedType& bounded_type = BoundedType::ZoneHandle(
-      reader->isolate(), NEW_OBJECT(BoundedType));
+      reader->zone(), NEW_OBJECT(BoundedType));
   reader->AddBackRef(object_id, &bounded_type, kIsDeserialized);
 
   // Set the object tags.
@@ -452,7 +452,7 @@
   intptr_t len = reader->ReadSmiValue();
 
   TypeArguments& type_arguments = TypeArguments::ZoneHandle(
-      reader->isolate(), NEW_OBJECT_WITH_LEN_SPACE(TypeArguments, len, kind));
+      reader->zone(), NEW_OBJECT_WITH_LEN_SPACE(TypeArguments, len, kind));
   reader->AddBackRef(object_id, &type_arguments, kIsDeserialized);
 
   // Set the instantiations field, which is only read from a full snapshot.
@@ -531,7 +531,7 @@
          (kind == Snapshot::kFull));
 
   // Allocate function object.
-  PatchClass& cls = PatchClass::ZoneHandle(reader->isolate(),
+  PatchClass& cls = PatchClass::ZoneHandle(reader->zone(),
                                             NEW_OBJECT(PatchClass));
   reader->AddBackRef(object_id, &cls, kIsDeserialized);
 
@@ -583,7 +583,7 @@
 
   // Allocate closure data object.
   ClosureData& data = ClosureData::ZoneHandle(
-      reader->isolate(), NEW_OBJECT(ClosureData));
+      reader->zone(), NEW_OBJECT(ClosureData));
   reader->AddBackRef(object_id, &data, kIsDeserialized);
 
   // Set the object tags.
@@ -643,7 +643,7 @@
 
   // Allocate redirection data object.
   RedirectionData& data = RedirectionData::ZoneHandle(
-      reader->isolate(), NEW_OBJECT(RedirectionData));
+      reader->zone(), NEW_OBJECT(RedirectionData));
   reader->AddBackRef(object_id, &data, kIsDeserialized);
 
   // Set the object tags.
@@ -695,7 +695,7 @@
 
   // Allocate function object.
   Function& func = Function::ZoneHandle(
-      reader->isolate(), NEW_OBJECT(Function));
+      reader->zone(), NEW_OBJECT(Function));
   reader->AddBackRef(object_id, &func, kIsDeserialized);
 
   // Set the object tags.
@@ -773,7 +773,7 @@
          (kind == Snapshot::kFull));
 
   // Allocate field object.
-  Field& field = Field::ZoneHandle(reader->isolate(), NEW_OBJECT(Field));
+  Field& field = Field::ZoneHandle(reader->zone(), NEW_OBJECT(Field));
   reader->AddBackRef(object_id, &field, kIsDeserialized);
 
   // Set the object tags.
@@ -837,7 +837,7 @@
 
   // Create the literal token object.
   LiteralToken& literal_token = LiteralToken::ZoneHandle(
-      reader->isolate(), NEW_OBJECT(LiteralToken));
+      reader->zone(), NEW_OBJECT(LiteralToken));
   reader->AddBackRef(object_id, &literal_token, kIsDeserialized);
 
   // Set the object tags.
@@ -897,7 +897,7 @@
 
   // Create the token stream object.
   TokenStream& token_stream = TokenStream::ZoneHandle(
-      reader->isolate(), NEW_OBJECT_WITH_LEN(TokenStream, len));
+      reader->zone(), NEW_OBJECT_WITH_LEN(TokenStream, len));
   reader->AddBackRef(object_id, &token_stream, kIsDeserialized);
 
   // Set the object tags.
@@ -906,7 +906,7 @@
   // Read the stream of tokens into the TokenStream object for script
   // snapshots as we made a copy of token stream.
   if (kind == Snapshot::kScript) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     RawExternalTypedData* stream = token_stream.GetStream();
     reader->ReadBytes(stream->ptr()->data_, len);
   }
@@ -960,7 +960,7 @@
          (kind == Snapshot::kFull));
 
   // Allocate script object.
-  Script& script = Script::ZoneHandle(reader->isolate(), NEW_OBJECT(Script));
+  Script& script = Script::ZoneHandle(reader->zone(), NEW_OBJECT(Script));
   reader->AddBackRef(object_id, &script, kIsDeserialized);
 
   // Set the object tags.
@@ -1024,7 +1024,7 @@
   ASSERT(reader != NULL);
   ASSERT(kind != Snapshot::kMessage);
 
-  Library& library = Library::ZoneHandle(reader->isolate(), Library::null());
+  Library& library = Library::ZoneHandle(reader->zone(), Library::null());
   reader->AddBackRef(object_id, &library, kIsDeserialized);
 
   if ((kind == Snapshot::kScript) && RawObject::IsCreatedFromSnapshot(tags)) {
@@ -1139,7 +1139,7 @@
 
   // Allocate library prefix object.
   LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(
-      reader->isolate(), NEW_OBJECT(LibraryPrefix));
+      reader->zone(), NEW_OBJECT(LibraryPrefix));
   reader->AddBackRef(object_id, &prefix, kIsDeserialized);
 
   // Set the object tags.
@@ -1203,7 +1203,7 @@
 
   // Allocate Namespace object.
   Namespace& ns = Namespace::ZoneHandle(
-      reader->isolate(), NEW_OBJECT(Namespace));
+      reader->zone(), NEW_OBJECT(Namespace));
   reader->AddBackRef(object_id, &ns, kIsDeserialized);
 
   // Set the object tags.
@@ -1366,7 +1366,7 @@
 
   // Allocate context object.
   int32_t num_vars = reader->Read<int32_t>();
-  Context& context = Context::ZoneHandle(reader->isolate());
+  Context& context = Context::ZoneHandle(reader->zone());
   reader->AddBackRef(object_id, &context, kIsDeserialized);
   if (num_vars == 0) {
     context ^= reader->object_store()->empty_context();
@@ -1501,7 +1501,7 @@
 
   // Allocate ApiError object.
   ApiError& api_error =
-      ApiError::ZoneHandle(reader->isolate(), NEW_OBJECT(ApiError));
+      ApiError::ZoneHandle(reader->zone(), NEW_OBJECT(ApiError));
   reader->AddBackRef(object_id, &api_error, kIsDeserialized);
 
   // Set the object tags.
@@ -1547,7 +1547,7 @@
 
   // Allocate LanguageError object.
   LanguageError& language_error =
-      LanguageError::ZoneHandle(reader->isolate(), NEW_OBJECT(LanguageError));
+      LanguageError::ZoneHandle(reader->zone(), NEW_OBJECT(LanguageError));
   reader->AddBackRef(object_id, &language_error, kIsDeserialized);
 
   // Set the object tags.
@@ -1599,7 +1599,7 @@
                                                     intptr_t tags,
                                                     Snapshot::Kind kind) {
   UnhandledException& result = UnhandledException::ZoneHandle(
-      reader->isolate(), NEW_OBJECT(UnhandledException));
+      reader->zone(), NEW_OBJECT(UnhandledException));
   reader->AddBackRef(object_id, &result, kIsDeserialized);
 
   // Set the object tags.
@@ -1658,7 +1658,7 @@
 
   // Create an Instance object or get canonical one if it is a canonical
   // constant.
-  Instance& obj = Instance::ZoneHandle(reader->isolate(), Instance::null());
+  Instance& obj = Instance::ZoneHandle(reader->zone(), Instance::null());
   if (kind == Snapshot::kFull) {
     obj = reader->NewInstance();
   } else {
@@ -1709,7 +1709,7 @@
   int64_t value = reader->Read<int64_t>();
 
   // Create a Mint object or get canonical one if it is a canonical constant.
-  Mint& mint = Mint::ZoneHandle(reader->isolate(), Mint::null());
+  Mint& mint = Mint::ZoneHandle(reader->zone(), Mint::null());
   if (kind == Snapshot::kFull) {
     mint = reader->NewMint(value);
   } else {
@@ -1759,7 +1759,7 @@
   ASSERT(reader != NULL);
 
   // Allocate bigint object.
-  Bigint& obj = Bigint::ZoneHandle(reader->isolate(), NEW_OBJECT(Bigint));
+  Bigint& obj = Bigint::ZoneHandle(reader->zone(), NEW_OBJECT(Bigint));
   reader->AddBackRef(object_id, &obj, kIsDeserialized);
 
   // Set all the object fields.
@@ -1822,7 +1822,7 @@
   double value = reader->ReadDouble();
 
   // Create a Double object or get canonical one if it is a canonical constant.
-  Double& dbl = Double::ZoneHandle(reader->isolate(), Double::null());
+  Double& dbl = Double::ZoneHandle(reader->zone(), Double::null());
   if (kind == Snapshot::kFull) {
     dbl = reader->NewDouble(value);
   } else {
@@ -1889,10 +1889,8 @@
   ASSERT(reader != NULL);
   if (RawObject::IsCanonical(tags)) {
     // Set up canonical string object.
-    Isolate* isolate = reader->isolate();
     ASSERT(reader != NULL);
-    CharacterType* ptr =
-        isolate->current_zone()->Alloc<CharacterType>(len);
+    CharacterType* ptr = reader->zone()->Alloc<CharacterType>(len);
     for (intptr_t i = 0; i < len; i++) {
       ptr[i] = reader->Read<CharacterType>();
     }
@@ -1905,7 +1903,7 @@
     if (len == 0) {
       return;
     }
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     CharacterType* str_addr = StringType::CharAddr(*str_obj, 0);
     for (intptr_t i = 0; i < len; i++) {
       *str_addr = reader->Read<CharacterType>();
@@ -1923,10 +1921,10 @@
   ASSERT(reader != NULL);
   intptr_t len = reader->ReadSmiValue();
   intptr_t hash = reader->ReadSmiValue();
-  String& str_obj = String::Handle(reader->isolate(), String::null());
+  String& str_obj = String::Handle(reader->zone(), String::null());
 
   if (kind == Snapshot::kFull) {
-    ASSERT(reader->isolate()->no_gc_scope_depth() != 0);
+    ASSERT(reader->isolate()->no_safepoint_scope_depth() != 0);
     RawOneByteString* obj = reader->NewOneByteString(len);
     str_obj = obj;
     str_obj.set_tags(tags);
@@ -1953,14 +1951,14 @@
   ASSERT(reader != NULL);
   intptr_t len = reader->ReadSmiValue();
   intptr_t hash = reader->ReadSmiValue();
-  String& str_obj = String::Handle(reader->isolate(), String::null());
+  String& str_obj = String::Handle(reader->zone(), String::null());
 
   if (kind == Snapshot::kFull) {
     RawTwoByteString* obj = reader->NewTwoByteString(len);
     str_obj = obj;
     str_obj.set_tags(tags);
     str_obj.SetHash(hash);
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     uint16_t* raw_ptr = (len > 0)? CharAddr(str_obj, 0) : NULL;
     for (intptr_t i = 0; i < len; i++) {
       ASSERT(CharAddr(str_obj, i) == raw_ptr);  // Will trigger assertions.
@@ -2120,7 +2118,7 @@
   Array* array = reinterpret_cast<Array*>(
       reader->GetBackRef(object_id));
   if (array == NULL) {
-    array = &(Array::ZoneHandle(reader->isolate(),
+    array = &(Array::ZoneHandle(reader->zone(),
                                 NEW_OBJECT_WITH_LEN_SPACE(Array, len, kind)));
     reader->AddBackRef(object_id, array, kIsDeserialized);
   }
@@ -2141,7 +2139,7 @@
   Array* array = reinterpret_cast<Array*>(reader->GetBackRef(object_id));
   if (array == NULL) {
     array = &(Array::ZoneHandle(
-        reader->isolate(),
+        reader->zone(),
         NEW_OBJECT_WITH_LEN_SPACE(ImmutableArray, len, kind)));
     reader->AddBackRef(object_id, array, kIsDeserialized);
   }
@@ -2186,7 +2184,7 @@
 
   // Read the length so that we can determine instance size to allocate.
   GrowableObjectArray& array = GrowableObjectArray::ZoneHandle(
-      reader->isolate(), GrowableObjectArray::null());
+      reader->zone(), GrowableObjectArray::null());
   if (kind == Snapshot::kFull) {
     array = reader->NewGrowableObjectArray();
   } else {
@@ -2230,7 +2228,7 @@
   ASSERT(reader != NULL);
 
   LinkedHashMap& map = LinkedHashMap::ZoneHandle(
-      reader->isolate(), LinkedHashMap::null());
+      reader->zone(), LinkedHashMap::null());
   if (kind == Snapshot::kFull || kind == Snapshot::kScript) {
     // The immutable maps that seed map literals are not yet VM-internal, so
     // we don't reach this.
@@ -2283,7 +2281,7 @@
   float value3 = reader->Read<float>();
 
   // Create a Float32x4 object.
-  Float32x4& simd = Float32x4::ZoneHandle(reader->isolate(),
+  Float32x4& simd = Float32x4::ZoneHandle(reader->zone(),
                                           Float32x4::null());
   if (kind == Snapshot::kFull) {
     simd = reader->NewFloat32x4(value0, value1, value2, value3);
@@ -2329,7 +2327,7 @@
   uint32_t value3 = reader->Read<uint32_t>();
 
   // Create a Float32x4 object.
-  Int32x4& simd = Int32x4::ZoneHandle(reader->isolate(), Int32x4::null());
+  Int32x4& simd = Int32x4::ZoneHandle(reader->zone(), Int32x4::null());
 
   if (kind == Snapshot::kFull) {
     simd = reader->NewInt32x4(value0, value1, value2, value3);
@@ -2373,7 +2371,7 @@
   double value1 = reader->Read<double>();
 
   // Create a Float64x2 object.
-  Float64x2& simd = Float64x2::ZoneHandle(reader->isolate(),
+  Float64x2& simd = Float64x2::ZoneHandle(reader->zone(),
                                           Float64x2::null());
   if (kind == Snapshot::kFull) {
     simd = reader->NewFloat64x2(value0, value1);
@@ -2419,7 +2417,7 @@
 
   intptr_t cid = RawObject::ClassIdTag::decode(tags);
   intptr_t len = reader->ReadSmiValue();
-  TypedData& result = TypedData::ZoneHandle(reader->isolate(),
+  TypedData& result = TypedData::ZoneHandle(reader->zone(),
       (kind == Snapshot::kFull) ? reader->NewTypedData(cid, len)
                                 : TypedData::New(cid, len, HEAP_SPACE(kind)));
   reader->AddBackRef(object_id, &result, kIsDeserialized);
@@ -2434,7 +2432,7 @@
     case kTypedDataInt8ArrayCid:
     case kTypedDataUint8ArrayCid:
     case kTypedDataUint8ClampedArrayCid: {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
       uint8_t* data = reinterpret_cast<uint8_t*>(result.DataAddr(0));
       reader->ReadBytes(data, length_in_bytes);
       break;
@@ -2631,7 +2629,7 @@
                                     Snapshot::Kind kind) {
   uint64_t id = reader->Read<uint64_t>();
 
-  Capability& result = Capability::ZoneHandle(reader->isolate(),
+  Capability& result = Capability::ZoneHandle(reader->zone(),
                                               Capability::New(id));
   reader->AddBackRef(object_id, &result, kIsDeserialized);
   return result.raw();
@@ -2682,7 +2680,7 @@
   uint64_t id = reader->Read<uint64_t>();
   uint64_t origin_id = reader->Read<uint64_t>();
 
-  SendPort& result = SendPort::ZoneHandle(reader->isolate(),
+  SendPort& result = SendPort::ZoneHandle(reader->zone(),
                                           SendPort::New(id, origin_id));
   reader->AddBackRef(object_id, &result, kIsDeserialized);
   return result.raw();
@@ -2709,7 +2707,7 @@
                                     intptr_t tags,
                                     Snapshot::Kind kind) {
   if (kind == Snapshot::kFull) {
-    Stacktrace& result = Stacktrace::ZoneHandle(reader->isolate(),
+    Stacktrace& result = Stacktrace::ZoneHandle(reader->zone(),
                                                 reader->NewStacktrace());
     reader->AddBackRef(object_id, &result, kIsDeserialized);
 
@@ -2774,7 +2772,7 @@
 
   // Allocate JSRegExp object.
   JSRegExp& regex = JSRegExp::ZoneHandle(
-      reader->isolate(), JSRegExp::New(len, HEAP_SPACE(kind)));
+      reader->zone(), JSRegExp::New(len, HEAP_SPACE(kind)));
   reader->AddBackRef(object_id, &regex, kIsDeserialized);
 
   // Set the object tags.
@@ -2827,7 +2825,7 @@
 
   // Allocate the weak property object.
   WeakProperty& weak_property = WeakProperty::ZoneHandle(
-      reader->isolate(), WeakProperty::New(HEAP_SPACE(kind)));
+      reader->zone(), WeakProperty::New(HEAP_SPACE(kind)));
   reader->AddBackRef(object_id, &weak_property, kIsDeserialized);
 
   // Set the object tags.
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
index 5d31fbf..d251935 100644
--- a/runtime/vm/regexp.cc
+++ b/runtime/vm/regexp.cc
@@ -10,9 +10,9 @@
 #include "vm/unibrow-inl.h"
 #include "vm/unicode.h"
 #include "vm/symbols.h"
+#include "vm/thread.h"
 
-#define I (isolate())
-#define CI (compiler->isolate())
+#define Z (zone())
 
 namespace dart {
 
@@ -334,7 +334,7 @@
     current_expansion_factor_ = value;
   }
 
-  Isolate* isolate() const { return isolate_; }
+  Zone* zone() const { return zone_; }
 
   static const intptr_t kNoRegister = -1;
 
@@ -349,7 +349,7 @@
   bool reg_exp_too_big_;
   intptr_t current_expansion_factor_;
   FrequencyCollator frequency_collator_;
-  Isolate* isolate_;
+  Zone* zone_;
 };
 
 
@@ -380,8 +380,8 @@
       specialization_cid_(specialization_cid),
       reg_exp_too_big_(false),
       current_expansion_factor_(1),
-      isolate_(Isolate::Current()) {
-  accept_ = new(I) EndNode(EndNode::ACCEPT, I);
+      zone_(Thread::Current()->zone()) {
+  accept_ = new(Z) EndNode(EndNode::ACCEPT, Z);
 }
 
 
@@ -461,7 +461,7 @@
 // nodes.  It normalizes the state of the code generator to ensure we can
 // generate generic code.
 intptr_t Trace::FindAffectedRegisters(OutSet* affected_registers,
-                                      Isolate* isolate) {
+                                      Zone* zone) {
   intptr_t max_register = RegExpCompiler::kNoRegister;
   for (DeferredAction* action = actions_;
        action != NULL;
@@ -469,10 +469,10 @@
     if (action->action_type() == ActionNode::CLEAR_CAPTURES) {
       Interval range = static_cast<DeferredClearCaptures*>(action)->range();
       for (intptr_t i = range.from(); i <= range.to(); i++)
-        affected_registers->Set(i, isolate);
+        affected_registers->Set(i, zone);
       if (range.to() > max_register) max_register = range.to();
     } else {
-      affected_registers->Set(action->reg(), isolate);
+      affected_registers->Set(action->reg(), zone);
       if (action->reg() > max_register) max_register = action->reg();
     }
   }
@@ -503,7 +503,7 @@
                                    const OutSet& affected_registers,
                                    OutSet* registers_to_pop,
                                    OutSet* registers_to_clear,
-                                   Isolate* isolate) {
+                                   Zone* zone) {
   for (intptr_t reg = 0; reg <= max_register; reg++) {
     if (!affected_registers.Get(reg)) {
       continue;
@@ -595,9 +595,9 @@
     // Prepare for the undo-action (e.g., push if it's going to be popped).
     if (undo_action == ACTION_RESTORE) {
       assembler->PushRegister(reg);
-      registers_to_pop->Set(reg, isolate);
+      registers_to_pop->Set(reg, zone);
     } else if (undo_action == ACTION_CLEAR) {
-      registers_to_clear->Set(reg, isolate);
+      registers_to_clear->Set(reg, zone);
     }
     // Perform the chronologically last action (or accumulated increment)
     // for the register.
@@ -642,8 +642,8 @@
     // position which we may need to emit here.
     assembler->PushCurrentPosition();
   }
-
-  intptr_t max_register = FindAffectedRegisters(&affected_registers, CI);
+  Zone* zone = successor->zone();
+  intptr_t max_register = FindAffectedRegisters(&affected_registers, zone);
   OutSet registers_to_pop;
   OutSet registers_to_clear;
   PerformDeferredActions(assembler,
@@ -651,7 +651,7 @@
                          affected_registers,
                          &registers_to_pop,
                          &registers_to_clear,
-                         CI);
+                         zone);
   if (cp_offset_ != 0) {
     assembler->AdvanceCurrentPosition(cp_offset_);
   }
@@ -728,9 +728,9 @@
 }
 
 
-void GuardedAlternative::AddGuard(Guard* guard, Isolate* isolate) {
+void GuardedAlternative::AddGuard(Guard* guard, Zone* zone) {
   if (guards_ == NULL)
-    guards_ = new(isolate) ZoneGrowableArray<Guard*>(1);
+    guards_ = new(zone) ZoneGrowableArray<Guard*>(1);
   guards_->Add(guard);
 }
 
@@ -739,7 +739,7 @@
                                     intptr_t val,
                                     RegExpNode* on_success) {
   ActionNode* result =
-      new(on_success->isolate()) ActionNode(SET_REGISTER, on_success);
+      new(on_success->zone()) ActionNode(SET_REGISTER, on_success);
   result->data_.u_store_register.reg = reg;
   result->data_.u_store_register.value = val;
   return result;
@@ -749,7 +749,7 @@
 ActionNode* ActionNode::IncrementRegister(intptr_t reg,
                                           RegExpNode* on_success) {
   ActionNode* result =
-      new(on_success->isolate()) ActionNode(INCREMENT_REGISTER, on_success);
+      new(on_success->zone()) ActionNode(INCREMENT_REGISTER, on_success);
   result->data_.u_increment_register.reg = reg;
   return result;
 }
@@ -759,7 +759,7 @@
                                       bool is_capture,
                                       RegExpNode* on_success) {
   ActionNode* result =
-      new(on_success->isolate()) ActionNode(STORE_POSITION, on_success);
+      new(on_success->zone()) ActionNode(STORE_POSITION, on_success);
   result->data_.u_position_register.reg = reg;
   result->data_.u_position_register.is_capture = is_capture;
   return result;
@@ -769,7 +769,7 @@
 ActionNode* ActionNode::ClearCaptures(Interval range,
                                       RegExpNode* on_success) {
   ActionNode* result =
-      new(on_success->isolate()) ActionNode(CLEAR_CAPTURES, on_success);
+      new(on_success->zone()) ActionNode(CLEAR_CAPTURES, on_success);
   result->data_.u_clear_captures.range_from = range.from();
   result->data_.u_clear_captures.range_to = range.to();
   return result;
@@ -780,7 +780,7 @@
                                       intptr_t position_reg,
                                       RegExpNode* on_success) {
   ActionNode* result =
-      new(on_success->isolate()) ActionNode(BEGIN_SUBMATCH, on_success);
+      new(on_success->zone()) ActionNode(BEGIN_SUBMATCH, on_success);
   result->data_.u_submatch.stack_pointer_register = stack_reg;
   result->data_.u_submatch.current_position_register = position_reg;
   return result;
@@ -793,7 +793,7 @@
                                                 intptr_t clear_register_from,
                                                 RegExpNode* on_success) {
   ActionNode* result =
-      new(on_success->isolate()) ActionNode(POSITIVE_SUBMATCH_SUCCESS,
+      new(on_success->zone()) ActionNode(POSITIVE_SUBMATCH_SUCCESS,
                                             on_success);
   result->data_.u_submatch.stack_pointer_register = stack_reg;
   result->data_.u_submatch.current_position_register = position_reg;
@@ -808,7 +808,7 @@
                                         intptr_t repetition_limit,
                                         RegExpNode* on_success) {
   ActionNode* result =
-      new(on_success->isolate()) ActionNode(EMPTY_MATCH_CHECK, on_success);
+      new(on_success->zone()) ActionNode(EMPTY_MATCH_CHECK, on_success);
   result->data_.u_empty_match_check.start_register = start_register;
   result->data_.u_empty_match_check.repetition_register = repetition_register;
   result->data_.u_empty_match_check.repetition_limit = repetition_limit;
@@ -878,7 +878,7 @@
 }
 
 
-static inline bool EmitSimpleCharacter(Isolate* isolate,
+static inline bool EmitSimpleCharacter(Zone* zone,
                                        RegExpCompiler* compiler,
                                        uint16_t c,
                                        BlockLabel* on_failure,
@@ -901,7 +901,7 @@
 
 // Only emits non-letters (things that don't have case).  Only used for case
 // independent matches.
-static inline bool EmitAtomNonLetter(Isolate* isolate,
+static inline bool EmitAtomNonLetter(Zone* zone,
                                      RegExpCompiler* compiler,
                                      uint16_t c,
                                      BlockLabel* on_failure,
@@ -974,7 +974,7 @@
 }
 
 
-typedef bool EmitCharacterFunction(Isolate* isolate,
+typedef bool EmitCharacterFunction(Zone* zone,
                                    RegExpCompiler* compiler,
                                    uint16_t c,
                                    BlockLabel* on_failure,
@@ -984,7 +984,7 @@
 
 // Only emits letters (things that have case).  Only used for case independent
 // matches.
-static inline bool EmitAtomLetter(Isolate* isolate,
+static inline bool EmitAtomLetter(Zone* zone,
                                   RegExpCompiler* compiler,
                                   uint16_t c,
                                   BlockLabel* on_failure,
@@ -1123,7 +1123,7 @@
   }
   // TODO(erikcorry): Cache these.
   const TypedData& ba = TypedData::ZoneHandle(
-        masm->isolate(),
+        masm->zone(),
         TypedData::New(kTypedDataUint8ArrayCid, kSize, Heap::kOld));
   for (intptr_t i = 0; i < kSize; i++) {
     ba.SetUint8(i, templ[i]);
@@ -1395,7 +1395,7 @@
                           intptr_t cp_offset,
                           bool check_offset,
                           bool preloaded,
-                          Isolate* isolate) {
+                          Zone* zone) {
   ZoneGrowableArray<CharacterRange>* ranges = cc->ranges();
   if (!CharacterRange::IsCanonical(ranges)) {
     CharacterRange::Canonicalize(ranges);
@@ -1469,7 +1469,7 @@
   // was already one there we fall through for success on that entry.
   // Subsequent entries have alternating meaning (success/failure).
   ZoneGrowableArray<int>* range_boundaries =
-      new(isolate) ZoneGrowableArray<int>(last_valid_range);
+      new(zone) ZoneGrowableArray<int>(last_valid_range);
 
   bool zeroth_entry_is_failure = !cc->is_negated();
 
@@ -2195,7 +2195,7 @@
   // Only some of the nodes survived the filtering.  We need to rebuild the
   // alternatives list.
   ZoneGrowableArray<GuardedAlternative>* new_alternatives =
-      new(I) ZoneGrowableArray<GuardedAlternative>(surviving);
+      new(Z) ZoneGrowableArray<GuardedAlternative>(surviving);
   for (intptr_t i = 0; i < choice_count; i++) {
     RegExpNode* replacement =
         (*alternatives_)[i].node()->FilterOneByte(depth - 1, ignore_case);
@@ -2357,7 +2357,7 @@
                                    not_at_start));
     if (eats_at_least >= 1) {
       BoyerMooreLookahead* bm =
-          new(I) BoyerMooreLookahead(eats_at_least, compiler, I);
+          new(Z) BoyerMooreLookahead(eats_at_least, compiler, Z);
       FillInBMInfo(0, kRecursionBudget, bm, not_at_start);
       if (bm->at(0)->is_non_word())
         next_is_word_character = Trace::FALSE_VALUE;
@@ -2569,7 +2569,7 @@
             break;
         }
         if (emit_function != NULL) {
-          bool bound_checked = emit_function(I,
+          bool bound_checked = emit_function(Z,
                                              compiler,
                                              quarks->At(j),
                                              backtrack,
@@ -2592,7 +2592,7 @@
                       cp_offset,
                       *checked_up_to < cp_offset,
                       preloaded,
-                      I);
+                      Z);
         UpdateBoundsCheck(cp_offset, checked_up_to);
       }
     }
@@ -2715,7 +2715,7 @@
       ZoneGrowableArray<CharacterRange>* ranges = cc->ranges();
       intptr_t range_count = ranges->length();
       for (intptr_t j = 0; j < range_count; j++) {
-        (*ranges)[j].AddCaseEquivalents(ranges, is_one_byte, I);
+        (*ranges)[j].AddCaseEquivalents(ranges, is_one_byte, Z);
       }
     }
   }
@@ -2946,7 +2946,7 @@
 
 
 BoyerMooreLookahead::BoyerMooreLookahead(
-    intptr_t length, RegExpCompiler* compiler, Isolate* isolate)
+    intptr_t length, RegExpCompiler* compiler, Zone* zone)
     : length_(length),
       compiler_(compiler) {
   if (compiler->one_byte()) {
@@ -2954,9 +2954,9 @@
   } else {
     max_char_ = Utf16::kMaxCodeUnit;
   }
-  bitmaps_ = new(isolate) ZoneGrowableArray<BoyerMoorePositionInfo*>(length);
+  bitmaps_ = new(zone) ZoneGrowableArray<BoyerMoorePositionInfo*>(length);
   for (intptr_t i = 0; i < length; i++) {
-    bitmaps_->Add(new(isolate) BoyerMoorePositionInfo(isolate));
+    bitmaps_->Add(new(zone) BoyerMoorePositionInfo(zone));
   }
 }
 
@@ -3121,7 +3121,7 @@
   }
 
   const TypedData& boolean_skip_table = TypedData::ZoneHandle(
-        compiler_->isolate(),
+        compiler_->zone(),
         TypedData::New(kTypedDataUint8ArrayCid, kSize, Heap::kOld));
   intptr_t skip_distance = GetSkipTable(
       min_lookahead, max_lookahead, boolean_skip_table);
@@ -3410,7 +3410,7 @@
                                     kRecursionBudget,
                                     false));
     if (eats_at_least >= 1) {
-      bm = new(I) BoyerMooreLookahead(eats_at_least, compiler, I);
+      bm = new(Z) BoyerMooreLookahead(eats_at_least, compiler, Z);
       GuardedAlternative alt0 = alternatives_->At(0);
       alt0.node()->FillInBMInfo(0, kRecursionBudget, bm, false);
     }
@@ -3948,23 +3948,26 @@
 // -------------------------------------------------------------------
 // Tree to graph conversion
 
+// The zone in which we allocate graph nodes.
+#define OZ (on_success->zone())
+
 RegExpNode* RegExpAtom::ToNode(RegExpCompiler* compiler,
                                RegExpNode* on_success) {
   ZoneGrowableArray<TextElement>* elms =
-      new(CI) ZoneGrowableArray<TextElement>(1);
+      new(OZ) ZoneGrowableArray<TextElement>(1);
   elms->Add(TextElement::Atom(this));
-  return new(CI) TextNode(elms, on_success);
+  return new(OZ) TextNode(elms, on_success);
 }
 
 
 RegExpNode* RegExpText::ToNode(RegExpCompiler* compiler,
                                RegExpNode* on_success) {
   ZoneGrowableArray<TextElement>* elms =
-      new(CI) ZoneGrowableArray<TextElement>(1);
+      new(OZ) ZoneGrowableArray<TextElement>(1);
   for (intptr_t  i = 0; i < elements()->length(); i++) {
     elms->Add(elements()->At(i));
   }
-  return new(CI) TextNode(elms, on_success);
+  return new(OZ) TextNode(elms, on_success);
 }
 
 
@@ -4061,7 +4064,7 @@
 
 RegExpNode* RegExpCharacterClass::ToNode(RegExpCompiler* compiler,
                                          RegExpNode* on_success) {
-  return new(CI) TextNode(this, on_success);
+  return new(OZ) TextNode(this, on_success);
 }
 
 
@@ -4070,7 +4073,7 @@
   ZoneGrowableArray<RegExpTree*>* alternatives = this->alternatives();
   intptr_t length = alternatives->length();
   ChoiceNode* result =
-      new(CI) ChoiceNode(length, CI);
+      new(OZ) ChoiceNode(length, OZ);
   for (intptr_t i = 0; i < length; i++) {
     GuardedAlternative alternative(alternatives->At(i)->ToNode(compiler,
                                                                on_success));
@@ -4165,7 +4168,7 @@
   intptr_t body_start_reg = RegExpCompiler::kNoRegister;
   Interval capture_registers = body->CaptureRegisters();
   bool needs_capture_clearing = !capture_registers.is_empty();
-  Isolate* isolate = compiler->isolate();
+  Zone* zone = compiler->zone();
 
   if (body_can_be_empty) {
     body_start_reg = compiler->AllocateRegister();
@@ -4197,7 +4200,7 @@
         // Unroll the optional matches up to max.
         RegExpNode* answer = on_success;
         for (intptr_t i = 0; i < max; i++) {
-          ChoiceNode* alternation = new(isolate) ChoiceNode(2, isolate);
+          ChoiceNode* alternation = new(zone) ChoiceNode(2, zone);
           if (is_greedy) {
             alternation->AddAlternative(
                 GuardedAlternative(body->ToNode(compiler, answer)));
@@ -4220,8 +4223,8 @@
   intptr_t reg_ctr = needs_counter
       ? compiler->AllocateRegister()
       : RegExpCompiler::kNoRegister;
-  LoopChoiceNode* center = new(isolate) LoopChoiceNode(body->min_match() == 0,
-                                                       isolate);
+  LoopChoiceNode* center = new(zone) LoopChoiceNode(body->min_match() == 0,
+                                                       zone);
   if (not_at_start) center->set_not_at_start();
   RegExpNode* loop_return = needs_counter
       ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center))
@@ -4247,13 +4250,13 @@
   GuardedAlternative body_alt(body_node);
   if (has_max) {
     Guard* body_guard =
-        new(isolate) Guard(reg_ctr, Guard::LT, max);
-    body_alt.AddGuard(body_guard, isolate);
+        new(zone) Guard(reg_ctr, Guard::LT, max);
+    body_alt.AddGuard(body_guard, zone);
   }
   GuardedAlternative rest_alt(on_success);
   if (has_min) {
-    Guard* rest_guard = new(isolate) Guard(reg_ctr, Guard::GEQ, min);
-    rest_alt.AddGuard(rest_guard, isolate);
+    Guard* rest_guard = new(zone) Guard(reg_ctr, Guard::GEQ, min);
+    rest_alt.AddGuard(rest_guard, zone);
   }
   if (is_greedy) {
     center->AddLoopAlternative(body_alt);
@@ -4290,7 +4293,7 @@
       intptr_t stack_pointer_register = compiler->AllocateRegister();
       intptr_t position_register = compiler->AllocateRegister();
       // The ChoiceNode to distinguish between a newline and end-of-input.
-      ChoiceNode* result = new ChoiceNode(2, on_success->isolate());
+      ChoiceNode* result = new ChoiceNode(2, on_success->zone());
       // Create a newline atom.
       ZoneGrowableArray<CharacterRange>* newline_ranges =
           new ZoneGrowableArray<CharacterRange>(3);
@@ -4324,7 +4327,7 @@
 
 RegExpNode* RegExpBackReference::ToNode(RegExpCompiler* compiler,
                                         RegExpNode* on_success) {
-  return new(CI)
+  return new(OZ)
       BackReferenceNode(RegExpCapture::StartRegister(index()),
                         RegExpCapture::EndRegister(index()),
                         on_success);
@@ -4376,15 +4379,15 @@
     GuardedAlternative body_alt(
         body()->ToNode(
             compiler,
-            success = new(CI) NegativeSubmatchSuccess(stack_pointer_register,
+            success = new(OZ) NegativeSubmatchSuccess(stack_pointer_register,
                                                       position_register,
                                                       register_count,
                                                       register_start,
-                                                      CI)));
+                                                      OZ)));
     ChoiceNode* choice_node =
-        new(CI) NegativeLookaheadChoiceNode(body_alt,
+        new(OZ) NegativeLookaheadChoiceNode(body_alt,
                                             GuardedAlternative(on_success),
-                                            CI);
+                                            OZ);
     return ActionNode::BeginSubmatch(stack_pointer_register,
                                      position_register,
                                      choice_node);
@@ -4499,7 +4502,7 @@
 void CharacterRange::AddCaseEquivalents(
                         ZoneGrowableArray<CharacterRange>* ranges,
                         bool is_one_byte,
-                        Isolate* isolate) {
+                        Zone* zone) {
   uint16_t bottom = from();
   uint16_t top = to();
   if (is_one_byte && !RangeContainsLatin1Equivalents(*this)) {
@@ -4753,12 +4756,12 @@
 }
 
 
-void OutSet::Set(unsigned value, Isolate* isolate) {
+void OutSet::Set(unsigned value, Zone* zone) {
   if (value < kFirstLimit) {
     first_ |= (1 << value);
   } else {
     if (remaining_ == NULL)
-      remaining_ = new(isolate) ZoneGrowableArray<unsigned>(1);
+      remaining_ = new(zone) ZoneGrowableArray<unsigned>(1);
 
     bool remaining_contains_value = ArrayContains(remaining_, value);
     if (remaining_->is_empty() || !remaining_contains_value) {
@@ -4977,14 +4980,14 @@
     RegExpCompileData* data,
     const ParsedFunction* parsed_function,
     const ZoneGrowableArray<const ICData*>& ic_data_array) {
-  Isolate* isolate = Isolate::Current();
+  Zone* zone = Thread::Current()->zone();
 
   const Function& function = parsed_function->function();
   const intptr_t specialization_cid = function.regexp_cid();
   const bool is_one_byte = (specialization_cid == kOneByteStringCid ||
                             specialization_cid == kExternalOneByteStringCid);
-  JSRegExp& regexp = JSRegExp::Handle(isolate, function.regexp());
-  const String& pattern = String::Handle(isolate, regexp.pattern());
+  JSRegExp& regexp = JSRegExp::Handle(zone, function.regexp());
+  const String& pattern = String::Handle(zone, regexp.pattern());
 
   ASSERT(!regexp.IsNull());
   ASSERT(!pattern.IsNull());
@@ -5020,7 +5023,7 @@
         RegExpQuantifier::ToNode(0,
                                  RegExpTree::kInfinity,
                                  false,
-                                 new(isolate) RegExpCharacterClass('*'),
+                                 new(zone) RegExpCharacterClass('*'),
                                  &compiler,
                                  captured_body,
                                  data->contains_anchor);
@@ -5028,11 +5031,11 @@
     if (data->contains_anchor) {
       // Unroll loop once, to take care of the case that might start
       // at the start of input.
-      ChoiceNode* first_step_node = new(isolate) ChoiceNode(2, isolate);
+      ChoiceNode* first_step_node = new(zone) ChoiceNode(2, zone);
       first_step_node->AddAlternative(GuardedAlternative(captured_body));
       first_step_node->AddAlternative(GuardedAlternative(
-          new(isolate) TextNode(
-              new(isolate) RegExpCharacterClass('*'), loop_node)));
+          new(zone) TextNode(
+              new(zone) RegExpCharacterClass('*'), loop_node)));
       node = first_step_node;
     } else {
       node = loop_node;
@@ -5047,7 +5050,7 @@
     }
   }
 
-  if (node == NULL) node = new(isolate) EndNode(EndNode::BACKTRACK, isolate);
+  if (node == NULL) node = new(zone) EndNode(EndNode::BACKTRACK, zone);
   data->node = node;
   Analysis analysis(ignore_case, is_one_byte);
   analysis.EnsureAnalyzed(node);
@@ -5059,11 +5062,11 @@
   // Native regexp implementation.
 
   IRRegExpMacroAssembler* macro_assembler =
-      new(isolate) IRRegExpMacroAssembler(specialization_cid,
+      new(zone) IRRegExpMacroAssembler(specialization_cid,
                                           data->capture_count,
                                           parsed_function,
                                           ic_data_array,
-                                          isolate);
+                                          zone);
 
   // Inserted here, instead of in Assembler, because it depends on information
   // in the AST that isn't replicated in the Node structure.
@@ -5095,17 +5098,17 @@
 }
 
 
-static void CreateSpecializedFunction(Isolate* isolate,
+static void CreateSpecializedFunction(Zone* zone,
                                       const JSRegExp& regexp,
                                       intptr_t specialization_cid,
                                       const Object& owner) {
   const intptr_t kParamCount = RegExpMacroAssembler::kParamCount;
 
-  Function& fn = Function::Handle(isolate, Function::New(
+  Function& fn = Function::Handle(zone, Function::New(
       // Append the regexp pattern to the function name.
-      String::Handle(isolate, Symbols::New(
-          String::Handle(isolate, String::Concat(
-              String::Handle(isolate, String::Concat(
+      String::Handle(zone, Symbols::New(
+          String::Handle(zone, String::Concat(
+              String::Handle(zone, String::Concat(
                   Symbols::Irregexp(),
                   Symbols::ColonSpace(), Heap::kOld)),
               String::Handle(regexp.pattern()), Heap::kOld)))),
@@ -5120,15 +5123,15 @@
 
   // TODO(zerny): Share these arrays between all irregexp functions.
   fn.set_num_fixed_parameters(kParamCount);
-  fn.set_parameter_types(Array::Handle(isolate, Array::New(kParamCount,
+  fn.set_parameter_types(Array::Handle(zone, Array::New(kParamCount,
                                                            Heap::kOld)));
-  fn.set_parameter_names(Array::Handle(isolate, Array::New(kParamCount,
+  fn.set_parameter_names(Array::Handle(zone, Array::New(kParamCount,
                                                            Heap::kOld)));
-  fn.SetParameterTypeAt(0, Type::Handle(isolate, Type::DynamicType()));
+  fn.SetParameterTypeAt(0, Type::Handle(zone, Type::DynamicType()));
   fn.SetParameterNameAt(0, Symbols::string_param());
-  fn.SetParameterTypeAt(1, Type::Handle(isolate, Type::DynamicType()));
+  fn.SetParameterTypeAt(1, Type::Handle(zone, Type::DynamicType()));
   fn.SetParameterNameAt(1, Symbols::start_index_param());
-  fn.set_result_type(Type::Handle(isolate, Type::ArrayType()));
+  fn.set_result_type(Type::Handle(zone, Type::ArrayType()));
 
   // Cache the result.
   regexp.set_function(specialization_cid, fn);
@@ -5141,7 +5144,7 @@
 }
 
 
-RawJSRegExp* RegExpEngine::CreateJSRegExp(Isolate* isolate,
+RawJSRegExp* RegExpEngine::CreateJSRegExp(Zone* zone,
                                           const String& pattern,
                                           bool multi_line,
                                           bool ignore_case) {
@@ -5161,14 +5164,14 @@
   regexp.set_is_complex();
   regexp.set_is_global();   // All dart regexps are global.
 
-  const Library& lib = Library::Handle(isolate, Library::CoreLibrary());
+  const Library& lib = Library::Handle(zone, Library::CoreLibrary());
   const Class& owner = Class::Handle(
-      isolate, lib.LookupClass(Symbols::RegExp()));
+      zone, lib.LookupClass(Symbols::RegExp()));
 
-  CreateSpecializedFunction(isolate, regexp, kOneByteStringCid, owner);
-  CreateSpecializedFunction(isolate, regexp, kTwoByteStringCid, owner);
-  CreateSpecializedFunction(isolate, regexp, kExternalOneByteStringCid, owner);
-  CreateSpecializedFunction(isolate, regexp, kExternalTwoByteStringCid, owner);
+  CreateSpecializedFunction(zone, regexp, kOneByteStringCid, owner);
+  CreateSpecializedFunction(zone, regexp, kTwoByteStringCid, owner);
+  CreateSpecializedFunction(zone, regexp, kExternalOneByteStringCid, owner);
+  CreateSpecializedFunction(zone, regexp, kExternalTwoByteStringCid, owner);
 
   return regexp.raw();
 }
diff --git a/runtime/vm/regexp.h b/runtime/vm/regexp.h
index 91e244a..e0808d6 100644
--- a/runtime/vm/regexp.h
+++ b/runtime/vm/regexp.h
@@ -51,12 +51,12 @@
   bool IsSingleton() const { return (from_ == to_); }
   void AddCaseEquivalents(ZoneGrowableArray<CharacterRange>* ranges,
                           bool is_one_byte,
-                          Isolate* isolate);
+                          Zone* zone);
   static void Split(ZoneGrowableArray<CharacterRange>* base,
                     GrowableArray<const intptr_t> overlay,
                     ZoneGrowableArray<CharacterRange>** included,
                     ZoneGrowableArray<CharacterRange>** excluded,
-                    Isolate* isolate);
+                    Zone* zone);
   // Whether a range list is in canonical form: Ranges ordered by from value,
   // and ranges non-overlapping and non-adjacent.
   static bool IsCanonical(ZoneGrowableArray<CharacterRange>* ranges);
@@ -84,7 +84,7 @@
 class OutSet: public ZoneAllocated {
  public:
   OutSet() : first_(0), remaining_(NULL), successors_(NULL) { }
-  OutSet* Extend(unsigned value, Isolate* isolate);
+  OutSet* Extend(unsigned value, Zone* zone);
   bool Get(unsigned value) const;
   static const unsigned kFirstLimit = 32;
 
@@ -92,7 +92,7 @@
   // Destructively set a value in this set.  In most cases you want
   // to use Extend instead to ensure that only one instance exists
   // that contains the same values.
-  void Set(unsigned value, Isolate* isolate);
+  void Set(unsigned value, Zone* zone);
 
   // The successors are a list of sets that contain the same values
   // as this set and the one more value that is not present in this
@@ -300,8 +300,8 @@
 
 class RegExpNode: public ZoneAllocated {
  public:
-  explicit RegExpNode(Isolate* isolate)
-  : replacement_(NULL), trace_count_(0), isolate_(isolate) {
+  explicit RegExpNode(Zone* zone)
+  : replacement_(NULL), trace_count_(0), zone_(zone) {
     bm_info_[0] = bm_info_[1] = NULL;
   }
   virtual ~RegExpNode();
@@ -398,7 +398,7 @@
     return bm_info_[not_at_start ? 1 : 0];
   }
 
-  Isolate* isolate() const { return isolate_; }
+  Zone* zone() const { return zone_; }
 
  protected:
   enum LimitResult { DONE, CONTINUE };
@@ -421,7 +421,7 @@
   // deferred operations in the current trace and generating a goto.
   intptr_t trace_count_;
   BoyerMooreLookahead* bm_info_[2];
-  Isolate* isolate_;
+  Zone* zone_;
 };
 
 
@@ -460,7 +460,7 @@
 class SeqRegExpNode: public RegExpNode {
  public:
   explicit SeqRegExpNode(RegExpNode* on_success)
-      : RegExpNode(on_success->isolate()), on_success_(on_success) { }
+      : RegExpNode(on_success->zone()), on_success_(on_success) { }
   RegExpNode* on_success() { return on_success_; }
   void set_on_success(RegExpNode* node) { on_success_ = node; }
   virtual RegExpNode* FilterOneByte(intptr_t depth, bool ignore_case);
@@ -577,7 +577,7 @@
   TextNode(RegExpCharacterClass* that,
            RegExpNode* on_success)
       : SeqRegExpNode(on_success),
-        elms_(new(isolate()) ZoneGrowableArray<TextElement>(1)) {
+        elms_(new(zone()) ZoneGrowableArray<TextElement>(1)) {
     elms_->Add(TextElement::CharClass(that));
   }
   virtual void Accept(NodeVisitor* visitor);
@@ -632,20 +632,20 @@
     AFTER_NEWLINE
   };
   static AssertionNode* AtEnd(RegExpNode* on_success) {
-    return new(on_success->isolate()) AssertionNode(AT_END, on_success);
+    return new(on_success->zone()) AssertionNode(AT_END, on_success);
   }
   static AssertionNode* AtStart(RegExpNode* on_success) {
-    return new(on_success->isolate()) AssertionNode(AT_START, on_success);
+    return new(on_success->zone()) AssertionNode(AT_START, on_success);
   }
   static AssertionNode* AtBoundary(RegExpNode* on_success) {
-    return new(on_success->isolate()) AssertionNode(AT_BOUNDARY, on_success);
+    return new(on_success->zone()) AssertionNode(AT_BOUNDARY, on_success);
   }
   static AssertionNode* AtNonBoundary(RegExpNode* on_success) {
-    return new(on_success->isolate()) AssertionNode(AT_NON_BOUNDARY,
+    return new(on_success->zone()) AssertionNode(AT_NON_BOUNDARY,
                                                     on_success);
   }
   static AssertionNode* AfterNewline(RegExpNode* on_success) {
-    return new(on_success->isolate()) AssertionNode(AFTER_NEWLINE, on_success);
+    return new(on_success->zone()) AssertionNode(AFTER_NEWLINE, on_success);
   }
   virtual void Accept(NodeVisitor* visitor);
   virtual void Emit(RegExpCompiler* compiler, Trace* trace);
@@ -708,8 +708,8 @@
 class EndNode: public RegExpNode {
  public:
   enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS };
-  explicit EndNode(Action action, Isolate* isolate)
-      : RegExpNode(isolate), action_(action) { }
+  explicit EndNode(Action action, Zone* zone)
+      : RegExpNode(zone), action_(action) { }
   virtual void Accept(NodeVisitor* visitor);
   virtual void Emit(RegExpCompiler* compiler, Trace* trace);
   virtual intptr_t EatsAtLeast(intptr_t still_to_find,
@@ -741,8 +741,8 @@
                           intptr_t position_reg,
                           intptr_t clear_capture_count,
                           intptr_t clear_capture_start,
-                          Isolate* isolate)
-      : EndNode(NEGATIVE_SUBMATCH_SUCCESS, isolate),
+                          Zone* zone)
+      : EndNode(NEGATIVE_SUBMATCH_SUCCESS, zone),
         stack_pointer_register_(stack_pointer_reg),
         current_position_register_(position_reg),
         clear_capture_count_(clear_capture_count),
@@ -778,7 +778,7 @@
 class GuardedAlternative {
  public:
   explicit GuardedAlternative(RegExpNode* node) : node_(node), guards_(NULL) { }
-  void AddGuard(Guard* guard, Isolate* isolate);
+  void AddGuard(Guard* guard, Zone* zone);
   RegExpNode* node() { return node_; }
   void set_node(RegExpNode* node) { node_ = node; }
   ZoneGrowableArray<Guard*>* guards() { return guards_; }
@@ -796,9 +796,9 @@
 
 class ChoiceNode: public RegExpNode {
  public:
-  explicit ChoiceNode(intptr_t expected_size, Isolate* isolate)
-      : RegExpNode(isolate),
-        alternatives_(new(isolate)
+  explicit ChoiceNode(intptr_t expected_size, Zone* zone)
+      : RegExpNode(zone),
+        alternatives_(new(zone)
                       ZoneGrowableArray<GuardedAlternative>(expected_size)),
         not_at_start_(false),
         being_calculated_(false) { }
@@ -879,8 +879,8 @@
  public:
   explicit NegativeLookaheadChoiceNode(GuardedAlternative this_must_fail,
                                        GuardedAlternative then_do_this,
-                                       Isolate* isolate)
-      : ChoiceNode(2, isolate) {
+                                       Zone* zone)
+      : ChoiceNode(2, zone) {
     AddAlternative(this_must_fail);
     AddAlternative(then_do_this);
   }
@@ -912,8 +912,8 @@
 
 class LoopChoiceNode: public ChoiceNode {
  public:
-  explicit LoopChoiceNode(bool body_can_be_zero_length, Isolate* isolate)
-      : ChoiceNode(2, isolate),
+  explicit LoopChoiceNode(bool body_can_be_zero_length, Zone* zone)
+      : ChoiceNode(2, zone),
         loop_node_(NULL),
         continue_node_(NULL),
         body_can_be_zero_length_(body_can_be_zero_length) { }
@@ -996,8 +996,8 @@
 
 class BoyerMoorePositionInfo : public ZoneAllocated {
  public:
-  explicit BoyerMoorePositionInfo(Isolate* isolate)
-      : map_(new(isolate) ZoneGrowableArray<bool>(kMapSize)),
+  explicit BoyerMoorePositionInfo(Zone* zone)
+      : map_(new(zone) ZoneGrowableArray<bool>(kMapSize)),
         map_count_(0),
         w_(kNotYet),
         s_(kNotYet),
@@ -1034,7 +1034,7 @@
 class BoyerMooreLookahead : public ZoneAllocated{
  public:
   BoyerMooreLookahead(intptr_t length, RegExpCompiler* compiler,
-                      Isolate* Isolate);
+                      Zone* Zone);
 
   intptr_t length() { return length_; }
   intptr_t max_char() { return max_char_; }
@@ -1244,13 +1244,13 @@
   void AdvanceCurrentPositionInTrace(intptr_t by, RegExpCompiler* compiler);
 
  private:
-  intptr_t FindAffectedRegisters(OutSet* affected_registers, Isolate* isolate);
+  intptr_t FindAffectedRegisters(OutSet* affected_registers, Zone* zone);
   void PerformDeferredActions(RegExpMacroAssembler* macro,
                               intptr_t max_register,
                               const OutSet& affected_registers,
                               OutSet* registers_to_pop,
                               OutSet* registers_to_clear,
-                              Isolate* isolate);
+                              Zone* zone);
   void RestoreAffectedRegisters(RegExpMacroAssembler* macro,
                                 intptr_t max_register,
                                 const OutSet& registers_to_pop,
@@ -1402,7 +1402,7 @@
       const ZoneGrowableArray<const ICData*>& ic_data_array);
 
   static RawJSRegExp* CreateJSRegExp(
-      Isolate* isolate,
+      Zone* zone,
       const String& pattern,
       bool multi_line,
       bool ignore_case);
diff --git a/runtime/vm/regexp_assembler.cc b/runtime/vm/regexp_assembler.cc
index 46a9b21..e4e3247 100644
--- a/runtime/vm/regexp_assembler.cc
+++ b/runtime/vm/regexp_assembler.cc
@@ -16,14 +16,14 @@
 #include "vm/unibrow-inl.h"
 #include "vm/unicode.h"
 
-#define I isolate()
+#define Z zone()
 
 // Debugging output macros. TAG() is called at the head of each interesting
 // function and prints its name during execution if irregexp tracing is enabled.
 #define TAG() if (FLAG_trace_irregexp) { TAG_(); }
 #define TAG_() \
   Print(PushArgument( \
-    Bind(new(I) ConstantInstr(String::ZoneHandle(I, String::Concat( \
+    Bind(new(Z) ConstantInstr(String::ZoneHandle(Z, String::Concat( \
         String::Handle(String::New("TAG: ")), \
         String::Handle(String::New(__FUNCTION__)), Heap::kOld))))));
 
@@ -68,10 +68,10 @@
  * to matches_param_ on successful match.
  */
 
-RegExpMacroAssembler::RegExpMacroAssembler(Isolate* isolate)
+RegExpMacroAssembler::RegExpMacroAssembler(Zone* zone)
   : slow_safe_compiler_(false),
     global_mode_(NOT_GLOBAL),
-    isolate_(isolate) {
+    zone_(zone) {
 }
 
 
@@ -84,8 +84,8 @@
     intptr_t capture_count,
     const ParsedFunction* parsed_function,
     const ZoneGrowableArray<const ICData*>& ic_data_array,
-    Isolate* isolate)
-    : RegExpMacroAssembler(isolate),
+    Zone* zone)
+    : RegExpMacroAssembler(zone),
       specialization_cid_(specialization_cid),
       parsed_function_(parsed_function),
       ic_data_array_(ic_data_array),
@@ -99,9 +99,9 @@
       start_index_param_(NULL),
       registers_count_(0),
       saved_registers_count_((capture_count + 1) * 2),
-      stack_array_cell_(Array::ZoneHandle(isolate, Array::New(1, Heap::kOld))),
+      stack_array_cell_(Array::ZoneHandle(zone, Array::New(1, Heap::kOld))),
       // The registers array is allocated at a fixed size after assembly.
-      registers_array_(TypedData::ZoneHandle(isolate, TypedData::null())) {
+      registers_array_(TypedData::ZoneHandle(zone, TypedData::null())) {
   switch (specialization_cid) {
     case kOneByteStringCid:
     case kExternalOneByteStringCid: mode_ = ASCII; break;
@@ -115,23 +115,23 @@
   // Allocate an initial stack backing of the minimum stack size. The stack
   // backing is indirectly referred to so we can reuse it on subsequent matches
   // even in the case where the backing has been enlarged and thus reallocated.
-  stack_array_cell_.SetAt(0, TypedData::Handle(isolate,
+  stack_array_cell_.SetAt(0, TypedData::Handle(zone,
     TypedData::New(kTypedDataInt32ArrayCid, kMinStackSize / 4, Heap::kOld)));
 
   // Create and generate all preset blocks.
   entry_block_ =
-      new(isolate) GraphEntryInstr(
+      new(zone) GraphEntryInstr(
         *parsed_function_,
-        new(isolate) TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex),
+        new(zone) TargetEntryInstr(block_id_.Alloc(), kInvalidTryIndex),
         Isolate::kNoDeoptId);
   start_block_ =
-      new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
+      new(zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
   success_block_ =
-      new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
+      new(zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
   backtrack_block_ =
-      new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
+      new(zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
   exit_block_ =
-      new(isolate) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
+      new(zone) JoinEntryInstr(block_id_.Alloc(), kInvalidTryIndex);
 
   GenerateEntryBlock();
   GenerateSuccessBlock();
@@ -201,12 +201,12 @@
 
   // Generate a local list variable to represent "registers" and
   // initialize capture registers (others remain garbage).
-  StoreLocal(registers_, Bind(new(I) ConstantInstr(registers_array_)));
+  StoreLocal(registers_, Bind(new(Z) ConstantInstr(registers_array_)));
   ClearRegisters(0, saved_registers_count_ - 1);
 
   // Generate a local list variable to represent the backtracking stack.
   PushArgumentInstr* stack_cell_push =
-      PushArgument(Bind(new(I) ConstantInstr(stack_array_cell_)));
+      PushArgument(Bind(new(Z) ConstantInstr(stack_array_cell_)));
   StoreLocal(stack_, Bind(InstanceCall(
       InstanceCallDescriptor::FromToken(Token::kINDEX),
       stack_cell_push,
@@ -225,11 +225,11 @@
 
   const intptr_t entries_count = entry_block_->indirect_entries().length();
 
-  TypedData& offsets = TypedData::ZoneHandle(I,
+  TypedData& offsets = TypedData::ZoneHandle(Z,
       TypedData::New(kTypedDataInt32ArrayCid, entries_count, Heap::kOld));
 
   PushArgumentInstr* block_offsets_push =
-      PushArgument(Bind(new(I) ConstantInstr(offsets)));
+      PushArgument(Bind(new(Z) ConstantInstr(offsets)));
   PushArgumentInstr* block_id_push = PushArgument(Bind(PopStack()));
 
   Value* offset_value =
@@ -237,7 +237,7 @@
                         block_offsets_push,
                         block_id_push));
 
-  backtrack_goto_ = new(I) IndirectGotoInstr(&offsets, offset_value);
+  backtrack_goto_ = new(Z) IndirectGotoInstr(&offsets, offset_value);
   CloseBlockWith(backtrack_goto_);
 
   // Add an edge from the "indirect" goto to each of the targets.
@@ -252,10 +252,10 @@
   set_current_instruction(success_block_);
   TAG();
 
-  Value* type = Bind(new(I) ConstantInstr(
-      TypeArguments::ZoneHandle(I, TypeArguments::null())));
+  Value* type = Bind(new(Z) ConstantInstr(
+      TypeArguments::ZoneHandle(Z, TypeArguments::null())));
   Value* length = Bind(Uint64Constant(saved_registers_count_));
-  Value* array = Bind(new(I) CreateArrayInstr(kNoSourcePos, type, length));
+  Value* array = Bind(new(Z) CreateArrayInstr(kNoSourcePos, type, length));
   StoreLocal(result_, array);
 
   // Store captured offsets in the `matches` parameter.
@@ -280,7 +280,7 @@
   PRINT(PushLocal(result_));
 
   // Return true on success.
-  AppendInstruction(new(I) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_))));
+  AppendInstruction(new(Z) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_))));
 }
 
 
@@ -289,7 +289,7 @@
   TAG();
 
   // Return false on failure.
-  AppendInstruction(new(I) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_))));
+  AppendInstruction(new(Z) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_))));
 }
 
 
@@ -321,7 +321,7 @@
     const Function& function,
     const String& input,
     const Smi& start_offset,
-    Isolate* isolate) {
+    Zone* zone) {
   // Create the argument list.
   const Array& args = Array::Handle(Array::New(2));
   args.SetAt(0, input);
@@ -330,7 +330,7 @@
   // And finally call the generated code.
 
   const Object& retval =
-      Object::Handle(isolate, DartEntry::InvokeFunction(function, args));
+      Object::Handle(zone, DartEntry::InvokeFunction(function, args));
   if (retval.IsError()) {
     const Error& error = Error::Cast(retval);
     OS::Print("%s\n", error.ToErrorCString());
@@ -382,9 +382,9 @@
 
 LocalVariable* IRRegExpMacroAssembler::Parameter(const String& name,
                                                  intptr_t index) const {
-  const Type& local_type = Type::ZoneHandle(I, Type::DynamicType());
+  const Type& local_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* local =
-      new(I) LocalVariable(kNoSourcePos, name, local_type);
+      new(Z) LocalVariable(kNoSourcePos, name, local_type);
 
   intptr_t param_frame_index = kParamEndSlotFromFp + kParamCount - index;
   local->set_index(param_frame_index);
@@ -394,9 +394,9 @@
 
 
 LocalVariable* IRRegExpMacroAssembler::Local(const String& name) {
-  const Type& local_type = Type::ZoneHandle(I, Type::DynamicType());
+  const Type& local_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* local =
-      new(I) LocalVariable(kNoSourcePos, name, local_type);
+      new(Z) LocalVariable(kNoSourcePos, name, local_type);
   local->set_index(GetNextLocalIndex());
 
   return local;
@@ -404,33 +404,33 @@
 
 
 ConstantInstr* IRRegExpMacroAssembler::Int64Constant(int64_t value) const {
-  return new(I) ConstantInstr(
-        Integer::ZoneHandle(I, Integer::New(value, Heap::kOld)));
+  return new(Z) ConstantInstr(
+        Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld)));
 }
 
 
 ConstantInstr* IRRegExpMacroAssembler::Uint64Constant(uint64_t value) const {
-  return new(I) ConstantInstr(
-        Integer::ZoneHandle(I, Integer::NewFromUint64(value, Heap::kOld)));
+  return new(Z) ConstantInstr(
+        Integer::ZoneHandle(Z, Integer::NewFromUint64(value, Heap::kOld)));
 }
 
 
 ConstantInstr* IRRegExpMacroAssembler::BoolConstant(bool value) const {
-  return new(I) ConstantInstr(value ? Bool::True() : Bool::False());
+  return new(Z) ConstantInstr(value ? Bool::True() : Bool::False());
 }
 
 
 ConstantInstr* IRRegExpMacroAssembler::StringConstant(const char* value) const {
-  return new(I) ConstantInstr(
-        String::ZoneHandle(I, String::New(value, Heap::kOld)));
+  return new(Z) ConstantInstr(
+        String::ZoneHandle(Z, String::New(value, Heap::kOld)));
 }
 
 
 ConstantInstr* IRRegExpMacroAssembler::WordCharacterMapConstant() const {
-  const Library& lib = Library::Handle(I, Library::CoreLibrary());
-  const Class& regexp_class = Class::Handle(I,
+  const Library& lib = Library::Handle(Z, Library::CoreLibrary());
+  const Class& regexp_class = Class::Handle(Z,
         lib.LookupClassAllowPrivate(Symbols::JSSyntaxRegExp()));
-  const Field& word_character_field = Field::ZoneHandle(I,
+  const Field& word_character_field = Field::ZoneHandle(Z,
       regexp_class.LookupStaticField(Symbols::_wordCharacterMap()));
   ASSERT(!word_character_field.IsNull());
 
@@ -439,8 +439,8 @@
   }
   ASSERT(!word_character_field.IsUninitialized());
 
-  return new(I) ConstantInstr(
-        Instance::ZoneHandle(I, word_character_field.value()));
+  return new(Z) ConstantInstr(
+        Instance::ZoneHandle(Z, word_character_field.value()));
 }
 
 
@@ -481,7 +481,7 @@
              rhs));
   Value* rhs_value = Bind(BoolConstant(true));
 
-  return new(I) StrictCompareInstr(
+  return new(Z) StrictCompareInstr(
       kNoSourcePos, strict_comparison, lhs_value, rhs_value, true);
 }
 
@@ -496,7 +496,7 @@
 StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
     const Function& function) const {
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(0);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(0);
   return StaticCall(function, arguments);
 }
 
@@ -505,7 +505,7 @@
     const Function& function,
     PushArgumentInstr* arg1) const {
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
   arguments->Add(arg1);
 
   return StaticCall(function, arguments);
@@ -517,7 +517,7 @@
     PushArgumentInstr* arg1,
     PushArgumentInstr* arg2) const {
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
   arguments->Add(arg1);
   arguments->Add(arg2);
 
@@ -528,7 +528,7 @@
 StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
     const Function& function,
     ZoneGrowableArray<PushArgumentInstr*>* arguments) const {
-  return new(I) StaticCallInstr(kNoSourcePos,
+  return new(Z) StaticCallInstr(kNoSourcePos,
                                 function,
                                 Object::null_array(),
                                 arguments,
@@ -540,7 +540,7 @@
     const InstanceCallDescriptor& desc,
     PushArgumentInstr* arg1) const {
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(1);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
   arguments->Add(arg1);
 
   return InstanceCall(desc, arguments);
@@ -552,7 +552,7 @@
     PushArgumentInstr* arg1,
     PushArgumentInstr* arg2) const {
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(2);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(2);
   arguments->Add(arg1);
   arguments->Add(arg2);
 
@@ -566,7 +566,7 @@
     PushArgumentInstr* arg2,
     PushArgumentInstr* arg3) const {
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
-      new(I) ZoneGrowableArray<PushArgumentInstr*>(3);
+      new(Z) ZoneGrowableArray<PushArgumentInstr*>(3);
   arguments->Add(arg1);
   arguments->Add(arg2);
   arguments->Add(arg3);
@@ -579,7 +579,7 @@
     const InstanceCallDescriptor& desc,
     ZoneGrowableArray<PushArgumentInstr*> *arguments) const {
   return
-    new(I) InstanceCallInstr(kNoSourcePos,
+    new(Z) InstanceCallInstr(kNoSourcePos,
                              desc.name,
                              desc.token_kind,
                              arguments,
@@ -590,13 +590,13 @@
 
 
 LoadLocalInstr* IRRegExpMacroAssembler::LoadLocal(LocalVariable* local) const {
-  return new(I) LoadLocalInstr(*local);
+  return new(Z) LoadLocalInstr(*local);
 }
 
 
 void IRRegExpMacroAssembler::StoreLocal(LocalVariable* local,
                                         Value* value) {
-  Do(new(I) StoreLocalInstr(*local, value));
+  Do(new(Z) StoreLocalInstr(*local, value));
 }
 
 
@@ -609,7 +609,7 @@
   AppendInstruction(definition);
   definition->set_temp_index(temp_id_.Alloc());
 
-  return new(I) Value(definition);
+  return new(Z) Value(definition);
 }
 
 
@@ -620,10 +620,10 @@
 
 Value* IRRegExpMacroAssembler::BindLoadLocal(const LocalVariable& local) {
   if (local.IsConst()) {
-    return Bind(new(I) ConstantInstr(*local.ConstValue()));
+    return Bind(new(Z) ConstantInstr(*local.ConstValue()));
   }
   ASSERT(!local.is_captured());
-  return Bind(new(I) LoadLocalInstr(local));
+  return Bind(new(Z) LoadLocalInstr(local));
 }
 
 
@@ -694,7 +694,7 @@
 
 PushArgumentInstr* IRRegExpMacroAssembler::PushArgument(Value* value) {
   arg_id_.Alloc();
-  PushArgumentInstr* push = new(I) PushArgumentInstr(value);
+  PushArgumentInstr* push = new(Z) PushArgumentInstr(value);
   // Do *not* use Do() for push argument instructions.
   AppendInstruction(push);
   return push;
@@ -708,15 +708,15 @@
 
 void IRRegExpMacroAssembler::Print(const char* str) {
   Print(PushArgument(
-    Bind(new(I) ConstantInstr(
-           String::ZoneHandle(I, String::New(str, Heap::kOld))))));
+    Bind(new(Z) ConstantInstr(
+           String::ZoneHandle(Z, String::New(str, Heap::kOld))))));
 }
 
 
 void IRRegExpMacroAssembler::Print(PushArgumentInstr* argument) {
   const Library& lib = Library::Handle(Library::CoreLibrary());
   const Function& print_fn = Function::ZoneHandle(
-        I, lib.LookupFunctionAllowPrivate(Symbols::print()));
+        Z, lib.LookupFunctionAllowPrivate(Symbols::print()));
   Do(StaticCall(print_fn, argument));
 }
 
@@ -1064,7 +1064,7 @@
     Value* length_value = Bind(LoadLocal(capture_length_));
 
     Definition* is_match_def =
-        new(I) CaseInsensitiveCompareUC16Instr(
+        new(Z) CaseInsensitiveCompareUC16Instr(
                             string_value,
                             lhs_index_value,
                             rhs_index_value,
@@ -1294,7 +1294,7 @@
   TAG();
 
   PushArgumentInstr* table_push =
-      PushArgument(Bind(new(I) ConstantInstr(table)));
+      PushArgument(Bind(new(Z) ConstantInstr(table)));
   PushArgumentInstr* index_push = PushLocal(current_character_);
 
   if (mode_ != ASCII || kTableMask != Symbols::kMaxOneCharCodeSymbol) {
@@ -1638,7 +1638,7 @@
       length_push,
       PushArgument(Bind(Uint64Constant(stack_limit_slack()))))));
   PushArgumentInstr* stack_pointer_push = PushLocal(stack_pointer_);
-  BranchInstr* branch = new(I) BranchInstr(
+  BranchInstr* branch = new(Z) BranchInstr(
       Comparison(kGT, capacity_push, stack_pointer_push));
   CloseBlockWith(branch);
 
@@ -1658,8 +1658,8 @@
 
 void IRRegExpMacroAssembler::GrowStack() {
   TAG();
-  Value* cell = Bind(new(I) ConstantInstr(stack_array_cell_));
-  StoreLocal(stack_, Bind(new(I) GrowRegExpStackInstr(cell)));
+  Value* cell = Bind(new(Z) ConstantInstr(stack_array_cell_));
+  StoreLocal(stack_, Bind(new(Z) GrowRegExpStackInstr(cell)));
 }
 
 
@@ -1799,7 +1799,7 @@
   // If the condition is not true, fall through to a new block.
   BlockLabel fallthrough;
 
-  BranchInstr* branch = new(I) BranchInstr(comparison);
+  BranchInstr* branch = new(Z) BranchInstr(comparison);
   *branch->true_successor_address() =
       TargetWithJoinGoto(true_successor_block);
   *branch->false_successor_address() =
@@ -1812,11 +1812,11 @@
 
 TargetEntryInstr* IRRegExpMacroAssembler::TargetWithJoinGoto(
     JoinEntryInstr* dst) {
-  TargetEntryInstr* target = new(I) TargetEntryInstr(
+  TargetEntryInstr* target = new(Z) TargetEntryInstr(
           block_id_.Alloc(), kInvalidTryIndex);
   blocks_.Add(target);
 
-  target->AppendInstruction(new(I) GotoInstr(dst));
+  target->AppendInstruction(new(Z) GotoInstr(dst));
 
   return target;
 }
@@ -1824,11 +1824,11 @@
 
 IndirectEntryInstr* IRRegExpMacroAssembler::IndirectWithJoinGoto(
     JoinEntryInstr* dst) {
-  IndirectEntryInstr* target = new(I) IndirectEntryInstr(
+  IndirectEntryInstr* target = new(Z) IndirectEntryInstr(
           block_id_.Alloc(), indirect_id_.Alloc(), kInvalidTryIndex);
   blocks_.Add(target);
 
-  target->AppendInstruction(new(I) GotoInstr(dst));
+  target->AppendInstruction(new(Z) GotoInstr(dst));
 
   return target;
 }
@@ -1836,7 +1836,7 @@
 
 void IRRegExpMacroAssembler::CheckPreemption() {
   TAG();
-  AppendInstruction(new(I) CheckStackOverflowInstr(kNoSourcePos, 0));
+  AppendInstruction(new(Z) CheckStackOverflowInstr(kNoSourcePos, 0));
 }
 
 
@@ -1913,15 +1913,15 @@
     // the first value is consumed to obtain the second value which is consumed
     // by LoadCodeUnitsAtInstr below.
     Value* external_val =
-        Bind(new(I) LoadUntaggedInstr(pattern_val, external_offset));
+        Bind(new(Z) LoadUntaggedInstr(pattern_val, external_offset));
     pattern_val =
-        Bind(new(I) LoadUntaggedInstr(external_val, data_offset));
+        Bind(new(Z) LoadUntaggedInstr(external_val, data_offset));
   }
 
   // Here pattern_val might be untagged so this must not trigger a GC.
   Value* index_val = BindLoadLocal(*index);
 
-  return Bind(new(I) LoadCodeUnitsInstr(
+  return Bind(new(Z) LoadCodeUnitsInstr(
       pattern_val,
       index_val,
       characters,
diff --git a/runtime/vm/regexp_assembler.h b/runtime/vm/regexp_assembler.h
index ebca0c2..56b4158 100644
--- a/runtime/vm/regexp_assembler.h
+++ b/runtime/vm/regexp_assembler.h
@@ -84,7 +84,7 @@
     kIRImplementation
   };
 
-  explicit RegExpMacroAssembler(Isolate* isolate);
+  explicit RegExpMacroAssembler(Zone* zone);
   virtual ~RegExpMacroAssembler();
   // The maximal number of pushes between stack checks. Users must supply
   // kCheckStackLimit flag to push operations (instead of kNoStackLimitCheck)
@@ -209,12 +209,12 @@
     return global_mode_ == GLOBAL;
   }
 
-  Isolate* isolate() const { return isolate_; }
+  Zone* zone() const { return zone_; }
 
  private:
   bool slow_safe_compiler_;
   bool global_mode_;
-  Isolate* isolate_;
+  Zone* zone_;
 };
 
 
@@ -238,7 +238,7 @@
                          intptr_t capture_count,
                          const ParsedFunction* parsed_function,
                          const ZoneGrowableArray<const ICData*>& ic_data_array,
-                         Isolate* isolate);
+                         Zone* zone);
   virtual ~IRRegExpMacroAssembler();
 
   virtual bool CanReadUnaligned();
@@ -254,7 +254,7 @@
   static RawArray* Execute(const Function& function,
                            const String& input,
                            const Smi& start_offset,
-                           Isolate* isolate);
+                           Zone* zone);
 
   virtual bool IsClosed() const { return (current_instruction_ == NULL); }
 
diff --git a/runtime/vm/regexp_parser.cc b/runtime/vm/regexp_parser.cc
index 79e802b..9db51dd 100644
--- a/runtime/vm/regexp_parser.cc
+++ b/runtime/vm/regexp_parser.cc
@@ -8,13 +8,13 @@
 
 namespace dart {
 
-#define I isolate()
+#define Z zone()
 
 // Enables possessive quantifier syntax for testing.
 static const bool FLAG_regexp_possessive_quantifier = false;
 
 RegExpBuilder::RegExpBuilder()
-    : isolate_(Isolate::Current()),
+    : zone_(Thread::Current()->zone()),
       pending_empty_(false),
       characters_(NULL),
       terms_(),
@@ -29,7 +29,7 @@
 void RegExpBuilder::FlushCharacters() {
   pending_empty_ = false;
   if (characters_ != NULL) {
-    RegExpTree* atom = new(I) RegExpAtom(characters_);
+    RegExpTree* atom = new(Z) RegExpAtom(characters_);
     characters_ = NULL;
     text_.Add(atom);
     LAST(ADD_ATOM);
@@ -45,7 +45,7 @@
   } else if (num_text == 1) {
     terms_.Add(text_.Last());
   } else {
-    RegExpText* text = new(I) RegExpText();
+    RegExpText* text = new(Z) RegExpText();
     for (intptr_t i = 0; i < num_text; i++)
       text_[i]->AppendToText(text);
     terms_.Add(text);
@@ -57,7 +57,7 @@
 void RegExpBuilder::AddCharacter(uint16_t c) {
   pending_empty_ = false;
   if (characters_ == NULL) {
-    characters_ = new(I) ZoneGrowableArray<uint16_t>(4);
+    characters_ = new(Z) ZoneGrowableArray<uint16_t>(4);
   }
   characters_->Add(c);
   LAST(ADD_CHAR);
@@ -107,11 +107,11 @@
     alternative = terms_.Last();
   } else {
     ZoneGrowableArray<RegExpTree*>* terms =
-        new(I) ZoneGrowableArray<RegExpTree*>();
+        new(Z) ZoneGrowableArray<RegExpTree*>();
     for (intptr_t i = 0; i < terms_.length(); i++) {
       terms->Add(terms_[i]);
     }
-    alternative = new(I) RegExpAlternative(terms);
+    alternative = new(Z) RegExpAlternative(terms);
   }
   alternatives_.Add(alternative);
   terms_.Clear();
@@ -129,11 +129,11 @@
     return alternatives_.Last();
   }
   ZoneGrowableArray<RegExpTree*>* alternatives =
-      new(I) ZoneGrowableArray<RegExpTree*>();
+      new(Z) ZoneGrowableArray<RegExpTree*>();
   for (intptr_t i = 0; i < alternatives_.length(); i++) {
     alternatives->Add(alternatives_[i]);
   }
-  return new(I) RegExpDisjunction(alternatives);
+  return new(Z) RegExpDisjunction(alternatives);
 }
 
 
@@ -151,22 +151,22 @@
     // Last atom was character.
 
     ZoneGrowableArray<uint16_t> *char_vector =
-        new(I) ZoneGrowableArray<uint16_t>();
+        new(Z) ZoneGrowableArray<uint16_t>();
     char_vector->AddArray(*characters_);
     intptr_t num_chars = char_vector->length();
     if (num_chars > 1) {
       ZoneGrowableArray<uint16_t> *prefix =
-          new(I) ZoneGrowableArray<uint16_t>();
+          new(Z) ZoneGrowableArray<uint16_t>();
       for (intptr_t i = 0; i < num_chars - 1; i++) {
         prefix->Add(char_vector->At(i));
       }
-      text_.Add(new(I) RegExpAtom(prefix));
-      ZoneGrowableArray<uint16_t> *tail = new(I) ZoneGrowableArray<uint16_t>();
+      text_.Add(new(Z) RegExpAtom(prefix));
+      ZoneGrowableArray<uint16_t> *tail = new(Z) ZoneGrowableArray<uint16_t>();
       tail->Add(char_vector->At(num_chars - 1));
       char_vector = tail;
     }
     characters_ = NULL;
-    atom = new(I) RegExpAtom(char_vector);
+    atom = new(Z) RegExpAtom(char_vector);
     FlushText();
   } else if (text_.length() > 0) {
     DEBUG_ASSERT(last_added_ == ADD_ATOM);
@@ -189,7 +189,7 @@
     UNREACHABLE();
     return;
   }
-  terms_.Add(new(I) RegExpQuantifier(min, max, quantifier_type, atom));
+  terms_.Add(new(Z) RegExpQuantifier(min, max, quantifier_type, atom));
   LAST(ADD_TERM);
 }
 
@@ -199,7 +199,7 @@
 RegExpParser::RegExpParser(const String& in,
                            String* error,
                            bool multiline)
-    : isolate_(Isolate::Current()),
+    : zone_(Thread::Current()->zone()),
       error_(error),
       captures_(NULL),
       in_(in),
@@ -217,13 +217,13 @@
 
 
 bool RegExpParser::ParseFunction(ParsedFunction *parsed_function) {
-  Isolate* isolate = parsed_function->isolate();
+  Zone* zone = parsed_function->zone();
   JSRegExp& regexp = JSRegExp::Handle(parsed_function->function().regexp());
 
   const String& pattern = String::Handle(regexp.pattern());
   const bool multiline = regexp.is_multi_line();
 
-  RegExpCompileData* compile_data = new(isolate) RegExpCompileData();
+  RegExpCompileData* compile_data = new(zone) RegExpCompileData();
   if (!RegExpParser::ParseRegExp(pattern, multiline, compile_data)) {
     // Parsing failures are handled in the JSRegExp factory constructor.
     UNREACHABLE();
@@ -319,7 +319,7 @@
 //   Atom Quantifier
 RegExpTree* RegExpParser::ParseDisjunction() {
   // Used to store current state while parsing subexpressions.
-  RegExpParserState initial_state(NULL, INITIAL, 0, I);
+  RegExpParserState initial_state(NULL, INITIAL, 0, Z);
   RegExpParserState* stored_state = &initial_state;
   // Cache the builder in a local variable for quick access.
   RegExpBuilder* builder = initial_state.builder();
@@ -357,14 +357,14 @@
 
       // Build result of subexpression.
       if (group_type == CAPTURE) {
-        RegExpCapture* capture = new(I) RegExpCapture(body, capture_index);
+        RegExpCapture* capture = new(Z) RegExpCapture(body, capture_index);
         (*captures_)[capture_index - 1] = capture;
         body = capture;
       } else if (group_type != GROUPING) {
         ASSERT(group_type == POSITIVE_LOOKAHEAD ||
                group_type == NEGATIVE_LOOKAHEAD);
         bool is_positive = (group_type == POSITIVE_LOOKAHEAD);
-        body = new(I) RegExpLookahead(body,
+        body = new(Z) RegExpLookahead(body,
                                       is_positive,
                                       end_capture_index - capture_index,
                                       capture_index);
@@ -388,10 +388,10 @@
       Advance();
       if (multiline_) {
         builder->AddAssertion(
-            new(I) RegExpAssertion(RegExpAssertion::START_OF_LINE));
+            new(Z) RegExpAssertion(RegExpAssertion::START_OF_LINE));
       } else {
         builder->AddAssertion(
-            new(I) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
+            new(Z) RegExpAssertion(RegExpAssertion::START_OF_INPUT));
         set_contains_anchor();
       }
       continue;
@@ -445,7 +445,7 @@
       }
       // Store current state and begin new disjunction parsing.
       stored_state = new RegExpParserState(stored_state, subexpr_type,
-                                           captures_started(), I);
+                                           captures_started(), Z);
       builder = stored_state->builder();
       continue;
     }
@@ -996,7 +996,7 @@
     Advance();
   }
   ZoneGrowableArray<CharacterRange>* ranges =
-      new(I) ZoneGrowableArray<CharacterRange>(2);
+      new(Z) ZoneGrowableArray<CharacterRange>(2);
   while (has_more() && current() != ']') {
     uint16_t char_class = kNoCharClass;
     CharacterRange first = ParseClassAtom(&char_class);
@@ -1038,7 +1038,7 @@
     ranges->Add(CharacterRange::Everything());
     is_negated = !is_negated;
   }
-  return new(I) RegExpCharacterClass(ranges, is_negated);
+  return new(Z) RegExpCharacterClass(ranges, is_negated);
 }
 
 
diff --git a/runtime/vm/regexp_parser.h b/runtime/vm/regexp_parser.h
index 3030782..aed1423 100644
--- a/runtime/vm/regexp_parser.h
+++ b/runtime/vm/regexp_parser.h
@@ -32,9 +32,9 @@
   void FlushText();
   void FlushTerms();
 
-  Isolate* isolate() const { return isolate_; }
+  Zone* zone() const { return zone_; }
 
-  Isolate* isolate_;
+  Zone* zone_;
   bool pending_empty_;
   ZoneGrowableArray<uint16_t>* characters_;
   GrowableArray<RegExpTree*> terms_;
@@ -118,9 +118,9 @@
     RegExpParserState(RegExpParserState* previous_state,
                       SubexpressionType group_type,
                       intptr_t disjunction_capture_index,
-                      Isolate *isolate)
+                      Zone *zone)
         : previous_state_(previous_state),
-          builder_(new(isolate) RegExpBuilder()),
+          builder_(new(zone) RegExpBuilder()),
           group_type_(group_type),
           disjunction_capture_index_(disjunction_capture_index) {}
     // Parser state of containing expression, if any.
@@ -146,7 +146,7 @@
     intptr_t disjunction_capture_index_;
   };
 
-  Isolate* isolate() { return isolate_; }
+  Zone* zone() { return zone_; }
 
   uint32_t current() { return current_; }
   bool has_more() { return has_more_; }
@@ -155,7 +155,7 @@
   const String& in() { return in_; }
   void ScanForCaptures();
 
-  Isolate* isolate_;
+  Zone* zone_;
   String* error_;
   ZoneGrowableArray<RegExpCapture*>* captures_;
   const String& in_;
diff --git a/runtime/vm/regexp_test.cc b/runtime/vm/regexp_test.cc
index 4af8974..b8b962f 100644
--- a/runtime/vm/regexp_test.cc
+++ b/runtime/vm/regexp_test.cc
@@ -14,14 +14,14 @@
 DECLARE_FLAG(bool, use_jscre);
 
 static RawArray* Match(const String& pat, const String& str) {
-  Isolate* isolate = Isolate::Current();
+  Zone* zone = Thread::Current()->zone();
   const JSRegExp& regexp = JSRegExp::Handle(
-      RegExpEngine::CreateJSRegExp(isolate, pat, false, false));
+      RegExpEngine::CreateJSRegExp(zone, pat, false, false));
   const intptr_t cid = str.GetClassId();
   const Function& fn = Function::Handle(regexp.function(cid));
   EXPECT(!fn.IsNull());
   const Smi& idx = Smi::Handle(Smi::New(0));
-  return IRRegExpMacroAssembler::Execute(fn, str, idx, Isolate::Current());
+  return IRRegExpMacroAssembler::Execute(fn, str, idx, zone);
 }
 
 TEST_CASE(RegExp_OneByteString) {
diff --git a/runtime/vm/resolver.cc b/runtime/vm/resolver.cc
index 7274efa..89d9ff6 100644
--- a/runtime/vm/resolver.cc
+++ b/runtime/vm/resolver.cc
@@ -91,6 +91,7 @@
 
   extractor.set_extracted_method_closure(closure_function);
   extractor.set_is_debuggable(false);
+  extractor.set_is_visible(false);
 
   owner.AddFunction(extractor);
 
diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h
index 9f70b8d..f0580a6 100644
--- a/runtime/vm/runtime_entry.h
+++ b/runtime/vm/runtime_entry.h
@@ -67,20 +67,29 @@
   extern void DRT_##name(NativeArguments arguments);                           \
   extern const RuntimeEntry k##name##RuntimeEntry(                             \
       "DRT_"#name, &DRT_##name, argument_count, false, false);                 \
-  static void DRT_Helper##name(Isolate* isolate, NativeArguments arguments);   \
+  static void DRT_Helper##name(Isolate* isolate,                               \
+                               Thread* thread,                                 \
+                               Zone* zone,                                     \
+                               NativeArguments arguments);                     \
   void DRT_##name(NativeArguments arguments) {                                 \
     CHECK_STACK_ALIGNMENT;                                                     \
     VERIFY_ON_TRANSITION;                                                      \
     ASSERT(arguments.ArgCount() == argument_count);                            \
     if (FLAG_trace_runtime_calls) OS::Print("Runtime call: %s\n", ""#name);    \
     {                                                                          \
-      StackZone zone(arguments.isolate());                                     \
-      HANDLESCOPE(arguments.isolate());                                        \
-      DRT_Helper##name(arguments.isolate(), arguments);                        \
+      Isolate* isolate = arguments.isolate();                                  \
+      Thread* thread = isolate->mutator_thread();                              \
+      ASSERT(thread == Thread::Current());                                     \
+      StackZone zone(isolate);                                                 \
+      HANDLESCOPE(isolate);                                                    \
+      DRT_Helper##name(isolate, thread, zone.GetZone(), arguments);            \
     }                                                                          \
     VERIFY_ON_TRANSITION;                                                      \
   }                                                                            \
-  static void DRT_Helper##name(Isolate* isolate, NativeArguments arguments)
+  static void DRT_Helper##name(Isolate* isolate,                               \
+                               Thread* thread,                                 \
+                               Zone* zone,                                     \
+                               NativeArguments arguments)
 
 #define DECLARE_RUNTIME_ENTRY(name)                                            \
   extern const RuntimeEntry k##name##RuntimeEntry
@@ -92,7 +101,7 @@
       argument_count, true, false);                                            \
   type DLRT_##name(__VA_ARGS__) {                                              \
     CHECK_STACK_ALIGNMENT;                                                     \
-    NoGCScope no_gc_scope;                                                     \
+    NoSafepointScope no_safepoint_scope;                                       \
 
 #define END_LEAF_RUNTIME_ENTRY }
 
diff --git a/runtime/vm/scanner.cc b/runtime/vm/scanner.cc
index 69c5cec..f33d0b4 100644
--- a/runtime/vm/scanner.cc
+++ b/runtime/vm/scanner.cc
@@ -18,8 +18,8 @@
 DEFINE_FLAG(bool, print_tokens, false, "Print scanned tokens.");
 
 
-// Quick access to the locally defined isolate() method.
-#define I (isolate())
+// Quick access to the locally defined zone() method.
+#define Z (zone())
 
 
 class ScanContext : public ZoneAllocated {
@@ -83,7 +83,7 @@
       saved_context_(NULL),
       private_key_(String::ZoneHandle(private_key.raw())),
       char_at_func_(src.CharAtFunc()),
-      isolate_(Isolate::Current()) {
+      zone_(Thread::Current()->zone()) {
   Reset();
 }
 
@@ -93,7 +93,7 @@
 
 void Scanner::ErrorMsg(const char* msg) {
   current_token_.kind = Token::kERROR;
-  current_token_.literal = &String::ZoneHandle(I, Symbols::New(msg));
+  current_token_.literal = &String::ZoneHandle(Z, Symbols::New(msg));
   current_token_.position = c0_pos_;
   token_start_ = lookahead_pos_;
   current_token_.offset = lookahead_pos_;
@@ -101,7 +101,7 @@
 
 
 void Scanner::PushContext() {
-  ScanContext* ctx = new(I) ScanContext(this);
+  ScanContext* ctx = new(Z) ScanContext(this);
   saved_context_ = ctx;
   string_delimiter_ = '\0';
   string_is_multiline_ = false;
@@ -328,7 +328,7 @@
   // We did not read a keyword.
   current_token_.kind = Token::kIDENT;
   String& literal =
-      String::ZoneHandle(I, Symbols::New(source_, ident_pos, ident_length));
+      String::ZoneHandle(Z, Symbols::New(source_, ident_pos, ident_length));
   if (ident_char0 == Library::kPrivateIdentifierStart) {
     // Private identifiers are mangled on a per library basis.
     literal = String::Concat(literal, private_key_);
@@ -386,7 +386,7 @@
   }
   if (current_token_.kind != Token::kILLEGAL) {
     intptr_t len = lookahead_pos_ - token_start_;
-    String& str = String::ZoneHandle(I,
+    String& str = String::ZoneHandle(Z,
         String::SubString(source_, token_start_, len, Heap::kOld));
     str = Symbols::New(str);
     current_token_.literal = &str;
@@ -541,7 +541,7 @@
       // Scanned a string piece.
       ASSERT(string_chars.data() != NULL);
       // Strings are canonicalized: Allocate a symbol.
-      current_token_.literal = &String::ZoneHandle(I,
+      current_token_.literal = &String::ZoneHandle(Z,
           Symbols::FromUTF32(string_chars.data(), string_chars.length()));
       // Preserve error tokens.
       if (current_token_.kind != Token::kERROR) {
@@ -564,7 +564,7 @@
           Recognize(Token::kSTRING);
           ASSERT(string_chars.data() != NULL);
           // Strings are canonicalized: Allocate a symbol.
-          current_token_.literal = &String::ZoneHandle(I,
+          current_token_.literal = &String::ZoneHandle(Z,
               Symbols::FromUTF32(string_chars.data(), string_chars.length()));
         }
         EndStringLiteral();
@@ -929,7 +929,7 @@
 
 
 const Scanner::GrowableTokenStream& Scanner::GetStream() {
-  GrowableTokenStream* ts = new(I) GrowableTokenStream(128);
+  GrowableTokenStream* ts = new(Z) GrowableTokenStream(128);
   ScanAll(ts);
   if (FLAG_print_tokens) {
     Scanner::PrintTokens(*ts);
diff --git a/runtime/vm/scanner.h b/runtime/vm/scanner.h
index 2c5f64a..7558a1d 100644
--- a/runtime/vm/scanner.h
+++ b/runtime/vm/scanner.h
@@ -182,7 +182,7 @@
 
   CharAtFunc CallCharAt() const { return char_at_func_; }
 
-  Isolate* isolate() const { return isolate_; }
+  Zone* zone() const { return zone_; }
 
   static void PrintTokens(const GrowableTokenStream& ts);
 
@@ -211,7 +211,7 @@
 
   const CharAtFunc char_at_func_;
 
-  Isolate* isolate_;
+  Zone* zone_;
 
   static KeywordTable keywords_[Token::kNumKeywords];
   static int keywords_char_offset_[kNumLowercaseChars];
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index 05a4654..49601a1 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -10,6 +10,11 @@
 
 namespace dart {
 
+DEFINE_FLAG(bool, share_enclosing_context, true,
+            "Allocate captured variables in the existing context of an "
+            "enclosing scope (up to innermost loop) and spare the allocation "
+            "of a local context.");
+
 int SourceLabel::FunctionLevel() const {
   ASSERT(owner() != NULL);
   return owner()->function_level();
@@ -148,7 +153,16 @@
     // This scope becomes the current context owner.
     set_context_level(1);
     *context_owner = this;
+  } else if (!FLAG_share_enclosing_context && ((*context_owner) != this)) {
+    // The captured variable is in a child scope of the context owner and we do
+    // not share contexts.
+    // This scope will allocate and chain a new context.
+    ASSERT(num_context_variables_ == 0);
+    // This scope becomes the current context owner.
+    set_context_level((*context_owner)->context_level() + 1);
+    *context_owner = this;
   } else if ((*context_owner)->loop_level() < loop_level()) {
+    ASSERT(FLAG_share_enclosing_context);
     // The captured variable is at a deeper loop level than the current context.
     // This scope will allocate and chain a new context.
     ASSERT(num_context_variables_ == 0);
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index faa56a8..bc6d263 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -79,6 +79,11 @@
     is_captured_parameter_ = value;
   }
 
+  // By convention, internal variables start with a colon.
+  bool IsInternal() const {
+    return name_.CharAt(0) == ':';
+  }
+
   bool IsConst() const {
     return const_value_ != NULL;
   }
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index b8cea45..5cb1721 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -573,14 +573,14 @@
   message.SetUint64(0, Utils::HostToBigEndian64(meta_bytes));
   offset += sizeof(uint64_t);
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     meta.ToUTF8(static_cast<uint8_t*>(message.DataAddr(offset)), meta_bytes);
     offset += meta_bytes;
   }
   // TODO(koda): It would be nice to avoid this copy (requires changes to
   // MessageWriter code).
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     memmove(message.DataAddr(offset), data, size);
     offset += size;
   }
@@ -1555,43 +1555,6 @@
 }
 
 
-static const MethodParameter* get_call_site_data_params[] = {
-  ISOLATE_PARAMETER,
-  new IdParameter("targetId", true),
-  NULL,
-};
-
-
-static bool GetCallSiteData(Isolate* isolate, JSONStream* js) {
-  const char* target_id = js->LookupParam("targetId");
-  Object& obj = Object::Handle(LookupHeapObject(isolate, target_id, NULL));
-  if (obj.raw() == Object::sentinel().raw()) {
-    PrintInvalidParamError(js, "targetId");
-    return true;
-  }
-  if (obj.IsFunction()) {
-    const Function& func = Function::Cast(obj);
-    const GrowableObjectArray& ics =
-        GrowableObjectArray::Handle(func.CollectICsWithSourcePositions());
-    JSONObject jsobj(js);
-    jsobj.AddProperty("type", "_CallSiteData");
-    jsobj.AddProperty("function", func);
-    JSONArray elements(&jsobj, "callSites");
-    Smi& line = Smi::Handle();
-    Smi& column = Smi::Handle();
-    ICData& ic_data = ICData::Handle();
-    for (intptr_t i = 0; i < ics.Length();) {
-      ic_data ^= ics.At(i++);
-      line ^= ics.At(i++);
-      column ^= ics.At(i++);
-      ic_data.PrintToJSONArray(&elements, line.Value(), column.Value());
-    }
-    return true;
-  }
-  return false;
-}
-
-
 class GetInstancesVisitor : public ObjectGraph::Visitor {
  public:
   GetInstancesVisitor(const Class& cls, const Array& storage)
@@ -1733,15 +1696,9 @@
 };
 
 
-static const MethodParameter* get_coverage_params[] = {
-  ISOLATE_PARAMETER,
-  NULL,
-};
-
-
-static bool GetCoverage(Isolate* isolate, JSONStream* js) {
+static bool GetHitsOrSites(Isolate* isolate, JSONStream* js, bool as_sites) {
   if (!js->HasParam("targetId")) {
-    CodeCoverage::PrintJSON(isolate, js, NULL);
+    CodeCoverage::PrintJSON(isolate, js, NULL, as_sites);
     return true;
   }
   const char* target_id = js->LookupParam("targetId");
@@ -1752,22 +1709,22 @@
   }
   if (obj.IsScript()) {
     ScriptCoverageFilter sf(Script::Cast(obj));
-    CodeCoverage::PrintJSON(isolate, js, &sf);
+    CodeCoverage::PrintJSON(isolate, js, &sf, as_sites);
     return true;
   }
   if (obj.IsLibrary()) {
     LibraryCoverageFilter lf(Library::Cast(obj));
-    CodeCoverage::PrintJSON(isolate, js, &lf);
+    CodeCoverage::PrintJSON(isolate, js, &lf, as_sites);
     return true;
   }
   if (obj.IsClass()) {
     ClassCoverageFilter cf(Class::Cast(obj));
-    CodeCoverage::PrintJSON(isolate, js, &cf);
+    CodeCoverage::PrintJSON(isolate, js, &cf, as_sites);
     return true;
   }
   if (obj.IsFunction()) {
     FunctionCoverageFilter ff(Function::Cast(obj));
-    CodeCoverage::PrintJSON(isolate, js, &ff);
+    CodeCoverage::PrintJSON(isolate, js, &ff, as_sites);
     return true;
   }
   PrintError(js, "%s: Invalid 'targetId' parameter value: "
@@ -1777,6 +1734,30 @@
 }
 
 
+static const MethodParameter* get_coverage_params[] = {
+  ISOLATE_PARAMETER,
+  NULL,
+};
+
+
+static bool GetCoverage(Isolate* isolate, JSONStream* js) {
+  // TODO(rmacnak): Remove this response; it is subsumed by GetCallSiteData.
+  return GetHitsOrSites(isolate, js, false);
+}
+
+
+static const MethodParameter* get_call_site_data_params[] = {
+  ISOLATE_PARAMETER,
+  new IdParameter("targetId", true),
+  NULL,
+};
+
+
+static bool GetCallSiteData(Isolate* isolate, JSONStream* js) {
+  return GetHitsOrSites(isolate, js, true);
+}
+
+
 static const MethodParameter* add_breakpoint_params[] = {
   ISOLATE_PARAMETER,
   new IdParameter("scriptId", true),
@@ -2304,7 +2285,7 @@
   bool ref = js->HasParam("ref") && js->ParamIs("ref", "true");
   Object& object = Object::Handle(isolate);
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     ContainsAddressVisitor visitor(isolate, addr);
     object = isolate->heap()->FindObject(&visitor);
   }
diff --git a/runtime/vm/service/constants.dart b/runtime/vm/service/constants.dart
index 3697f65..8804863 100644
--- a/runtime/vm/service/constants.dart
+++ b/runtime/vm/service/constants.dart
@@ -6,6 +6,7 @@
 
 // These must be kept in sync with runtime/vm/service.cc.
 class Constants {
+  static const int SERVICE_EXIT_MESSAGE_ID = 0;
   static const int ISOLATE_STARTUP_MESSAGE_ID = 1;
   static const int ISOLATE_SHUTDOWN_MESSAGE_ID = 2;
 
diff --git a/runtime/vm/service/vmservice.dart b/runtime/vm/service/vmservice.dart
index d4eca93..934bd6f 100644
--- a/runtime/vm/service/vmservice.dart
+++ b/runtime/vm/service/vmservice.dart
@@ -18,6 +18,8 @@
 final RawReceivePort isolateLifecyclePort = new RawReceivePort();
 final RawReceivePort scriptLoadPort = new RawReceivePort();
 
+typedef ShutdownCallback();
+
 class VMService extends MessageRouter {
   static VMService _instance;
   /// Collection of currently connected clients.
@@ -32,6 +34,8 @@
   /// A port used to receive events from the VM.
   final RawReceivePort eventPort;
 
+  ShutdownCallback onShutdown;
+
   void _addClient(Client client) {
     clients.add(client);
   }
@@ -94,12 +98,28 @@
     }
   }
 
+  void _exit() {
+    if (onShutdown != null) {
+      onShutdown();
+    }
+    isolateLifecyclePort.close();
+    scriptLoadPort.close();
+    var clientList = clients.toList();
+    for (var client in clientList) {
+      client.close();
+    }
+    _onExit();
+  }
+
   void messageHandler(message) {
     assert(message is List);
-    if (message is List && message.length == 4) {
+    if (message is List && (message.length == 4)) {
       _controlMessageHandler(message[0], message[1], message[2], message[3]);
-    } else if (message is List && message.length == 2) {
+    } else if (message is List && (message.length == 2)) {
       _eventMessageHandler(message[0], message[1]);
+    } else if (message is List && (message.length == 1)) {
+      assert(message[0] == Constants.SERVICE_EXIT_MESSAGE_ID);
+      _exit();
     } else {
       Logger.root.severe('Unexpected message: $message');
     }
@@ -164,3 +184,5 @@
     native "VMService_SetEventMask";
 
 void _onStart() native "VMService_OnStart";
+
+void _onExit() native "VMService_OnExit";
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 650b040..c9a47c2 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -116,6 +116,7 @@
 
 
 // These must be kept in sync with service/constants.dart
+#define VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID 0
 #define VM_SERVICE_ISOLATE_STARTUP_MESSAGE_ID 1
 #define VM_SERVICE_ISOLATE_SHUTDOWN_MESSAGE_ID 2
 
@@ -134,13 +135,26 @@
 }
 
 
+static RawArray* MakeServiceExitMessage() {
+  const Array& list = Array::Handle(Array::New(1));
+  ASSERT(!list.IsNull());
+  const intptr_t code = VM_SERVICE_ISOLATE_EXIT_MESSAGE_ID;
+  const Integer& code_int = Integer::Handle(Integer::New(code));
+  list.SetAt(0, code_int);
+  return list.raw();
+}
+
+
 const char* ServiceIsolate::kName = "vm-service";
 Isolate* ServiceIsolate::isolate_ = NULL;
 Dart_Port ServiceIsolate::port_ = ILLEGAL_PORT;
 Dart_Port ServiceIsolate::load_port_ = ILLEGAL_PORT;
 Dart_IsolateCreateCallback ServiceIsolate::create_callback_ = NULL;
+uint8_t* ServiceIsolate::exit_message_ = NULL;
+intptr_t ServiceIsolate::exit_message_length_ = 0;
 Monitor* ServiceIsolate::monitor_ = NULL;
 bool ServiceIsolate::initializing_ = true;
+bool ServiceIsolate::shutting_down_ = false;
 
 
 class RegisterRunningIsolatesVisitor : public IsolateVisitor {
@@ -205,7 +219,8 @@
   static void SendIsolateServiceMessage(Dart_NativeArguments args) {
     NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
     Isolate* isolate = arguments->isolate();
-    StackZone zone(isolate);
+    StackZone stack_zone(isolate);
+    Zone* zone = stack_zone.GetZone();  // Used by GET_NON_NULL_NATIVE_ARGUMENT.
     HANDLESCOPE(isolate);
     GET_NON_NULL_NATIVE_ARGUMENT(SendPort, sp, arguments->NativeArgAt(0));
     GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(1));
@@ -228,7 +243,8 @@
   static void SendRootServiceMessage(Dart_NativeArguments args) {
     NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
     Isolate* isolate = arguments->isolate();
-    StackZone zone(isolate);
+    StackZone stack_zone(isolate);
+    Zone* zone = stack_zone.GetZone();  // Used by GET_NON_NULL_NATIVE_ARGUMENT.
     HANDLESCOPE(isolate);
     GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(0));
     Service::HandleRootMessage(message);
@@ -237,7 +253,8 @@
   static void SetEventMask(Dart_NativeArguments args) {
     NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
     Isolate* isolate = arguments->isolate();
-    StackZone zone(isolate);
+    StackZone stack_zone(isolate);
+    Zone* zone = stack_zone.GetZone();  // Used by GET_NON_NULL_NATIVE_ARGUMENT.
     HANDLESCOPE(isolate);
     GET_NON_NULL_NATIVE_ARGUMENT(Integer, mask, arguments->NativeArgAt(0));
     Service::SetEventMask(mask.AsTruncatedUint32Value());
@@ -276,6 +293,18 @@
       Isolate::VisitIsolates(&register_isolates);
     }
   }
+
+  static void OnExit(Dart_NativeArguments args) {
+    NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+    Isolate* isolate = arguments->isolate();
+    StackZone zone(isolate);
+    HANDLESCOPE(isolate);
+    {
+      if (FLAG_trace_service) {
+        OS::Print("vm-service: processed exit message.\n");
+      }
+    }
+  }
 };
 
 
@@ -295,6 +324,8 @@
     ServiceIsolateNatives::SetEventMask},
   {"VMService_OnStart", 0,
     ServiceIsolateNatives::OnStart },
+  {"VMService_OnExit", 0,
+    ServiceIsolateNatives::OnExit },
 };
 
 
@@ -431,6 +462,23 @@
 }
 
 
+void ServiceIsolate::SendServiceExitMessage() {
+  if (!IsRunning()) {
+    return;
+  }
+  if ((exit_message_ == NULL) || (exit_message_length_ == 0)) {
+    return;
+  }
+  if (FLAG_trace_service) {
+    OS::Print("vm-service: sending service exit message.\n");
+  }
+  PortMap::PostMessage(new Message(port_,
+                                   exit_message_,
+                                   exit_message_length_,
+                                   Message::kNormalPriority));
+}
+
+
 void ServiceIsolate::SetServicePort(Dart_Port port) {
   MonitorLocker ml(monitor_);
   port_ = port;
@@ -503,6 +551,31 @@
 }
 
 
+void ServiceIsolate::ConstructExitMessageAndCache(Isolate* isolate) {
+  // Construct and cache exit message here so we can send it without needing an
+  // isolate.
+  StartIsolateScope iso_scope(isolate);
+  StackZone zone(isolate);
+  HANDLESCOPE(isolate);
+  ASSERT(exit_message_ == NULL);
+  ASSERT(exit_message_length_ == 0);
+  const Array& list = Array::Handle(MakeServiceExitMessage());
+  ASSERT(!list.IsNull());
+  MessageWriter writer(&exit_message_, &allocator, false);
+  writer.WriteMessage(list);
+  exit_message_length_ = writer.BytesWritten();
+  ASSERT(exit_message_ != NULL);
+  ASSERT(exit_message_length_ != 0);
+}
+
+
+void ServiceIsolate::FinishedExiting() {
+  MonitorLocker ml(monitor_);
+  shutting_down_ = false;
+  ml.NotifyAll();
+}
+
+
 void ServiceIsolate::FinishedInitializing() {
   MonitorLocker ml(monitor_);
   initializing_ = false;
@@ -540,6 +613,8 @@
 
     Isolate::SetCurrent(NULL);
 
+    ServiceIsolate::ConstructExitMessageAndCache(isolate);
+
     RunMain(isolate);
 
     ServiceIsolate::FinishedInitializing();
@@ -577,6 +652,7 @@
     if (FLAG_trace_service) {
       OS::Print("vm-service: Shutdown.\n");
     }
+    ServiceIsolate::FinishedExiting();
   }
 
   void RunMain(Isolate* isolate) {
@@ -639,6 +715,24 @@
 }
 
 
+void ServiceIsolate::Shutdown() {
+  if (!IsRunning()) {
+    return;
+  }
+  {
+    MonitorLocker ml(monitor_);
+    shutting_down_ = true;
+  }
+  SendServiceExitMessage();
+  {
+    MonitorLocker ml(monitor_);
+    while (shutting_down_ && (port_ != ILLEGAL_PORT)) {
+      ml.Wait();
+    }
+  }
+}
+
+
 Dart_Handle ServiceIsolate::GetSource(const char* name) {
   ASSERT(name != NULL);
   int i = 0;
diff --git a/runtime/vm/service_isolate.h b/runtime/vm/service_isolate.h
index 824d136..e71027f 100644
--- a/runtime/vm/service_isolate.h
+++ b/runtime/vm/service_isolate.h
@@ -28,11 +28,15 @@
   static void Run();
   static bool SendIsolateStartupMessage();
   static bool SendIsolateShutdownMessage();
+  static void SendServiceExitMessage();
+  static void Shutdown();
 
  protected:
   static void SetServicePort(Dart_Port port);
   static void SetServiceIsolate(Isolate* isolate);
   static void SetLoadPort(Dart_Port port);
+  static void ConstructExitMessageAndCache(Isolate* isolate);
+  static void FinishedExiting();
   static void FinishedInitializing();
   static void MaybeInjectVMServiceLibrary(Isolate* isolate);
   static Dart_IsolateCreateCallback create_callback() {
@@ -44,8 +48,11 @@
                                        Dart_Handle url);
 
   static Dart_IsolateCreateCallback create_callback_;
+  static uint8_t* exit_message_;
+  static intptr_t exit_message_length_;
   static Monitor* monitor_;
   static bool initializing_;
+  static bool shutting_down_;
   static Isolate* isolate_;
   static Dart_Port port_;
   static Dart_Port load_port_;
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index 7fe9b0c..eadd7fa 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -35,8 +35,8 @@
     }
 
     // Parse the message.
-    SnapshotReader reader(message->data(), message->len(),
-                          Snapshot::kMessage, Isolate::Current());
+    SnapshotReader reader(message->data(), message->len(), Snapshot::kMessage,
+                          Isolate::Current(), Thread::Current()->zone());
     const Object& response_obj = Object::Handle(reader.ReadObject());
     String& response = String::Handle();
     response ^= response_obj.raw();
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 8ef91b4..8af983f 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -164,10 +164,12 @@
 SnapshotReader::SnapshotReader(const uint8_t* buffer,
                                intptr_t size,
                                Snapshot::Kind kind,
-                               Isolate* isolate)
+                               Isolate* isolate,
+                               Zone* zone)
     : BaseReader(buffer, size),
       kind_(kind),
       isolate_(isolate),
+      zone_(zone),
       heap_(isolate->heap()),
       old_space_(isolate->heap()->old_space()),
       cls_(Class::Handle(isolate)),
@@ -219,7 +221,7 @@
          !IsSingletonClassId(GetVMIsolateObjectId(class_header)));
   ASSERT((SerializedHeaderTag::decode(class_header) != kObjectId) ||
          !IsObjectStoreClassId(SerializedHeaderData::decode(class_header)));
-  Class& cls = Class::ZoneHandle(isolate(), Class::null());
+  Class& cls = Class::ZoneHandle(zone(), Class::null());
   AddBackRef(object_id, &cls, kIsDeserialized);
   // Read the library/class information and lookup the class.
   str_ ^= ReadObjectImpl(class_header);
@@ -244,7 +246,7 @@
   // First create a function object and associate it with the specified
   // 'object_id'.
   Function& func = Function::Handle(isolate(), Function::null());
-  Instance& obj = Instance::ZoneHandle(isolate(), Instance::null());
+  Instance& obj = Instance::ZoneHandle(zone(), Instance::null());
   AddBackRef(object_id, &obj, kIsDeserialized);
 
   // Read the library/class/function information and lookup the function.
@@ -356,7 +358,7 @@
   // instance of it. The individual fields will be read later.
   intptr_t header_id = SerializedHeaderData::decode(class_header);
   if (header_id == kInstanceObjectId) {
-    Instance& result = Instance::ZoneHandle(isolate(), Instance::null());
+    Instance& result = Instance::ZoneHandle(zone(), Instance::null());
     AddBackRef(object_id, &result, kIsNotDeserialized);
 
     cls_ ^= ReadObjectImpl();  // Read class information.
@@ -385,7 +387,7 @@
     // Read the length and allocate an object based on the len.
     intptr_t len = ReadSmiValue();
     Array& array = Array::ZoneHandle(
-        isolate(),
+        zone(),
         ((kind_ == Snapshot::kFull) ?
          NewArray(len) : Array::New(len, HEAP_SPACE(kind_))));
     AddBackRef(object_id, &array, kIsNotDeserialized);
@@ -396,7 +398,7 @@
     // Read the length and allocate an object based on the len.
     intptr_t len = ReadSmiValue();
     Array& array = Array::ZoneHandle(
-        isolate(),
+        zone(),
         (kind_ == Snapshot::kFull) ?
         NewImmutableArray(len) : ImmutableArray::New(len, HEAP_SPACE(kind_)));
     AddBackRef(object_id, &array, kIsNotDeserialized);
@@ -494,7 +496,7 @@
   // TODO(asiva): Add a check here to ensure we have the right heap
   // size for the full snapshot being read.
   {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     HeapLocker hl(isolate, old_space());
 
     // Read in all the objects stored in the object store.
@@ -589,7 +591,7 @@
 
 #define ALLOC_NEW_OBJECT_WITH_LEN(type, length)                                \
   ASSERT(kind_ == Snapshot::kFull);                                            \
-  ASSERT(isolate()->no_gc_scope_depth() != 0);                                 \
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);                          \
   Raw##type* obj = reinterpret_cast<Raw##type*>(                               \
       AllocateUninitialized(k##type##Cid, type::InstanceSize(length)));        \
   obj->StoreSmi(&(obj->ptr()->length_), Smi::New(length));                     \
@@ -623,7 +625,7 @@
 
 RawTokenStream* SnapshotReader::NewTokenStream(intptr_t len) {
   ASSERT(kind_ == Snapshot::kFull);
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   stream_ = reinterpret_cast<RawTokenStream*>(
       AllocateUninitialized(kTokenStreamCid, TokenStream::InstanceSize()));
   uint8_t* array = const_cast<uint8_t*>(CurrentBufferAddress());
@@ -641,7 +643,7 @@
 
 RawContext* SnapshotReader::NewContext(intptr_t num_variables) {
   ASSERT(kind_ == Snapshot::kFull);
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   RawContext* obj = reinterpret_cast<RawContext*>(
       AllocateUninitialized(kContextCid, Context::InstanceSize(num_variables)));
   obj->ptr()->num_variables_ = num_variables;
@@ -651,7 +653,7 @@
 
 RawClass* SnapshotReader::NewClass(intptr_t class_id) {
   ASSERT(kind_ == Snapshot::kFull);
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   if (class_id < kNumPredefinedCids) {
     ASSERT((class_id >= kInstanceCid) &&
            (class_id <= kNullCid));
@@ -670,7 +672,7 @@
 
 RawInstance* SnapshotReader::NewInstance() {
   ASSERT(kind_ == Snapshot::kFull);
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   RawInstance* obj = reinterpret_cast<RawInstance*>(
       AllocateUninitialized(kObjectCid, Instance::InstanceSize()));
   return obj;
@@ -679,7 +681,7 @@
 
 RawMint* SnapshotReader::NewMint(int64_t value) {
   ASSERT(kind_ == Snapshot::kFull);
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   RawMint* obj = reinterpret_cast<RawMint*>(
       AllocateUninitialized(kMintCid, Mint::InstanceSize()));
   obj->ptr()->value_ = value;
@@ -689,7 +691,7 @@
 
 RawDouble* SnapshotReader::NewDouble(double value) {
   ASSERT(kind_ == Snapshot::kFull);
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   RawDouble* obj = reinterpret_cast<RawDouble*>(
       AllocateUninitialized(kDoubleCid, Double::InstanceSize()));
   obj->ptr()->value_ = value;
@@ -699,7 +701,7 @@
 
 RawTypedData* SnapshotReader::NewTypedData(intptr_t class_id, intptr_t len) {
   ASSERT(kind_ == Snapshot::kFull);
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   const intptr_t lengthInBytes = len * TypedData::ElementSizeInBytes(class_id);
   RawTypedData* obj = reinterpret_cast<RawTypedData*>(
       AllocateUninitialized(class_id, TypedData::InstanceSize(lengthInBytes)));
@@ -710,7 +712,7 @@
 
 #define ALLOC_NEW_OBJECT(type)                                                 \
   ASSERT(kind_ == Snapshot::kFull);                                            \
-  ASSERT(isolate()->no_gc_scope_depth() != 0);                                 \
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);                          \
   return reinterpret_cast<Raw##type*>(                                         \
       AllocateUninitialized(k##type##Cid, type::InstanceSize()));              \
 
@@ -808,7 +810,7 @@
 RawFloat32x4* SnapshotReader::NewFloat32x4(float v0, float v1, float v2,
                                            float v3) {
   ASSERT(kind_ == Snapshot::kFull);
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   RawFloat32x4* obj = reinterpret_cast<RawFloat32x4*>(
       AllocateUninitialized(kFloat32x4Cid, Float32x4::InstanceSize()));
   obj->ptr()->value_[0] = v0;
@@ -822,7 +824,7 @@
 RawInt32x4* SnapshotReader::NewInt32x4(uint32_t v0, uint32_t v1, uint32_t v2,
                                        uint32_t v3) {
   ASSERT(kind_ == Snapshot::kFull);
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   RawInt32x4* obj = reinterpret_cast<RawInt32x4*>(
       AllocateUninitialized(kInt32x4Cid, Int32x4::InstanceSize()));
   obj->ptr()->value_[0] = v0;
@@ -835,7 +837,7 @@
 
 RawFloat64x2* SnapshotReader::NewFloat64x2(double v0, double v1) {
   ASSERT(kind_ == Snapshot::kFull);
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   RawFloat64x2* obj = reinterpret_cast<RawFloat64x2*>(
       AllocateUninitialized(kFloat64x2Cid, Float64x2::InstanceSize()));
   obj->ptr()->value_[0] = v0;
@@ -894,7 +896,7 @@
 
 RawObject* SnapshotReader::AllocateUninitialized(intptr_t class_id,
                                                  intptr_t size) {
-  ASSERT(isolate()->no_gc_scope_depth() != 0);
+  ASSERT(isolate()->no_safepoint_scope_depth() != 0);
   ASSERT(Utils::IsAligned(size, kObjectAlignment));
 
   // Allocate memory where all words look like smis. This is currently
@@ -992,7 +994,7 @@
     Instance* result = reinterpret_cast<Instance*>(GetBackRef(object_id));
     intptr_t instance_size = 0;
     if (result == NULL) {
-      result = &(Instance::ZoneHandle(isolate(), Instance::null()));
+      result = &(Instance::ZoneHandle(zone(), Instance::null()));
       AddBackRef(object_id, result, kIsDeserialized);
       cls_ ^= ReadObjectImpl();
       ASSERT(!cls_.IsNull());
@@ -1218,7 +1220,7 @@
     return;
   }
 
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   RawClass* cls = class_table_->At(raw->GetClassId());
   intptr_t class_id = cls->ptr()->id_;
   ASSERT(class_id == raw->GetClassId());
@@ -1333,7 +1335,7 @@
 
     // Write out the full snapshot.
     {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
 
       // Write out all the objects in the object store of the isolate which
       // is the root set for all dart allocated objects at this point.
@@ -1388,7 +1390,7 @@
 
 
 intptr_t ForwardList::MarkAndAddObject(RawObject* raw, SerializeState state) {
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   intptr_t object_id = next_object_id();
   ASSERT(object_id <= kMaxObjectId);
   uword value = 0;
@@ -1405,7 +1407,7 @@
 
 
 void ForwardList::UnmarkAll() const {
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   for (intptr_t id = first_object_id(); id < next_object_id(); ++id) {
     const Node* node = NodeForObjectId(id);
     RawObject* raw = node->raw();
@@ -1420,7 +1422,7 @@
   // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3)
   // - Object that has already been written: (negative id in stream | 0x3)
 
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
 
   // First check if it is a Smi (i.e not a heap object).
   if (!rawobj->IsHeapObject()) {
@@ -1522,7 +1524,7 @@
   //    (object size in multiples of kObjectAlignment | 0x1)
   //    serialized fields of the object
   //    ......
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   uword tags = raw->ptr()->tags_;
   ASSERT(SerializedHeaderTag::decode(tags) == kObjectId);
   intptr_t object_id = SerializedHeaderData::decode(tags);
@@ -1913,7 +1915,7 @@
 
     // Write out the library object.
     {
-      NoGCScope no_gc;
+      NoSafepointScope no_safepoint;
 
       // Write out the library object.
       WriteObject(lib.raw());
@@ -1947,7 +1949,7 @@
   // the message.
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
-    NoGCScope no_gc;
+    NoSafepointScope no_safepoint;
     WriteObject(obj.raw());
     UnmarkAll();
   } else {
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index a30b64e..37a6d1e 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -245,9 +245,11 @@
   SnapshotReader(const uint8_t* buffer,
                  intptr_t size,
                  Snapshot::Kind kind,
-                 Isolate* isolate);
+                 Isolate* isolate,
+                 Zone* zone);
   ~SnapshotReader() { }
 
+  Zone* zone() const { return zone_; }
   Isolate* isolate() const { return isolate_; }
   Heap* heap() const { return heap_; }
   ObjectStore* object_store() const { return isolate_->object_store(); }
@@ -373,6 +375,7 @@
 
   Snapshot::Kind kind_;  // Indicates type of snapshot(full, script, message).
   Isolate* isolate_;  // Current isolate.
+  Zone* zone_;  // Zone for allocations while reading snapshot.
   Heap* heap_;  // Heap of the current isolate.
   PageSpace* old_space_;  // Old space of the current isolate.
   Class& cls_;  // Temporary Class handle.
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 53fb9a6..94d6d08 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -158,7 +158,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   const Object& serialized_object = Object::Handle(reader.ReadObject());
   EXPECT(Equals(null_object, serialized_object));
 
@@ -184,7 +184,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   const Object& serialized_object = Object::Handle(reader.ReadObject());
   EXPECT(Equals(smi, serialized_object));
 
@@ -211,7 +211,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   const Object& serialized_object = Object::Handle(reader.ReadObject());
   EXPECT(Equals(smi, serialized_object));
 
@@ -235,7 +235,8 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(),
+                        Thread::Current()->zone());
   const Object& serialized_object = Object::Handle(reader.ReadObject());
   EXPECT(serialized_object.IsMint());
 
@@ -306,7 +307,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   const Object& serialized_object = Object::Handle(reader.ReadObject());
   EXPECT(Equals(dbl, serialized_object));
 
@@ -333,7 +334,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   const Object& serialized_object = Object::Handle(reader.ReadObject());
   fprintf(stderr, "%s / %s\n", bl.ToCString(), serialized_object.ToCString());
 
@@ -362,7 +363,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   const Object& serialized_object = Object::Handle(reader.ReadObject());
   EXPECT(Equals(bl, serialized_object));
 
@@ -397,7 +398,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   Bigint& obj = Bigint::Handle();
   obj ^= reader.ReadObject();
 
@@ -425,7 +426,8 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(),
+                        Thread::Current()->zone());
   Bigint& serialized_bigint = Bigint::Handle();
   serialized_bigint ^= reader.ReadObject();
   const char* str1 = bigint.ToHexCString(allocator);
@@ -489,7 +491,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len, Snapshot::kMessage,
-                        Isolate::Current());
+                        Isolate::Current(), Thread::Current()->zone());
   EXPECT(Object::class_class() == reader.ReadObject());
   EXPECT(Object::type_arguments_class() == reader.ReadObject());
   EXPECT(Object::function_class() == reader.ReadObject());
@@ -520,7 +522,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   String& serialized_str = String::Handle();
   serialized_str ^= reader.ReadObject();
   EXPECT(str.Equals(serialized_str));
@@ -568,7 +570,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   Array& serialized_array = Array::Handle();
   serialized_array ^= reader.ReadObject();
   EXPECT(array.CanonicalizeEquals(serialized_array));
@@ -653,7 +655,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   Array& serialized_array = Array::Handle();
   serialized_array ^= reader.ReadObject();
   EXPECT(array.CanonicalizeEquals(serialized_array));
@@ -686,7 +688,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   TypedData& serialized_typed_data = TypedData::Handle();
   serialized_typed_data ^= reader.ReadObject();
   EXPECT(serialized_typed_data.IsTypedData());
@@ -719,7 +721,8 @@
     writer.WriteMessage(array);                                               \
     intptr_t buffer_len = writer.BytesWritten();                              \
     SnapshotReader reader(buffer, buffer_len,                                 \
-                          Snapshot::kMessage, Isolate::Current());            \
+                          Snapshot::kMessage, Isolate::Current(),             \
+                          zone.GetZone());                                    \
     TypedData& serialized_array = TypedData::Handle();                        \
     serialized_array ^= reader.ReadObject();                                  \
     for (int i = 0; i < kArrayLength; i++) {                                  \
@@ -743,7 +746,8 @@
     writer.WriteMessage(array);                                               \
     intptr_t buffer_len = writer.BytesWritten();                              \
     SnapshotReader reader(buffer, buffer_len,                                 \
-                          Snapshot::kMessage, Isolate::Current());            \
+                          Snapshot::kMessage, Isolate::Current(),             \
+                          zone.GetZone());                                    \
     TypedData& serialized_array = TypedData::Handle();                        \
     serialized_array ^= reader.ReadObject();                                  \
     for (int i = 0; i < length; i++) {                                        \
@@ -795,7 +799,7 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, buffer_len,
-                        Snapshot::kMessage, Isolate::Current());
+                        Snapshot::kMessage, Isolate::Current(), zone.GetZone());
   TypedData& serialized_typed_data = TypedData::Handle();
   serialized_typed_data ^= reader.ReadObject();
   EXPECT(serialized_typed_data.IsTypedData());
@@ -926,7 +930,8 @@
 
   // Read object back from the snapshot.
   SnapshotReader reader(buffer, writer.BytesWritten(),
-                        Snapshot::kScript, Isolate::Current());
+                        Snapshot::kScript, Isolate::Current(),
+                        Thread::Current()->zone());
   Script& serialized_script = Script::Handle();
   serialized_script ^= reader.ReadObject();
 
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index bd8b095..f8537c3 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -81,7 +81,7 @@
   // helper functions to the raw object interface.
   ASSERT(isolate_ == Isolate::Current());
   ASSERT(visitor != NULL);
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   Code code;
   code = LookupDartCode();
   if (!code.IsNull()) {
@@ -173,7 +173,7 @@
   // We add a no gc scope to ensure that the code below does not trigger
   // a GC as we are handling raw object references here. It is possible
   // that the code is called while a GC is in progress, that is ok.
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   RawCode* code = GetCodeObject();
   ASSERT(code == Code::null() || code->ptr()->owner_ != Function::null());
   return code;
@@ -184,7 +184,7 @@
   // We add a no gc scope to ensure that the code below does not trigger
   // a GC as we are handling raw object references here. It is possible
   // that the code is called while a GC is in progress, that is ok.
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   const uword pc_marker =
       *(reinterpret_cast<uword*>(fp() + (kPcMarkerSlotFromFp * kWordSize)));
   if (pc_marker != 0) {
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
new file mode 100644
index 0000000..199fd78
--- /dev/null
+++ b/runtime/vm/thread.cc
@@ -0,0 +1,30 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/thread.h"
+
+#include "vm/isolate.h"
+#include "vm/os_thread.h"
+
+
+namespace dart {
+
+// The single thread local key which stores all the thread local data
+// for a thread.
+// TODO(koda): Can we merge this with ThreadInterrupter::thread_state_key_?
+ThreadLocalKey Thread::thread_key = OSThread::kUnsetThreadLocalKey;
+
+
+void Thread::InitOnce() {
+  ASSERT(thread_key == OSThread::kUnsetThreadLocalKey);
+  thread_key = OSThread::CreateThreadLocal();
+  ASSERT(thread_key != OSThread::kUnsetThreadLocalKey);
+}
+
+
+void Thread::SetCurrent(Thread* current) {
+  OSThread::SetThreadLocal(thread_key, reinterpret_cast<uword>(current));
+}
+
+}  // namespace dart
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 26362c9..bc5c998 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -5,38 +5,48 @@
 #ifndef VM_THREAD_H_
 #define VM_THREAD_H_
 
-#include "vm/isolate.h"
+#include "vm/base_isolate.h"
+#include "vm/globals.h"
+#include "vm/os_thread.h"
 
 namespace dart {
 
+class CHA;
+class Isolate;
+
 // A VM thread; may be executing Dart code or performing helper tasks like
-// garbage collection.
+// garbage collection or compilation.
 class Thread {
  public:
+  explicit Thread(Isolate* isolate)
+      : isolate_(isolate),
+        cha_(NULL) {}
+
+  static void InitOnce();
+
   static Thread* Current() {
-    // For now, there is still just one thread per isolate, and the Thread
-    // class just aliases the Isolate*. Once all interfaces and uses have been
-    // updated to distinguish between isolates and threads, Thread will get its
-    // own thread-local storage key.
-    return reinterpret_cast<Thread*>(Isolate::Current());
+    return reinterpret_cast<Thread*>(OSThread::GetThreadLocal(thread_key));
   }
+  static void SetCurrent(Thread* current);
 
   // The topmost zone used for allocation in this thread.
   Zone* zone() {
-    return reinterpret_cast<BaseIsolate*>(this)->current_zone();
+    return reinterpret_cast<BaseIsolate*>(isolate())->current_zone();
   }
 
-  // The isolate that this thread is operating on.
-  Isolate* isolate() {
-    return reinterpret_cast<Isolate*>(this);
-  }
+  // The isolate that this thread is operating on, or NULL if none.
+  Isolate* isolate() const { return isolate_; }
 
-  // The log for this thread.
-  class Log* Log() {
-    return reinterpret_cast<Isolate*>(this)->Log();
-  }
+  // The (topmost) CHA for the compilation in this thread.
+  CHA* cha() const { return cha_; }
+  void set_cha(CHA* value) { cha_ = value; }
 
  private:
+  static ThreadLocalKey thread_key;
+
+  Isolate* isolate_;
+  CHA* cha_;
+
   DISALLOW_COPY_AND_ASSIGN(Thread);
 };
 
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index b0cb897..3b58c7a 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -275,10 +275,10 @@
 
 
 bool CompilerTest::TestCompileFunction(const Function& function) {
-  Isolate* isolate = Isolate::Current();
-  ASSERT(isolate != NULL);
+  Thread* thread = Thread::Current();
+  ASSERT(thread != NULL);
   ASSERT(ClassFinalizer::AllClassesFinalized());
-  const Error& error = Error::Handle(Compiler::CompileFunction(isolate,
+  const Error& error = Error::Handle(Compiler::CompileFunction(thread,
                                                                function));
   return error.IsNull();
 }
diff --git a/runtime/vm/verifier.cc b/runtime/vm/verifier.cc
index 8b4898c..85b56c8 100644
--- a/runtime/vm/verifier.cc
+++ b/runtime/vm/verifier.cc
@@ -67,7 +67,7 @@
 
 
 void VerifyPointersVisitor::VerifyPointers(MarkExpectation mark_expectation) {
-  NoGCScope no_gc;
+  NoSafepointScope no_safepoint;
   Isolate* isolate = Isolate::Current();
   ObjectSet* allocated_set =
       isolate->heap()->CreateAllocatedObjectSet(mark_expectation);
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index d2dc6b5..709be94 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -432,6 +432,7 @@
     'symbols.h',
     'tags.cc',
     'tags.h',
+    'thread.cc',
     'thread.h',
     'thread_interrupter.cc',
     'thread_interrupter.h',
diff --git a/sdk/bin/pub.bat b/sdk/bin/pub.bat
index 7fd3f91..904d054 100644
--- a/sdk/bin/pub.bat
+++ b/sdk/bin/pub.bat
@@ -35,7 +35,7 @@
 set DART=%BUILD_DIR%\dart-sdk\bin\dart
 
 rem Run pub.
-set PUB="%SDK_DIR%\lib\_internal\pub.dart"
+set PUB="%SDK_DIR%\lib\_internal\pub\bin\pub.dart"
 "%DART%" %VM_OPTIONS% --package-root="%PACKAGES_DIR%" "%PUB%" %*
 
 endlocal
diff --git a/sdk/lib/_internal/compiler/js_lib/annotations.dart b/sdk/lib/_internal/compiler/js_lib/annotations.dart
index 435221d..c200980 100644
--- a/sdk/lib/_internal/compiler/js_lib/annotations.dart
+++ b/sdk/lib/_internal/compiler/js_lib/annotations.dart
@@ -22,6 +22,11 @@
   const NoInline();
 }
 
+/// Tells the optimizing compiler to always inline the annotated method.
+class ForceInline {
+  const ForceInline();
+}
+
 // Ensures that the annotated method is represented internally using
 // IR nodes ([:value == true:]) or AST nodes ([:value == false:]).
 class IrRepresentation {
diff --git a/sdk/lib/_internal/compiler/js_lib/foreign_helper.dart b/sdk/lib/_internal/compiler/js_lib/foreign_helper.dart
index 8a400f8..8d83d5c 100644
--- a/sdk/lib/_internal/compiler/js_lib/foreign_helper.dart
+++ b/sdk/lib/_internal/compiler/js_lib/foreign_helper.dart
@@ -16,38 +16,71 @@
  * on the number of arguments.
  *
  * The [typeDescription] argument is interpreted as a description of the
- * behavior of the JavaScript code.  Currently it describes the types that may
- * be returned by the expression, with the additional behavior that the returned
- * values may be fresh instances of the types.  The type information must be
- * correct as it is trusted by the compiler in optimizations, and it must be
- * precise as possible since it is used for native live type analysis to
- * tree-shake large parts of the DOM libraries.  If poorly written, the
- * [typeDescription] will cause unnecessarily bloated programs.  (You can check
- * for this by compiling with `--verbose`; there is an info message describing
- * the number of native (DOM) types that can be removed, which usually should be
- * greater than zero.)
+ * behavior of the JavaScript code.  Currently it describes the side effects
+ * types that may be returned by the expression, with the additional behavior
+ * that the returned values may be fresh instances of the types.  The type
+ * information must be correct as it is trusted by the compiler in
+ * optimizations, and it must be precise as possible since it is used for native
+ * live type analysis to tree-shake large parts of the DOM libraries.  If poorly
+ * written, the [typeDescription] will cause unnecessarily bloated programs.
+ * (You can check for this by compiling with `--verbose`; there is an info
+ * message describing the number of native (DOM) types that can be removed,
+ * which usually should be greater than zero.)
  *
- * The [typeDescription] is a [String] which contains a union of types separated
- * by vertical bar `|` symbols, e.g.  `"num|String"` describes the union of
- * numbers and Strings.  There is no type in Dart that is this precise.  The
- * Dart alternative would be `Object` or `dynamic`, but these types imply that
- * the JS-code might also be creating instances of all the DOM types.  If `null`
- * is possible, it must be specified explicitly, e.g. `"String|Null"`.
- * [typeDescription] has several extensions to help describe the behavior more
- * accurately.  In addition to the union type already described:
+ * The [typeDescription] must be a [String]. Two forms of it are supported:
  *
- *  + `=Object` is a plain JavaScript object.  Some DOM methods return instances
- *     that have no corresponing Dart type (e.g. cross-frame documents),
- *     `=Object` can be used to describe these untyped' values.
+ * 1) a union of types separated by vertical bar `|` symbols, e.g.
+ *    `"num|String"` describes the union of numbers and Strings.  There is no
+ *    type in Dart that is this precise.  The Dart alternative would be `Object`
+ *    or `dynamic`, but these types imply that the JS-code might also be
+ *    creating instances of all the DOM types.
  *
- *  + `var` (or empty string).  If the entire [typeDescription] is `var` (or
- *    empty string) then the type is `dynamic` but the code is known to not
- *    create any instances.
+ *    If `null` is possible, it must be specified explicitly, e.g.
+ *    `"String|Null"`. [typeDescription] has several extensions to help describe
+ *    the behavior more accurately.  In addition to the union type already
+ *    described:
  *
- * Examples:
+ *    + `=Object` is a plain JavaScript object.  Some DOM methods return
+ *       instances that have no corresponing Dart type (e.g. cross-frame
+ *       documents), `=Object` can be used to describe these untyped' values.
  *
- *     // Parent window might be an opaque cross-frame window.
- *     var thing = JS('=Object|Window', '#.parent', myWindow);
+ *    + `var` (or empty string).  If the entire [typeDescription] is `var` (or
+ *      empty string) then the type is `dynamic` but the code is known to not
+ *      create any instances.
+ *
+ *   Examples:
+ *
+ *       // Parent window might be an opaque cross-frame window.
+ *       var thing = JS('=Object|Window', '#.parent', myWindow);
+ *
+ * 2) a sequence of the form `<tag>:<value>;` where `<tag>` is one of
+ *    `creates`, `returns`, `effects` or `depends`.
+ *
+ *    The first two tags are used to specify the created and returned types of
+ *    the expression. The value of `creates` and `returns` is a type string as
+ *    defined in 1).
+ *
+ *    The tags `effects` and `depends` encode the side effects of this call.
+ *    They can be omitted, in which case the expression is parsed and a safe
+ *    conservative side-effect estimation is computed.
+ *
+ *    The values of `effects` and `depends` may be 'all', 'none' or a
+ *    comma-separated list of 'no-index', 'no-instance' and 'no-static'.
+ *
+ *    The value 'all' indicates that the call affects/depends on every
+ *    side-effect. The flag 'none' signals that the call does not affect
+ *    (resp. depends on) anything.
+ *
+ *    The value 'no-index' indicates that the call does *not* do (resp. depends
+ *    on) any array index-store. The flag 'no-instance' indicates that the call
+ *    does not modify (resp. depends on) any instance variable. Similarly,
+ *    the 'no-static' value indicates that the call does not modify (resp.
+ *    depends on) any static variable.
+ *
+ *    The `effects` and `depends` flag must be used in tandem. Either both are
+ *    specified or none is.
+ *
+ *    Each tag (including the type tags) may only occur once in the sequence.
  *
  * Guidelines:
  *
@@ -102,9 +135,10 @@
  *
  * In the future we may extend [typeDescription] to include other aspects of the
  * behavior, for example, separating the returned types from the instantiated
- * types, or including effects to allow the compiler to perform more
- * optimizations around the code.  This might be an extension of [JS] or a new
- * function similar to [JS] with additional arguments for the new information.
+ * types to allow the compiler to perform more optimizations around the code.
+ *
+ * This might be an extension of [JS] or a new function similar to [JS] with
+ * additional arguments for the new information.
  */
 // Add additional optional arguments if needed. The method is treated internally
 // as a variable argument method.
diff --git a/sdk/lib/_internal/compiler/js_lib/interceptors.dart b/sdk/lib/_internal/compiler/js_lib/interceptors.dart
index 833f006..5ec9e93 100644
--- a/sdk/lib/_internal/compiler/js_lib/interceptors.dart
+++ b/sdk/lib/_internal/compiler/js_lib/interceptors.dart
@@ -26,6 +26,7 @@
                               regExpGetNative,
                               regExpCaptureCount,
                               stringContainsUnchecked,
+                              stringIndexOfStringUnchecked,
                               stringLastIndexOfUnchecked,
                               stringReplaceAllFuncUnchecked,
                               stringReplaceAllUnchecked,
diff --git a/sdk/lib/_internal/compiler/js_lib/js_helper.dart b/sdk/lib/_internal/compiler/js_lib/js_helper.dart
index 544eed6..1e83b62 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_helper.dart
@@ -7,19 +7,20 @@
 import 'dart:_async_await_error_codes' as async_error_codes;
 
 import 'dart:_js_embedded_names' show
-    JsGetName,
-    GET_TYPE_FROM_NAME,
-    GET_ISOLATE_TAG,
-    INTERCEPTED_NAMES,
-    INTERCEPTORS_BY_TAG,
-    LEAF_TAGS,
-    METADATA,
     DEFERRED_LIBRARY_URIS,
     DEFERRED_LIBRARY_HASHES,
+    GET_TYPE_FROM_NAME,
+    GET_ISOLATE_TAG,
     INITIALIZE_LOADED_HUNK,
+    INTERCEPTED_NAMES,
+    INTERCEPTORS_BY_TAG,
     IS_HUNK_LOADED,
     IS_HUNK_INITIALIZED,
-    NATIVE_SUPERCLASS_TAG_NAME;
+    JsGetName,
+    LEAF_TAGS,
+    METADATA,
+    NATIVE_SUPERCLASS_TAG_NAME,
+    TYPES;
 
 import 'dart:collection';
 
@@ -30,9 +31,9 @@
     leaveJsAsync;
 
 import 'dart:async' show
-    Future,
-    DeferredLoadException,
     Completer,
+    DeferredLoadException,
+    Future,
     StreamController,
     Stream,
     StreamSubscription,
@@ -69,7 +70,7 @@
 
 import 'dart:_interceptors';
 import 'dart:_internal' as _symbol_dev;
-import 'dart:_internal' show MappedIterable, EfficientLength;
+import 'dart:_internal' show EfficientLength, MappedIterable;
 
 import 'dart:_native_typed_data';
 
@@ -536,7 +537,7 @@
   @NoInline()
   computeFunctionRti(jsConstructor) {
     if (JS('bool', 'typeof # == "number"', functionType)) {
-      return getMetadata(functionType);
+      return getType(functionType);
     } else if (JS('bool', 'typeof # == "function"', functionType)) {
       var fakeInstance = JS('', 'new #()', jsConstructor);
       setRuntimeTypeInfo(
@@ -556,6 +557,11 @@
   return JS('', '#[#]', metadata, index);
 }
 
+getType(int index) {
+  var types = JS_EMBEDDED_GLOBAL('', TYPES);
+  return JS('', '#[#]', types, index);
+}
+
 class Primitives {
   /// Isolate-unique ID for caching [JsClosureMirror.function].
   /// Note the initial value is used by the first isolate (or if there are no
@@ -586,82 +592,93 @@
     return JS('int', '#', hash);
   }
 
-  static _throwFormatException(String string) {
-    throw new FormatException(string);
+  @NoInline()
+  static int _parseIntError(String source, int handleError(String source)) {
+    if (handleError == null) throw new FormatException(source);
+    return handleError(source);
   }
 
   static int parseInt(String source,
                       int radix,
                       int handleError(String source)) {
-    if (handleError == null) handleError = _throwFormatException;
-
     checkString(source);
-    var match = JS('JSExtendableArray|Null',
-        r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i.exec(#)',
-        source);
+    var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
+    var match = JS('JSExtendableArray|Null', '#.exec(#)', re, source);
     int digitsIndex = 1;
     int hexIndex = 2;
     int decimalIndex = 3;
     int nonDecimalHexIndex = 4;
+    if (match == null) {
+      // TODO(sra): It might be that the match failed due to unrecognized U+0085
+      // spaces.  We could replace them with U+0020 spaces and try matching
+      // again.
+      return _parseIntError(source, handleError);
+    }
+    String decimalMatch = match[decimalIndex];
     if (radix == null) {
-      radix = 10;
-      if (match != null) {
-        if (match[hexIndex] != null) {
-          // Cannot fail because we know that the digits are all hex.
-          return JS('num', r'parseInt(#, 16)', source);
-        }
-        if (match[decimalIndex] != null) {
-          // Cannot fail because we know that the digits are all decimal.
-          return JS('num', r'parseInt(#, 10)', source);
-        }
-        return handleError(source);
+      if (decimalMatch != null) {
+        // Cannot fail because we know that the digits are all decimal.
+        return JS('int', r'parseInt(#, 10)', source);
       }
-    } else {
-      if (radix is! int) throw new ArgumentError("Radix is not an integer");
-      if (radix < 2 || radix > 36) {
-        throw new RangeError("Radix $radix not in range 2..36");
+      if (match[hexIndex] != null) {
+        // Cannot fail because we know that the digits are all hex.
+        return JS('int', r'parseInt(#, 16)', source);
       }
-      if (match != null) {
-        if (radix == 10 && match[decimalIndex] != null) {
-          // Cannot fail because we know that the digits are all decimal.
-          return JS('num', r'parseInt(#, 10)', source);
-        }
-        if (radix < 10 || match[decimalIndex] == null) {
-          // We know that the characters must be ASCII as otherwise the
-          // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
-          // guaranteed to be a safe operation, since it preserves digits
-          // and lower-cases ASCII letters.
-          int maxCharCode;
-          if (radix <= 10) {
-            // Allow all digits less than the radix. For example 0, 1, 2 for
-            // radix 3.
-            // "0".codeUnitAt(0) + radix - 1;
-            maxCharCode = 0x30 + radix - 1;
-          } else {
-            // Letters are located after the digits in ASCII. Therefore we
-            // only check for the character code. The regexp above made already
-            // sure that the string does not contain anything but digits or
-            // letters.
-            // "a".codeUnitAt(0) + (radix - 10) - 1;
-            maxCharCode = 0x61 + radix - 10 - 1;
-          }
-          String digitsPart = match[digitsIndex];
-          for (int i = 0; i < digitsPart.length; i++) {
-            int characterCode = digitsPart.codeUnitAt(0) | 0x20;
-            if (digitsPart.codeUnitAt(i) > maxCharCode) {
-              return handleError(source);
-            }
-          }
+      return _parseIntError(source, handleError);
+    }
+
+    if (radix is! int) throw new ArgumentError("Radix is not an integer");
+    if (radix < 2 || radix > 36) {
+      throw new RangeError.range(radix, 2, 36, "radix");
+    }
+    if (radix == 10 && decimalMatch != null) {
+      // Cannot fail because we know that the digits are all decimal.
+      return JS('int', r'parseInt(#, 10)', source);
+    }
+    // If radix >= 10 and we have only decimal digits the string is safe.
+    // Otherwise we need to check the digits.
+    if (radix < 10 || decimalMatch == null) {
+      // We know that the characters must be ASCII as otherwise the
+      // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
+      // guaranteed to be a safe operation, since it preserves digits
+      // and lower-cases ASCII letters.
+      int maxCharCode;
+      if (radix <= 10) {
+        // Allow all digits less than the radix. For example 0, 1, 2 for
+        // radix 3.
+        // "0".codeUnitAt(0) + radix - 1;
+        maxCharCode = (0x30 - 1) + radix;
+      } else {
+        // Letters are located after the digits in ASCII. Therefore we
+        // only check for the character code. The regexp above made already
+        // sure that the string does not contain anything but digits or
+        // letters.
+        // "a".codeUnitAt(0) + (radix - 10) - 1;
+        maxCharCode = (0x61 - 10 - 1) + radix;
+      }
+      assert(match[digitsIndex] is String);
+      String digitsPart = JS('String', '#[#]', match, digitsIndex);
+      for (int i = 0; i < digitsPart.length; i++) {
+        int characterCode = digitsPart.codeUnitAt(i) | 0x20;
+        if (characterCode > maxCharCode) {
+          return _parseIntError(source, handleError);
         }
       }
     }
-    if (match == null) return handleError(source);
-    return JS('num', r'parseInt(#, #)', source, radix);
+    // The above matching and checks ensures the source has at least one digits
+    // and all digits are suitable for the radix, so parseInt cannot return NaN.
+    return JS('int', r'parseInt(#, #)', source, radix);
+  }
+
+  @NoInline()
+  static double _parseDoubleError(String source,
+                                  double handleError(String source)) {
+    if (handleError == null) throw new FormatException(source);
+    return handleError(source);
   }
 
   static double parseDouble(String source, double handleError(String source)) {
     checkString(source);
-    if (handleError == null) handleError = _throwFormatException;
     // Notice that JS parseFloat accepts garbage at the end of the string.
     // Accept only:
     // - [+/-]NaN
@@ -672,7 +689,7 @@
             r'/^\s*[+-]?(?:Infinity|NaN|'
                 r'(?:\.\d+|\d+(?:\.\d*)?)(?:[eE][+-]?\d+)?)\s*$/.test(#)',
             source)) {
-      return handleError(source);
+      return _parseDoubleError(source, handleError);
     }
     var result = JS('num', r'parseFloat(#)', source);
     if (result.isNaN) {
@@ -680,7 +697,7 @@
       if (trimmed == 'NaN' || trimmed == '+NaN' || trimmed == '-NaN') {
         return result;
       }
-      return handleError(source);
+      return _parseDoubleError(source, handleError);
     }
     return result;
   }
@@ -750,12 +767,13 @@
   static bool get isD8 {
     return JS('bool',
               'typeof version == "function"'
-              ' && typeof os == "object" && "system" in os');
+              ' && typeof os == "object" && "setenv" in os');
   }
 
   static bool get isJsshell {
     return JS('bool',
-              'typeof version == "function" && typeof system == "function"');
+              'typeof version == "function" '
+              ' && typeof os == "object" && "getenv" in os');
   }
 
   static String currentUri() {
@@ -1128,20 +1146,47 @@
 
   static applyFunctionWithPositionalArguments(Function function,
                                               List positionalArguments) {
-    int argumentCount = 0;
     List arguments;
 
     if (positionalArguments != null) {
       if (JS('bool', '# instanceof Array', positionalArguments)) {
-        arguments = positionalArguments;
+        arguments = JS('JSArray', '#', positionalArguments);
       } else {
         arguments = new List.from(positionalArguments);
       }
-      argumentCount = JS('int', '#.length', arguments);
     } else {
       arguments = [];
     }
 
+    if (arguments.length == 0) {
+      String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX0);
+      if (JS('bool', '!!#[#]', function, selectorName)) {
+        return JS('', '#[#]()', function, selectorName);
+      }
+    } else if (arguments.length == 1) {
+      String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX1);
+      if (JS('bool', '!!#[#]', function, selectorName)) {
+        return JS('', '#[#](#[0])', function, selectorName, arguments);
+      }
+    } else if (arguments.length == 2) {
+      String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX2);
+      if (JS('bool', '!!#[#]', function, selectorName)) {
+        return JS('', '#[#](#[0],#[1])', function, selectorName,
+            arguments, arguments);
+      }
+    } else if (arguments.length == 3) {
+      String selectorName = JS_GET_NAME(JsGetName.CALL_PREFIX3);
+      if (JS('bool', '!!#[#]', function, selectorName)) {
+        return JS('', '#[#](#[0],#[1],#[2])', function, selectorName,
+            arguments, arguments, arguments);
+      }
+    }
+    return _genericApplyFunctionWithPositionalArguments(function, arguments);
+  }
+
+  static _genericApplyFunctionWithPositionalArguments(Function function,
+                                                      List arguments) {
+    int argumentCount = arguments.length;
     String selectorName =
         '${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$$argumentCount';
     var jsFunction = JS('var', '#[#]', function, selectorName);
@@ -1150,7 +1195,7 @@
       jsFunction = JS('', '#["call*"]', interceptor);
 
       if (jsFunction == null) {
-        return functionNoSuchMethod(function, positionalArguments, null);
+        return functionNoSuchMethod(function, arguments, null);
       }
       ReflectionInfo info = new ReflectionInfo(jsFunction);
       int requiredArgumentCount = info.requiredParameterCount;
@@ -1159,11 +1204,11 @@
       if (info.areOptionalParametersNamed ||
           requiredArgumentCount > argumentCount ||
           maxArgumentCount < argumentCount) {
-        return functionNoSuchMethod(function, positionalArguments, null);
+        return functionNoSuchMethod(function, arguments, null);
       }
       arguments = new List.from(arguments);
       for (int pos = argumentCount; pos < maxArgumentCount; pos++) {
-        arguments.add(info.defaultValue(pos));
+        arguments.add(getMetadata(info.defaultValue(pos)));
       }
     }
     // We bound 'this' to [function] because of how we compile
@@ -2150,13 +2195,13 @@
 
     var signatureFunction;
     if (JS('bool', 'typeof # == "number"', functionType)) {
-      var metadata = JS_EMBEDDED_GLOBAL('', METADATA);
+      var types = JS_EMBEDDED_GLOBAL('', TYPES);
       // It is ok, if the access is inlined into the JS. The access is safe in
       // and outside the function. In fact we prefer if there is a textual
       // inlining.
       signatureFunction =
           JS('', '(function(s){return function(){return #[s]}})(#)',
-              metadata,
+              types,
               functionType);
     } else if (!isStatic
                && JS('bool', 'typeof # == "function"', functionType)) {
@@ -3667,18 +3712,28 @@
                      AsyncStarStreamController controller) {
   if (identical(bodyFunctionOrErrorCode, async_error_codes.SUCCESS)) {
     // This happens on return from the async* function.
-    controller.close();
+    if (controller.cancelationCompleter != null) {
+      controller.cancelationCompleter.complete();
+    } else {
+      controller.close();
+    }
     return;
   } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) {
     // The error is a js-error.
-    controller.addError(unwrapException(object),
-                        getTraceFromException(object));
-    controller.close();
+    if (controller.cancelationCompleter != null) {
+      controller.cancelationCompleter.completeError(
+          unwrapException(object),
+          getTraceFromException(object));
+    } else {
+      controller.addError(unwrapException(object),
+                          getTraceFromException(object));
+      controller.close();
+    }
     return;
   }
 
   if (object is IterationMarker) {
-    if (controller.stopRunning) {
+    if (controller.cancelationCompleter != null) {
       _wrapJsFunctionForAsync(bodyFunctionOrErrorCode,
           async_error_codes.STREAM_WAS_CANCELED)(null);
       return;
@@ -3735,7 +3790,8 @@
 class AsyncStarStreamController {
   StreamController controller;
   Stream get stream => controller.stream;
-  bool stopRunning = false;
+  Completer cancelationCompleter = null;
+  bool get isCanceled => cancelationCompleter != null;
   bool isAdding = false;
   bool isPaused = false;
   add(event) => controller.add(event);
@@ -3762,8 +3818,12 @@
           asyncStarHelper(null, body, this);
         }
       }, onCancel: () {
-        stopRunning = true;
-        if (isPaused) asyncStarHelper(null, body, this);
+        if (!controller.isClosed) {
+          cancelationCompleter = new Completer();
+          if (isPaused) asyncStarHelper(null, body, this);
+
+          return cancelationCompleter.future;
+        }
       });
   }
 }
diff --git a/sdk/lib/_internal/compiler/js_lib/js_mirrors.dart b/sdk/lib/_internal/compiler/js_lib/js_mirrors.dart
index 5945867..9fc50b7 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_mirrors.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_mirrors.dart
@@ -55,6 +55,7 @@
     createUnmangledInvocationMirror,
     getMangledTypeName,
     getMetadata,
+    getType,
     getRuntimeType,
     runtimeTypeToString,
     setRuntimeTypeInfo,
@@ -287,7 +288,7 @@
   TypeMirror get upperBound {
     if (_cachedUpperBound != null) return _cachedUpperBound;
     return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation(
-        owner, getMetadata(_typeVariable.bound));
+        owner, getType(_typeVariable.bound));
   }
 
   bool isSubtypeOf(TypeMirror other) => throw new UnimplementedError();
@@ -649,7 +650,7 @@
     //  }
     //  The typedefType is the index into the metadata table.
     int index = JS('int', '#[#]', descriptor, TYPEDEF_TYPE_PROPERTY_NAME);
-    mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index));
+    mirror = new JsTypedefMirror(symbol, mangledName, getType(index));
   } else {
     fields = JS('', '#[#]', descriptor,
         JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY));
@@ -1185,14 +1186,8 @@
 
   _newProbeFn(String id, bool useEval) {
     if (useEval) {
-      // We give the probe function a name to make it appear nicely in
-      // profiles and when debugging. The name also makes the source code
-      // for the function more "unique" so the underlying JavaScript
-      // engine is less likely to re-use an existing piece of generated
-      // code as the result of calling eval. In return, this leads to
-      // less polymorphic access in the probe function.
-      var body = "(function probe\$$id(c){return c.$id})";
-      return JS('', '(function(b){return eval(b)})(#)', body);
+      String body = "return c.$id;";
+      return JS('', 'new Function("c", #)', body);
     } else {
       return JS('', '(function(n){return(function(c){return c[n]})})(#)', id);
     }
@@ -1200,16 +1195,15 @@
 
   _newGetterFn(String name, bool useEval) {
     if (!useEval) return _newGetterNoEvalFn(name);
-    // We give the getter function a name that associates it with the
-    // class of the reflectee. This makes it easier to spot in profiles
-    // and when debugging, but it also means that the underlying JavaScript
-    // engine will only share the generated code for accessors on the
+    // We use a comment that associates the generated function with the
+    // class of the reflectee. This makes it more likely that the underlying
+    // JavaScript engine will only share the generated code for accessors on the
     // same class (through caching of eval'ed code). This makes the
     // generated call to the getter - e.g. o.get$foo() - much more likely
     // to be monomorphic and inlineable.
     String className = JS('String', '#.constructor.name', reflectee);
-    var body = "(function $className\$$name(o){return o.$name()})";
-    return JS('', '(function(b){return eval(b)})(#)', body);
+    String body = "/* $className */ return o.$name();";
+    return JS('', 'new Function("o", #)', body);
   }
 
   _newGetterNoEvalFn(n) => JS('',
@@ -1224,12 +1218,10 @@
     if (!useEval) return _newInterceptGetterNoEvalFn(name, interceptor);
     String className = JS('String', '#.constructor.name', interceptor);
     String functionName = '$className\$$name';
-    var body =
-        '(function(i) {'
+    String body =
         '  function $functionName(o){return i.$name(o)}'
-        '  return $functionName;'
-        '})';
-    return JS('', '(function(b){return eval(b)})(#)(#)', body, interceptor);
+        '  return $functionName;';
+    return JS('', '(new Function("i", #))(#)', body, interceptor);
   }
 
   _newInterceptGetterNoEvalFn(n, i) => JS('',
@@ -1510,7 +1502,7 @@
     List<int> typeInformation =
         JS('List|Null', '#[#]', typeInformationContainer, _class._mangledName);
     assert(typeInformation != null);
-    var type = getMetadata(typeInformation[0]);
+    var type = getType(typeInformation[0]);
     return _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
   }
 
@@ -1679,6 +1671,9 @@
 
   List<JsMethodMirror> _getMethodsWithOwner(DeclarationMirror methodOwner) {
     var prototype = JS('', '#.prototype', _jsConstructor);
+    // The prototype might not have been processed yet, so do that now.
+    JS('', '#[#]()', prototype,
+                     JS_GET_NAME(JsGetName.DEFERRED_ACTION_PROPERTY));
     List<String> keys = extractKeys(prototype);
     var result = <JsMethodMirror>[];
     for (String key in keys) {
@@ -1986,7 +1981,7 @@
       List<int> typeInformation =
           JS('List|Null', '#[#]', typeInformationContainer, _mangledName);
       if (typeInformation != null) {
-        var type = getMetadata(typeInformation[0]);
+        var type = getType(typeInformation[0]);
         _superclass = typeMirrorFromRuntimeTypeRepresentation(this, type);
       } else {
         var superclassName = _fieldsDescriptor.split(';')[0];
@@ -2044,7 +2039,7 @@
     List<ClassMirror> result = const <ClassMirror>[];
     if (typeInformation != null) {
       ClassMirror lookupType(int i) {
-        var type = getMetadata(i);
+        var type = getType(i);
         return typeMirrorFromRuntimeTypeRepresentation(owner, type);
       }
 
@@ -2188,7 +2183,7 @@
   String get _prettyName => 'VariableMirror';
 
   TypeMirror get type {
-    return typeMirrorFromRuntimeTypeRepresentation(owner, getMetadata(_type));
+    return typeMirrorFromRuntimeTypeRepresentation(owner, getType(_type));
   }
 
   DeclarationMirror get owner => _owner;
diff --git a/sdk/lib/_internal/compiler/js_lib/js_names.dart b/sdk/lib/_internal/compiler/js_lib/js_names.dart
index 7058b07..76c72be 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_names.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_names.dart
@@ -27,55 +27,118 @@
 /// A map from mangled names to "reflective" names, that is, unmangled names
 /// with some additional information, such as, number of required arguments.
 /// This map is for mangled names used as instance members.
-final Map<String, String> mangledNames =
-    computeMangledNames(
-        JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES),
-        false);
+final _LazyMangledNamesMap mangledNames = new _LazyMangledInstanceNamesMap(
+    JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES));
 
 /// A map from "reflective" names to mangled names (the reverse of
 /// [mangledNames]).
-final Map<String, String> reflectiveNames =
-    computeReflectiveNames(mangledNames);
+final _LazyReflectiveNamesMap reflectiveNames =
+    new _LazyReflectiveNamesMap(JS_EMBEDDED_GLOBAL('=Object', MANGLED_NAMES),
+        true);
 
 /// A map from mangled names to "reflective" names (see [mangledNames]).  This
 /// map is for globals, that is, static and top-level members.
-final Map<String, String> mangledGlobalNames = computeMangledNames(
-        JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES),
-        true);
+final _LazyMangledNamesMap mangledGlobalNames = new _LazyMangledNamesMap(
+    JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES));
 
 /// A map from "reflective" names to mangled names (the reverse of
 /// [mangledGlobalNames]).
-final Map<String, String> reflectiveGlobalNames =
-    computeReflectiveNames(mangledGlobalNames);
+final _LazyReflectiveNamesMap reflectiveGlobalNames =
+    new _LazyReflectiveNamesMap(
+        JS_EMBEDDED_GLOBAL('=Object', MANGLED_GLOBAL_NAMES), false);
 
-/// [jsMangledNames] is a JavaScript object literal.  The keys are the mangled
-/// names, and the values are the "reflective" names.
-Map<String, String> computeMangledNames(jsMangledNames, bool isGlobal) {
-  preserveNames();
-  var keys = extractKeys(jsMangledNames);
-  var result = <String, String>{};
-  String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX);
-  int getterPrefixLength = getterPrefix.length;
-  String setterPrefix = JS_GET_NAME(JsGetName.SETTER_PREFIX);
-  for (String key in keys) {
-    String value = JS('String', '#[#]', jsMangledNames, key);
-    result[key] = value;
-    if (!isGlobal) {
-      if (key.startsWith(getterPrefix)) {
-        result['$setterPrefix${key.substring(getterPrefixLength)}'] = '$value=';
-      }
-    }
+/// Implements a mapping from mangled names to their reflective counterparts.
+/// The propertiy names of [_jsMangledNames] are the mangled names, and the
+/// values are the "reflective" names.
+class _LazyMangledNamesMap {
+  /// [_jsMangledNames] is a JavaScript object literal.
+  var _jsMangledNames;
+
+  _LazyMangledNamesMap(this._jsMangledNames);
+
+  String operator[](String key) {
+    var result = JS('var', '#[#]', _jsMangledNames, key);
+    // Filter out all non-string values to protect against polution from
+    // anciliary fields in [_jsMangledNames].
+    bool filter =
+        JS('bool', 'typeof # !== "string"', result);
+    // To ensure that the inferrer sees that result is a String, we explicitly
+    // give it a better type here.
+    return filter ? null : JS('String', '#', result);
   }
-  return result;
 }
 
-Map<String, String> computeReflectiveNames(Map<String, String> map) {
-  preserveNames();
-  var result = <String, String>{};
-  map.forEach((String mangledName, String reflectiveName) {
-    result[reflectiveName] = mangledName;
-  });
-  return result;
+/// Extends [_LazyMangledNamesMap] with additional support for adding mappings
+/// from mangled setter names to their reflective counterpart by rewriting a
+/// corresponding entry for a getter name, if it exists.
+class _LazyMangledInstanceNamesMap extends _LazyMangledNamesMap {
+  _LazyMangledInstanceNamesMap(_jsMangledNames) : super(_jsMangledNames);
+
+  String operator[](String key) {
+    String result = super[key];
+    String setterPrefix = JS_GET_NAME(JsGetName.SETTER_PREFIX);
+    if (result == null && key.startsWith(setterPrefix)) {
+      String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX);
+      int setterPrefixLength = setterPrefix.length;
+
+      // Generate the setter name from the getter name.
+      key = '$getterPrefix${key.substring(setterPrefixLength)}';
+      result = super[key];
+      return (result != null) ? "${result}=" : null;
+    }
+    return result;
+  }
+}
+
+/// Implements the inverse of [_LazyMangledNamesMap]. As it would be too
+/// expensive to seach the mangled names map for a value that corresponds to
+/// the lookup key on each invocation, we compute the full mapping in demand
+/// and cache it. The cache is invalidated when the underlying [_jsMangledNames]
+/// object changes its length. This condition is sufficient as the name mapping
+/// can only grow over time.
+/// When [_isInstance] is true, we also apply the inverse of the setter/getter
+/// name conversion implemented by [_LazyMangledInstanceNamesMap].
+class _LazyReflectiveNamesMap {
+  /// [_jsMangledNames] is a JavaScript object literal.
+  final _jsMangledNames;
+  final bool _isInstance;
+  int _cacheLength = 0;
+  Map<String, String> _cache;
+
+  _LazyReflectiveNamesMap(this._jsMangledNames, this._isInstance);
+
+  Map<String, String> _updateReflectiveNames() {
+    preserveNames();
+    Map<String, String> result = <String, String>{};
+    List keys = JS('List', 'Object.keys(#)', _jsMangledNames);
+    for (String key in keys) {
+      var reflectiveName = JS('var', '#[#]', _jsMangledNames, key);
+      // Filter out all non-string values to protect against polution from
+      // anciliary fields in [_jsMangledNames].
+      bool filter = JS('bool', 'typeof # !== "string"', reflectiveName);
+      if (filter) continue;
+      result[reflectiveName] = JS('String', '#', key);
+
+      String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX);
+      if (_isInstance && key.startsWith(getterPrefix)) {
+        int getterPrefixLength = getterPrefix.length;
+        String setterPrefix = JS_GET_NAME(JsGetName.SETTER_PREFIX);
+        result['$reflectiveName='] =
+            '$setterPrefix${key.substring(getterPrefixLength)}';
+      }
+    }
+    return result;
+  }
+
+  int get _jsMangledNamesLength => JS('int', '#.length', _jsMangledNames);
+
+  String operator[](String key) {
+    if (_cache == null || _jsMangledNamesLength != _cacheLength) {
+      _cache = _updateReflectiveNames();
+      _cacheLength = _jsMangledNamesLength;
+    }
+    return _cache[key];
+  }
 }
 
 @NoInline()
diff --git a/sdk/lib/_internal/compiler/js_lib/js_number.dart b/sdk/lib/_internal/compiler/js_lib/js_number.dart
index c05f4f4..c1357e0 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_number.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_number.dart
@@ -167,7 +167,9 @@
 
   String toRadixString(int radix) {
     checkInt(radix);
-    if (radix < 2 || radix > 36) throw new RangeError(radix);
+    if (radix < 2 || radix > 36) {
+      throw new RangeError.range(radix, 2, 36, "radix");
+    }
     String result = JS('String', r'#.toString(#)', this, radix);
     const int rightParenCode = 0x29;
     if (result.codeUnitAt(result.length - 1) != rightParenCode) {
diff --git a/sdk/lib/_internal/compiler/js_lib/js_rti.dart b/sdk/lib/_internal/compiler/js_lib/js_rti.dart
index 70bb241..7246aa4 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_rti.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_rti.dart
@@ -17,15 +17,13 @@
  * these:
  *  1) a JavaScript constructor for a class C: the represented type is the raw
  *     type C.
- *  2) a Dart object: this is the interceptor instance for a native type.
- *  3) a JavaScript object: this represents a class for which there is no
- *     JavaScript constructor, because it is only used in type arguments or it
- *     is native. The represented type is the raw type of this class.
- *  4) a JavaScript array: the first entry is of type 1, 2 or 3 and contains the
+ *  2) a JavaScript array: the first entry is of type 1 and contains the
  *     subtyping flags and the substitution of the type and the rest of the
  *     array are the type arguments.
- *  5) `null`: the dynamic type.
- *
+ *  3) `null`: the dynamic type.
+ *  4) a JavaScript object representing the function type. For instance, it has
+ *     the form  {ret: rti, args: [rti], opt: [rti], named: {name: rti}} for a
+ *     function with a return type, regular, optional and named arguments.
  *
  * To check subtype relations between generic classes we use a JavaScript
  * expression that describes the necessary substitution for type arguments.
diff --git a/sdk/lib/_internal/compiler/js_lib/js_string.dart b/sdk/lib/_internal/compiler/js_lib/js_string.dart
index f7da941..84e0ac0 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_string.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_string.dart
@@ -384,7 +384,7 @@
       throw new RangeError.range(start, 0, this.length);
     }
     if (pattern is String) {
-      return JS('int', r'#.indexOf(#, #)', this, pattern, start);
+      return stringIndexOfStringUnchecked(this, pattern, start);
     }
     if (pattern is JSSyntaxRegExp) {
       JSSyntaxRegExp re = pattern;
diff --git a/sdk/lib/_internal/compiler/js_lib/preambles/jsshell.js b/sdk/lib/_internal/compiler/js_lib/preambles/jsshell.js
index e804019..0012539 100644
--- a/sdk/lib/_internal/compiler/js_lib/preambles/jsshell.js
+++ b/sdk/lib/_internal/compiler/js_lib/preambles/jsshell.js
@@ -10,7 +10,7 @@
 
   // Location (Uri.base)
 
-  var workingDirectory = environment["PWD"];
+  var workingDirectory = os.getenv("PWD");
 
   // Global properties. "self" refers to the global object, so adding a
   // property to "self" defines a global variable.
diff --git a/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart b/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart
index 50e0ab1..dff276d 100644
--- a/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart
@@ -46,6 +46,10 @@
 const DEFERRED_INITIALIZED = 'deferredInitialized';
 const PRECOMPILED = 'precompiled';
 
+/// A list of types used in the program e.g. for reflection or encoding of
+/// function types.
+const TYPES = 'types';
+
 /// Returns a function that creates a new Isolate (its static state).
 ///
 /// (floitsch): Note that this will probably go away, since one JS heap will
@@ -71,10 +75,15 @@
   GETTER_PREFIX,
   SETTER_PREFIX,
   CALL_PREFIX,
+  CALL_PREFIX0,
+  CALL_PREFIX1,
+  CALL_PREFIX2,
+  CALL_PREFIX3,
   CALL_CATCH_ALL,
   REFLECTABLE,
   CLASS_DESCRIPTOR_PROPERTY,
   REQUIRED_PARAMETER_PROPERTY,
   DEFAULT_VALUES_PROPERTY,
-  CALL_NAME_PROPERTY
+  CALL_NAME_PROPERTY,
+  DEFERRED_ACTION_PROPERTY
 }
diff --git a/sdk/lib/_internal/compiler/js_lib/string_helper.dart b/sdk/lib/_internal/compiler/js_lib/string_helper.dart
index 567e404..0206fe1 100644
--- a/sdk/lib/_internal/compiler/js_lib/string_helper.dart
+++ b/sdk/lib/_internal/compiler/js_lib/string_helper.dart
@@ -4,6 +4,22 @@
 
 part of _js_helper;
 
+stringIndexOfStringUnchecked(receiver, other, startIndex) {
+  return JS('int', '#.indexOf(#, #)', receiver, other, startIndex);
+}
+
+substring1Unchecked(receiver, startIndex) {
+  return JS('String', '#.substring(#)', receiver, startIndex);
+}
+
+substring2Unchecked(receiver, startIndex, endIndex) {
+  return JS('String', '#.substring(#, #)', receiver, startIndex, endIndex);
+}
+
+stringContainsStringUnchecked(receiver, other, startIndex) {
+  return stringIndexOfStringUnchecked(receiver, other, startIndex) >= 0;
+}
+
 class StringMatch implements Match {
   const StringMatch(int this.start,
                     String this.input,
@@ -33,19 +49,19 @@
   final String pattern;
 }
 
-List<Match> allMatchesInStringUnchecked(String needle, String haystack,
+List<Match> allMatchesInStringUnchecked(String pattern, String string,
                                         int startIndex) {
   // Copied from StringBase.allMatches in
   // /runtime/lib/string_base.dart
   List<Match> result = new List<Match>();
-  int length = haystack.length;
-  int patternLength = needle.length;
+  int length = string.length;
+  int patternLength = pattern.length;
   while (true) {
-    int position = haystack.indexOf(needle, startIndex);
+    int position = stringIndexOfStringUnchecked(string, pattern, startIndex);
     if (position == -1) {
       break;
     }
-    result.add(new StringMatch(position, haystack, needle));
+    result.add(new StringMatch(position, string, pattern));
     int endIndex = position + patternLength;
     if (endIndex == length) {
       break;
@@ -60,7 +76,7 @@
 
 stringContainsUnchecked(receiver, other, startIndex) {
   if (other is String) {
-    return receiver.indexOf(other, startIndex) != -1;
+    return stringContainsStringUnchecked(receiver, other, startIndex);
   } else if (other is JSSyntaxRegExp) {
     return other.hasMatch(receiver.substring(startIndex));
   } else {
@@ -69,51 +85,51 @@
   }
 }
 
-stringReplaceJS(receiver, replacer, to) {
+stringReplaceJS(receiver, replacer, replacement) {
   // The JavaScript String.replace method recognizes replacement
   // patterns in the replacement string. Dart does not have that
   // behavior.
-  to = JS('String', r'#.replace(/\$/g, "$$$$")', to);
-  return JS('String', r'#.replace(#, #)', receiver, replacer, to);
+  replacement = JS('String', r'#.replace(/\$/g, "$$$$")', replacement);
+  return JS('String', r'#.replace(#, #)', receiver, replacer, replacement);
 }
 
-stringReplaceFirstRE(receiver, regexp, to, startIndex) {
+stringReplaceFirstRE(receiver, regexp, replacement, startIndex) {
   var match = regexp._execGlobal(receiver, startIndex);
   if (match == null) return receiver;
   var start = match.start;
   var end = match.end;
-  return stringReplaceRangeUnchecked(receiver, start, end, to);
+  return stringReplaceRangeUnchecked(receiver, start, end, replacement);
 }
 
 const String ESCAPE_REGEXP = r'[[\]{}()*+?.\\^$|]';
 
-stringReplaceAllUnchecked(receiver, from, to) {
-  checkString(to);
-  if (from is String) {
-    if (from == "") {
+stringReplaceAllUnchecked(receiver, pattern, replacement) {
+  checkString(replacement);
+  if (pattern is String) {
+    if (pattern == "") {
       if (receiver == "") {
-        return to;
+        return replacement;
       } else {
         StringBuffer result = new StringBuffer();
         int length = receiver.length;
-        result.write(to);
+        result.write(replacement);
         for (int i = 0; i < length; i++) {
           result.write(receiver[i]);
-          result.write(to);
+          result.write(replacement);
         }
         return result.toString();
       }
     } else {
       var quoter = JS('', "new RegExp(#, 'g')", ESCAPE_REGEXP);
-      var quoted = JS('String', r'#.replace(#, "\\$&")', from, quoter);
+      var quoted = JS('String', r'#.replace(#, "\\$&")', pattern, quoter);
       var replacer = JS('', "new RegExp(#, 'g')", quoted);
-      return stringReplaceJS(receiver, replacer, to);
+      return stringReplaceJS(receiver, replacer, replacement);
     }
-  } else if (from is JSSyntaxRegExp) {
-    var re = regExpGetGlobalNative(from);
-    return stringReplaceJS(receiver, re, to);
+  } else if (pattern is JSSyntaxRegExp) {
+    var re = regExpGetGlobalNative(pattern);
+    return stringReplaceJS(receiver, re, replacement);
   } else {
-    checkNull(from);
+    checkNull(pattern);
     // TODO(floitsch): implement generic String.replace (with patterns).
     throw "String.replaceAll(Pattern) UNIMPLEMENTED";
   }
@@ -123,15 +139,17 @@
 String _stringIdentity(String string) => string;
 
 stringReplaceAllFuncUnchecked(receiver, pattern, onMatch, onNonMatch) {
-  if (pattern is! Pattern) {
-    throw new ArgumentError("${pattern} is not a Pattern");
-  }
   if (onMatch == null) onMatch = _matchString;
   if (onNonMatch == null) onNonMatch = _stringIdentity;
   if (pattern is String) {
     return stringReplaceAllStringFuncUnchecked(receiver, pattern,
                                                onMatch, onNonMatch);
   }
+  // Pattern test here is indistingishable from at the top of the method but we
+  // don't need to do it on the `pattern is String` path.
+  if (pattern is! Pattern) {
+    throw new ArgumentError("${pattern} is not a Pattern");
+  }
   StringBuffer buffer = new StringBuffer();
   int startIndex = 0;
   for (Match match in pattern.allMatches(receiver)) {
@@ -180,7 +198,7 @@
   StringBuffer buffer = new StringBuffer();
   int startIndex = 0;
   while (startIndex < length) {
-    int position = receiver.indexOf(pattern, startIndex);
+    int position = stringIndexOfStringUnchecked(receiver, pattern, startIndex);
     if (position == -1) {
       break;
     }
@@ -193,34 +211,32 @@
 }
 
 
-stringReplaceFirstUnchecked(receiver, from, to, int startIndex) {
-  if (from is String) {
-    int index = receiver.indexOf(from, startIndex);
+stringReplaceFirstUnchecked(receiver, pattern, replacement, int startIndex) {
+  if (pattern is String) {
+    int index = stringIndexOfStringUnchecked(receiver, pattern, startIndex);
     if (index < 0) return receiver;
-    int end = index + from.length;
-    return stringReplaceRangeUnchecked(receiver, index, end, to);
+    int end = index + pattern.length;
+    return stringReplaceRangeUnchecked(receiver, index, end, replacement);
   }
-  if (from is JSSyntaxRegExp) {
-    return startIndex == 0 ?
-        stringReplaceJS(receiver, regExpGetNative(from), to) :
-        stringReplaceFirstRE(receiver, from, to, startIndex);
+  if (pattern is JSSyntaxRegExp) {
+    return startIndex == 0
+        ? stringReplaceJS(receiver, regExpGetNative(pattern), replacement)
+        : stringReplaceFirstRE(receiver, pattern, replacement, startIndex);
   }
-  checkNull(from);
-  Iterator<Match> matches = from.allMatches(receiver, startIndex).iterator;
+  checkNull(pattern);
+  Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator;
   if (!matches.moveNext()) return receiver;
   Match match = matches.current;
-  return '${receiver.substring(0, match.start)}$to'
-         '${receiver.substring(match.end)}';
+  return receiver.replaceRange(match.start, match.end, replacement);
 }
 
-stringReplaceFirstMappedUnchecked(receiver, from, replace,
+stringReplaceFirstMappedUnchecked(receiver, pattern, replace,
                                   int startIndex) {
-  Iterator<Match> matches = from.allMatches(receiver, startIndex).iterator;
+  Iterator<Match> matches = pattern.allMatches(receiver, startIndex).iterator;
   if (!matches.moveNext()) return receiver;
   Match match = matches.current;
   String replacement = "${replace(match)}";
-  return '${receiver.substring(0, match.start)}$replacement'
-         '${receiver.substring(match.end)}';
+  return receiver.replaceRange(match.start, match.end, replacement);
 }
 
 stringJoinUnchecked(array, separator) {
diff --git a/sdk/lib/_internal/pub/lib/src/command/build.dart b/sdk/lib/_internal/pub/lib/src/command/build.dart
index 7a6685a..1a88922 100644
--- a/sdk/lib/_internal/pub/lib/src/command/build.dart
+++ b/sdk/lib/_internal/pub/lib/src/command/build.dart
@@ -93,7 +93,8 @@
             .map((asset) => asset.id);
 
         return Future.wait(assets.map(_writeAsset)).then((_) {
-          builtFiles += _copyBrowserJsFiles(dart2JSEntrypoints);
+          return _copyBrowserJsFiles(dart2JSEntrypoints, assets);
+        }).then((_) {
           log.message('Built $builtFiles ${pluralize('file', builtFiles)} '
               'to "$outputDirectory".');
 
@@ -190,13 +191,11 @@
   /// If this package depends directly on the `browser` package, this ensures
   /// that the JavaScript bootstrap files are copied into `packages/browser/`
   /// directories next to each entrypoint in [entrypoints].
-  ///
-  /// Returns the number of files it copied.
-  int _copyBrowserJsFiles(Iterable<AssetId> entrypoints) {
+  Future _copyBrowserJsFiles(Iterable<AssetId> entrypoints, AssetSet assets) {
     // Must depend on the browser package.
     if (!entrypoint.root.immediateDependencies.any(
         (dep) => dep.name == 'browser' && dep.source == 'hosted')) {
-      return 0;
+      return new Future.value();
     }
 
     // Get all of the subdirectories that contain Dart entrypoints.
@@ -209,29 +208,17 @@
         .where((dir) => path.split(dir).length > 1)
         .toSet();
 
-    for (var dir in entrypointDirs) {
+    var jsAssets = assets.where((asset) =>
+        asset.id.package == 'browser' && asset.id.extension == '.js');
+    return Future.wait(entrypointDirs.expand((dir) {
       // TODO(nweiz): we should put browser JS files next to any HTML file
       // rather than any entrypoint. An HTML file could import an entrypoint
       // that's not adjacent.
-      _addBrowserJs(dir, "dart");
-      _addBrowserJs(dir, "interop");
-    }
-
-    return entrypointDirs.length * 2;
-  }
-
-  // TODO(nweiz): do something more principled when issue 6101 is fixed.
-  /// Ensures that the [name].js file is copied into [directory] in [target],
-  /// under `packages/browser/`.
-  void _addBrowserJs(String directory, String name) {
-    var jsPath = entrypoint.root.path(
-        outputDirectory, directory, 'packages', 'browser', '$name.js');
-    ensureDir(path.dirname(jsPath));
-
-    // TODO(rnystrom): This won't work if we get rid of symlinks and the top
-    // level "packages" directory. Will need to copy from the browser
-    // directory.
-    copyFile(path.join(entrypoint.packagesDir, 'browser', '$name.js'), jsPath);
+      return jsAssets.map((asset) {
+        var jsPath = path.join(dir, _idToPath(asset.id));
+        return _writeOutputFile(asset, jsPath);
+      });
+    }));
   }
 
   /// Converts [entry] to a JSON object for use with JSON-formatted output.
diff --git a/sdk/lib/_internal/pub/lib/src/io.dart b/sdk/lib/_internal/pub/lib/src/io.dart
index 9662d1f..d3c779b 100644
--- a/sdk/lib/_internal/pub/lib/src/io.dart
+++ b/sdk/lib/_internal/pub/lib/src/io.dart
@@ -933,7 +933,7 @@
 ///
 /// Returns a [ByteStream] that emits the contents of the archive.
 ByteStream createTarGz(List contents, {baseDir}) {
-  return new ByteStream(futureStream(new Future.sync(() {
+  return new ByteStream(futureStream(new Future.sync(() async {
     var buffer = new StringBuffer();
     buffer.write('Creating .tag.gz stream containing:\n');
     contents.forEach((file) => buffer.write('$file\n'));
@@ -950,41 +950,51 @@
     }).toList();
 
     if (Platform.operatingSystem != "windows") {
-      var args = ["--create", "--gzip", "--directory", baseDir];
-      args.addAll(contents);
-      // TODO(nweiz): It's possible that enough command-line arguments will
-      // make the process choke, so at some point we should save the arguments
-      // to a file and pass them in via --files-from for tar and -i@filename
-      // for 7zip.
-      return startProcess("tar", args).then((process) => process.stdout);
+      var args = [
+        "--create",
+        "--gzip",
+        "--directory",
+        baseDir,
+        "--files-from",
+        "/dev/stdin"
+      ];
+
+      var process = await startProcess("tar", args);
+      process.stdin.add(UTF8.encode(contents.join("\n")));
+      process.stdin.close();
+      return process.stdout;
     }
 
     // Don't use [withTempDir] here because we don't want to delete the temp
     // directory until the returned stream has closed.
     var tempDir = createSystemTempDir();
-    return new Future.sync(() {
+
+    try {
+      // Create the file containing the list of files to compress.
+      var contentsPath = path.join(tempDir, "files.txt");
+      writeTextFile(contentsPath, contents.join("\n"));
+
       // Create the tar file.
       var tarFile = path.join(tempDir, "intermediate.tar");
-      var args = ["a", "-w$baseDir", tarFile];
-      args.addAll(contents.map((entry) => '-i!$entry'));
+      var args = ["a", "-w$baseDir", tarFile, "@$contentsPath"];
 
       // We're passing 'baseDir' both as '-w' and setting it as the working
       // directory explicitly here intentionally. The former ensures that the
       // files added to the archive have the correct relative path in the
       // archive. The latter enables relative paths in the "-i" args to be
       // resolved.
-      return runProcess(pathTo7zip, args, workingDir: baseDir).then((_) {
-        // GZIP it. 7zip doesn't support doing both as a single operation.
-        // Send the output to stdout.
-        args = ["a", "unused", "-tgzip", "-so", tarFile];
-        return startProcess(pathTo7zip, args);
-      }).then((process) => process.stdout);
-    }).then((stream) {
-      return stream.transform(onDoneTransformer(() => deleteEntry(tempDir)));
-    }).catchError((e) {
+      await runProcess(pathTo7zip, args, workingDir: baseDir);
+
+      // GZIP it. 7zip doesn't support doing both as a single operation.
+      // Send the output to stdout.
+      args = ["a", "unused", "-tgzip", "-so", tarFile];
+      return (await startProcess(pathTo7zip, args))
+          .stdout
+          .transform(onDoneTransformer(() => deleteEntry(tempDir)));
+    } catch (_) {
       deleteEntry(tempDir);
-      throw e;
-    });
+      rethrow;
+    }
   })));
 }
 
diff --git a/sdk/lib/_internal/pub/pub.status b/sdk/lib/_internal/pub/pub.status
index 449c482..a9f84bd 100644
--- a/sdk/lib/_internal/pub/pub.status
+++ b/sdk/lib/_internal/pub/pub.status
@@ -16,3 +16,4 @@
 
 [ $runtime == vm && $system == windows ]
 test/run/app_can_read_from_stdin_test: Fail # Issue 19448
+test/lish/many_files_test: Fail # Issue 22996
diff --git a/sdk/lib/_internal/pub/test/lish/many_files_test.dart b/sdk/lib/_internal/pub/test/lish/many_files_test.dart
new file mode 100644
index 0000000..1adec26
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/lish/many_files_test.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math' as math;
+
+import 'package:path/path.dart' as p;
+import 'package:scheduled_test/scheduled_test.dart';
+import 'package:scheduled_test/scheduled_server.dart';
+import 'package:shelf/shelf.dart' as shelf;
+
+import '../../lib/src/exit_codes.dart' as exit_codes;
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+import 'utils.dart';
+
+/// The maximum number of bytes in an entire path.
+///
+/// This is [Windows's number][MAX_PATH], which is a much tighter constraint
+/// than OS X or Linux. We use it everywhere for consistency.
+///
+/// [MAX_PATH]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa383130(v=vs.85).aspx
+const _pathMax = 260;
+
+main() {
+  initConfig();
+
+  integration('archives and uploads a package with more files than can fit on '
+      'the command line', () {
+    d.validPackage.create();
+
+    var argMax;
+    if (Platform.isWindows) {
+      // On Windows, the maximum argument list length is 8^5 bytes.
+      argMax = math.pow(8, 5);
+    } else {
+      // On POSIX, the maximum argument list length can be retrieved
+      // automatically.
+      var result = Process.runSync("getconf", ["ARG_MAX"]);
+      if (result.exitCode != 0) {
+        fail("getconf failed with exit code ${result.exitCode}:\n"
+            "${result.stderr}");
+      }
+
+      argMax = int.parse(result.stdout);
+    }
+
+    schedule(() {
+      var appRoot = p.join(sandboxDir, appPath);
+
+      // We'll make the filenames as long as possible to reduce the number of
+      // files we have to create to hit the maximum. However, the tar process
+      // uses relative paths, which means we can't count the root as part of the
+      // length.
+      var lengthPerFile = _pathMax - appRoot.length;
+
+      // Create enough files to hit [argMax]. This may be a slight overestimate,
+      // since other options are passed to the tar command line, but we don't
+      // know how long those will be.
+      var filesToCreate = (argMax / lengthPerFile).ceil();
+
+      for (var i = 0; i < filesToCreate; i++) {
+        var iString = i.toString();
+
+        // The file name contains "x"s to make the path hit [_pathMax],
+        // followed by a number to distinguish different files.
+        var fileName =
+          "x" * (_pathMax - appRoot.length - iString.length - 1) + iString;
+
+        new File(p.join(appRoot, fileName)).writeAsStringSync("");
+      }
+    });
+
+    var server = new ScheduledServer();
+    d.credentialsFile(server, 'access token').create();
+    var pub = startPublish(server);
+
+    confirmPublish(pub);
+    handleUploadForm(server);
+    handleUpload(server);
+
+    server.handle('GET', '/create', (request) {
+      return new shelf.Response.ok(JSON.encode({
+        'success': {'message': 'Package test_pkg 1.0.0 uploaded!'}
+      }));
+    });
+
+    pub.stdout.expect(startsWith('Uploading...'));
+    pub.stdout.expect('Package test_pkg 1.0.0 uploaded!');
+    pub.shouldExit(exit_codes.SUCCESS);
+  });
+}
diff --git a/sdk/lib/_internal/pub/test/test_pub.dart b/sdk/lib/_internal/pub/test/test_pub.dart
index cb555a0..b0ec23f 100644
--- a/sdk/lib/_internal/pub/test/test_pub.dart
+++ b/sdk/lib/_internal/pub/test/test_pub.dart
@@ -464,12 +464,7 @@
   // TODO(rnystrom): This is overly specific and inflexible regarding different
   // test packages. Should validate this a little more loosely.
   pub.stdout.expect(startsWith('Publishing test_pkg 1.0.0 to '));
-  pub.stdout.expect(emitsLines(
-      "|-- LICENSE\n"
-      "|-- lib\n"
-      "|   '-- test_pkg.dart\n"
-      "'-- pubspec.yaml\n"
-      "\n"
+  pub.stdout.expect(consumeThrough(
       "Looks great! Are you ready to upload your package (y/n)?"));
   pub.writeLine("y");
 }
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index a0cfeb1..7297754 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -304,18 +304,28 @@
 
     // Mark the target as chained (and as such half-completed).
     target._isChained = true;
-    source.then((value) {
-        assert(target._isChained);
-        target._completeWithValue(value);
-      },
-      // TODO(floitsch): eventually we would like to make this non-optional
-      // and dependent on the listeners of the target future. If none of
-      // the target future's listeners want to have the stack trace we don't
-      // need a trace.
-      onError: (error, [stackTrace]) {
-        assert(target._isChained);
-        target._completeError(error, stackTrace);
+    try {
+      source.then((value) {
+          assert(target._isChained);
+          target._completeWithValue(value);
+        },
+        // TODO(floitsch): eventually we would like to make this non-optional
+        // and dependent on the listeners of the target future. If none of
+        // the target future's listeners want to have the stack trace we don't
+        // need a trace.
+        onError: (error, [stackTrace]) {
+          assert(target._isChained);
+          target._completeError(error, stackTrace);
+        });
+    } catch (e, s) {
+      // This only happens if the `then` call threw synchronously when given
+      // valid arguments.
+      // That requires a non-conforming implementation of the Future interface,
+      // which should, hopefully, never happen.
+      scheduleMicrotask(() {
+        target._completeError(e, s);
       });
+    }
   }
 
   // Take the value (when completed) of source and complete target with that
@@ -399,7 +409,7 @@
       } else {
         // Case 2 from above. Chain the future immidiately.
         // Note that we are still completing asynchronously (through
-        // _chainForeignFuture)..
+        // _chainForeignFuture).
         _chainForeignFuture(typedFuture, this);
       }
       return;
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index 3d36b39..144921a 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -307,12 +307,14 @@
   static int checkValidRange(int start, int end, int length,
                               [String startName, String endName,
                                String message]) {
-    if (start < 0 || start > length) {
+    // Comparing with `0` as receiver produces better dart2js type inference.
+    // Ditto `start > end` below.
+    if (0 > start || start > length) {
       if (startName == null) startName = "start";
       throw new RangeError.range(start, 0, length, startName, message);
     }
     if (end != null) {
-      if (end < start || end > length) {
+      if (start > end || end > length) {
         if (endName == null) endName = "end";
         throw new RangeError.range(end, start, length, endName, message);
       }
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 681b8e8..1d29a72 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -277,6 +277,13 @@
    * value is used instead. If no [onError] is provided, a [FormatException]
    * is thrown.
    *
+   * The [onError] handler can be chosen to return `null`.  This is preferable
+   * to to throwing and then immediately catching the [FormatException].
+   * Example:
+   *
+   *     var value = int.parse(text, onError: (source) => null);
+   *     if (value == null) ... handle the problem
+   *
    * The [onError] function is only invoked if [source] is a [String]. It is
    * not invoked if the [source] is, for example, `null`.
    */
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 735b712..c08cc44 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -275,7 +275,8 @@
       return Animation._create_2(target, keyframes, timingInput);
     }
     if ((timingInput is Map || timingInput == null) && (keyframes is List<Map> || keyframes == null) && (target is Element || target == null)) {
-      return Animation._create_3(target, keyframes, timingInput);
+      var timingInput_1 = convertDartToNative_Dictionary(timingInput);
+      return Animation._create_3(target, keyframes, timingInput_1);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
   }
@@ -385,6 +386,9 @@
   // To suppress missing implicit constructor warnings.
   factory AnimationPlayer._() { throw new UnsupportedError("Not supported"); }
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(document.body.animate)');
+
   @DomName('AnimationPlayer.currentTime')
   @DocsEditable()
   @Experimental() // untriaged
@@ -2033,8 +2037,8 @@
       return;
     }
     if (dirtyHeight != null && dirtyWidth != null && dirtyY != null && dirtyX != null) {
-      var imagedata_2 = convertDartToNative_ImageData(imagedata);
-      _putImageData_2(imagedata_2, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
+      var imagedata_1 = convertDartToNative_ImageData(imagedata);
+      _putImageData_2(imagedata_1, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
       return;
     }
     throw new ArgumentError("Incorrect number or type of arguments");
@@ -2521,7 +2525,8 @@
   @DomName('CircularGeofencingRegion.CircularGeofencingRegion')
   @DocsEditable()
   factory CircularGeofencingRegion(Map init) {
-    return CircularGeofencingRegion._create_1(init);
+    var init_1 = convertDartToNative_Dictionary(init);
+    return CircularGeofencingRegion._create_1(init_1);
   }
   static CircularGeofencingRegion _create_1(init) => JS('CircularGeofencingRegion', 'new CircularGeofencingRegion(#)', init);
 
@@ -7326,13 +7331,13 @@
       return;
     }
     if (successCallback != null) {
-      var options_2 = convertDartToNative_Dictionary(options);
-      __getDirectory_2(path, options_2, successCallback);
+      var options_1 = convertDartToNative_Dictionary(options);
+      __getDirectory_2(path, options_1, successCallback);
       return;
     }
     if (options != null) {
-      var options_3 = convertDartToNative_Dictionary(options);
-      __getDirectory_3(path, options_3);
+      var options_1 = convertDartToNative_Dictionary(options);
+      __getDirectory_3(path, options_1);
       return;
     }
     __getDirectory_4(path);
@@ -7375,13 +7380,13 @@
       return;
     }
     if (successCallback != null) {
-      var options_2 = convertDartToNative_Dictionary(options);
-      __getFile_2(path, options_2, successCallback);
+      var options_1 = convertDartToNative_Dictionary(options);
+      __getFile_2(path, options_1, successCallback);
       return;
     }
     if (options != null) {
-      var options_3 = convertDartToNative_Dictionary(options);
-      __getFile_3(path, options_3);
+      var options_1 = convertDartToNative_Dictionary(options);
+      __getFile_3(path, options_1);
       return;
     }
     __getFile_4(path);
@@ -9096,7 +9101,8 @@
       return DomPoint._create_1();
     }
     if ((point_OR_x is Map || point_OR_x == null) && y == null && z == null && w == null) {
-      return DomPoint._create_2(point_OR_x);
+      var point_1 = convertDartToNative_Dictionary(point_OR_x);
+      return DomPoint._create_2(point_1);
     }
     if ((y is num || y == null) && (point_OR_x is num || point_OR_x == null) && z == null && w == null) {
       return DomPoint._create_3(point_OR_x, y);
@@ -11198,6 +11204,55 @@
   void leftView() {}
 
   /**
+   * Creates a new AnimationEffect object whose target element is the object
+   * on which the method is called, and calls the play() method of the
+   * AnimationTimeline object of the document timeline of the node document
+   * of the element, passing the newly created AnimationEffect as the argument
+   * to the method. Returns an AnimationPlayer for the effect.
+   *
+   * Examples
+   *
+   *     var animation = elem.animate([{"opacity": 75}, {"opacity": 0}], 200);
+   *
+   *     var animation = elem.animate([
+   *       {"transform": "translate(100px, -100%)"},
+   *       {"transform" : "translate(400px, 500px)"}
+   *     ], 1500);  
+   *
+   * The [frames] parameter is an Iterable<Map>, where the
+   * map entries specify CSS animation effects. The
+   * [timing] paramter can be a double, representing the number of milliseconds
+   * for the transition, or a Map with fields corresponding to those
+   * of the [Timing] object.
+   *
+   * This is not yet supported in Dartium.
+  **/
+// TODO(alanknight): Correct above comment once it works in Dartium.
+  @Experimental
+  @SupportedBrowser(SupportedBrowser.CHROME, '36')
+  AnimationPlayer animate(Iterable<Map<String, dynamic>> frames, [timing]) {
+    if (frames is! Iterable || !(frames.every((x) => x is Map))) {
+      throw new ArgumentError("The frames parameter should be a List of Maps "
+          "with frame information");
+    }
+    var convertedFrames = frames;
+    if (convertedFrames is Iterable) {
+      convertedFrames = frames.map(convertDartToNative_Dictionary).toList();
+    }
+    var convertedTiming = timing;
+    if (convertedTiming is Map) {
+      convertedTiming = convertDartToNative_Dictionary(convertedTiming);
+    }
+    return convertedTiming == null
+      ? _animate(convertedFrames)
+      : _animate(convertedFrames, convertedTiming);
+  }
+
+  @DomName('Element.animate')
+  @JSName('animate')
+  @Experimental() // untriaged
+  AnimationPlayer _animate(Object effect, [timing]) native;
+  /**
    * Called by the DOM whenever an attribute on this has been changed.
    */
   void attributeChanged(String name, String oldValue, String newValue) {}
@@ -12673,11 +12728,6 @@
   @DocsEditable()
   final String tagName;
 
-  @DomName('Element.animate')
-  @DocsEditable()
-  @Experimental() // untriaged
-  AnimationPlayer animate(Object effect, [Object timing]) native;
-
   @DomName('Element.blur')
   @DocsEditable()
   void blur() native;
@@ -13893,7 +13943,8 @@
   @DocsEditable()
   static EventSource _factoryEventSource(String url, [Map eventSourceInit]) {
     if (eventSourceInit != null) {
-      return EventSource._create_1(url, eventSourceInit);
+      var eventSourceInit_1 = convertDartToNative_Dictionary(eventSourceInit);
+      return EventSource._create_1(url, eventSourceInit_1);
     }
     return EventSource._create_2(url);
   }
@@ -14859,19 +14910,22 @@
       return FontFace._create_1(family, source);
     }
     if ((descriptors is Map || descriptors == null) && (source is String || source == null) && (family is String || family == null)) {
-      return FontFace._create_2(family, source, descriptors);
+      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
+      return FontFace._create_2(family, source, descriptors_1);
     }
     if ((source is TypedData || source == null) && (family is String || family == null) && descriptors == null) {
       return FontFace._create_3(family, source);
     }
     if ((descriptors is Map || descriptors == null) && (source is TypedData || source == null) && (family is String || family == null)) {
-      return FontFace._create_4(family, source, descriptors);
+      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
+      return FontFace._create_4(family, source, descriptors_1);
     }
     if ((source is ByteBuffer || source == null) && (family is String || family == null) && descriptors == null) {
       return FontFace._create_5(family, source);
     }
     if ((descriptors is Map || descriptors == null) && (source is ByteBuffer || source == null) && (family is String || family == null)) {
-      return FontFace._create_6(family, source, descriptors);
+      var descriptors_1 = convertDartToNative_Dictionary(descriptors);
+      return FontFace._create_6(family, source, descriptors_1);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
   }
@@ -16106,7 +16160,8 @@
       return Headers._create_2(input);
     }
     if ((input is Map || input == null)) {
-      return Headers._create_3(input);
+      var input_1 = convertDartToNative_Dictionary(input);
+      return Headers._create_3(input_1);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
   }
@@ -19995,6 +20050,8 @@
 
 @DocsEditable()
 @DomName('MediaSource')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE, '11')
 // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#mediasource
 @Experimental()
 @Native("MediaSource")
@@ -20009,6 +20066,9 @@
   }
   static MediaSource _create_1() => JS('MediaSource', 'new MediaSource()');
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.MediaSource)');
+
   @DomName('MediaSource.activeSourceBuffers')
   @DocsEditable()
   final SourceBufferList activeSourceBuffers;
@@ -20585,8 +20645,8 @@
       _postMessage_1(message_1, transfer);
       return;
     }
-    var message_2 = convertDartToNative_SerializedScriptValue(message);
-    _postMessage_2(message_2);
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1);
     return;
   }
   @JSName('postMessage')
@@ -22684,16 +22744,15 @@
 @Native("Notification")
 class Notification extends EventTarget {
 
-  factory Notification(String title, {String titleDir: null, String body: null,
-      String bodyDir: null, String tag: null, String iconUrl: null}) {
+  factory Notification(String title, {String dir: null, String body: null,
+      String lang: null, String tag: null, String icon: null}) {
 
     var parsedOptions = {};
-    if (titleDir != null) parsedOptions['titleDir'] = titleDir;
+    if (dir != null) parsedOptions['dir'] = dir;
     if (body != null) parsedOptions['body'] = body;
-    if (bodyDir != null) parsedOptions['bodyDir'] = bodyDir;
+    if (lang != null) parsedOptions['lang'] = lang;
     if (tag != null) parsedOptions['tag'] = tag;
-    if (iconUrl != null) parsedOptions['iconUrl'] = iconUrl;
-
+    if (icon != null) parsedOptions['icon'] = icon;
     return Notification._factoryNotification(title, parsedOptions);
   }
   // To suppress missing implicit constructor warnings.
@@ -22743,13 +22802,17 @@
   @DocsEditable()
   static Notification _factoryNotification(String title, [Map options]) {
     if (options != null) {
-      return Notification._create_1(title, options);
+      var options_1 = convertDartToNative_Dictionary(options);
+      return Notification._create_1(title, options_1);
     }
     return Notification._create_2(title);
   }
   static Notification _create_1(title, options) => JS('Notification', 'new Notification(#,#)', title, options);
   static Notification _create_2(title) => JS('Notification', 'new Notification(#)', title);
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => JS('bool', '!!(window.Notification)');
+
   @DomName('Notification.body')
   @DocsEditable()
   @Experimental() // untriaged
@@ -25098,8 +25161,8 @@
       return;
     }
     if (configuration != null) {
-      var configuration_3 = convertDartToNative_Dictionary(configuration);
-      _updateIce_2(configuration_3);
+      var configuration_1 = convertDartToNative_Dictionary(configuration);
+      _updateIce_2(configuration_1);
       return;
     }
     _updateIce_3();
@@ -25886,8 +25949,8 @@
       return _fetch_3(request);
     }
     if (requestInitDict != null && (request is _Request || request == null)) {
-      var requestInitDict_2 = convertDartToNative_Dictionary(requestInitDict);
-      return _fetch_4(request, requestInitDict_2);
+      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
+      return _fetch_4(request, requestInitDict_1);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
   }
@@ -29868,7 +29931,8 @@
       return WebSocket._create_2(url, protocol_OR_protocols);
     }
     if ((protocol_OR_protocols is List<String> || protocol_OR_protocols == null) && (url is String || url == null)) {
-      return WebSocket._create_3(url, protocol_OR_protocols);
+      List protocols_1 = convertDartToNative_StringArray(protocol_OR_protocols);
+      return WebSocket._create_3(url, protocols_1);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
   }
@@ -31352,8 +31416,8 @@
       _postMessage_1(message_1, targetOrigin, transfer);
       return;
     }
-    var message_2 = convertDartToNative_SerializedScriptValue(message);
-    _postMessage_2(message_2, targetOrigin);
+    var message_1 = convertDartToNative_SerializedScriptValue(message);
+    _postMessage_2(message_1, targetOrigin);
     return;
   }
   @JSName('postMessage')
@@ -31428,8 +31492,8 @@
       return;
     }
     if (scrollOptions != null && (y is int) && (x is int)) {
-      var scrollOptions_2 = convertDartToNative_Dictionary(scrollOptions);
-      _scroll_4(x, y, scrollOptions_2);
+      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
+      _scroll_4(x, y, scrollOptions_1);
       return;
     }
     throw new ArgumentError("Incorrect number or type of arguments");
@@ -31516,8 +31580,8 @@
       return;
     }
     if (scrollOptions != null && (y is int) && (x is int)) {
-      var scrollOptions_2 = convertDartToNative_Dictionary(scrollOptions);
-      _scrollBy_4(x, y, scrollOptions_2);
+      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
+      _scrollBy_4(x, y, scrollOptions_1);
       return;
     }
     throw new ArgumentError("Incorrect number or type of arguments");
@@ -31598,8 +31662,8 @@
       return;
     }
     if (scrollOptions != null && (y is int) && (x is int)) {
-      var scrollOptions_2 = convertDartToNative_Dictionary(scrollOptions);
-      _scrollTo_4(x, y, scrollOptions_2);
+      var scrollOptions_1 = convertDartToNative_Dictionary(scrollOptions);
+      _scrollTo_4(x, y, scrollOptions_1);
       return;
     }
     throw new ArgumentError("Incorrect number or type of arguments");
@@ -33964,13 +34028,15 @@
       return _Request._create_1(input);
     }
     if ((requestInitDict is Map || requestInitDict == null) && (input is String || input == null)) {
-      return _Request._create_2(input, requestInitDict);
+      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
+      return _Request._create_2(input, requestInitDict_1);
     }
     if ((input is _Request || input == null) && requestInitDict == null) {
       return _Request._create_3(input);
     }
     if ((requestInitDict is Map || requestInitDict == null) && (input is _Request || input == null)) {
-      return _Request._create_4(input, requestInitDict);
+      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict);
+      return _Request._create_4(input, requestInitDict_1);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
   }
@@ -34029,25 +34095,29 @@
       return _Response._create_1(body_OR_input);
     }
     if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is String || body_OR_input == null)) {
-      return _Response._create_2(body_OR_input, requestInitDict_OR_responseInitDict);
+      var responseInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
+      return _Response._create_2(body_OR_input, responseInitDict_1);
     }
     if ((body_OR_input is Blob || body_OR_input == null) && requestInitDict_OR_responseInitDict == null) {
       return _Response._create_3(body_OR_input);
     }
     if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is Blob || body_OR_input == null)) {
-      return _Response._create_4(body_OR_input, requestInitDict_OR_responseInitDict);
+      var responseInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
+      return _Response._create_4(body_OR_input, responseInitDict_1);
     }
     if ((body_OR_input is TypedData || body_OR_input == null) && requestInitDict_OR_responseInitDict == null) {
       return _Response._create_5(body_OR_input);
     }
     if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is TypedData || body_OR_input == null)) {
-      return _Response._create_6(body_OR_input, requestInitDict_OR_responseInitDict);
+      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
+      return _Response._create_6(body_OR_input, requestInitDict_1);
     }
     if ((body_OR_input is ByteBuffer || body_OR_input == null) && requestInitDict_OR_responseInitDict == null) {
       return _Response._create_7(body_OR_input);
     }
     if ((requestInitDict_OR_responseInitDict is Map || requestInitDict_OR_responseInitDict == null) && (body_OR_input is ByteBuffer || body_OR_input == null)) {
-      return _Response._create_8(body_OR_input, requestInitDict_OR_responseInitDict);
+      var requestInitDict_1 = convertDartToNative_Dictionary(requestInitDict_OR_responseInitDict);
+      return _Response._create_8(body_OR_input, requestInitDict_1);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
   }
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 2a991bd..4b331b7 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -951,6 +951,9 @@
   // To suppress missing implicit constructor warnings.
   factory AnimationPlayer._() { throw new UnsupportedError("Not supported"); }
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('AnimationPlayer.currentTime')
   @DocsEditable()
   @Experimental() // untriaged
@@ -22046,6 +22049,8 @@
 
 @DocsEditable()
 @DomName('MediaSource')
+@SupportedBrowser(SupportedBrowser.CHROME)
+@SupportedBrowser(SupportedBrowser.IE, '11')
 // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#mediasource
 @Experimental()
 class MediaSource extends EventTarget {
@@ -22058,6 +22063,9 @@
     return _blink.BlinkMediaSource.instance.constructorCallback_0_();
   }
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('MediaSource.activeSourceBuffers')
   @DocsEditable()
   SourceBufferList get activeSourceBuffers => _blink.BlinkMediaSource.instance.activeSourceBuffers_Getter_(this);
@@ -24835,16 +24843,15 @@
 @Experimental() // experimental
 class Notification extends EventTarget {
 
-  factory Notification(String title, {String titleDir: null, String body: null,
-      String bodyDir: null, String tag: null, String iconUrl: null}) {
+  factory Notification(String title, {String dir: null, String body: null,
+      String lang: null, String tag: null, String icon: null}) {
 
     var parsedOptions = {};
-    if (titleDir != null) parsedOptions['titleDir'] = titleDir;
+    if (dir != null) parsedOptions['dir'] = dir;
     if (body != null) parsedOptions['body'] = body;
-    if (bodyDir != null) parsedOptions['bodyDir'] = bodyDir;
+    if (lang != null) parsedOptions['lang'] = lang;
     if (tag != null) parsedOptions['tag'] = tag;
-    if (iconUrl != null) parsedOptions['iconUrl'] = iconUrl;
-
+    if (icon != null) parsedOptions['icon'] = icon;
     return Notification._factoryNotification(title, parsedOptions);
   }
   // To suppress missing implicit constructor warnings.
@@ -24899,6 +24906,9 @@
     return _blink.BlinkNotification.instance.constructorCallback_1_(title);
   }
 
+  /// Checks if this type is supported on the current platform.
+  static bool get supported => true;
+
   @DomName('Notification.body')
   @DocsEditable()
   @Experimental() // untriaged
diff --git a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
index 3dd4a77..3db17c2 100644
--- a/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
+++ b/sdk/lib/indexed_db/dart2js/indexed_db_dart2js.dart
@@ -1042,8 +1042,8 @@
       var key_2 = convertDartToNative_SerializedScriptValue(key);
       return _add_1(value_1, key_2);
     }
-    var value_3 = convertDartToNative_SerializedScriptValue(value);
-    return _add_2(value_3);
+    var value_1 = convertDartToNative_SerializedScriptValue(value);
+    return _add_2(value_1);
   }
   @JSName('add')
   @DomName('IDBObjectStore.add')
@@ -1081,13 +1081,13 @@
       return _createIndex_2(name, keyPath, options_1);
     }
     if ((keyPath is List<String> || keyPath == null) && options == null) {
-      List keyPath_2 = convertDartToNative_StringArray(keyPath);
-      return _createIndex_3(name, keyPath_2);
+      List keyPath_1 = convertDartToNative_StringArray(keyPath);
+      return _createIndex_3(name, keyPath_1);
     }
     if (options != null && (keyPath is List<String> || keyPath == null)) {
-      List keyPath_3 = convertDartToNative_StringArray(keyPath);
-      var options_4 = convertDartToNative_Dictionary(options);
-      return _createIndex_4(name, keyPath_3, options_4);
+      List keyPath_1 = convertDartToNative_StringArray(keyPath);
+      var options_2 = convertDartToNative_Dictionary(options);
+      return _createIndex_4(name, keyPath_1, options_2);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
   }
@@ -1153,8 +1153,8 @@
       var key_2 = convertDartToNative_SerializedScriptValue(key);
       return _put_1(value_1, key_2);
     }
-    var value_3 = convertDartToNative_SerializedScriptValue(value);
-    return _put_2(value_3);
+    var value_1 = convertDartToNative_SerializedScriptValue(value);
+    return _put_2(value_1);
   }
   @JSName('put')
   @DomName('IDBObjectStore.put')
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index 46b17dc..f450cb6 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -286,8 +286,8 @@
           if (response is int) {
             id = response;
             next();
-	  } else if (response is Error) {
-            controller.addError(response);
+          } else if (response is Error) {
+            controller.addError(response, response.stackTrace);
             close();
           } else {
             error(response);
@@ -379,8 +379,8 @@
       if (errorPath == null) errorPath = path;
       controller.addError(
           new FileSystemException("Directory listing failed",
-                                 errorPath,
-                                 err));
+                                  errorPath,
+                                  err));
     } else {
       controller.addError(
           new FileSystemException("Internal error"));
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 34e03de..2dac1b8 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -208,9 +208,7 @@
           onError: error,
           cancelOnError: true);
       })
-      .catchError((e) {
-        completer.completeError(e);
-      });
+      .catchError(completer.completeError);
     return completer.future;
   }
 
diff --git a/sdk/lib/io/http_impl.dart b/sdk/lib/io/http_impl.dart
index dd03aeb..bd382bc 100644
--- a/sdk/lib/io/http_impl.dart
+++ b/sdk/lib/io/http_impl.dart
@@ -1055,11 +1055,11 @@
     return socket.addStream(controller.stream)
         .then((_) {
           return outbound;
-        }, onError: (error) {
+        }, onError: (error, stackTrace) {
           // Be sure to close it in case of an error.
           if (_gzip) _gzipSink.close();
           _socketError = true;
-          _doneCompleter.completeError(error);
+          _doneCompleter.completeError(error, stackTrace);
           if (_ignoreError(error)) {
             return outbound;
           } else {
@@ -1133,8 +1133,8 @@
         .then((_) {
           _doneCompleter.complete(socket);
           return outbound;
-        }, onError: (error) {
-          _doneCompleter.completeError(error);
+        }, onError: (error, stackTrace) {
+          _doneCompleter.completeError(error, stackTrace);
           if (_ignoreError(error)) {
             return outbound;
           } else {
@@ -2246,11 +2246,11 @@
           _HttpConnection connection = new _HttpConnection(socket, this);
           _idleConnections.add(connection);
         },
-        onError: (error) {
+        onError: (error, stackTrace) {
           // Ignore HandshakeExceptions as they are bound to a single request,
           // and are not fatal for the server.
           if (error is! HandshakeException) {
-            _controller.addError(error);
+            _controller.addError(error, stackTrace);
           }
         },
         onDone: _controller.close);
@@ -2315,10 +2315,6 @@
     }
   }
 
-  void _handleError(error) {
-    if (!closed) _controller.addError(error);
-  }
-
   void _connectionClosed(_HttpConnection connection) {
     // Remove itself from either idle or active connections.
     connection.unlink();
diff --git a/sdk/lib/io/http_parser.dart b/sdk/lib/io/http_parser.dart
index d941aa4..09f06ea 100644
--- a/sdk/lib/io/http_parser.dart
+++ b/sdk/lib/io/http_parser.dart
@@ -321,7 +321,7 @@
     // how the _HttpIncoming signals the parser.
     _socketSubscription = stream.listen(
         _onData,
-        onError: _onError,
+        onError: _controller.addError,
         onDone: _onDone);
   }
 
@@ -845,10 +845,6 @@
     _controller.close();
   }
 
-  void _onError(e, [StackTrace stackTrace]) {
-    _controller.addError(e, stackTrace);
-  }
-
   String get version {
     switch (_httpVersion) {
       case _HttpVersion.HTTP10:
diff --git a/sdk/lib/io/io_sink.dart b/sdk/lib/io/io_sink.dart
index 0c27522..78c15fa 100644
--- a/sdk/lib/io/io_sink.dart
+++ b/sdk/lib/io/io_sink.dart
@@ -143,8 +143,9 @@
     _controller.add(data);
   }
 
-  void addError(error, [StackTrace stackTrace]) =>
-      _controller.addError(error, stackTrace);
+  void addError(error, [StackTrace stackTrace]) {
+    _controller.addError(error, stackTrace);
+  }
 
   Future addStream(Stream<T> stream) {
     if (_isBound) {
@@ -196,21 +197,21 @@
   }
 
   void _closeTarget() {
-    _target.close()
-        .then((value) => _completeDone(value: value),
-              onError: (error) => _completeDone(error: error));
+    _target.close().then(_completeDoneValue, onError: _completeDoneError);
   }
 
   Future get done => _doneFuture;
 
-  void _completeDone({value, error}) {
+  void _completeDoneValue(value) {
     if (_doneCompleter == null) return;
-    if (error == null) {
-      _doneCompleter.complete(value);
-    } else {
-      _hasError = true;
-      _doneCompleter.completeError(error);
-    }
+    _doneCompleter.complete(value);
+    _doneCompleter = null;
+  }
+
+  void _completeDoneError(error, StackTrace stackTrace) {
+    if (_doneCompleter == null) return;
+    _hasError = true;
+    _doneCompleter.completeError(error, stackTrace);
     _doneCompleter = null;
   }
 
@@ -237,16 +238,16 @@
                   _closeTarget();
                 }
               },
-              onError: (error) {
+              onError: (error, stackTrace) {
                 if (_isBound) {
                   // A new stream takes over - forward errors to that stream.
-                  _controllerCompleter.completeError(error);
+                  _controllerCompleter.completeError(error, stackTrace);
                   _controllerCompleter = null;
                   _controllerInstance = null;
                 } else {
                   // No new stream. No need to close target, as it have already
                   // failed.
-                  _completeDone(error: error);
+                  _completeDoneError(error, stackTrace);
                 }
               });
     }
diff --git a/sdk/lib/io/platform_impl.dart b/sdk/lib/io/platform_impl.dart
index d735521..3883957 100644
--- a/sdk/lib/io/platform_impl.dart
+++ b/sdk/lib/io/platform_impl.dart
@@ -48,6 +48,7 @@
         path.startsWith('https:') ||
         path.startsWith('package:') ||
         path.startsWith('dart:') ||
+        path.startsWith('data:') ||
         path.startsWith('file:')) {
       script = Uri.parse(path);
     } else {
diff --git a/sdk/lib/io/secure_server_socket.dart b/sdk/lib/io/secure_server_socket.dart
index c987a48..c3ce9cf 100644
--- a/sdk/lib/io/secure_server_socket.dart
+++ b/sdk/lib/io/secure_server_socket.dart
@@ -275,21 +275,13 @@
       } else {
         _controller.add(secureConnection);
       }
-    }).catchError((e) {
+    }).catchError((e, s) {
       if (!_closed) {
-        _controller.addError(e);
+        _controller.addError(e, s);
       }
     });
   }
 
-  void _onError(e, [StackTrace stackTrace]) {
-    _controller.addError(e, stackTrace);
-  }
-
-  void _onDone() {
-    _controller.close();
-  }
-
   void _onPauseStateChange() {
     if (_controller.isPaused) {
       _subscription.pause();
@@ -301,14 +293,16 @@
   void _onSubscriptionStateChange() {
     if (_controller.hasListener) {
       _subscription = _socket.listen(_onData,
-                                     onDone: _onDone,
-                                     onError: _onError);
+                                     onError: _controller.addError,
+                                     onDone: _controller.close);
     } else {
       close();
     }
   }
 
-  void set _owner(owner) { (_socket as dynamic)._owner = owner; }
+  void set _owner(owner) {
+    (_socket as dynamic)._owner = owner;
+  }
 }
 
 
diff --git a/sdk/lib/io/secure_socket.dart b/sdk/lib/io/secure_socket.dart
index 44d6084..6b36eba 100644
--- a/sdk/lib/io/secure_socket.dart
+++ b/sdk/lib/io/secure_socket.dart
@@ -558,6 +558,12 @@
         throw new ArgumentError(
             "Subscription passed to TLS upgrade is paused");
       }
+      // If we are upgrading a socket that is already closed for read,
+      // report an error as if we received READ_CLOSED during the handshake.
+      dynamic s = _socket;  // Cast to dynamic to avoid warning.
+      if (s._socket.closedReadEventSent) {
+        _eventDispatcher(RawSocketEvent.READ_CLOSED);
+      }
       _socketSubscription
           ..onData(_eventDispatcher)
           ..onError(_reportError)
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index d703c8d..a759598 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -763,6 +763,11 @@
   final int port;
 
   const SocketException(this.message, {this.osError, this.address, this.port});
+  const SocketException.closed()
+      : message = 'Socket has been closed',
+        osError = null,
+        address = null,
+        port = null;
 
   String toString() {
     StringBuffer sb = new StringBuffer();
diff --git a/sdk/lib/math/random.dart b/sdk/lib/math/random.dart
index be338f9..0c1c76c 100644
--- a/sdk/lib/math/random.dart
+++ b/sdk/lib/math/random.dart
@@ -12,14 +12,16 @@
  */
 abstract class Random {
   /**
-   * Creates a random-number generator. The optional parameter [seed] is used
+   * Creates a random number generator.
+   *
+   * The optional parameter [seed] is used
    * to initialize the internal state of the generator. The implementation of
    * the random stream can change between releases of the library.
    */
   external factory Random([int seed]);
 
   /**
-   * Generates a positive random integer uniformly distributed on the range
+   * Generates a non-negative random integer uniformly distributed in the range
    * from 0, inclusive, to [max], exclusive.
    *
    * Implementation note: The default implementation supports [max] values
@@ -28,8 +30,8 @@
   int nextInt(int max);
 
   /**
-   * Generates a positive random floating point value uniformly distributed on
-   * the range from 0.0, inclusive, to 1.0, exclusive.
+   * Generates a non-negative random floating point value uniformly distributed
+   * in the range from 0.0, inclusive, to 1.0, exclusive.
    */
   double nextDouble();
 
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index f42f3d2..a88dee0 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -315,39 +315,28 @@
 LibTest/core/Stopwatch/start_A01_t03: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/core/Stopwatch/stop_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/core/Uri/Uri_A06_t03: Pass, Slow
-LibTest/core/double/roundToDouble_A01_t01: RuntimeError # co19-roll r706: Please triage this failure.
-LibTest/core/double/round_A01_t01: RuntimeError # co19-roll r706: Please triage this failure
 LibTest/isolate/ReceivePort/asBroadcastStream_A04_t03: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/isolate/SendPort/send_A02_t05: RuntimeError # TODO(ahe): Please triage this failure.
 LibTest/isolate/SendPort/send_A02_t06: RuntimeError # TODO(ahe): Please triage this failure.
 LibTest/typed_data/Float32List/Float32List.view_A06_t01: fail # co19-roll r587: Please triage this failure
-LibTest/typed_data/Float32List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float32x4List/Float32x4List.view_A06_t01: fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Float64List/Float64List.view_A06_t01: fail # co19-roll r587: Please triage this failure
-LibTest/typed_data/Float64List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Float64List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int16List/Int16List.view_A06_t01: fail # co19-roll r587: Please triage this failure
-LibTest/typed_data/Int16List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int16List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int16List/toList_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int32List/Int32List.view_A06_t01: fail # co19-roll r587: Please triage this failure
-LibTest/typed_data/Int32List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int32List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int32List/toList_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int32x4/operator_OR_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
-LibTest/typed_data/Int8List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int8List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint16List/Uint16List.view_A06_t01: fail # co19-roll r587: Please triage this failure
-LibTest/typed_data/Uint16List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint16List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint16List/toList_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint32List/Uint32List.view_A06_t01: fail # co19-roll r587: Please triage this failure
-LibTest/typed_data/Uint32List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint32List/toList_A01_t01: Skip # issue 16934, co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint8ClampedList/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint8ClampedList/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint8List/hashCode_A01_t01: fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint8List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
 
 [ $compiler == dart2js && $checked && $runtime == jsshell]
@@ -585,7 +574,6 @@
 LayoutTests/fast/css/font-face-unicode-range-load_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-face-unicode-range-monospace_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-events_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-loadingdone_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # Please triage this failure
@@ -1711,7 +1699,7 @@
 LayoutTests/fast/css/font-property-priority_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-shorthand-from-longhands_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-shorthand-mix-inherit_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Uses FontFace class, not defined for this browser.
 LayoutTests/fast/css/fontfaceset-download-error_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-events_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError # Please triage this failure
@@ -3209,7 +3197,7 @@
 LayoutTests/fast/css/font-face-unicode-range-monospace_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-shorthand-from-longhands_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Uses FontFace class, not defined for this browser.
 LayoutTests/fast/css/fontfaceset-download-error_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-events_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError # Please triage this failure
@@ -4471,7 +4459,7 @@
 LayoutTests/fast/css/font-face-unicode-range-load_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-shorthand-from-longhands_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Uses FontFace class not defined for this browser
 LayoutTests/fast/css/fontfaceset-download-error_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-events_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError # Please triage this failure
@@ -5526,6 +5514,12 @@
 WebPlatformTest/webstorage/storage_local_setitem_t01: RuntimeError # Please triage this failure
 WebPlatformTest/webstorage/storage_session_setitem_t01: RuntimeError # Please triage this failure
 
+# This test is not flaky: IE10 on Windows 7 is different from IE10 on Windows 8.
+# The test fails on Windows 7's version, but it is currently not possible to test
+# for the OS version (see https://code.google.com/p/dart/issues/detail?id=22806).
+[ $compiler == dart2js && $runtime == ie10 ]
+LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: RuntimeError, Pass # Issue 22752. Please triage this failure.
+
 [ $compiler == dart2js && $runtime == ie10 ]
 Language/12_Expressions/00_Object_Identity/1_Object_Identity_A05_t02: RuntimeError # Please triage this failure
 Language/12_Expressions/17_Getter_Invocation_A03_t02: Skip # Times out. Please triage this failure
@@ -5864,7 +5858,7 @@
 LayoutTests/fast/css/font-family-trailing-bracket-gunk_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-shorthand-from-longhands_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-shorthand-mix-inherit_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Uses FontFace class, not defined for this browser
 LayoutTests/fast/css/fontfaceset-download-error_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-events_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError # Please triage this failure
@@ -6803,7 +6797,7 @@
 LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/sub-pixel/cssom-subpixel-precision_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/sub-pixel/shadows-computed-style_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/sub-pixel/table-cells-have-stable-width_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/sub-pixel/table-cells-have-stable-width_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/svg/getbbox_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/svg/tabindex-focus_t01: RuntimeError # Please triage this failure
@@ -7842,7 +7836,7 @@
 LayoutTests/fast/css/box-sizing-backwards-compat-prefix_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/child-selector-implicit-tbody_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/comment-before-charset-external_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/comment-before-charset-external_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/computed-offset-with-zoom_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/content-language-case-insensitivity_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/content-language-dynamically-added_t01: RuntimeError # Please triage this failure
@@ -7885,7 +7879,7 @@
 LayoutTests/fast/css/font-family-trailing-bracket-gunk_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-shorthand-from-longhands_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-shorthand-mix-inherit_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/fontface-properties_t01: RuntimeError # Uses FontFace class, not defined for this browser
 LayoutTests/fast/css/fontfaceset-download-error_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-events_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError # Please triage this failure
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 5b52c5e..ac0106b 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -12,8 +12,6 @@
 LayoutTests/fast/writing-mode/flipped-blocks-hit-test-overflow_t01: Pass, RuntimeError # Issue 21605
 
 [ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) ]
-LayoutTests/fast/dom/fragment-activation-focuses-target_t01: Fail # Chromium 39 beta patches
-
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Issue 20540
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Skip # Issue 20540
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip # Issue 20540
diff --git a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
index f12b8f1..a7bb1ba 100644
--- a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
+++ b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
@@ -23,6 +23,13 @@
 
   // Some things in dart_printer are not yet used
   "lib/src/dart_backend/backend_ast_nodes.dart": const [" is never "],
+
+  // Uncalled error methods in SemanticSendVisitor and subclasses.
+  "lib/src/resolution/semantic_visitor.dart": const [
+      "The method 'error"],
+  "lib/src/resolution/semantic_visitor_mixins.dart": const [
+      "The method 'error",
+      "Mixin' is never used."]
 };
 
 void main() {
diff --git a/tests/compiler/dart2js/async_await_js_transform_test.dart b/tests/compiler/dart2js/async_await_js_transform_test.dart
index 36aa10d..f1f2d32 100644
--- a/tests/compiler/dart2js/async_await_js_transform_test.dart
+++ b/tests/compiler/dart2js/async_await_js_transform_test.dart
@@ -15,7 +15,8 @@
       null,
       asyncHelper: new VariableUse("thenHelper"),
       newCompleter: new VariableUse("Completer"),
-      safeVariableName: (String name) => "__$name").rewrite(fun);
+      safeVariableName: (String name) => "__$name",
+      bodyName: "body").rewrite(fun);
 
   JavaScriptPrintingOptions options = new JavaScriptPrintingOptions();
   SimpleJavaScriptPrintingContext context =
diff --git a/tests/compiler/dart2js/backend_dart/opt_constprop_test.dart b/tests/compiler/dart2js/backend_dart/opt_constprop_test.dart
index b072aeb..149b58e 100644
--- a/tests/compiler/dart2js/backend_dart/opt_constprop_test.dart
+++ b/tests/compiler/dart2js/backend_dart/opt_constprop_test.dart
@@ -28,7 +28,7 @@
 //  }
 
 String CP1_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetPrim (v1 (Constant (Int 1)))
       (LetCont
@@ -44,7 +44,7 @@
         (InvokeMethod v0 == (v1) k0)))))
 """;
 String CP1_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetPrim (v1 (Constant (Int 1)))
       (LetCont
@@ -77,7 +77,7 @@
 //  }
 
 String CP2_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetCont
         ((rec k0 ()
@@ -141,7 +141,7 @@
       (InvokeContinuation k0 ()))))
 """;
 String CP2_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetCont
         ((rec k0 ()
@@ -218,7 +218,7 @@
 //  }
 
 String CP3_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetCont
         ((k0 (v1)
@@ -240,7 +240,7 @@
 // Addition.
 
 String CP4_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetPrim (v1 (Constant (Int 2)))
       (LetCont
@@ -249,7 +249,7 @@
         (InvokeMethod v0 + (v1) k0)))))
 """;
 String CP4_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetPrim (v1 (Constant (Int 2)))
       (LetCont
@@ -262,7 +262,7 @@
 // Array access operator (no optimization).
 
 String CP5_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetPrim (v1 (Constant (Int 2)))
       (LetCont
@@ -275,7 +275,7 @@
 // Division by 0.
 
 String CP6_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetPrim (v1 (Constant (Int 0)))
       (LetCont
@@ -284,7 +284,7 @@
         (InvokeMethod v0 / (v1) k0)))))
 """;
 String CP6_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetPrim (v1 (Constant (Int 0)))
       (LetCont
@@ -297,7 +297,7 @@
 // Concatenate strings.
 
 String CP7_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (String "b")))
     (LetPrim (v1 (Constant (String "d")))
       (LetPrim (v2 (Constant (String "a")))
@@ -312,7 +312,7 @@
               (ConcatenateStrings (v2 v0 v3 v1 v4) k0))))))))
 """;
 String CP7_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (String "b")))
     (LetPrim (v1 (Constant (String "d")))
       (LetPrim (v2 (Constant (String "a")))
@@ -334,7 +334,7 @@
 // Simple branch removal.
 
 String CP8_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetPrim (v1 (Constant (Int 1)))
       (LetCont
@@ -349,7 +349,7 @@
         (InvokeMethod v0 == (v1) k0)))))
 """;
 String CP8_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetPrim (v1 (Constant (Int 1)))
       (LetCont
@@ -368,7 +368,7 @@
 // While loop.
 
 String CP9_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetCont
         ((rec k0 (v1)
@@ -406,7 +406,7 @@
       (InvokeContinuation k0 (v0)))))
 """;
 String CP9_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 1)))
     (LetCont
         ((rec k0 (v1)
@@ -453,7 +453,7 @@
 //  }
 
 String CP10_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont
         ((rec k0 (v1)
diff --git a/tests/compiler/dart2js/backend_dart/opt_redundant_phi_test.dart b/tests/compiler/dart2js/backend_dart/opt_redundant_phi_test.dart
index 3007f31..50422e2 100644
--- a/tests/compiler/dart2js/backend_dart/opt_redundant_phi_test.dart
+++ b/tests/compiler/dart2js/backend_dart/opt_redundant_phi_test.dart
@@ -19,7 +19,7 @@
 // }
 
 String READ_IN_LOOP_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 42)))
     (LetPrim (v1 (Constant (Int 0)))
       (LetCont
@@ -49,7 +49,7 @@
 """;
 
 String READ_IN_LOOP_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 42)))
     (LetPrim (v1 (Constant (Int 0)))
       (LetCont
@@ -94,7 +94,7 @@
 // are removed from k5, and only then can k0 be optimized as well.
 
 const String INNER_LOOP_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 42)))
     (LetPrim (v1 (Constant (Int 0)))
       (LetCont
@@ -147,7 +147,7 @@
 """;
 
 const String INNER_LOOP_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 42)))
     (LetPrim (v1 (Constant (Int 0)))
       (LetCont
@@ -210,7 +210,7 @@
 // }
 
 String BASIC_LOOP_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont
        ((rec k0 (v1)
@@ -245,7 +245,7 @@
 // IR written by hand since this case is currently not being generated.
 
 String SCOPING_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetCont
       ((k0 (v1)
          (InvokeStatic print (v1) return)))
@@ -255,7 +255,7 @@
 """;
 
 String SCOPING_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont
         ((k0 ()
@@ -268,7 +268,7 @@
 // IR written by hand.
 
 String NEVER_INVOKED_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont
         ((k0 (v1)
diff --git a/tests/compiler/dart2js/backend_dart/opt_shrinking_test.dart b/tests/compiler/dart2js/backend_dart/opt_shrinking_test.dart
index fca6d1e..906a6cf 100644
--- a/tests/compiler/dart2js/backend_dart/opt_shrinking_test.dart
+++ b/tests/compiler/dart2js/backend_dart/opt_shrinking_test.dart
@@ -20,13 +20,13 @@
 //  }
 
 String DEAD_VAL_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 42)))
     (LetPrim (v1 (Constant (Int 0)))
       (InvokeContinuation return (v1)))))
 """;
 String DEAD_VAL_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (InvokeContinuation return (v0))))
 """;
@@ -41,7 +41,7 @@
 //  }
 
 String ITERATIVE_DEAD_VAL1_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 42)))
     (LetPrim (v1 (Constant (Int 1)))
       (LetCont ((k0 (v2)
@@ -54,17 +54,17 @@
 // Iterative dead-val. IR written by hand.
 
 String ITERATIVE_DEAD_VAL2_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 42)))
     (LetPrim (v1
         (CreateFunction
-          (FunctionDefinition f (i) return
+          (FunctionDefinition f () (i) return
             (InvokeContinuation return (v0)))))
       (LetPrim (v2 (Constant (Int 0)))
         (InvokeContinuation return (v2))))))
 """;
 String ITERATIVE_DEAD_VAL2_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (InvokeContinuation return (v0))))
 """;
@@ -73,7 +73,7 @@
 // IR written by hand.
 
 String DEAD_CONT_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v4 (Constant (Int 0)))
     (LetCont ((k0 (v0)
                 (InvokeConstructor List () return)))
@@ -85,7 +85,7 @@
         (InvokeStatic print (v4) k1)))))
 """;
 String DEAD_CONT_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((k0 (v1)
                 (LetCont ((k1 (v2)
@@ -98,7 +98,7 @@
 // Iterative dead-cont. IR written by hand.
 
 String ITERATIVE_DEAD_CONT_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v4 (Constant (Int 0)))
     (LetCont ((k0 (v0)
                 (InvokeConstructor List () return)))
@@ -112,7 +112,7 @@
           (InvokeStatic print (v4) k1))))))
 """;
 String ITERATIVE_DEAD_CONT_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((k0 (v1)
                 (LetCont ((k1 (v2)
@@ -126,7 +126,7 @@
 // IR written by hand.
 
 String BETA_CONT_LIN_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetCont ((k0 (v0)
               (LetCont ((k1 (v1)
                           (LetCont ((k2 (v2)
@@ -138,7 +138,7 @@
       (InvokeContinuation k0 (v4)))))
 """;
 String BETA_CONT_LIN_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((k0 (v1)
                 (LetCont ((k1 (v2)
@@ -151,7 +151,7 @@
 // Beta-cont-lin with recursive continuation. IR written by hand.
 
 String RECURSIVE_BETA_CONT_LIN_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetCont ((rec k0 (v0)
               (InvokeContinuation rec k0 (v0))))
     (LetPrim (v1 (Constant (Int 0)))
@@ -162,7 +162,7 @@
 // Beta-cont-lin used inside body. IR written by hand.
 
 String USED_BETA_CONT_LIN_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((k0 (v1)
                 (LetCont ((k1 (v2)
@@ -173,12 +173,12 @@
                   (InvokeStatic print (v1) k1))))
       (LetPrim (v5
                  (CreateFunction
-                   (FunctionDefinition f () return
+                   (FunctionDefinition f () () return
                      (InvokeContinuation return (v1)))))
         (InvokeContinuation k0 (v0))))))
 """;
 String USED_BETA_CONT_LIN_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((k0 (v1)
                 (LetCont ((k1 (v2)
@@ -199,7 +199,7 @@
 // TODO(kmillikin): To test continuation eta reduction, use eta redexes that are
 // not overlapping beta redexes.
 String ETA_CONT_IN = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (LetCont ((rec k0 (v1)
                 (InvokeContinuation return (v0))))
@@ -207,12 +207,12 @@
                   (InvokeContinuation k0 (v2))))
         (LetPrim (v3
                    (CreateFunction
-                     (FunctionDefinition f () return
+                     (FunctionDefinition f () () return
                        (InvokeContinuation k0 (v0)))))
           (InvokeContinuation k1 (v0)))))))
 """;
 String ETA_CONT_OUT = """
-(FunctionDefinition main () return
+(FunctionDefinition main () () return
   (LetPrim (v0 (Constant (Int 0)))
     (InvokeContinuation return (v0))))
 """;
@@ -223,7 +223,7 @@
 
 // Parameter v1 is unused in k0.
 String DEAD_PARAMETER_IN = """
-(FunctionDefinition main (x) return
+(FunctionDefinition main () (x) return
   (LetCont ((k0 (v0 v1 v2)
               (InvokeStatic foo (v0 v2) return)))
     (LetCont ((k1 ()
@@ -239,7 +239,7 @@
       (Branch (IsTrue x) k1 k2))))
 """;
 String DEAD_PARAMETER_OUT = """
-(FunctionDefinition main (x) return
+(FunctionDefinition main () (x) return
   (LetCont ((k0 (v0 v1)
               (InvokeStatic foo (v0 v1) return)))
     (LetCont ((k1 ()
@@ -257,7 +257,7 @@
 // Dead parameter reductions can create an eta-cont redex by removing unused
 // continuation parameters and thus creating the eta redex.
 String CREATE_ETA_CONT_IN = """
-(FunctionDefinition main (x) return
+(FunctionDefinition main () (x) return
   (LetCont ((rec loop (v0)
               (InvokeContinuation rec loop (v0))))
     (LetCont ((created (v1 v2 v3)
@@ -275,7 +275,7 @@
         (Branch (IsTrue x) then else)))))
 """;
 String CREATE_ETA_CONT_OUT = """
-(FunctionDefinition main (x) return
+(FunctionDefinition main () (x) return
   (LetCont ((rec k0 (v0)
               (InvokeContinuation rec k0 (v0))))
     (LetCont ((k1 ()
diff --git a/tests/compiler/dart2js/backend_dart/sexpr_test.dart b/tests/compiler/dart2js/backend_dart/sexpr_test.dart
index f1a9351..bbe09e2 100644
--- a/tests/compiler/dart2js/backend_dart/sexpr_test.dart
+++ b/tests/compiler/dart2js/backend_dart/sexpr_test.dart
@@ -111,7 +111,8 @@
         String withoutNullConstants = combined.replaceAll("Constant null", "");
         Expect.isFalse(withoutNullConstants.contains("null"));
         for (String token in expectedTokens) {
-          Expect.isTrue(combined.contains(token));
+          Expect.isTrue(combined.contains(token),
+              "'$combined' doesn't contain '$token' in test:\n$code");
         }
 
         return sexprs;
@@ -160,7 +161,10 @@
           , "LiteralMap"
           // Parameters are encoded by name only and hence are not in this list.
           , "ReifyTypeVar"
-          , "This"
+
+          , "(this)"   // 'this' Parameter declarations
+          , "this"     // 'this' Parameter uses
+
           ];
 
   asyncTest(() => testStringifier(CODE, tokens).then((List<String> sexprs) {
diff --git a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart b/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
index 3c982c74..1f06307 100644
--- a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
+++ b/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
@@ -87,7 +87,17 @@
 
   String read([String expected]) {
     if (expected != null) {
-      assert(current == expected);
+      if (current != expected) {
+        print('expected "$expected", found "$current"');
+        int start = _index - 15;
+        String dotdotdot = '... ';
+        if (start < 0) {
+          start = 0;
+          dotdotdot = '';
+        }
+        print('${dotdotdot}${_list.sublist(start, _index + 1).join(' ')}');
+        assert(current == expected);
+      }
     }
     return _list[_index++];
   }
@@ -268,6 +278,20 @@
       element = new DummyElement(tokens.read());
     }
 
+    // (this) or ()
+    Definition thisParameter = null;
+    tokens.consumeStart();
+    if (tokens.current != ')') {
+      String thisName = tokens.read();
+      if (name2variable.containsKey(thisName)) {
+        thisParameter = name2variable[thisName];
+      } else {
+        thisParameter = new Parameter(new DummyElement(thisName));
+        name2variable[thisName] = thisParameter;
+      }
+    }
+    tokens.consumeEnd();
+
     // (parameters)
     List<Definition> parameters = <Definition>[];
     tokens.consumeStart();
@@ -292,7 +316,7 @@
     Expression body = parseExpression();
 
     tokens.consumeEnd();
-    return new FunctionDefinition(element, parameters,
+    return new FunctionDefinition(element, thisParameter, parameters,
         new RunnableBody(body, cont), null, null);
   }
 
diff --git a/tests/compiler/dart2js/dart2js_batch2_test.dart b/tests/compiler/dart2js/dart2js_batch2_test.dart
index d2a1845..644c790 100644
--- a/tests/compiler/dart2js/dart2js_batch2_test.dart
+++ b/tests/compiler/dart2js/dart2js_batch2_test.dart
@@ -39,7 +39,7 @@
     tmpDir = directory;
     String newPath = path.join(directory.path, "dart2js_batch2_run.dart");
     File source =
-        new File(Platform.script.resolve("dart2js_batch2_run.dart").path);
+        new File.fromUri(Platform.script.resolve("dart2js_batch2_run.dart"));
     source.copySync(newPath);
   });
 }
diff --git a/tests/compiler/dart2js/expect_annotations2_test.dart b/tests/compiler/dart2js/expect_annotations2_test.dart
index 4357c1d..580ba3a 100644
--- a/tests/compiler/dart2js/expect_annotations2_test.dart
+++ b/tests/compiler/dart2js/expect_annotations2_test.dart
@@ -14,6 +14,11 @@
         foo(y) => 49912344 + y;
 
         class A {
+          var field;
+
+          @NoInline()
+          A([this.field = 4711]);
+
           @NoInline()
           static bar(x) => x + 123455;
 
@@ -25,6 +30,7 @@
           print(foo(23412));
           print(A.bar(87654));
           print(new A().gee(1337, 919182));
+          print(new A().field + 1);
         }'''};
 
 void main() {
@@ -41,5 +47,6 @@
     Expect.isFalse(jsOutput.contains('49935756'));
     Expect.isFalse(jsOutput.contains('211109'));
     Expect.isFalse(jsOutput.contains('82155031'));
+    Expect.isFalse(jsOutput.contains('4712'));
   }));
 }
diff --git a/tests/compiler/dart2js/flatten_test.dart b/tests/compiler/dart2js/flatten_test.dart
new file mode 100644
index 0000000..cc28c2f
--- /dev/null
+++ b/tests/compiler/dart2js/flatten_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library subtype_test;
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'type_test_helper.dart';
+import 'package:compiler/src/dart_types.dart';
+import "package:compiler/src/elements/elements.dart"
+       show Element, ClassElement;
+
+void main() {
+  asyncTest(() => TypeEnvironment.create(r"""
+      abstract class F<T> implements Future<T> {}
+      abstract class G<T> implements Future<G<T>> {}
+      abstract class H<T> implements Future<H<H<T>>> {}
+      """).then((env) {
+
+    void check(DartType T, DartType expectedFlattenedType) {
+      DartType flattenedType = env.flatten(T);
+      Expect.equals(expectedFlattenedType, flattenedType,
+                    "Unexpected flattening of '$T' = '$flattenedType',"
+                    "expected '$expectedFlattenedType'.");
+    }
+
+    ClassElement Future_ = env.getElement('Future');
+    ClassElement F = env.getElement('F');
+    ClassElement G = env.getElement('G');
+    ClassElement H = env.getElement('H');
+    DartType int_ = env['int'];
+    DartType dynamic_ = env['dynamic'];
+    DartType Future_int = instantiate(Future_, [int_]);
+    DartType F_int = instantiate(F, [int_]);
+    DartType G_int = instantiate(G, [int_]);
+    DartType H_int = instantiate(H, [int_]);
+    DartType H_H_int = instantiate(H, [H_int]);
+
+    // flatten(int) = int
+    check(int_, int_);
+
+    // flatten(Future) = dynamic
+    check(Future_.rawType, dynamic_);
+
+    // flatten(Future<int>) = int
+    check(Future_int, int_);
+
+    // flatten(Future<Future<int>>) = int
+    check(instantiate(Future_, [Future_int]), int_);
+
+    // flatten(F) = dynamic
+    check(F.rawType, dynamic_);
+
+    // flatten(F<int>) = int
+    check(F_int, int_);
+
+    // flatten(F<Future<int>>) = Future<int>
+    check(instantiate(F, [Future_int]), Future_int);
+
+    // flatten(G) = G
+    check(G.rawType, G.rawType);
+
+    // flatten(G<int>) = G<int>
+    check(G_int, G_int);
+
+    // flatten(H) = H<H>
+    check(H.rawType, instantiate(H, [H.rawType]));
+
+    // flatten(H<int>) = H<H<int>>
+    check(H_int, H_H_int);
+
+    // flatten(Future<F<int>>) = int
+    check(instantiate(Future_, [F_int]), int_);
+
+    // flatten(Future<G<int>>) = int
+    check(instantiate(Future_, [G_int]), G_int);
+
+    // flatten(Future<H<int>>) = int
+    check(instantiate(Future_, [H_int]), H_H_int);
+  }));
+}
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
index 60deac3..902ea6b 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
@@ -130,6 +130,52 @@
   P.print(P.DateTime$now().isBefore$1(P.DateTime$now()));
   return null;
 }"""),
+  // Static calls
+  const TestEntry("""
+foo() { print(42); }
+main() { foo(); }
+""", r"""
+function() {
+  V.foo();
+  return null;
+}"""),
+  // Static getters
+  const TestEntry("""
+var foo = 42;
+main() { print(foo); }
+""", r"""
+function() {
+  P.print($.foo);
+  return null;
+}"""),
+  const TestEntry("""
+get foo { print(42); }
+main() { foo; }
+""", r"""
+function() {
+  V.foo();
+  return null;
+}"""),
+  // Static setters
+  const TestEntry("""
+var foo = 0;
+main() { print(foo = 42); }
+""", r"""
+function() {
+  var v0;
+  v0 = 42;
+  $.foo = v0;
+  P.print(v0);
+  return null;
+}"""),
+  const TestEntry("""
+set foo(x) { print(x); }
+main() { foo = 42; }
+""", r"""
+function() {
+  V.foo(42);
+  return null;
+}""")
 ];
 
 
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
index ddad2f6..cc20b1b 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
@@ -21,12 +21,12 @@
 """,
 r"""
 function(x) {
-  var box_0, a;
-  box_0 = {};
-  box_0.x_0 = x;
-  a = new V.main_a(box_0);
-  x = box_0.x_0;
-  box_0.x_0 = J.getInterceptor$ns(x).$add(x, "1");
+  var _box_0, a;
+  _box_0 = {};
+  _box_0._captured_x_0 = x;
+  a = new V.main_a(_box_0);
+  x = _box_0._captured_x_0;
+  _box_0._captured_x_0 = J.getInterceptor$ns(x).$add(x, "1");
   P.print(a.call$0());
   return null;
 }"""),
@@ -55,12 +55,12 @@
 """,
 r"""
 function() {
-  var box_0, a, x;
-  box_0 = {};
-  box_0.x_0 = 122;
-  a = new V.main_closure(box_0);
-  x = box_0.x_0;
-  box_0.x_0 = J.getInterceptor$ns(x).$add(x, 1);
+  var _box_0, a, x;
+  _box_0 = {};
+  _box_0._captured_x_0 = 122;
+  a = new V.main_closure(_box_0);
+  x = _box_0._captured_x_0;
+  _box_0._captured_x_0 = J.getInterceptor$ns(x).$add(x, 1);
   P.print(a.call$0());
   return null;
 }"""),
@@ -78,12 +78,12 @@
 """,
 r"""
 function() {
-  var box_0, a, x;
-  box_0 = {};
-  box_0.x_0 = 122;
-  a = new V.main_closure(box_0);
-  x = box_0.x_0;
-  box_0.x_0 = J.getInterceptor$ns(x).$add(x, 1);
+  var _box_0, a, x;
+  _box_0 = {};
+  _box_0._captured_x_0 = 122;
+  a = new V.main_closure(_box_0);
+  x = _box_0._captured_x_0;
+  _box_0._captured_x_0 = J.getInterceptor$ns(x).$add(x, 1);
   P.print(a.call$0().call$0());
   return null;
 }"""),
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
index 1e5f4bf..13547488 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
@@ -98,12 +98,12 @@
 }""",
 r"""
 function(x, y) {
-  var box_0, v0;
-  box_0 = {};
-  box_0.x1_0 = x;
-  v0 = new V.Sub(y, new V.Base_closure(box_0));
+  var _box_0, v0;
+  _box_0 = {};
+  _box_0._captured_x1_0 = x;
+  v0 = new V.Sub(y, new V.Base_closure(_box_0));
   v0.Base0$0();
-  v0.Base$1(box_0);
+  v0.Base$1(_box_0);
   v0.Sub$2(x, y);
   return v0;
 }"""),
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_runtime_types_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_runtime_types_test.dart
new file mode 100644
index 0000000..86f8260
--- /dev/null
+++ b/tests/compiler/dart2js/js_backend_cps_ir_runtime_types_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=-DUSE_CPS_IR=true
+
+// Tests for the runtime type implementation.
+
+library basic_tests;
+
+import 'js_backend_cps_ir.dart';
+
+const String getTypeArgument = r'H.getTypeArgumentByIndex';
+const String getSubstitutedTypeArgument = 'H.getRuntimeTypeArgument';
+const String typeToString = r'H.runtimeTypeToString';
+const String createType = r'H.createRuntimeType';
+
+const List<TestEntry> tests = const [
+    const TestEntry.forMethod("function(C#foo)",
+r"""
+class C<T> {
+  foo() => print(T);
+}
+
+main() {
+  new C<int>().foo();
+}""",
+"""
+function() {
+  return P.print($createType($typeToString($getTypeArgument(this, 0))));
+}"""),
+    const TestEntry.forMethod("function(C#foo)",
+r"""
+class C<T, U> {
+  foo() => print(U);
+}
+
+class D extends C<int, double> {}
+
+main() {
+  new D().foo();
+}""",
+"""
+function() {
+  return P.print($createType($typeToString($getSubstitutedTypeArgument(this, "\$asC", 1))));
+}"""),
+];
+
+void main() {
+  runTests(tests);
+}
diff --git a/tests/compiler/dart2js/js_spec_string_test.dart b/tests/compiler/dart2js/js_spec_string_test.dart
index 42d938e..8ebbfd7 100644
--- a/tests/compiler/dart2js/js_spec_string_test.dart
+++ b/tests/compiler/dart2js/js_spec_string_test.dart
@@ -8,13 +8,18 @@
 import 'package:compiler/src/native/native.dart';
 import 'package:compiler/src/dart2jslib.dart'
     show DiagnosticListener;
+import 'package:compiler/src/universe/universe.dart'
+    show SideEffects;
 
 const OBJECT = 'Object';
 const NULL = 'Null';
 
 class Listener implements DiagnosticListener {
   String errorMessage;
-  internalError(spannable, message) => errorMessage = message;
+  internalError(spannable, message) {
+    errorMessage = message;
+    throw "error";
+  }
 
   noSuchMethod(_) => null;
 }
@@ -22,24 +27,155 @@
 void test(String specString,
           {List returns,
            List creates,
+           SideEffects expectedSideEffects,
            bool expectError: false}) {
   List actualReturns = [];
   List actualCreates = [];
+  SideEffects actualSideEffects;
   Listener listener = new Listener();
-  NativeBehavior.processSpecString(
-      listener,
-      null,
-      specString,
-      resolveType: (t) => t,
-      typesReturned: actualReturns, typesInstantiated: actualCreates,
-      objectType: OBJECT, nullType: NULL);
-  if (expectError) {
+  try {
+    NativeBehavior.processSpecString(
+        listener,
+        null,
+        specString,
+        setSideEffects: (effects) { actualSideEffects = effects; },
+        resolveType: (t) => t,
+        typesReturned: actualReturns, typesInstantiated: actualCreates,
+        objectType: OBJECT, nullType: NULL);
+  } catch (e) {
+    Expect.isTrue(expectError);
     Expect.isNotNull(listener.errorMessage, 'Internal error expected.');
-  } else {
-    Expect.isNull(listener.errorMessage, 'Unexpected internal error.');
-    Expect.listEquals(returns, actualReturns, 'Unexpected returns.');
-    Expect.listEquals(creates, actualCreates, 'Unexpected creates.');
+    return;
   }
+  Expect.isNull(listener.errorMessage, 'Unexpected internal error.');
+  Expect.listEquals(returns, actualReturns, 'Unexpected returns.');
+  Expect.listEquals(creates, actualCreates, 'Unexpected creates.');
+  Expect.equals(expectedSideEffects, actualSideEffects);
+}
+
+void testWithSideEffects(String specString,
+                          {List returns,
+                           List creates,
+                           bool expectError: false}) {
+
+  void sideEffectsTest(String newSpecString, SideEffects expectedSideEffects,
+                       {bool sideEffectsExpectError}) {
+    test(newSpecString,
+         returns: returns,
+         creates: creates,
+         expectedSideEffects: expectedSideEffects,
+         expectError: sideEffectsExpectError == null
+             ? expectError
+             : sideEffectsExpectError);
+  }
+
+  SideEffects emptySideEffects = new SideEffects.empty();
+  sideEffectsTest(specString + "effects:none;depends:none;",
+                  emptySideEffects);
+  sideEffectsTest(specString + "depends:none;effects:none;",
+                  emptySideEffects);
+  sideEffectsTest("effects:none;depends:none;" + specString,
+                  emptySideEffects);
+  sideEffectsTest("depends:none;effects:none;" + specString,
+                  emptySideEffects);
+
+  SideEffects effects = new SideEffects();
+  effects.clearChangesIndex();
+  effects.clearAllDependencies();
+  sideEffectsTest(specString + "effects:no-index;depends:none;", effects);
+
+  effects = new SideEffects();
+  effects.clearAllSideEffects();
+  effects.clearDependsOnIndexStore();
+  sideEffectsTest(specString + "effects:none;depends:no-index;", effects);
+
+  effects = new SideEffects();
+  effects.clearChangesInstanceProperty();
+  effects.clearChangesStaticProperty();
+  effects.clearAllDependencies();
+  sideEffectsTest(specString + "effects:no-instance,no-static;depends:none;",
+                  effects);
+
+  effects = new SideEffects();
+  effects.clearAllSideEffects();
+  effects.clearDependsOnInstancePropertyStore();
+  effects.clearDependsOnStaticPropertyStore();
+  sideEffectsTest(specString + "effects:none;depends:no-instance,no-static;",
+                  effects);
+
+  effects = new SideEffects();
+  effects.clearChangesInstanceProperty();
+  effects.clearChangesStaticProperty();
+  effects.clearDependsOnIndexStore();
+  sideEffectsTest(
+      specString + "effects:no-instance,no-static;depends:no-index;", effects);
+
+  effects = new SideEffects();
+  effects.clearChangesIndex();
+  effects.clearDependsOnInstancePropertyStore();
+  effects.clearDependsOnStaticPropertyStore();
+  sideEffectsTest(
+      specString + "effects:no-index;depends:no-instance,no-static;", effects);
+
+  effects = new SideEffects();
+  effects.clearChangesIndex();
+  sideEffectsTest(specString + "effects:no-index;depends:all;", effects);
+
+  effects = new SideEffects();
+  effects.clearDependsOnIndexStore();
+  sideEffectsTest(specString + "effects:all;depends:no-index;", effects);
+
+  effects = new SideEffects();
+  effects.clearChangesInstanceProperty();
+  effects.clearChangesStaticProperty();
+  sideEffectsTest(specString + "effects:no-instance,no-static;depends:all;",
+                  effects);
+
+  effects = new SideEffects();
+  effects.clearDependsOnInstancePropertyStore();
+  effects.clearDependsOnStaticPropertyStore();
+  sideEffectsTest(specString + "effects:all;depends:no-instance,no-static;",
+                  effects);
+
+  sideEffectsTest(specString + "effects:no-instance,no-static;",
+                  effects,
+                  sideEffectsExpectError: true);
+
+  sideEffectsTest(specString + "depends:no-instance,no-static;",
+                  effects,
+                  sideEffectsExpectError: true);
+
+  sideEffectsTest(specString + "effects:none;",
+                  effects,
+                  sideEffectsExpectError: true);
+
+  sideEffectsTest(specString + "depends:all;",
+                  effects,
+                  sideEffectsExpectError: true);
+
+  sideEffectsTest(specString + "effects:no-instance,no-static;depends:foo;",
+                  effects,
+                  sideEffectsExpectError: true);
+
+  sideEffectsTest(specString + "effects:foo;depends:no-instance,no-static;",
+                  effects,
+                  sideEffectsExpectError: true);
+
+  sideEffectsTest(specString + "effects:all;depends:foo",
+                  effects,
+                  sideEffectsExpectError: true);
+
+  sideEffectsTest(specString + "effects:foo;depends:none;",
+                  effects,
+                  sideEffectsExpectError: true);
+
+  sideEffectsTest(specString + "effects:;depends:none;",
+                  effects,
+                  sideEffectsExpectError: true);
+
+  sideEffectsTest(specString + "effects:all;depends:;",
+                  effects,
+                  sideEffectsExpectError: true);
 }
 
 void main() {
@@ -73,4 +209,31 @@
       returns: ['A', 'B'], creates: ['A', 'C']);
   test(' returns:A|B|C;   creates:A;  ',
       returns: ['A', 'B', 'C'], creates: ['A']);
+
+  testWithSideEffects('returns:void;', returns: [], creates: []);
+  testWithSideEffects('returns:void;', returns: [], creates: []);
+  testWithSideEffects('returns:;', returns: [OBJECT, NULL], creates: []);
+  testWithSideEffects('returns:var;', returns: [OBJECT, NULL], creates: []);
+  testWithSideEffects('returns:A;', returns: ['A'], creates: []);
+  testWithSideEffects('returns:A|B;', returns: ['A', 'B'], creates: []);
+  testWithSideEffects('returns:A|B|C;', returns: ['A', 'B', 'C'], creates: []);
+
+  testWithSideEffects('creates:void;', expectError: true);
+  testWithSideEffects('creates:;', expectError: true);
+  testWithSideEffects('creates:var;', expectError: true);
+  testWithSideEffects('creates:A;', returns: [], creates: ['A']);
+  testWithSideEffects('creates:A|B;', returns: [], creates: ['A', 'B']);
+  testWithSideEffects('creates:A|B|C;', returns: [], creates: ['A', 'B', 'C']);
+
+  testWithSideEffects('returns:void;creates:A;', returns: [], creates: ['A']);
+  testWithSideEffects('returns:;creates:A|B;',
+      returns: [OBJECT, NULL], creates: ['A', 'B']);
+  testWithSideEffects('returns:var;creates:A|B|C;',
+      returns: [OBJECT, NULL], creates: ['A', 'B', 'C']);
+  testWithSideEffects('returns:A; creates:A|B|C; ',
+      returns: ['A'], creates: ['A', 'B', 'C']);
+  testWithSideEffects(' returns:A|B;  creates:A|C;',
+      returns: ['A', 'B'], creates: ['A', 'C']);
+  testWithSideEffects(' returns:A|B|C;   creates:A;  ',
+      returns: ['A', 'B', 'C'], creates: ['A']);
 }
diff --git a/tests/compiler/dart2js/mock_libraries.dart b/tests/compiler/dart2js/mock_libraries.dart
index 126a33e..f329e91 100644
--- a/tests/compiler/dart2js/mock_libraries.dart
+++ b/tests/compiler/dart2js/mock_libraries.dart
@@ -179,6 +179,7 @@
   'makeLiteralMap': 'makeLiteralMap(List keyValuePairs) {}',
   'Native': 'class Native {}',
   'NoInline': 'class NoInline {}',
+  'ForceInline': 'class ForceInline {}',
   'NoSideEffects': 'class NoSideEffects {}',
   'NoThrows': 'class NoThrows {}',
   'numberOrStringSuperNativeTypeCast':
diff --git a/tests/compiler/dart2js/no_such_method_enabled_test.dart b/tests/compiler/dart2js/no_such_method_enabled_test.dart
new file mode 100644
index 0000000..c9da1a0
--- /dev/null
+++ b/tests/compiler/dart2js/no_such_method_enabled_test.dart
@@ -0,0 +1,245 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'compiler_helper.dart';
+
+dummyImplTest() {
+  String source = """
+class A {
+  foo() => 3;
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+main() {
+  print(new A().foo());
+}
+""";
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(source, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    Expect.isFalse(compiler.backend.enabledNoSuchMethod);
+    ClassElement clsA = findElement(compiler, 'A');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.defaultImpls.contains(
+            clsA.lookupMember('noSuchMethod')));
+  }));
+}
+
+dummyImplTest2() {
+  String source = """
+class A extends B {
+  foo() => 3;
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B {}
+main() {
+  print(new A().foo());
+}
+""";
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(source, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    Expect.isFalse(compiler.backend.enabledNoSuchMethod);
+    ClassElement clsA = findElement(compiler, 'A');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.defaultImpls.contains(
+            clsA.lookupMember('noSuchMethod')));
+  }));
+}
+
+dummyImplTest3() {
+  String source = """
+class A extends B {
+  foo() => 3;
+  noSuchMethod(x) {
+    return super.noSuchMethod(x);
+  }
+}
+class B {}
+main() {
+  print(new A().foo());
+}
+""";
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(source, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    Expect.isFalse(compiler.backend.enabledNoSuchMethod);
+    ClassElement clsA = findElement(compiler, 'A');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.defaultImpls.contains(
+            clsA.lookupMember('noSuchMethod')));
+  }));
+}
+
+dummyImplTest4() {
+  String source = """
+class A extends B {
+  foo() => 3;
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+main() {
+  print(new A().foo());
+}
+""";
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(source, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    Expect.isFalse(compiler.backend.enabledNoSuchMethod);
+    ClassElement clsA = findElement(compiler, 'A');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.defaultImpls.contains(
+            clsA.lookupMember('noSuchMethod')));
+    ClassElement clsB = findElement(compiler, 'B');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.defaultImpls.contains(
+            clsB.lookupMember('noSuchMethod')));
+  }));
+}
+
+dummyImplTest5() {
+  String source = """
+class A extends B {
+  foo() => 3;
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B {
+  noSuchMethod(x) => throw 'foo';
+}
+main() {
+  print(new A().foo());
+}
+""";
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(source, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    Expect.isTrue(compiler.backend.enabledNoSuchMethod);
+    ClassElement clsA = findElement(compiler, 'A');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.throwingImpls.contains(
+            clsA.lookupMember('noSuchMethod')));
+    ClassElement clsB = findElement(compiler, 'B');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.throwingImpls.contains(
+            clsB.lookupMember('noSuchMethod')));
+  }));
+}
+
+dummyImplTest6() {
+  String source = """
+class A {
+  noSuchMethod(x) => 3;
+}
+main() {
+  print(new A().foo());
+}
+""";
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(source, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    Expect.isTrue(compiler.backend.enabledNoSuchMethod);
+    ClassElement clsA = findElement(compiler, 'A');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.otherImpls.contains(
+            clsA.lookupMember('noSuchMethod')));
+  }));
+}
+
+dummyImplTest7() {
+  String source = """
+class A {
+  noSuchMethod(x, [y]) => super.noSuchMethod(x);
+}
+main() {
+  print(new A().foo());
+}
+""";
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(source, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    Expect.isFalse(compiler.backend.enabledNoSuchMethod);
+    ClassElement clsA = findElement(compiler, 'A');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.defaultImpls.contains(
+            clsA.lookupMember('noSuchMethod')));
+  }));
+}
+
+dummyImplTest8() {
+  String source = """
+class A {
+  noSuchMethod(x, [y]) => super.noSuchMethod(x, y);
+}
+main() {
+  print(new A().foo());
+}
+""";
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(source, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    Expect.isTrue(compiler.backend.enabledNoSuchMethod);
+    ClassElement clsA = findElement(compiler, 'A');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.otherImpls.contains(
+            clsA.lookupMember('noSuchMethod')));
+  }));
+}
+
+dummyImplTest9() {
+  String source = """
+class A {
+  noSuchMethod(x, y) => super.noSuchMethod(x);
+}
+main() {
+  print(new A().foo());
+}
+""";
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(source, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    Expect.isTrue(compiler.backend.enabledNoSuchMethod);
+    ClassElement clsA = findElement(compiler, 'A');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.otherImpls.contains(
+            clsA.lookupMember('noSuchMethod')));
+  }));
+}
+
+dummyImplTest10() {
+  String source = """
+class A {
+  noSuchMethod(Invocation x) {
+    throw new UnsupportedException();
+  }
+}
+main() {
+  print(new A().foo());
+}
+""";
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(source, uri);
+  asyncTest(() => compiler.runCompiler(uri).then((_) {
+    Expect.isTrue(compiler.backend.enabledNoSuchMethod);
+    ClassElement clsA = findElement(compiler, 'A');
+    Expect.isTrue(
+        compiler.backend.noSuchMethodRegistry.throwingImpls.contains(
+            clsA.lookupMember('noSuchMethod')));
+  }));
+}
+
+main() {
+  dummyImplTest();
+  dummyImplTest2();
+  dummyImplTest3();
+  dummyImplTest4();
+  dummyImplTest5();
+  dummyImplTest6();
+  dummyImplTest7();
+  dummyImplTest8();
+  dummyImplTest9();
+  dummyImplTest10();
+}
diff --git a/tests/compiler/dart2js/one_line_dart_program.dart b/tests/compiler/dart2js/one_line_dart_program.dart
new file mode 100644
index 0000000..24a0c96
--- /dev/null
+++ b/tests/compiler/dart2js/one_line_dart_program.dart
@@ -0,0 +1 @@
+String main() => 499
\ No newline at end of file
diff --git a/tests/compiler/dart2js/scanner_test.dart b/tests/compiler/dart2js/scanner_test.dart
index f9f42fa..e3a82fb 100644
--- a/tests/compiler/dart2js/scanner_test.dart
+++ b/tests/compiler/dart2js/scanner_test.dart
@@ -7,13 +7,19 @@
 import 'package:compiler/src/util/characters.dart';
 import 'dart:typed_data';
 
-Token scan(List<int> bytes) => new Utf8BytesScanner.fromBytes(bytes).tokenize();
+Token scan(List<int> bytes) {
+  List<int> zeroTerminated = new Uint8List(bytes.length + 1);
+  zeroTerminated.setRange(0, bytes.length, bytes);
+  zeroTerminated[bytes.length] = 0;
+  return new Utf8BytesScanner.fromBytes(zeroTerminated).tokenize();
+}
 
 Token scanUTF8(List<int> bytes) {
   int l = bytes.length;
   List<int> stringLiteral = new Uint8List(l + 3);
   stringLiteral[0] = 0x27; // single quote
   stringLiteral[l+1] = 0x27; // single quote
+  // The bytes given to the scanner must be 0-terminated.
   stringLiteral[l+2] = $EOF;
   for (int i = 0; i < l; i++) {
     stringLiteral[i+1] = bytes[i];
diff --git a/tests/compiler/dart2js/semantic_visitor_test.dart b/tests/compiler/dart2js/semantic_visitor_test.dart
new file mode 100644
index 0000000..fea44dc
--- /dev/null
+++ b/tests/compiler/dart2js/semantic_visitor_test.dart
@@ -0,0 +1,4178 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file

+// for details. All rights reserved. Use of this source code is governed by a

+// BSD-style license that can be found in the LICENSE file.

+

+library dart2js.semantics_visitor_test;

+

+import 'package:async_helper/async_helper.dart';

+import 'package:expect/expect.dart';

+import 'package:compiler/src/constants/expressions.dart';

+import 'package:compiler/src/dart_types.dart';

+import 'package:compiler/src/dart2jslib.dart';

+import 'package:compiler/src/elements/elements.dart';

+import 'package:compiler/src/resolution/resolution.dart';

+import 'package:compiler/src/resolution/semantic_visitor.dart';

+import 'package:compiler/src/resolution/operators.dart';

+import 'package:compiler/src/tree/tree.dart';

+import 'package:compiler/src/util/util.dart';

+import 'memory_compiler.dart';

+

+class Visit {

+  final VisitKind method;

+  final element;

+  final rhs;

+  final arguments;

+  final receiver;

+  final name;

+  final expression;

+  final left;

+  final right;

+  final type;

+  final operator;

+  final index;

+  final getter;

+  final setter;

+  final constant;

+  final selector;

+

+  const Visit(this.method,

+              {this.element,

+               this.rhs,

+               this.arguments,

+               this.receiver,

+               this.name,

+               this.expression,

+               this.left,

+               this.right,

+               this.type,

+               this.operator,

+               this.index,

+               this.getter,

+               this.setter,

+               this.constant,

+               this.selector});

+

+  int get hashCode => toString().hashCode;

+

+  bool operator ==(other) => '$this' == '$other';

+

+  String toString() {

+    StringBuffer sb = new StringBuffer();

+    sb.write('method=$method');

+    if (element != null) {

+      sb.write(',element=$element');

+    }

+    if (rhs != null) {

+      sb.write(',rhs=$rhs');

+    }

+    if (arguments != null) {

+      sb.write(',arguments=$arguments');

+    }

+    if (receiver != null) {

+      sb.write(',receiver=$receiver');

+    }

+    if (name != null) {

+      sb.write(',name=$name');

+    }

+    if (expression != null) {

+      sb.write(',expression=$expression');

+    }

+    if (left != null) {

+      sb.write(',left=$left');

+    }

+    if (right != null) {

+      sb.write(',right=$right');

+    }

+    if (type != null) {

+      sb.write(',type=$type');

+    }

+    if (operator != null) {

+      sb.write(',operator=$operator');

+    }

+    if (index != null) {

+      sb.write(',index=$index');

+    }

+    if (getter != null) {

+      sb.write(',getter=$getter');

+    }

+    if (setter != null) {

+      sb.write(',setter=$setter');

+    }

+    if (constant != null) {

+      sb.write(',constant=$constant');

+    }

+    if (selector != null) {

+      sb.write(',selector=$selector');

+    }

+    return sb.toString();

+  }

+}

+

+class Test {

+  final String codeByPrefix;

+  final String code;

+  final /*Visit | List<Visit>*/ expectedVisits;

+  final String cls;

+

+  const Test(this.code, this.expectedVisits)

+      : cls = null, codeByPrefix = null;

+  const Test.clazz(this.code, this.expectedVisits)

+      : cls = 'C', codeByPrefix = null;

+  const Test.prefix(this.codeByPrefix, this.code, this.expectedVisits)

+      : cls = null;

+

+  String get method => 'm';

+

+  String toString() {

+    StringBuffer sb = new StringBuffer();

+    sb.writeln();

+    sb.writeln(code);

+    if (codeByPrefix != null) {

+      sb.writeln('imported by prefix:');

+      sb.writeln(codeByPrefix);

+    }

+    return sb.toString();

+  }

+}

+

+const List<Test> TESTS = const [

+    // Parameters

+    const Test('m(o) => o;',

+        const Visit(VisitKind.VISIT_PARAMETER_GET,

+                    element: 'parameter(m#o)')),

+    const Test('m(o) { o = 42; }',

+        const Visit(VisitKind.VISIT_PARAMETER_SET,

+                    element: 'parameter(m#o)',

+                    rhs:'42')),

+    const Test('m(o) { o(null, 42); }',

+        const Visit(VisitKind.VISIT_PARAMETER_INVOKE,

+                    element: 'parameter(m#o)',

+                    arguments: '(null,42)',

+                    selector: 'Selector(call, call, arity=2)')),

+

+    // Local variables

+    const Test('m() { var o; return o; }',

+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_GET,

+                    element: 'variable(m#o)')),

+    const Test('m() { var o; o = 42; }',

+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_SET,

+                    element: 'variable(m#o)',

+                    rhs:'42')),

+    const Test('m() { var o; o(null, 42); }',

+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_INVOKE,

+                    element: 'variable(m#o)',

+                    arguments: '(null,42)',

+                    selector: 'Selector(call, call, arity=2)')),

+

+    // Local functions

+    const Test('m() { o(a, b) {}; return o; }',

+        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_GET,

+                    element: 'function(m#o)')),

+    const Test('m() { o(a, b) {}; o(null, 42); }',

+        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_INVOKE,

+                    element: 'function(m#o)',

+                    arguments: '(null,42)',

+                    selector: 'Selector(call, call, arity=2)')),

+

+    // Static fields

+    const Test(

+        '''

+        class C { static var o; }

+        m() => C.o;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,

+                    element: 'field(C#o)')),

+    const Test.clazz(

+        '''

+        class C {

+          static var o;

+          m() => o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,

+                    element: 'field(C#o)')),

+    const Test.clazz(

+        '''

+        class C {

+          static var o;

+          m() => C.o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,

+                    element: 'field(C#o)')),

+    const Test.prefix(

+        '''

+        class C {

+          static var o;

+        }

+        ''',

+        'm() => p.C.o;',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,

+                    element: 'field(C#o)')),

+    const Test(

+        '''

+        class C { static var o; }

+        m() { C.o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,

+                    element: 'field(C#o)',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static var o;

+          m() { o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,

+                    element: 'field(C#o)',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static var o;

+          m() { C.o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,

+                    element: 'field(C#o)',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        class C {

+          static var o;

+        }

+        ''',

+        'm() { p.C.o = 42; }',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,

+                    element: 'field(C#o)',

+                    rhs: '42')),

+    const Test(

+        '''

+        class C { static var o; }

+        m() { C.o(null, 42); }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,

+                    element: 'field(C#o)',

+                    arguments: '(null,42)')),

+    const Test.clazz(

+        '''

+        class C {

+          static var o;

+          m() { o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,

+                    element: 'field(C#o)',

+                    arguments: '(null,42)')),

+    const Test.clazz(

+        '''

+        class C {

+          static var o;

+          m() { C.o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,

+                    element: 'field(C#o)',

+                    arguments: '(null,42)')),

+    const Test.prefix(

+        '''

+        class C {

+          static var o;

+        }

+        ''',

+        'm() { p.C.o(null, 42); }',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,

+                    element: 'field(C#o)',

+                    arguments: '(null,42)')),

+

+    // Static properties

+    const Test(

+        '''

+        class C {

+          static get o => null;

+        }

+        m() => C.o;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,

+                    element: 'getter(C#o)')),

+    const Test.clazz(

+        '''

+        class C {

+          static get o => null;

+          m() => o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,

+                    element: 'getter(C#o)')),

+    const Test.clazz(

+        '''

+        class C {

+          static get o => null;

+          m() => C.o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,

+                    element: 'getter(C#o)')),

+    const Test.prefix(

+        '''

+        class C {

+          static get o => null;

+        }

+        ''',

+        'm() => p.C.o;',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,

+                    element: 'getter(C#o)')),

+    const Test(

+        '''

+        class C { static set o(_) {} }

+        m() { C.o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,

+                    element: 'setter(C#o)',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static set o(_) {}

+          m() { o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,

+                    element: 'setter(C#o)',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static set o(_) {}

+          m() { C.o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,

+                    element: 'setter(C#o)',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        class C {

+          static set o(_) {}

+        }

+        ''',

+        'm() { p.C.o = 42; }',

+        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,

+                    element: 'setter(C#o)',

+                    rhs: '42')),

+    const Test(

+        '''

+        class C { static get o => null; }

+        m() => C.o(null, 42);

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,

+                    element: 'getter(C#o)',

+                    arguments: '(null,42)')),

+    const Test.clazz(

+        '''

+        class C {

+          static get o => null;

+          m() { o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,

+                    element: 'getter(C#o)',

+                    arguments: '(null,42)')),

+    const Test.clazz(

+        '''

+        class C {

+          static get o => null;

+          m() { C.o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,

+                    element: 'getter(C#o)',

+                    arguments: '(null,42)')),

+    const Test.prefix(

+        '''

+        class C {

+          static get o => null;

+        }

+        ''',

+        'm() { p.C.o(null, 42); }',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,

+                    element: 'getter(C#o)',

+                    arguments: '(null,42)')),

+

+    // Static functions

+    const Test(

+        '''

+        class C { static o(a, b) {} }

+        m() => C.o;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,

+                    element: 'function(C#o)')),

+    const Test.clazz(

+        '''

+        class C {

+          static o(a, b) {}

+          m() => o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,

+                    element: 'function(C#o)')),

+    const Test.clazz(

+        '''

+        class C {

+          static o(a, b) {}

+          m() => C.o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,

+                    element: 'function(C#o)')),

+    const Test.prefix(

+        '''

+        class C { static o(a, b) {} }

+        ''',

+        '''

+        m() => p.C.o;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,

+                    element: 'function(C#o)')),

+    const Test(

+        '''

+        class C { static o(a, b) {} }

+        m() => C.o(null, 42);

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,

+                    element: 'function(C#o)',

+                    arguments: '(null,42)')),

+    const Test.clazz(

+        '''

+        class C {

+          static o(a, b) {}

+          m() { o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,

+                    element: 'function(C#o)',

+                    arguments: '(null,42)')),

+    const Test.clazz(

+        '''

+        class C {

+          static o(a, b) {}

+          m() { C.o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,

+                    element: 'function(C#o)',

+                    arguments: '(null,42)')),

+    const Test.prefix(

+        '''

+        class C {

+          static o(a, b) {}

+        }

+        ''',

+        'm() { p.C.o(null, 42); }',

+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,

+                    element: 'function(C#o)',

+                    arguments: '(null,42)')),

+

+    // Top level fields

+    const Test(

+        '''

+        var o;

+        m() => o;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET,

+                    element: 'field(o)')),

+    const Test.prefix(

+        '''

+        var o;

+        ''',

+        'm() => p.o;',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET,

+                    element: 'field(o)')),

+    const Test(

+        '''

+        var o;

+        m() { o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,

+                    element: 'field(o)',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        var o;

+        ''',

+        'm() { p.o = 42; }',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,

+                    element: 'field(o)',

+                    rhs: '42')),

+    const Test(

+        '''

+        var o;

+        m() { o(null, 42); }

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,

+                    element: 'field(o)',

+                    arguments: '(null,42)')),

+    const Test.prefix(

+        '''

+        var o;

+        ''',

+        'm() { p.o(null, 42); }',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,

+                    element: 'field(o)',

+                    arguments: '(null,42)')),

+

+    // Top level properties

+    const Test(

+        '''

+        get o => null;

+        m() => o;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,

+                    element: 'getter(o)')),

+    const Test.prefix(

+        '''

+        get o => null;

+        ''',

+        '''

+        m() => p.o;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,

+                    element: 'getter(o)')),

+    const Test(

+        '''

+        set o(_) {}

+        m() { o = 42; }

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,

+                    element: 'setter(o)',

+                    rhs: '42')),

+    const Test.prefix(

+        '''

+        set o(_) {}

+        ''',

+        'm() { p.o = 42; }',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,

+                    element: 'setter(o)',

+                    rhs: '42')),

+    const Test(

+        '''

+        get o => null;

+        m() => o(null, 42);

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,

+                    element: 'getter(o)',

+                    arguments: '(null,42)')),

+    const Test.prefix(

+        '''

+        get o => null;

+        ''',

+        'm() { p.o(null, 42); }',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,

+                    element: 'getter(o)',

+                    arguments: '(null,42)')),

+

+    // Top level functions

+    const Test(

+        '''

+        o(a, b) {}

+        m() => o;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_GET,

+                    element: 'function(o)')),

+    const Test(

+        '''

+        o(a, b) {}

+        m() => o(null, 42);

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,

+                    element: 'function(o)',

+                    arguments: '(null,42)')),

+    const Test.prefix(

+        '''

+        o(a, b) {}

+        ''',

+        'm() { p.o(null, 42); }',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,

+                    element: 'function(o)',

+                    arguments: '(null,42)')),

+

+    // Dynamic properties

+    const Test('m(o) => o.foo;',

+        const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,

+                    receiver: 'o',

+                    name: 'foo')),

+    const Test('m(o) { o.foo = 42; }',

+        const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,

+                    receiver: 'o',

+                    name: 'foo',

+                    rhs: '42')),

+    const Test('m(o) { o.foo(null, 42); }',

+        const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,

+                    receiver: 'o',

+                    name: 'foo',

+                    arguments: '(null,42)')),

+

+    // This access

+    const Test.clazz(

+        '''

+        class C {

+          m() => this;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_GET)),

+    const Test.clazz(

+        '''

+        class C {

+          call(a, b) {}

+          m() { this(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_INVOKE,

+                    arguments: '(null,42)')),

+

+    // This properties

+    const Test.clazz(

+        '''

+        class C {

+          var foo;

+          m() => foo;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,

+                    name: 'foo')),

+    const Test.clazz(

+        '''

+        class C {

+          var foo;

+          m() => this.foo;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,

+                    name: 'foo')),

+    const Test.clazz(

+        '''

+        class C {

+          get foo => null;

+          m() => foo;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,

+                    name: 'foo')),

+    const Test.clazz(

+        '''

+        class C {

+          get foo => null;

+          m() => this.foo;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,

+                    name: 'foo')),

+    const Test.clazz(

+        '''

+        class C {

+          var foo;

+          m() { foo = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,

+                    name: 'foo',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          var foo;

+          m() { this.foo = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,

+                    name: 'foo',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          set foo(_) {}

+          m() { foo = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,

+                    name: 'foo',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          set foo(_) {}

+          m() { this.foo = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,

+                    name: 'foo',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          var foo;

+          m() { foo(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,

+                    name: 'foo',

+                    arguments: '(null,42)')),

+    const Test.clazz(

+        '''

+        class C {

+          var foo;

+          m() { this.foo(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,

+                    name: 'foo',

+                    arguments: '(null,42)')),

+

+    // Super fields

+    const Test.clazz(

+        '''

+        class B {

+          var o;

+        }

+        class C extends B {

+          m() => super.o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FIELD_GET,

+                    element: 'field(B#o)')),

+    const Test.clazz(

+        '''

+        class B {

+          var o;

+        }

+        class C extends B {

+          m() { super.o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FIELD_SET,

+                    element: 'field(B#o)',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class B {

+          var o;

+        }

+        class C extends B {

+          m() { super.o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FIELD_INVOKE,

+                    element: 'field(B#o)',

+                    arguments: '(null,42)')),

+

+    // Super properties

+    const Test.clazz(

+        '''

+        class B {

+          get o => null;

+        }

+        class C extends B {

+          m() => super.o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_GETTER_GET,

+                    element: 'getter(B#o)')),

+    const Test.clazz(

+        '''

+        class B {

+          set o(_) {}

+        }

+        class C extends B {

+          m() { super.o = 42; }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_SETTER_SET,

+                    element: 'setter(B#o)',

+                    rhs: '42')),

+    const Test.clazz(

+        '''

+        class B {

+          get o => null;

+        }

+        class C extends B {

+          m() { super.o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,

+                    element: 'getter(B#o)',

+                    arguments: '(null,42)')),

+

+    // Super methods

+    const Test.clazz(

+        '''

+        class B {

+          o(a, b) {}

+        }

+        class C extends B {

+          m() => super.o;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_METHOD_GET,

+                    element: 'function(B#o)')),

+    const Test.clazz(

+        '''

+        class B {

+          o(a, b) {}

+        }

+        class C extends B {

+          m() { super.o(null, 42); }

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_METHOD_INVOKE,

+                    element: 'function(B#o)',

+                    arguments: '(null,42)')),

+

+    // Expression invoke

+    const Test('m() => (a, b){}(null, 42);',

+        const Visit(VisitKind.VISIT_EXPRESSION_INVOKE,

+                    receiver: '(a,b){}',

+                    arguments: '(null,42)')),

+

+    // Class type literals

+    const Test(

+        '''

+        class C {}

+        m() => C;

+        ''',

+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,

+                    constant: 'C')),

+    const Test(

+        '''

+        class C {}

+        m() => C(null, 42);

+        ''',

+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,

+                    constant: 'C',

+                    arguments: '(null,42)')),

+

+    // Typedef type literals

+    const Test(

+        '''

+        typedef F();

+        m() => F;

+        ''',

+        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_GET,

+                    constant: 'F')),

+    const Test(

+        '''

+        typedef F();

+        m() => F(null, 42);

+        ''',

+        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,

+                    constant: 'F',

+                    arguments: '(null,42)')),

+

+    // Type variable type literals

+    const Test.clazz(

+        '''

+        class C<T> {

+          m() => T;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,

+                    element: 'type_variable(C#T)')),

+    const Test.clazz(

+        '''

+        class C<T> {

+          m() => T(null, 42);

+        }

+        ''',

+        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,

+                    element: 'type_variable(C#T)',

+                    arguments: '(null,42)')),

+

+    // Dynamic type literals

+    const Test(

+        '''

+        m() => dynamic;

+        ''',

+        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_GET,

+                    constant: 'dynamic')),

+    // TODO(johnniwinther): Enable this when we pass the right constant.

+    // Currently we generated the constant for `Type` instead of `dynamic`.

+    /*const Test(

+        '''

+        m() { dynamic(null, 42); }

+        ''',

+        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,

+                    constant: 'dynamic',

+                    arguments: '(null,42)')),*/

+

+    // Assert

+    const Test(

+        '''

+        m() { assert(false); }

+        ''',

+        const Visit(VisitKind.VISIT_ASSERT, expression: 'false')),

+

+    // Logical and

+    const Test(

+        '''

+        m() => true && false;

+        ''',

+        const Visit(VisitKind.VISIT_LOGICAL_AND, left: 'true', right: 'false')),

+

+    // Logical or

+    const Test(

+        '''

+        m() => true || false;

+        ''',

+        const Visit(VisitKind.VISIT_LOGICAL_OR, left: 'true', right: 'false')),

+

+    // Is test

+    const Test(

+        '''

+        class C {}

+        m() => 0 is C;

+        ''',

+        const Visit(VisitKind.VISIT_IS, expression: '0', type: 'C')),

+

+    // Is not test

+    const Test(

+        '''

+        class C {}

+        m() => 0 is! C;

+        ''',

+        const Visit(VisitKind.VISIT_IS_NOT, expression: '0', type: 'C')),

+

+    // Is test

+    const Test(

+        '''

+        class C {}

+        m() => 0 as C;

+        ''',

+        const Visit(VisitKind.VISIT_AS, expression: '0', type: 'C')),

+

+    // Binary operators

+    const Test(

+        '''

+        m() => 2 + 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '+', right: '3')),

+    const Test(

+        '''

+        m() => 2 - 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '-', right: '3')),

+    const Test(

+        '''

+        m() => 2 * 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '*', right: '3')),

+    const Test(

+        '''

+        m() => 2 / 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '/', right: '3')),

+    const Test(

+        '''

+        m() => 2 ~/ 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '~/', right: '3')),

+    const Test(

+        '''

+        m() => 2 % 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '%', right: '3')),

+    const Test(

+        '''

+        m() => 2 << 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '<<', right: '3')),

+    const Test(

+        '''

+        m() => 2 >> 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '>>', right: '3')),

+    const Test(

+        '''

+        m() => 2 <= 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '<=', right: '3')),

+    const Test(

+        '''

+        m() => 2 < 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '<', right: '3')),

+    const Test(

+        '''

+        m() => 2 >= 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '>=', right: '3')),

+    const Test(

+        '''

+        m() => 2 > 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '>', right: '3')),

+    const Test(

+        '''

+        m() => 2 & 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '&', right: '3')),

+    const Test(

+        '''

+        m() => 2 | 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '|', right: '3')),

+    const Test(

+        '''

+        m() => 2 ^ 3;

+        ''',

+        const Visit(VisitKind.VISIT_BINARY,

+                    left: '2', operator: '^', right: '3')),

+    const Test.clazz(

+        '''

+        class B {

+          operator +(_) => null;

+        }

+        class C extends B {

+          m() => super + 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_BINARY,

+                    element: 'function(B#+)',

+                    operator: '+',

+                    right: '42')),

+    // Index

+    const Test(

+        '''

+        m() => 2[3];

+        ''',

+        const Visit(VisitKind.VISIT_INDEX,

+                    receiver: '2', index: '3')),

+    const Test(

+        '''

+        m() => --2[3];

+        ''',

+        const Visit(VisitKind.VISIT_INDEX_PREFIX,

+                    receiver: '2', index: '3', operator: '--')),

+    const Test(

+        '''

+        m() => 2[3]++;

+        ''',

+        const Visit(VisitKind.VISIT_INDEX_POSTFIX,

+                    receiver: '2', index: '3', operator: '++')),

+    const Test.clazz(

+        '''

+        class B {

+          operator [](_) => null;

+        }

+        class C extends B {

+          m() => super[42];

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_INDEX,

+                    element: 'function(B#[])',

+                    index: '42')),

+    const Test.clazz(

+        '''

+        class B {

+          operator [](_) => null;

+          operator []=(a, b) {}

+        }

+        class C extends B {

+          m() => ++super[42];

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_INDEX_PREFIX,

+                    getter: 'function(B#[])',

+                    setter: 'function(B#[]=)',

+                    index: '42',

+                    operator: '++')),

+    const Test.clazz(

+        '''

+        class B {

+          operator [](_) => null;

+          operator []=(a, b) {}

+        }

+        class C extends B {

+          m() => super[42]--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_INDEX_POSTFIX,

+                    getter: 'function(B#[])',

+                    setter: 'function(B#[]=)',

+                    index: '42',

+                    operator: '--')),

+

+    // Equals

+    const Test(

+        '''

+        m() => 2 == 3;

+        ''',

+        const Visit(VisitKind.VISIT_EQUALS,

+                    left: '2', right: '3')),

+    const Test.clazz(

+        '''

+        class B {

+          operator ==(_) => null;

+        }

+        class C extends B {

+          m() => super == 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_EQUALS,

+                    element: 'function(B#==)',

+                    right: '42')),

+

+    // Not equals

+    const Test(

+        '''

+        m() => 2 != 3;

+        ''',

+        const Visit(VisitKind.VISIT_NOT_EQUALS,

+                    left: '2', right: '3')),

+    // TODO(johnniwinther): Enable this. Resolution does not store the element.

+    /*const Test.clazz(

+        '''

+        class B {

+          operator ==(_) => null;

+        }

+        class C extends B {

+          m() => super != 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_NOT_EQUALS,

+                    element: 'function(B#==)',

+                    right: '42')),*/

+

+    // Unary expression

+    const Test(

+        '''

+        m() => -false;

+        ''',

+        const Visit(VisitKind.VISIT_UNARY,

+                    expression: 'false', operator: '-')),

+    const Test(

+        '''

+        m() => ~false;

+        ''',

+        const Visit(VisitKind.VISIT_UNARY,

+                    expression: 'false', operator: '~')),

+    const Test.clazz(

+        '''

+        class B {

+          operator -() => null;

+        }

+        class C extends B {

+          m() => -super;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_UNARY,

+                    element: 'function(B#unary-)', operator: '-')),

+    const Test.clazz(

+        '''

+        class B {

+          operator ~() => null;

+        }

+        class C extends B {

+          m() => ~super;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_UNARY,

+                    element: 'function(B#~)', operator: '~')),

+    const Test(

+        '''

+        m() => !0;

+        ''',

+        const Visit(VisitKind.VISIT_NOT, expression: '0')),

+

+    // Index set

+    const Test(

+        '''

+        m() => 0[1] = 2;

+        ''',

+        const Visit(VisitKind.VISIT_INDEX_SET,

+            receiver: '0', index: '1', rhs: '2')),

+    const Test.clazz(

+        '''

+        class B {

+          operator []=(a, b) {}

+        }

+        class C extends B {

+          m() => super[1] = 2;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_INDEX_SET,

+            element: 'function(B#[]=)', index: '1', rhs: '2')),

+

+    // Compound assignment

+    const Test(

+        '''

+        m(a) => a.b += 42;

+        ''',

+        const [

+          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_COMPOUND,

+              receiver: 'a', operator: '+=', rhs: '42',

+              getter: 'Selector(getter, b, arity=0)',

+              setter: 'Selector(setter, b, arity=1)'),

+          const Visit(VisitKind.VISIT_PARAMETER_GET,

+              element: 'parameter(m#a)')

+        ]),

+    // TODO(johnniwinther): Enable this when type literals are recognized in

+    // SendSet.

+    /*const Test(

+        '''

+        class C {}

+        m(a) => C += 42;

+        ''',

+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,

+            constant: 'C', operator: '+=', rhs: '42')),

+    const Test(

+        '''

+        typedef F();

+        m(a) => F += 42;

+        ''',

+        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,

+            constant: 'F', operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class C<T> {

+          m(a) => T += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

+            element: 'type_variable(C#T)', operator: '+=', rhs: '42')),

+    const Test(

+        '''

+        m(a) => dynamic += 42;

+        ''',

+        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,

+            constant: 'dynamic',

+            operator: '+=', rhs: '42')),*/

+    const Test(

+        '''

+        m(a) => a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_PARAMETER_COMPOUND,

+            element: 'parameter(m#a)', operator: '+=', rhs: '42')),

+    const Test(

+        '''

+        m() {

+          var a;

+          a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_COMPOUND,

+            element: 'variable(m#a)', operator: '+=', rhs: '42')),

+    const Test(

+        '''

+        var a;

+        m() => a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_COMPOUND,

+            element: 'field(a)', operator: '+=', rhs: '42')),

+    const Test(

+        '''

+        get a => 0;

+        set a(_) {}

+        m() => a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,

+            getter: 'getter(a)', setter: 'setter(a)',

+            operator: '+=', rhs: '42')),

+    const Test(

+        '''

+        class C {

+          static var a;

+        }

+        m() => C.a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,

+            element: 'field(C#a)', operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static var a;

+          m() => C.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,

+            element: 'field(C#a)', operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static var a;

+          m() => a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,

+            element: 'field(C#a)', operator: '+=', rhs: '42')),

+    const Test.prefix(

+        '''

+        class C {

+          static var a;

+        }

+        ''',

+        '''

+        m() => p.C.a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,

+            element: 'field(C#a)', operator: '+=', rhs: '42')),

+    const Test(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+        }

+        m() => C.a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+          m() => C.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+          m() => a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '+=', rhs: '42')),

+    const Test.prefix(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+        }

+        ''',

+        '''

+        m() => p.C.a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '+=', rhs: '42')),

+    // TODO(johnniwinther): Enable these when dart2js supports method and setter

+    // with the same name.

+    /*const Test(

+        '''

+        class C {

+          static a() {}

+          static set a(_) {}

+        }

+        m() => C.a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,

+            getter: 'function(C#a)', setter: 'setter(C#a)',

+            operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static a() {}

+          static set a(_) {}

+          m() => C.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,

+            getter: 'function(C#a)', setter: 'setter(C#a)',

+            operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class C {

+          static a() {}

+          static set a(_) {}

+          m() => a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,

+            getter: 'function(C#a)', setter: 'setter(C#a)',

+            operator: '+=', rhs: '42')),

+    const Test.prefix(

+        '''

+        class C {

+          static a() {}

+          static set a(_) {}

+        }

+        ''',

+        '''

+        m() => p.C.a += 42;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,

+            getter: 'function(C#a)', setter: 'setter(C#a)',

+            operator: '+=', rhs: '42')),*/

+    const Test.clazz(

+        '''

+        class C {

+          var a;

+          m() => a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,

+            operator: '+=', rhs: '42',

+            getter: 'Selector(getter, a, arity=0)',

+            setter: 'Selector(setter, a, arity=1)')),

+    const Test.clazz(

+        '''

+        class C {

+          var a = 0;

+          m() => this.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,

+            operator: '+=', rhs: '42',

+            getter: 'Selector(getter, a, arity=0)',

+            setter: 'Selector(setter, a, arity=1)')),

+    const Test.clazz(

+        '''

+        class B {

+          var a = 0;

+        }

+        class C extends B {

+          m() => super.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FIELD_COMPOUND,

+            element: 'field(B#a)', operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class B {

+          get a => 0;

+          set a (_) {}

+        }

+        class C extends B {

+          m() => super.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,

+            getter: 'getter(B#a)', setter: 'setter(B#a)',

+            operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class A {

+          get a => 0;

+        }

+        class B extends A {

+          set a (_) {}

+        }

+        class C extends B {

+          m() => super.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,

+            getter: 'getter(A#a)', setter: 'setter(B#a)',

+            operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class A {

+          var a;

+        }

+        class B extends A {

+          get a => 0;

+        }

+

+        class C extends B {

+          m() => super.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_COMPOUND,

+            getter: 'getter(B#a)', setter: 'field(A#a)',

+            operator: '+=', rhs: '42')),

+    const Test.clazz(

+        '''

+        class A {

+          var a;

+        }

+        class B extends A {

+          set a(_) {}

+        }

+

+        class C extends B {

+          m() => super.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_COMPOUND,

+            getter: 'field(A#a)', setter: 'setter(B#a)',

+            operator: '+=', rhs: '42')),

+    // TODO(johnniwinther): Enable this when dart2js supports shadow setters.

+    /*const Test.clazz(

+        '''

+        class A {

+          var a;

+        }

+        class B extends A {

+          final a;

+        }

+

+        class C extends B {

+          m() => super.a += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,

+            getter: 'field(B#a)', setter: 'field(A#a)',

+            operator: '+=', rhs: '42')),*/

+

+    // Compound index assignment

+    const Test(

+        '''

+        m() => 0[1] += 42;

+        ''',

+        const Visit(VisitKind.VISIT_COMPOUND_INDEX_SET,

+            receiver: '0', index: '1', operator: '+=', rhs: '42')),

+    // TODO(johnniwinther): Enable this when the getter element is stored.

+    /*const Test.clazz(

+        '''

+        class B {

+          operator [](_) {}

+          operator []=(a, b) {}

+        }

+        class C extends B {

+          m() => super[1] += 42;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_COMPOUND_INDEX_SET,

+            getter: 'function(B#[])', setter: 'function(B#[]=)',

+            index: '1', operator: '+=', rhs: '42')),*/

+

+    // Prefix expression

+    const Test(

+        '''

+        m(a) => --a.b;

+        ''',

+        const [

+          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_PREFIX,

+              receiver: 'a', operator: '--',

+              getter: 'Selector(getter, b, arity=0)',

+              setter: 'Selector(setter, b, arity=1)'),

+          const Visit(VisitKind.VISIT_PARAMETER_GET,

+              element: 'parameter(m#a)')

+        ]),

+    const Test(

+        '''

+        m(a) => ++a;

+        ''',

+        const Visit(VisitKind.VISIT_PARAMETER_PREFIX,

+            element: 'parameter(m#a)', operator: '++')),

+    const Test(

+        '''

+        m() {

+          var a;

+          --a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_PREFIX,

+            element: 'variable(m#a)', operator: '--')),

+    const Test(

+        '''

+        var a;

+        m() => ++a;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_PREFIX,

+            element: 'field(a)', operator: '++')),

+    const Test(

+        '''

+        get a => 0;

+        set a(_) {}

+        m() => --a;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,

+            getter: 'getter(a)', setter: 'setter(a)',

+            operator: '--')),

+    const Test(

+        '''

+        class C {

+          static var a;

+        }

+        m() => ++C.a;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,

+            element: 'field(C#a)', operator: '++')),

+    const Test.clazz(

+        '''

+        class C {

+          static var a;

+          m() => ++C.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,

+            element: 'field(C#a)', operator: '++')),

+    const Test.clazz(

+        '''

+        class C {

+          static var a;

+          m() => --a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,

+            element: 'field(C#a)', operator: '--')),

+    const Test.prefix(

+        '''

+        class C {

+          static var a;

+        }

+        ''',

+        '''

+        m() => --p.C.a;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,

+            element: 'field(C#a)', operator: '--')),

+    const Test(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+        }

+        m() => ++C.a;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '++')),

+    const Test.clazz(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+          m() => --C.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '--')),

+    const Test.clazz(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+          m() => --a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '--')),

+    const Test.prefix(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+        }

+        ''',

+        '''

+        m() => ++p.C.a;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '++')),

+    const Test.clazz(

+        '''

+        class C {

+          var a;

+          m() => --a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,

+            operator: '--',

+            getter: 'Selector(getter, a, arity=0)',

+            setter: 'Selector(setter, a, arity=1)')),

+    const Test.clazz(

+        '''

+        class C {

+          var a = 0;

+          m() => ++this.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,

+            operator: '++',

+            getter: 'Selector(getter, a, arity=0)',

+            setter: 'Selector(setter, a, arity=1)')),

+    const Test.clazz(

+        '''

+        class B {

+          var a = 0;

+        }

+        class C extends B {

+          m() => --super.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FIELD_PREFIX,

+            element: 'field(B#a)', operator: '--')),

+    const Test.clazz(

+        '''

+        class B {

+          get a => 0;

+          set a (_) {}

+        }

+        class C extends B {

+          m() => --super.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,

+            getter: 'getter(B#a)', setter: 'setter(B#a)',

+            operator: '--')),

+    const Test.clazz(

+        '''

+        class A {

+          get a => 0;

+        }

+        class B extends A {

+          set a (_) {}

+        }

+        class C extends B {

+          m() => ++super.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,

+            getter: 'getter(A#a)', setter: 'setter(B#a)',

+            operator: '++')),

+    const Test.clazz(

+        '''

+        class A {

+          var a;

+        }

+        class B extends A {

+          get a => 0;

+        }

+

+        class C extends B {

+          m() => --super.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_PREFIX,

+            getter: 'getter(B#a)', setter: 'field(A#a)',

+            operator: '--')),

+    const Test.clazz(

+        '''

+        class A {

+          var a;

+        }

+        class B extends A {

+          set a(_) {}

+        }

+

+        class C extends B {

+          m() => ++super.a;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_PREFIX,

+            getter: 'field(A#a)', setter: 'setter(B#a)',

+            operator: '++')),

+

+    // Prefix expression

+    const Test(

+        '''

+        m(a) => a.b--;

+        ''',

+        const [

+          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_POSTFIX,

+              receiver: 'a', operator: '--',

+              getter: 'Selector(getter, b, arity=0)',

+              setter: 'Selector(setter, b, arity=1)'),

+          const Visit(VisitKind.VISIT_PARAMETER_GET,

+              element: 'parameter(m#a)')

+        ]),

+    const Test(

+        '''

+        m(a) => a++;

+        ''',

+        const Visit(VisitKind.VISIT_PARAMETER_POSTFIX,

+            element: 'parameter(m#a)', operator: '++')),

+    const Test(

+        '''

+        m() {

+          var a;

+          a--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_POSTFIX,

+            element: 'variable(m#a)', operator: '--')),

+    const Test(

+        '''

+        var a;

+        m() => a++;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_POSTFIX,

+            element: 'field(a)', operator: '++')),

+    const Test(

+        '''

+        get a => 0;

+        set a(_) {}

+        m() => a--;

+        ''',

+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,

+            getter: 'getter(a)', setter: 'setter(a)',

+            operator: '--')),

+    const Test(

+        '''

+        class C {

+          static var a;

+        }

+        m() => C.a++;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,

+            element: 'field(C#a)', operator: '++')),

+    const Test.clazz(

+        '''

+        class C {

+          static var a;

+          m() => C.a++;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,

+            element: 'field(C#a)', operator: '++')),

+    const Test.clazz(

+        '''

+        class C {

+          static var a;

+          m() => a--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,

+            element: 'field(C#a)', operator: '--')),

+    const Test.prefix(

+        '''

+        class C {

+          static var a;

+        }

+        ''',

+        '''

+        m() => p.C.a--;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,

+            element: 'field(C#a)', operator: '--')),

+    const Test(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+        }

+        m() => C.a++;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '++')),

+    const Test.clazz(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+          m() => C.a--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '--')),

+    const Test.clazz(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+          m() => a--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '--')),

+    const Test.prefix(

+        '''

+        class C {

+          static get a => 0;

+          static set a(_) {}

+        }

+        ''',

+        '''

+        m() => p.C.a++;

+        ''',

+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,

+            getter: 'getter(C#a)', setter: 'setter(C#a)',

+            operator: '++')),

+    const Test.clazz(

+        '''

+        class C {

+          var a;

+          m() => a--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,

+            operator: '--',

+            getter: 'Selector(getter, a, arity=0)',

+            setter: 'Selector(setter, a, arity=1)')),

+    const Test.clazz(

+        '''

+        class C {

+          var a = 0;

+          m() => this.a++;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,

+            operator: '++',

+            getter: 'Selector(getter, a, arity=0)',

+            setter: 'Selector(setter, a, arity=1)')),

+    const Test.clazz(

+        '''

+        class B {

+          var a = 0;

+        }

+        class C extends B {

+          m() => super.a--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FIELD_POSTFIX,

+            element: 'field(B#a)', operator: '--')),

+    const Test.clazz(

+        '''

+        class B {

+          get a => 0;

+          set a (_) {}

+        }

+        class C extends B {

+          m() => super.a--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,

+            getter: 'getter(B#a)', setter: 'setter(B#a)',

+            operator: '--')),

+    const Test.clazz(

+        '''

+        class A {

+          get a => 0;

+        }

+        class B extends A {

+          set a (_) {}

+        }

+        class C extends B {

+          m() => super.a++;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,

+            getter: 'getter(A#a)', setter: 'setter(B#a)',

+            operator: '++')),

+    const Test.clazz(

+        '''

+        class A {

+          var a;

+        }

+        class B extends A {

+          get a => 0;

+        }

+

+        class C extends B {

+          m() => super.a--;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_POSTFIX,

+            getter: 'getter(B#a)', setter: 'field(A#a)',

+            operator: '--')),

+    const Test.clazz(

+        '''

+        class A {

+          var a;

+        }

+        class B extends A {

+          set a(_) {}

+        }

+

+        class C extends B {

+          m() => super.a++;

+        }

+        ''',

+        const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_POSTFIX,

+            getter: 'field(A#a)', setter: 'setter(B#a)',

+            operator: '++')),

+

+];

+

+main() {

+  Map<String, String> sourceFiles = {};

+  Map<String, Test> testMap = {};

+  StringBuffer mainSource = new StringBuffer();

+  int index = 0;

+  TESTS.forEach((Test test) {

+    StringBuffer testSource = new StringBuffer();

+    if (test.codeByPrefix != null) {

+      String prefixFilename = 'pre$index.dart';

+      sourceFiles[prefixFilename] = test.codeByPrefix;

+      testSource.writeln("import '$prefixFilename' as p;");

+    }

+

+    String filename = 'lib$index.dart';

+    testSource.writeln(test.code);

+    sourceFiles[filename] = testSource.toString();

+    mainSource.writeln("import '$filename';");

+    testMap[filename] = test;

+    index++;

+  });

+  mainSource.writeln("main() {}");

+  sourceFiles['main.dart'] = mainSource.toString();

+

+  asyncTest(() {

+    Compiler compiler = compilerFor(sourceFiles,

+        options: ['--analyze-all', '--analyze-only']);

+    return compiler.run(Uri.parse('memory:main.dart')).then((_) {

+      testMap.forEach((String filename, Test test) {

+        LibraryElement library = compiler.libraryLoader.lookupLibrary(

+            Uri.parse('memory:$filename'));

+        var expectedVisits = test.expectedVisits;

+        if (expectedVisits is! List) {

+          expectedVisits = [expectedVisits];

+        }

+        AstElement element;

+        String cls = test.cls;

+        String method = test.method;

+        if (cls == null) {

+          element = library.find(method);

+        } else {

+          ClassElement classElement = library.find(cls);

+          Expect.isNotNull(classElement,

+                           "Class '$cls' not found in:\n"

+                           "${library.compilationUnit.script.text}");

+          element = classElement.localLookup(method);

+        }

+        Expect.isNotNull(element, "Element '$method' not found in:\n"

+                                  "${library.compilationUnit.script.text}");

+        ResolvedAst resolvedAst = element.resolvedAst;

+        SemanticTestVisitor visitor =

+            new SemanticTestVisitor(resolvedAst.elements);

+        try {

+          compiler.withCurrentElement(resolvedAst.element, () {

+            //print(resolvedAst.node.toDebugString());

+            resolvedAst.node.accept(visitor);

+          });

+        } catch (e, s) {

+          Expect.fail("$e:\n$s\nIn test:\n"

+                      "${library.compilationUnit.script.text}");

+        }

+        Expect.listEquals(expectedVisits, visitor.visits,

+            "In test:\n"

+            "${library.compilationUnit.script.text}");

+      });

+    });

+  });

+}

+

+

+class SemanticTestVisitor extends SemanticVisitor with SemanticSendVisitor {

+  List<Visit> visits = <Visit>[];

+

+  SemanticTestVisitor(TreeElements elements) : super(elements);

+

+  apply(Node node, arg) => node.accept(this);

+

+  internalError(Spannable spannable, String message) {

+    throw new SpannableAssertionFailure(spannable, message);

+  }

+

+  SemanticSendVisitor get sendVisitor => this;

+

+  @override

+  visitNode(Node node) {

+    node.visitChildren(this);

+  }

+

+  @override

+  visitAs(

+      Send node,

+      Node expression,

+      DartType type,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_AS,

+        expression: expression, type: type));

+    apply(expression, arg);

+  }

+

+  @override

+  visitAssert(

+      Send node,

+      Node expression,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_ASSERT, expression: expression));

+    apply(expression, arg);

+  }

+

+  @override

+  errorInvalidAssert(

+      Send node,

+      NodeList arguments,

+      arg) {

+    // TODO: implement errorAssert

+  }

+

+  @override

+  visitBinary(

+      Send node,

+      Node left,

+      BinaryOperator operator,

+      Node right,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_BINARY,

+        left: left, operator: operator, right: right));

+    apply(left, arg);

+    apply(right, arg);

+  }

+

+  @override

+  visitIndex(

+      Send node,

+      Node receiver,

+      Node index,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_INDEX,

+        receiver: receiver, index: index));

+    apply(receiver, arg);

+    apply(index, arg);

+  }

+

+  @override

+  visitClassTypeLiteralGet(

+      Send node,

+      TypeConstantExpression constant,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,

+        constant: constant.getText()));

+  }

+

+  @override

+  visitClassTypeLiteralInvoke(

+      Send node,

+      TypeConstantExpression constant,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,

+        constant: constant.getText(), arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  errorClassTypeLiteralSet(

+      SendSet node,

+      TypeConstantExpression constant,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,

+        constant: constant.getText(), rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitNotEquals(

+      Send node,

+      Node left,

+      Node right,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_NOT_EQUALS,

+        left: left, right: right));

+    apply(left, arg);

+    apply(right, arg);

+  }

+

+  @override

+  visitDynamicPropertyPrefix(

+      Send node,

+      Node receiver,

+      IncDecOperator operator,

+      Selector getterSelector,

+      Selector setterSelector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_PREFIX,

+        receiver: receiver, operator: operator,

+        getter: getterSelector, setter: setterSelector));

+    apply(receiver, arg);

+  }

+

+  @override

+  visitDynamicPropertyPostfix(

+      Send node,

+      Node receiver,

+      IncDecOperator operator,

+      Selector getterSelector,

+      Selector setterSelector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_POSTFIX,

+        receiver: receiver, operator: operator,

+        getter: getterSelector, setter: setterSelector));

+    apply(receiver, arg);

+  }

+

+  @override

+  visitDynamicPropertyGet(

+      Send node,

+      Node receiver,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,

+        receiver: receiver, name: selector.name));

+  }

+

+  @override

+  visitDynamicPropertyInvoke(

+      Send node,

+      Node receiver,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,

+        receiver: receiver, name: selector.name, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitDynamicPropertySet(

+      SendSet node,

+      Node receiver,

+      Selector selector,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,

+        receiver: receiver, name: selector.name, rhs: rhs));

+  }

+

+  @override

+  visitDynamicTypeLiteralGet(

+      Send node,

+      TypeConstantExpression constant,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_GET,

+        constant: constant.getText()));

+  }

+

+  @override

+  visitDynamicTypeLiteralInvoke(

+      Send node,

+      TypeConstantExpression constant,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,

+        constant: constant.getText(), arguments: arguments));

+  }

+

+  @override

+  errorDynamicTypeLiteralSet(

+      Send node,

+      TypeConstantExpression constant,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET,

+        rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitExpressionInvoke(

+      Send node,

+      Node expression,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_EXPRESSION_INVOKE,

+        receiver: expression, arguments: arguments));

+  }

+

+  @override

+  visitIs(

+      Send node,

+      Node expression,

+      DartType type,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_IS,

+        expression: expression, type: type));

+    apply(expression, arg);

+  }

+

+  @override

+  visitIsNot(

+      Send node,

+      Node expression,

+      DartType type,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_IS_NOT,

+        expression: expression, type: type));

+    apply(expression, arg);

+  }

+

+  @override

+  visitLogicalAnd(

+      Send node,

+      Node left,

+      Node right,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_LOGICAL_AND,

+        left: left, right: right));

+    apply(left, arg);

+    apply(right, arg);

+  }

+

+  @override

+  visitLogicalOr(

+      Send node,

+      Node left,

+      Node right,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_LOGICAL_OR,

+        left: left, right: right));

+    apply(left, arg);

+    apply(right, arg);

+  }

+

+  @override

+  visitLocalFunctionGet(

+      Send node,

+      LocalFunctionElement function,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_GET,

+                         element: function));

+  }

+

+  @override

+  visitLocalFunctionInvoke(

+      Send node,

+      LocalFunctionElement function,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_INVOKE,

+        element: function, arguments: arguments, selector: selector));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitLocalVariableGet(

+      Send node,

+      LocalVariableElement variable,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_GET,

+                         element: variable));

+  }

+

+  @override

+  visitLocalVariableInvoke(

+      Send node,

+      LocalVariableElement variable,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_INVOKE,

+        element: variable, arguments: arguments, selector: selector));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitLocalVariableSet(

+      SendSet node,

+      LocalVariableElement variable,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_SET,

+        element: variable, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitParameterGet(

+      Send node,

+      ParameterElement parameter,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_GET, element: parameter));

+  }

+

+  @override

+  visitParameterInvoke(

+      Send node,

+      ParameterElement parameter,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_INVOKE,

+        element: parameter, arguments: arguments, selector: selector));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitParameterSet(

+      SendSet node,

+      ParameterElement parameter,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_SET,

+                         element: parameter, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitStaticFieldGet(

+      Send node,

+      FieldElement field,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_GET, element: field));

+  }

+

+  @override

+  visitStaticFieldInvoke(

+      Send node,

+      FieldElement field,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,

+        element: field, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitStaticFieldSet(

+      SendSet node,

+      FieldElement field,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_SET,

+        element: field, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitStaticFunctionGet(

+      Send node,

+      MethodElement function,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,

+        element: function));

+  }

+

+  @override

+  visitStaticFunctionInvoke(

+      Send node,

+      MethodElement function,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,

+        element: function, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitStaticGetterGet(

+      Send node,

+      FunctionElement getter,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_GET,

+        element: getter));

+  }

+

+  @override

+  visitStaticGetterInvoke(

+      Send node,

+      FunctionElement getter,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,

+        element: getter, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitStaticSetterSet(

+      SendSet node,

+      FunctionElement setter,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_SET,

+        element: setter, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperBinary(

+      Send node,

+      FunctionElement function,

+      BinaryOperator operator,

+      Node argument,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_BINARY,

+            element: function, operator: operator, right: argument));

+    apply(argument, arg);

+  }

+

+  @override

+  visitSuperIndex(

+      Send node,

+      FunctionElement function,

+      Node index,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX,

+            element: function, index: index));

+    apply(index, arg);

+  }

+

+  @override

+  visitSuperNotEquals(

+      Send node,

+      FunctionElement function,

+      Node argument,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_NOT_EQUALS,

+            element: function, right: argument));

+    apply(argument, arg);

+  }

+

+  @override

+  visitThisGet(Identifier node, arg) {

+    visits.add(new Visit(VisitKind.VISIT_THIS_GET));

+  }

+

+  @override

+  visitThisInvoke(

+      Send node,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_THIS_INVOKE, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitThisPropertyGet(

+      Send node,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_GET,

+                         name: selector.name));

+  }

+

+  @override

+  visitThisPropertyInvoke(

+      Send node,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,

+                         name: selector.name, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitThisPropertySet(

+      SendSet node,

+      Selector selector,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_SET,

+                         name: selector.name, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitTopLevelFieldGet(

+      Send node,

+      FieldElement field,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET, element: field));

+  }

+

+  @override

+  visitTopLevelFieldInvoke(

+      Send node,

+      FieldElement field,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,

+        element: field, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitTopLevelFieldSet(

+      SendSet node,

+      FieldElement field,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,

+        element: field, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitTopLevelFunctionGet(

+      Send node,

+      MethodElement function,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_GET,

+        element: function));

+  }

+

+  @override

+  visitTopLevelFunctionInvoke(

+      Send node,

+      MethodElement function,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,

+        element: function, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitTopLevelGetterGet(

+      Send node,

+      FunctionElement getter,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,

+        element: getter));

+  }

+

+  @override

+  visitTopLevelGetterInvoke(

+      Send node,

+      FunctionElement getter,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,

+        element: getter, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitTopLevelSetterSet(

+      SendSet node,

+      FunctionElement setter,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,

+        element: setter, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitTypeVariableTypeLiteralGet(

+      Send node,

+      TypeVariableElement element,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,

+        element: element));

+  }

+

+  @override

+  visitTypeVariableTypeLiteralInvoke(

+      Send node,

+      TypeVariableElement element,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,

+        element: element, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  errorTypeVariableTypeLiteralSet(

+      SendSet node,

+      TypeVariableElement element,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,

+        element: element, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitTypedefTypeLiteralGet(

+      Send node,

+      TypeConstantExpression constant,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_GET,

+        constant: constant.getText()));

+  }

+

+  @override

+  visitTypedefTypeLiteralInvoke(

+      Send node,

+      TypeConstantExpression constant,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,

+        constant: constant.getText(), arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  errorTypedefTypeLiteralSet(

+      SendSet node,

+      TypeConstantExpression constant,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET,

+        constant: constant.getText(), rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitUnary(

+      Send node,

+      UnaryOperator operator,

+      Node expression,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_UNARY,

+        expression: expression, operator: operator));

+    apply(expression, arg);

+  }

+

+  @override

+  visitNot(

+      Send node,

+      Node expression,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_NOT, expression: expression));

+    apply(expression, arg);

+  }

+

+  @override

+  visitSuperFieldGet(

+      Send node,

+      FieldElement field,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_GET, element: field));

+  }

+

+  @override

+  visitSuperFieldInvoke(

+      Send node,

+      FieldElement field,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_INVOKE,

+        element: field, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitSuperFieldSet(

+      SendSet node,

+      FieldElement field,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SET,

+        element: field, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperMethodGet(

+      Send node,

+      MethodElement method,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_GET, element: method));

+  }

+

+  @override

+  visitSuperMethodInvoke(

+      Send node,

+      MethodElement method,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_INVOKE,

+        element: method, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitSuperGetterGet(

+      Send node,

+      FunctionElement getter,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_GET, element: getter));

+  }

+

+  @override

+  visitSuperGetterInvoke(

+      Send node,

+      FunctionElement getter,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,

+        element: getter, arguments: arguments));

+    apply(arguments, arg);

+  }

+

+  @override

+  visitSuperSetterSet(

+      SendSet node,

+      FunctionElement setter,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_SET,

+        element: setter, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperUnary(

+      Send node,

+      UnaryOperator operator,

+      FunctionElement function,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_UNARY,

+        element: function, operator: operator));

+  }

+

+  @override

+  visitEquals(

+      Send node,

+      Node left,

+      Node right,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_EQUALS, left: left, right: right));

+    apply(left, arg);

+    apply(right, arg);

+  }

+

+  @override

+  visitSuperEquals(

+      Send node,

+      FunctionElement function,

+      Node argument,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_EQUALS,

+        element: function, right: argument));

+    apply(argument, arg);

+  }

+

+  @override

+  visitIndexSet(

+      Send node,

+      Node receiver,

+      Node index,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_INDEX_SET,

+        receiver: receiver, index: index, rhs: rhs));

+    apply(receiver, arg);

+    apply(index, arg);

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperIndexSet(

+      Send node,

+      FunctionElement function,

+      Node index,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_SET,

+        element: function, index: index, rhs: rhs));

+    apply(index, arg);

+    apply(rhs, arg);

+  }

+

+  @override

+  errorFinalLocalVariableSet(

+      SendSet node,

+      LocalVariableElement variable,

+      Node rhs,

+      arg) {

+    // TODO: implement errorFinalLocalVariableSet

+  }

+

+  @override

+  errorFinalParameterSet(

+      SendSet node,

+      ParameterElement parameter,

+      Node rhs,

+      arg) {

+    // TODO: implement errorFinalParameterSet

+  }

+

+  @override

+  errorFinalStaticFieldSet(

+      SendSet node,

+      FieldElement field,

+      Node rhs,

+      arg) {

+    // TODO: implement errorFinalStaticFieldSet

+  }

+

+  @override

+  errorFinalSuperFieldSet(

+      SendSet node,

+      FieldElement field,

+      Node rhs,

+      arg) {

+    // TODO: implement errorFinalSuperFieldSet

+  }

+

+  @override

+  errorFinalTopLevelFieldSet(

+      SendSet node,

+      FieldElement field,

+      Node rhs,

+      arg) {

+    // TODO: implement errorFinalTopLevelFieldSet

+  }

+

+  @override

+  errorLocalFunctionSet(

+      SendSet node,

+      LocalFunctionElement function,

+      Node rhs,

+      arg) {

+    // TODO: implement errorLocalFunctionSet

+  }

+

+  @override

+  errorStaticFunctionSet(

+      Send node,

+      MethodElement function,

+      Node rhs,

+      arg) {

+    // TODO: implement errorStaticFunctionSet

+  }

+

+  @override

+  errorStaticGetterSet(

+      SendSet node,

+      FunctionElement getter,

+      Node rhs,

+      arg) {

+    // TODO: implement errorStaticGetterSet

+  }

+

+  @override

+  errorStaticSetterGet(

+      Send node,

+      FunctionElement setter,

+      arg) {

+    // TODO: implement errorStaticSetterGet

+  }

+

+  @override

+  errorStaticSetterInvoke(

+      Send node,

+      FunctionElement setter,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    // TODO: implement errorStaticSetterInvoke

+  }

+

+  @override

+  errorSuperGetterSet(

+      SendSet node,

+      FunctionElement getter,

+      Node rhs,

+      arg) {

+    // TODO: implement errorSuperGetterSet

+  }

+

+  @override

+  errorSuperMethodSet(

+      Send node,

+      MethodElement method,

+      Node rhs,

+      arg) {

+    // TODO: implement errorSuperMethodSet

+  }

+

+  @override

+  errorSuperSetterGet(

+      Send node,

+      FunctionElement setter,

+      arg) {

+    // TODO: implement errorSuperSetterGet

+  }

+

+  @override

+  errorSuperSetterInvoke(

+      Send node,

+      FunctionElement setter,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    // TODO: implement errorSuperSetterInvoke

+  }

+

+  @override

+  errorTopLevelFunctionSet(

+      Send node,

+      MethodElement function,

+      Node rhs,

+      arg) {

+    // TODO: implement errorTopLevelFunctionSet

+  }

+

+  @override

+  errorTopLevelGetterSet(

+      SendSet node,

+      FunctionElement getter,

+      Node rhs,

+      arg) {

+    // TODO: implement errorTopLevelGetterSet

+  }

+

+  @override

+  errorTopLevelSetterGet(

+      Send node,

+      FunctionElement setter,

+      arg) {

+    // TODO: implement errorTopLevelSetterGet

+  }

+

+  @override

+  errorTopLevelSetterInvoke(

+      Send node,

+      FunctionElement setter,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    // TODO: implement errorTopLevelSetterInvoke

+  }

+

+  @override

+  visitDynamicPropertyCompound(

+      Send node,

+      Node receiver,

+      AssignmentOperator operator,

+      Node rhs,

+      Selector getterSelector,

+      Selector setterSelector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_COMPOUND,

+        receiver: receiver, operator: operator, rhs: rhs,

+        getter: getterSelector, setter: setterSelector));

+    apply(receiver, arg);

+    apply(rhs, arg);

+  }

+

+  @override

+  errorFinalLocalVariableCompound(

+      Send node,

+      LocalVariableElement variable,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    // TODO: implement errorFinalLocalVariableCompound

+  }

+

+  @override

+  errorFinalParameterCompound(

+      Send node,

+      ParameterElement parameter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    // TODO: implement errorFinalParameterCompound

+  }

+

+  @override

+  errorFinalStaticFieldCompound(

+      Send node,

+      FieldElement field,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    // TODO: implement errorFinalStaticFieldCompound

+  }

+

+  @override

+  errorFinalSuperFieldCompound(

+      Send node,

+      FieldElement field,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    // TODO: implement errorFinalSuperFieldCompound

+  }

+

+  @override

+  errorFinalTopLevelFieldCompound(

+      Send node,

+      FieldElement field,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    // TODO: implement errorFinalTopLevelFieldCompound

+  }

+

+  @override

+  errorLocalFunctionCompound(

+      Send node,

+      LocalFunctionElement function,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    // TODO: implement errorLocalFunctionCompound

+  }

+

+  @override

+  visitLocalVariableCompound(

+      Send node,

+      LocalVariableElement variable,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_COMPOUND,

+        element: variable, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitParameterCompound(

+      Send node,

+      ParameterElement parameter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_COMPOUND,

+        element: parameter, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitStaticFieldCompound(

+      Send node,

+      FieldElement field,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,

+        element: field, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitStaticGetterSetterCompound(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,

+        operator: operator, rhs: rhs,

+        getter: getter, setter: setter));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperFieldCompound(

+      Send node,

+      FieldElement field,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_COMPOUND,

+        element: field, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperGetterSetterCompound(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,

+        operator: operator, rhs: rhs,

+        getter: getter, setter: setter));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitThisPropertyCompound(

+      Send node,

+      AssignmentOperator operator,

+      Node rhs,

+      Selector getterSelector,

+      Selector setterSelector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,

+        operator: operator, rhs: rhs,

+        getter: getterSelector, setter: setterSelector));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitTopLevelFieldCompound(

+      Send node,

+      FieldElement field,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_COMPOUND,

+        element: field, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitTopLevelGetterSetterCompound(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,

+        operator: operator, rhs: rhs,

+        getter: getter, setter: setter));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitStaticMethodSetterCompound(

+      Send node,

+      FunctionElement method,

+      FunctionElement setter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,

+        operator: operator, rhs: rhs,

+        getter: method, setter: setter));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperFieldSetterCompound(

+      Send node,

+      FieldElement field,

+      FunctionElement setter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_COMPOUND,

+        operator: operator, rhs: rhs,

+        getter: field, setter: setter));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperGetterFieldCompound(

+      Send node,

+      FunctionElement getter,

+      FieldElement field,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_COMPOUND,

+        operator: operator, rhs: rhs,

+        getter: getter, setter: field));

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperMethodSetterCompound(

+      Send node,

+      FunctionElement method,

+      FunctionElement setter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    // TODO: implement visitSuperMethodSetterCompound

+  }

+

+  @override

+  visitTopLevelMethodSetterCompound(

+      Send node,

+      FunctionElement method,

+      FunctionElement setter,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    // TODO: implement visitTopLevelMethodSetterCompound

+  }

+

+  @override

+  visitCompoundIndexSet(

+      Send node,

+      Node receiver,

+      Node index,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_COMPOUND_INDEX_SET,

+        receiver: receiver, index: index, rhs: rhs, operator: operator));

+    apply(receiver, arg);

+    apply(index, arg);

+    apply(rhs, arg);

+  }

+

+  @override

+  visitSuperCompoundIndexSet(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      Node index,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_COMPOUND_INDEX_SET,

+        getter: getter, setter: setter,

+        index: index, rhs: rhs, operator: operator));

+    apply(index, arg);

+    apply(rhs, arg);

+  }

+

+  @override

+  errorClassTypeLiteralCompound(

+      Send node,

+      TypeConstantExpression constant,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_CLASS_TYPE_LITERAL_COMPOUND,

+        constant: constant.getText(), operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  errorDynamicTypeLiteralCompound(

+      Send node,

+      TypeConstantExpression constant,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_DYNAMIC_TYPE_LITERAL_COMPOUND,

+        constant: constant.getText(), operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  errorTypeVariableTypeLiteralCompound(

+      Send node,

+      TypeVariableElement element,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

+        element: element, operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  errorTypedefTypeLiteralCompound(

+      Send node,

+      TypeConstantExpression constant,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_TYPEDEF_TYPE_LITERAL_COMPOUND,

+        constant: constant.getText(), operator: operator, rhs: rhs));

+    apply(rhs, arg);

+  }

+

+  @override

+  errorLocalFunctionPrefix(

+      Send node,

+      LocalFunctionElement function,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement errorLocalFunctionPrefix

+  }

+

+  @override

+  errorClassTypeLiteralPrefix(

+      Send node,

+      TypeConstantExpression constant,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_CLASS_TYPE_LITERAL_PREFIX,

+        constant: constant.getText(), operator: operator));

+  }

+

+  @override

+  errorDynamicTypeLiteralPrefix(

+      Send node,

+      TypeConstantExpression constant,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_DYNAMIC_TYPE_LITERAL_PREFIX,

+        constant: constant.getText(), operator: operator));

+  }

+

+  @override

+  visitLocalVariablePrefix(

+      Send node,

+      LocalVariableElement variable,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_PREFIX,

+        element: variable, operator: operator));

+  }

+

+  @override

+  visitParameterPrefix(

+      Send node,

+      ParameterElement parameter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_PREFIX,

+        element: parameter, operator: operator));

+  }

+

+  @override

+  visitStaticFieldPrefix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,

+        element: field, operator: operator));

+  }

+

+  @override

+  visitStaticGetterSetterPrefix(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,

+        getter: getter, setter: setter, operator: operator));

+  }

+

+  @override

+  visitStaticMethodSetterPrefix(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement visitStaticMethodSetterPrefix

+  }

+

+  @override

+  visitSuperFieldFieldPrefix(

+      Send node,

+      FieldElement readField,

+      FieldElement writtenField,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement visitSuperFieldFieldPrefix

+  }

+

+  @override

+  visitSuperFieldPrefix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_PREFIX,

+        element: field, operator: operator));

+  }

+

+  @override

+  visitSuperFieldSetterPrefix(

+      Send node,

+      FieldElement field,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_PREFIX,

+        getter: field, setter: setter, operator: operator));

+  }

+

+  @override

+  visitSuperGetterFieldPrefix(

+      Send node,

+      FunctionElement getter,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_PREFIX,

+        getter: getter, setter: field, operator: operator));

+  }

+

+  @override

+  visitSuperGetterSetterPrefix(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,

+        getter: getter, setter: setter, operator: operator));

+  }

+

+  @override

+  visitSuperMethodSetterPrefix(

+      Send node,

+      FunctionElement method,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement visitSuperMethodSetterPrefix

+  }

+

+  @override

+  visitThisPropertyPrefix(

+      Send node,

+      IncDecOperator operator,

+      Selector getterSelector,

+      Selector setterSelector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,

+        operator: operator,

+        getter: getterSelector, setter: setterSelector));

+  }

+

+  @override

+  visitTopLevelFieldPrefix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_PREFIX,

+        element: field, operator: operator));

+  }

+

+  @override

+  visitTopLevelGetterSetterPrefix(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,

+        getter: getter, setter: setter, operator: operator));

+  }

+

+  @override

+  visitTopLevelMethodSetterPrefix(

+      Send node,

+      FunctionElement method,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement visitTopLevelMethodSetterPrefix

+  }

+

+  @override

+  errorTypeVariableTypeLiteralPrefix(

+      Send node,

+      TypeVariableElement element,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,

+        element: element, operator: operator));

+  }

+

+  @override

+  errorTypedefTypeLiteralPrefix(

+      Send node,

+      TypeConstantExpression constant,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_TYPEDEF_TYPE_LITERAL_PREFIX,

+        constant: constant.getText(), operator: operator));

+  }

+

+  @override

+  errorLocalFunctionPostfix(

+      Send node,

+      LocalFunctionElement function,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement errorLocalFunctionPostfix

+  }

+

+  @override

+  errorClassTypeLiteralPostfix(

+      Send node,

+      TypeConstantExpression constant,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_CLASS_TYPE_LITERAL_POSTFIX,

+        constant: constant.getText(), operator: operator));

+  }

+

+  @override

+  errorDynamicTypeLiteralPostfix(

+      Send node,

+      TypeConstantExpression constant,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_DYNAMIC_TYPE_LITERAL_POSTFIX,

+        constant: constant.getText(), operator: operator));

+  }

+

+  @override

+  visitLocalVariablePostfix(

+      Send node,

+      LocalVariableElement variable,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_POSTFIX,

+        element: variable, operator: operator));

+  }

+

+  @override

+  visitParameterPostfix(

+      Send node,

+      ParameterElement parameter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_POSTFIX,

+        element: parameter, operator: operator));

+  }

+

+  @override

+  visitStaticFieldPostfix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,

+        element: field, operator: operator));

+  }

+

+  @override

+  visitStaticGetterSetterPostfix(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,

+        getter: getter, setter: setter, operator: operator));

+  }

+

+  @override

+  visitStaticMethodSetterPostfix(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement visitStaticMethodSetterPostfix

+  }

+

+  @override

+  visitSuperFieldFieldPostfix(

+      Send node,

+      FieldElement readField,

+      FieldElement writtenField,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement visitSuperFieldFieldPostfix

+  }

+

+  @override

+  visitSuperFieldPostfix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_POSTFIX,

+        element: field, operator: operator));

+  }

+

+  @override

+  visitSuperFieldSetterPostfix(

+      Send node,

+      FieldElement field,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_POSTFIX,

+        getter: field, setter: setter, operator: operator));

+  }

+

+  @override

+  visitSuperGetterFieldPostfix(

+      Send node,

+      FunctionElement getter,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_POSTFIX,

+        getter: getter, setter: field, operator: operator));

+  }

+

+  @override

+  visitSuperGetterSetterPostfix(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,

+        getter: getter, setter: setter, operator: operator));

+  }

+

+  @override

+  visitSuperMethodSetterPostfix(

+      Send node,

+      FunctionElement method,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement visitSuperMethodSetterPostfix

+  }

+

+  @override

+  visitThisPropertyPostfix(

+      Send node,

+      IncDecOperator operator,

+      Selector getterSelector,

+      Selector setterSelector,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,

+        operator: operator,

+        getter: getterSelector, setter: setterSelector));

+  }

+

+  @override

+  visitTopLevelFieldPostfix(

+      Send node,

+      FieldElement field,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_POSTFIX,

+        element: field, operator: operator));

+  }

+

+  @override

+  visitTopLevelGetterSetterPostfix(

+      Send node,

+      FunctionElement getter,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,

+        getter: getter, setter: setter, operator: operator));

+  }

+

+  @override

+  visitTopLevelMethodSetterPostfix(

+      Send node,

+      FunctionElement method,

+      FunctionElement setter,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement visitTopLevelMethodSetterPostfix

+  }

+

+  @override

+  errorTypeVariableTypeLiteralPostfix(

+      Send node,

+      TypeVariableElement element,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,

+        element: element, operator: operator));

+  }

+

+  @override

+  errorTypedefTypeLiteralPostfix(

+      Send node,

+      TypeConstantExpression constant,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.ERROR_TYPEDEF_TYPE_LITERAL_POSTFIX,

+        constant: constant.getText(), operator: operator));

+  }

+

+  @override

+  visitConstantGet(

+      Send node,

+      ConstantExpression constant,

+      arg) {

+    // TODO: implement visitConstantGet

+  }

+

+  @override

+  visitConstantInvoke(

+      Send node,

+      ConstantExpression constant,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    // TODO: implement visitConstantInvoke

+  }

+

+  @override

+  errorUnresolvedCompound(

+      Send node,

+      ErroneousElement element,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    // TODO: implement errorUnresolvedCompound

+  }

+

+  @override

+  errorUnresolvedGet(

+      Send node,

+      ErroneousElement element,

+      arg) {

+    // TODO: implement errorUnresolvedGet

+  }

+

+  @override

+  errorUnresolvedInvoke(

+      Send node,

+      ErroneousElement element,

+      NodeList arguments,

+      Selector selector,

+      arg) {

+    // TODO: implement errorUnresolvedInvoke

+  }

+

+  @override

+  errorUnresolvedPostfix(

+      Send node,

+      ErroneousElement element,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement errorUnresolvedPostfix

+  }

+

+  @override

+  errorUnresolvedPrefix(

+      Send node,

+      ErroneousElement element,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement errorUnresolvedPrefix

+  }

+

+  @override

+  errorUnresolvedSet(

+      Send node,

+      ErroneousElement element,

+      Node rhs,

+      arg) {

+    // TODO: implement errorUnresolvedSet

+  }

+

+  @override

+  errorUndefinedBinaryExpression(

+      Send node,

+      Node left,

+      Operator operator,

+      Node right,

+      arg) {

+    // TODO: implement errorUndefinedBinaryExpression

+  }

+

+  @override

+  errorUndefinedUnaryExpression(

+      Send node,

+      Operator operator,

+      Node expression,

+      arg) {

+    // TODO: implement errorUndefinedUnaryExpression

+  }

+

+  @override

+  errorUnresolvedSuperBinary(

+      Send node,

+      ErroneousElement element,

+      BinaryOperator operator,

+      Node argument,

+      arg) {

+    // TODO: implement errorUnresolvedSuperBinary

+  }

+

+  @override

+  errorUnresolvedSuperCompoundIndexSet(

+      Send node,

+      ErroneousElement element,

+      Node index,

+      AssignmentOperator operator,

+      Node rhs,

+      arg) {

+    // TODO: implement errorUnresolvedSuperCompoundIndexSet

+  }

+

+  @override

+  errorUnresolvedSuperIndexSet(

+      Send node,

+      ErroneousElement element,

+      Node index,

+      Node rhs,

+      arg) {

+    // TODO: implement errorUnresolvedSuperIndexSet

+  }

+

+  @override

+  errorUnresolvedSuperUnary(

+      Send node,

+      UnaryOperator operator,

+      ErroneousElement element,

+      arg) {

+    // TODO: implement errorUnresolvedSuperUnary

+  }

+

+  @override

+  errorUnresolvedSuperIndex(

+      Send node,

+      Element element,

+      Node index,

+      arg) {

+    // TODO: implement errorUnresolvedSuperIndex

+  }

+

+  @override

+  errorUnresolvedSuperIndexPostfix(

+      Send node,

+      Element function,

+      Node index,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement errorUnresolvedSuperIndexPostfix

+  }

+

+  @override

+  errorUnresolvedSuperIndexPrefix(

+      Send node,

+      Element function,

+      Node index,

+      IncDecOperator operator,

+      arg) {

+    // TODO: implement errorUnresolvedSuperIndexPrefix

+  }

+

+  @override

+  visitIndexPostfix(

+      Send node,

+      Node receiver,

+      Node index,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_INDEX_POSTFIX,

+        receiver: receiver, index: index, operator: operator));

+    apply(receiver, arg);

+    apply(index, arg);

+  }

+

+  @override

+  visitIndexPrefix(

+      Send node,

+      Node receiver,

+      Node index,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_INDEX_PREFIX,

+        receiver: receiver, index: index, operator: operator));

+    apply(receiver, arg);

+    apply(index, arg);

+  }

+

+  @override

+  visitSuperIndexPostfix(

+      Send node,

+      FunctionElement indexFunction,

+      FunctionElement indexSetFunction,

+      Node index,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_POSTFIX,

+        getter: indexFunction, setter: indexSetFunction,

+        index: index, operator: operator));

+    apply(index, arg);

+  }

+

+  @override

+  visitSuperIndexPrefix(

+      Send node,

+      FunctionElement indexFunction,

+      FunctionElement indexSetFunction,

+      Node index,

+      IncDecOperator operator,

+      arg) {

+    visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_PREFIX,

+        getter: indexFunction, setter: indexSetFunction,

+        index: index, operator: operator));

+    apply(index, arg);

+  }

+}

+

+enum VisitKind {

+  VISIT_PARAMETER_GET,

+  VISIT_PARAMETER_SET,

+  VISIT_PARAMETER_INVOKE,

+  VISIT_PARAMETER_COMPOUND,

+  VISIT_PARAMETER_PREFIX,

+  VISIT_PARAMETER_POSTFIX,

+

+  VISIT_LOCAL_VARIABLE_GET,

+  VISIT_LOCAL_VARIABLE_SET,

+  VISIT_LOCAL_VARIABLE_INVOKE,

+  VISIT_LOCAL_VARIABLE_COMPOUND,

+  VISIT_LOCAL_VARIABLE_PREFIX,

+  VISIT_LOCAL_VARIABLE_POSTFIX,

+

+  VISIT_LOCAL_FUNCTION_GET,

+  VISIT_LOCAL_FUNCTION_INVOKE,

+

+  VISIT_STATIC_FIELD_GET,

+  VISIT_STATIC_FIELD_SET,

+  VISIT_STATIC_FIELD_INVOKE,

+  VISIT_STATIC_FIELD_COMPOUND,

+  VISIT_STATIC_FIELD_PREFIX,

+  VISIT_STATIC_FIELD_POSTFIX,

+

+  VISIT_STATIC_GETTER_GET,

+  VISIT_STATIC_SETTER_SET,

+  VISIT_STATIC_GETTER_INVOKE,

+  VISIT_STATIC_GETTER_SETTER_COMPOUND,

+  VISIT_STATIC_METHOD_SETTER_COMPOUND,

+  VISIT_STATIC_GETTER_SETTER_PREFIX,

+  VISIT_STATIC_GETTER_SETTER_POSTFIX,

+

+  VISIT_STATIC_FUNCTION_GET,

+  VISIT_STATIC_FUNCTION_INVOKE,

+

+  VISIT_TOP_LEVEL_FIELD_GET,

+  VISIT_TOP_LEVEL_FIELD_SET,

+  VISIT_TOP_LEVEL_FIELD_INVOKE,

+  VISIT_TOP_LEVEL_FIELD_COMPOUND,

+  VISIT_TOP_LEVEL_FIELD_PREFIX,

+  VISIT_TOP_LEVEL_FIELD_POSTFIX,

+

+  VISIT_TOP_LEVEL_GETTER_GET,

+  VISIT_TOP_LEVEL_SETTER_SET,

+  VISIT_TOP_LEVEL_GETTER_INVOKE,

+  VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,

+  VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,

+  VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,

+

+  VISIT_TOP_LEVEL_FUNCTION_GET,

+  VISIT_TOP_LEVEL_FUNCTION_INVOKE,

+

+  VISIT_DYNAMIC_PROPERTY_GET,

+  VISIT_DYNAMIC_PROPERTY_SET,

+  VISIT_DYNAMIC_PROPERTY_INVOKE,

+  VISIT_DYNAMIC_PROPERTY_COMPOUND,

+  VISIT_DYNAMIC_PROPERTY_PREFIX,

+  VISIT_DYNAMIC_PROPERTY_POSTFIX,

+

+  VISIT_THIS_GET,

+  VISIT_THIS_INVOKE,

+

+  VISIT_THIS_PROPERTY_GET,

+  VISIT_THIS_PROPERTY_SET,

+  VISIT_THIS_PROPERTY_INVOKE,

+  VISIT_THIS_PROPERTY_COMPOUND,

+  VISIT_THIS_PROPERTY_PREFIX,

+  VISIT_THIS_PROPERTY_POSTFIX,

+

+  VISIT_SUPER_FIELD_GET,

+  VISIT_SUPER_FIELD_SET,

+  VISIT_SUPER_FIELD_INVOKE,

+  VISIT_SUPER_FIELD_COMPOUND,

+  VISIT_SUPER_FIELD_PREFIX,

+  VISIT_SUPER_FIELD_POSTFIX,

+

+  VISIT_SUPER_GETTER_GET,

+  VISIT_SUPER_SETTER_SET,

+  VISIT_SUPER_GETTER_INVOKE,

+  VISIT_SUPER_GETTER_SETTER_COMPOUND,

+  VISIT_SUPER_GETTER_FIELD_COMPOUND,

+  VISIT_SUPER_FIELD_SETTER_COMPOUND,

+  VISIT_SUPER_GETTER_SETTER_PREFIX,

+  VISIT_SUPER_GETTER_FIELD_PREFIX,

+  VISIT_SUPER_FIELD_SETTER_PREFIX,

+  VISIT_SUPER_GETTER_SETTER_POSTFIX,

+  VISIT_SUPER_GETTER_FIELD_POSTFIX,

+  VISIT_SUPER_FIELD_SETTER_POSTFIX,

+

+  VISIT_SUPER_METHOD_GET,

+  VISIT_SUPER_METHOD_INVOKE,

+

+  VISIT_BINARY,

+  VISIT_INDEX,

+  VISIT_EQUALS,

+  VISIT_NOT_EQUALS,

+  VISIT_INDEX_PREFIX,

+  VISIT_INDEX_POSTFIX,

+

+  VISIT_SUPER_BINARY,

+  VISIT_SUPER_INDEX,

+  VISIT_SUPER_EQUALS,

+  VISIT_SUPER_NOT_EQUALS,

+  VISIT_SUPER_INDEX_PREFIX,

+  VISIT_SUPER_INDEX_POSTFIX,

+

+  VISIT_UNARY,

+  VISIT_SUPER_UNARY,

+  VISIT_NOT,

+

+  VISIT_EXPRESSION_INVOKE,

+

+  VISIT_CLASS_TYPE_LITERAL_GET,

+  VISIT_CLASS_TYPE_LITERAL_SET,

+  VISIT_CLASS_TYPE_LITERAL_INVOKE,

+  VISIT_CLASS_TYPE_LITERAL_BINARY,

+  ERROR_CLASS_TYPE_LITERAL_COMPOUND,

+  ERROR_CLASS_TYPE_LITERAL_PREFIX,

+  ERROR_CLASS_TYPE_LITERAL_POSTFIX,

+

+  VISIT_TYPEDEF_TYPE_LITERAL_GET,

+  VISIT_TYPEDEF_TYPE_LITERAL_SET,

+  VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,

+  VISIT_TYPEDEF_TYPE_LITERAL_BINARY,

+  ERROR_TYPEDEF_TYPE_LITERAL_COMPOUND,

+  ERROR_TYPEDEF_TYPE_LITERAL_PREFIX,

+  ERROR_TYPEDEF_TYPE_LITERAL_POSTFIX,

+

+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,

+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,

+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,

+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_BINARY,

+  ERROR_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

+  ERROR_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,

+  ERROR_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,

+

+  VISIT_DYNAMIC_TYPE_LITERAL_GET,

+  VISIT_DYNAMIC_TYPE_LITERAL_SET,

+  VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,

+  VISIT_DYNAMIC_TYPE_LITERAL_BINARY,

+  ERROR_DYNAMIC_TYPE_LITERAL_COMPOUND,

+  ERROR_DYNAMIC_TYPE_LITERAL_PREFIX,

+  ERROR_DYNAMIC_TYPE_LITERAL_POSTFIX,

+

+  VISIT_INDEX_SET,

+  VISIT_COMPOUND_INDEX_SET,

+  VISIT_SUPER_INDEX_SET,

+  VISIT_SUPER_COMPOUND_INDEX_SET,

+

+  VISIT_ASSERT,

+  VISIT_LOGICAL_AND,

+  VISIT_LOGICAL_OR,

+  VISIT_IS,

+  VISIT_IS_NOT,

+  VISIT_AS,

+

+  // TODO(johnniwinther): Add tests for error cases.

+}

diff --git a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
index 9e3a987..3f91350 100644
--- a/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_no_such_method_test.dart
@@ -6,6 +6,7 @@
 
 import "package:async_helper/async_helper.dart";
 import 'compiler_helper.dart';
+import 'package:compiler/src/types/types.dart';
 import 'parser_helper.dart';
 import 'type_mask_test_helper.dart';
 
@@ -94,6 +95,72 @@
 }
 """;
 
+const String TEST3 = """
+class A {
+  // We may ignore this for type inference because syntactically it always
+  // throws an exception.
+  noSuchMethod(im) => throw 'foo';
+}
+
+class B extends A {
+  foo() => {};
+}
+
+class C extends B {
+  foo() => {};
+}
+
+var a = [new B(), new C()][0];
+test1() => new A().foo();
+test2() => a.foo();
+test3() => new B().foo();
+test4() => new C().foo();
+test5() => (a ? new A() : new B()).foo();
+test6() => (a ? new B() : new C()).foo();
+
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+  test5();
+  test6();
+}
+""";
+
+const String TEST4 = """
+class A {
+  // We may ignore this for type inference because it forwards to a default
+  // noSuchMethod implementation, which always throws an exception.
+  noSuchMethod(im) => super.noSuchMethod(im);
+}
+
+class B extends A {
+  foo() => {};
+}
+
+class C extends B {
+  foo() => {};
+}
+
+var a = [new B(), new C()][0];
+test1() => new A().foo();
+test2() => a.foo();
+test3() => new B().foo();
+test4() => new C().foo();
+test5() => (a ? new A() : new B()).foo();
+test6() => (a ? new B() : new C()).foo();
+
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+  test5();
+  test6();
+}
+""";
+
 main() {
   Uri uri = new Uri(scheme: 'source');
 
@@ -134,4 +201,24 @@
     checkReturn(compiler2, 'test10', compiler2.typesTask.numType);
     checkReturn(compiler2, 'test11', compiler2.typesTask.doubleType);
   }));
+
+  var compiler3 = compilerFor(TEST3, uri);
+  asyncTest(() => compiler3.runCompiler(uri).then((_) {
+    checkReturn(compiler3, 'test1', const TypeMask.nonNullEmpty());
+    checkReturn(compiler3, 'test2', compiler3.typesTask.mapType);
+    checkReturn(compiler3, 'test3', compiler3.typesTask.mapType);
+    checkReturn(compiler3, 'test4', compiler3.typesTask.mapType);
+    checkReturn(compiler3, 'test5', compiler3.typesTask.mapType);
+    checkReturn(compiler3, 'test6', compiler3.typesTask.mapType);
+  }));
+
+  var compiler4 = compilerFor(TEST4, uri);
+  asyncTest(() => compiler4.runCompiler(uri).then((_) {
+    checkReturn(compiler4, 'test1', const TypeMask.nonNullEmpty());
+    checkReturn(compiler4, 'test2', compiler4.typesTask.mapType);
+    checkReturn(compiler4, 'test3', compiler4.typesTask.mapType);
+    checkReturn(compiler4, 'test4', compiler4.typesTask.mapType);
+    checkReturn(compiler4, 'test5', compiler4.typesTask.mapType);
+    checkReturn(compiler4, 'test6', compiler4.typesTask.mapType);
+  }));
 }
diff --git a/tests/compiler/dart2js/source_map_pub_build_validity_test.dart b/tests/compiler/dart2js/source_map_pub_build_validity_test.dart
index 46b671e..939f9a2 100644
--- a/tests/compiler/dart2js/source_map_pub_build_validity_test.dart
+++ b/tests/compiler/dart2js/source_map_pub_build_validity_test.dart
@@ -6,7 +6,7 @@
 
 import 'package:path/path.dart' as path;
 import 'package:async_helper/async_helper.dart';
-
+import 'package:expect/expect.dart';
 import 'source_map_validator_helper.dart';
 
 void main() {
@@ -22,8 +22,10 @@
     String file = path.join(tmpDir.path, 'build/web/sunflower.dart.js');
     print("Running '$command build --mode=debug' from '${tmpDir}'.");
     return Process.run(command, ['build','--mode=debug'],
-        workingDirectory: tmpDir.path).then((process) {
-      print(process.stdout);
+        workingDirectory: tmpDir.path).then((ProcessResult processResult) {
+      print(processResult.stdout);
+      print(processResult.stderr);
+      Expect.equals(0, processResult.exitCode, 'Unexpected exitCode from pub');
       validateSourceMap(new Uri.file(file, windows: Platform.isWindows));
       print("Deleting '${tmpDir.path}'.");
       tmpDir.deleteSync(recursive: true);
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart
index d1c5c93..4bf4380 100644
--- a/tests/compiler/dart2js/type_representation_test.dart
+++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -142,56 +142,56 @@
     expect(instantiate(List_, [int_]), '[$List_rep, $int_rep]');
     // List<Typedef>
     expect(instantiate(List_, [Typedef_]),
-        '[$List_rep, {$func: "void_", $retvoid: true}]',
-        '[$List_rep, {$func: "void_", $retvoid: true,'
+        '[$List_rep, {$func: "", $retvoid: true}]',
+        '[$List_rep, {$func: "", $retvoid: true,'
           ' $typedefTag: $Typedef_rep}]');
     expect(instantiate(List_, [Typedef2_]),
-        '[$List_rep, {$func: "int_", $ret: $int_rep}]',
-        '[$List_rep, {$func: "int_", $ret: $int_rep,'
+        '[$List_rep, {$func: "", $ret: $int_rep}]',
+        '[$List_rep, {$func: "", $ret: $int_rep,'
           ' $typedefTag: $Typedef2_rep}]');
     expect(instantiate(List_, [Typedef3_]),
-        '[$List_rep, {$func: "List_", $ret: [$List_rep, $int_rep]}]',
-        '[$List_rep, {$func: "List_", $ret: [$List_rep, $int_rep],'
+        '[$List_rep, {$func: "", $ret: [$List_rep, $int_rep]}]',
+        '[$List_rep, {$func: "", $ret: [$List_rep, $int_rep],'
           ' $typedefTag: $Typedef3_rep}]');
     expect(instantiate(List_, [Typedef4_]),
-        '[$List_rep, {$func: "args0"}]',
-        '[$List_rep, {$func: "args0", $typedefTag: $Typedef4_rep}]');
+        '[$List_rep, {$func: ""}]',
+        '[$List_rep, {$func: "", $typedefTag: $Typedef4_rep}]');
     expect(instantiate(List_, [Typedef5_]),
-        '[$List_rep, {$func: "dynamic__int_String",'
+        '[$List_rep, {$func: "",'
           ' $args: [$int_rep, $String_rep]}]',
-        '[$List_rep, {$func: "dynamic__int_String",'
+        '[$List_rep, {$func: "",'
           ' $args: [$int_rep, $String_rep], $typedefTag: $Typedef5_rep}]');
     expect(instantiate(List_, [Typedef6_]),
-        '[$List_rep, {$func: "dynamic__int__String",'
+        '[$List_rep, {$func: "",'
           ' $args: [$int_rep], $opt: [$String_rep]}]',
-        '[$List_rep, {$func: "dynamic__int__String",'
+        '[$List_rep, {$func: "",'
           ' $args: [$int_rep], $opt: [$String_rep],'
           ' $typedefTag: $Typedef6_rep}]');
     expect(instantiate(List_, [Typedef7_]),
-        '[$List_rep, {$func: "dynamic__int_String__List_dynamic", $args: '
-          '[$int_rep, $String_rep], $opt: [[$List_rep, $int_rep], null]}]',
-        '[$List_rep, {$func: "dynamic__int_String__List_dynamic", $args: '
-          '[$int_rep, $String_rep], $opt: [[$List_rep, $int_rep], null], '
+        '[$List_rep, {$func: "", $args: '
+          '[$int_rep, $String_rep], $opt: [[$List_rep, $int_rep],,]}]',
+        '[$List_rep, {$func: "", $args: '
+          '[$int_rep, $String_rep], $opt: [[$List_rep, $int_rep],,], '
           '$typedefTag: $Typedef7_rep}]');
     expect(instantiate(List_, [Typedef8_]),
-        '[$List_rep, {$func: "dynamic__int__String0", $args: [$int_rep],'
+        '[$List_rep, {$func: "", $args: [$int_rep],'
           ' $named: {b: $String_rep}}]',
-        '[$List_rep, {$func: "dynamic__int__String0", $args: [$int_rep],'
+        '[$List_rep, {$func: "", $args: [$int_rep],'
           ' $named: {b: $String_rep}, $typedefTag: $Typedef8_rep}]');
     expect(instantiate(List_, [Typedef9_]),
-        '[$List_rep, {$func: "dynamic__int_String__List_dynamic0", '
+        '[$List_rep, {$func: "", '
           '$args: [$int_rep, $String_rep], $named: '
           '{c: [$List_rep, $int_rep], d: null}}]',
-        '[$List_rep, {$func: "dynamic__int_String__List_dynamic0", '
+        '[$List_rep, {$func: "", '
           '$args: [$int_rep, $String_rep], $named: {c: [$List_rep, $int_rep],'
           ' d: null}, $typedefTag: $Typedef9_rep}]');
     expect(instantiate(List_, [Typedef10_]),
-        '[$List_rep, {$func: "dynamic__void__int__dynamic", '
-          '$args: [{$func: "void__int__dynamic", $retvoid: true, '
-          '$args: [$int_rep], $opt: [null]}]}]',
-        '[$List_rep, {$func: "dynamic__void__int__dynamic", '
-          '$args: [{$func: "void__int__dynamic", $retvoid: true, '
-          '$args: [$int_rep], $opt: [null]}], $typedefTag: $Typedef10_rep}]');
+        '[$List_rep, {$func: "", '
+          '$args: [{$func: "", $retvoid: true, '
+          '$args: [$int_rep], $opt: [,]}]}]',
+        '[$List_rep, {$func: "", '
+          '$args: [{$func: "", $retvoid: true, '
+          '$args: [$int_rep], $opt: [,]}], $typedefTag: $Typedef10_rep}]');
 
     // Map<K,V>
     expect(Map_.computeType(env.compiler),
@@ -207,50 +207,50 @@
 
     // void m1() {}
     expect(env.getElement('m1').computeType(env.compiler),
-           '{$func: "void_", $retvoid: true}');
+           '{$func: "", $retvoid: true}');
 
     // int m2() => 0;
     expect(env.getElement('m2').computeType(env.compiler),
-           '{$func: "int_", $ret: $int_rep}');
+           '{$func: "", $ret: $int_rep}');
 
     // List<int> m3() => null;
     expect(env.getElement('m3').computeType(env.compiler),
-           '{$func: "List_", $ret: [$List_rep, $int_rep]}');
+           '{$func: "", $ret: [$List_rep, $int_rep]}');
 
     // m4() {}
     expect(env.getElement('m4').computeType(env.compiler),
-           '{$func: "args0"}');
+           '{$func: ""}');
 
     // m5(int a, String b) {}
     expect(env.getElement('m5').computeType(env.compiler),
-           '{$func: "dynamic__int_String", $args: [$int_rep, $String_rep]}');
+           '{$func: "", $args: [$int_rep, $String_rep]}');
 
     // m6(int a, [String b]) {}
     expect(env.getElement('m6').computeType(env.compiler),
-           '{$func: "dynamic__int__String", $args: [$int_rep],'
+           '{$func: "", $args: [$int_rep],'
            ' $opt: [$String_rep]}');
 
     // m7(int a, String b, [List<int> c, d]) {}
     expect(env.getElement('m7').computeType(env.compiler),
-           '{$func: "dynamic__int_String__List_dynamic",'
+           '{$func: "",'
            ' $args: [$int_rep, $String_rep],'
-           ' $opt: [[$List_rep, $int_rep], null]}');
+           ' $opt: [[$List_rep, $int_rep],,]}');
 
     // m8(int a, {String b}) {}
     expect(env.getElement('m8').computeType(env.compiler),
-           '{$func: "dynamic__int__String0",'
+           '{$func: "",'
            ' $args: [$int_rep], $named: {b: $String_rep}}');
 
     // m9(int a, String b, {List<int> c, d}) {}
     expect(env.getElement('m9').computeType(env.compiler),
-           '{$func: "dynamic__int_String__List_dynamic0",'
+           '{$func: "",'
            ' $args: [$int_rep, $String_rep],'
            ' $named: {c: [$List_rep, $int_rep], d: null}}');
 
     // m10(void f(int a, [b])) {}
     expect(env.getElement('m10').computeType(env.compiler),
-           '{$func: "dynamic__void__int__dynamic", $args:'
-           ' [{$func: "void__int__dynamic",'
-           ' $retvoid: true, $args: [$int_rep], $opt: [null]}]}');
+           '{$func: "", $args:'
+           ' [{$func: "",'
+           ' $retvoid: true, $args: [$int_rep], $opt: [,]}]}');
   }));
 }
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index 45cd843..f571b36 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -41,7 +41,9 @@
     Compiler compiler;
     bool stopAfterTypeInference = mainSource != null;
     if (mainSource == null) {
-      source = 'main() {}\n$source';
+      source = '''import 'dart:async';
+                  main() {}
+                  $source''';
     } else {
       source = '$mainSource\n$source';
     }
@@ -123,6 +125,10 @@
     return compiler.types.computeLeastUpperBound(T, S);
   }
 
+  DartType flatten(DartType T) {
+    return compiler.types.flatten(T);
+  }
+
   FunctionType functionType(DartType returnType,
                             List<DartType> parameters,
                             {List<DartType> optionalParameters:
diff --git a/tests/compiler/dart2js/zero_termination_test.dart b/tests/compiler/dart2js/zero_termination_test.dart
new file mode 100644
index 0000000..501fb42
--- /dev/null
+++ b/tests/compiler/dart2js/zero_termination_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// A regression test for issue 22667.
+//
+// Makes sure that we don't print a '\0' character for files that are not
+// properly new-line terminated.
+library zero_termination_test;
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:path/path.dart' as path;
+
+Uri pathOfData = Platform.script;
+Directory tempDir;
+String outFilePath;
+
+_sendNotFound(HttpResponse response) {
+  response.statusCode = HttpStatus.NOT_FOUND;
+  response.close();
+}
+
+Future handleRequest(HttpRequest request) {
+  final String path = request.uri.path.substring(1);
+  final Uri requestPath = pathOfData.resolve(path);
+  final File file = new File(requestPath.toFilePath());
+  return file.exists().then((bool found) {
+    if (found) {
+      file.openRead()
+          .pipe(request.response)
+          .catchError((e) { _sendNotFound(request.response); });
+    } else {
+      _sendNotFound(request.response);
+    }
+  });
+}
+
+void cleanup() {
+  File outFile = new File(outFilePath);
+  if (outFile.existsSync()) {
+    outFile.deleteSync();
+  }
+}
+
+Future launchDart2Js(args) {
+  String ext = Platform.isWindows ? '.bat' : '';
+  String command =
+      path.normalize(path.join(path.fromUri(Platform.script),
+                    '../../../../sdk/bin/dart2js${ext}'));
+  return Process.run(command, args, stdoutEncoding: null);
+}
+
+void check(ProcessResult result) {
+  Expect.notEquals(0, result.exitCode);
+  List<int> stdout = result.stdout;
+  String stdoutString = UTF8.decode(stdout);
+  Expect.isTrue(stdoutString.contains("Error"));
+  // Make sure the "499" from the last line is in the output.
+  Expect.isTrue(stdoutString.contains("499"));
+
+  // Make sure that the output does not contain any 0 character.
+  Expect.isFalse(stdout.contains(0));
+}
+
+Future testFile() async {
+  String inFilePath = pathOfData.resolve('one_line_dart_program.dart').path;
+  List<String> args = [inFilePath, "--out=" + outFilePath];
+
+  await cleanup();
+  check(await launchDart2Js(args));
+  await cleanup();
+}
+
+Future serverRunning(HttpServer server) async {
+  int port = server.port;
+  String inFilePath = "http://127.0.0.1:$port/one_line_dart_program.dart";
+  List<String> args = [inFilePath, "--out=" + outFilePath];
+
+  server.listen(handleRequest);
+  try {
+    await cleanup();
+    check(await launchDart2Js(args));
+  } finally {
+    await server.close();
+    await cleanup();
+  }
+}
+
+Future testHttp() {
+  return HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 0)
+      .then((HttpServer server) => serverRunning(server));
+}
+
+runTests() async {
+  tempDir = Directory.systemTemp.createTempSync('directory_test');
+  outFilePath = path.join(tempDir.path, "out.js");
+
+  try {
+    await testFile();
+    await testHttp();
+  } finally {
+    await tempDir.delete(recursive:true);
+  }
+}
+
+main() {
+  asyncStart();
+  runTests().whenComplete(asyncEnd);
+}
diff --git a/tests/compiler/dart2js_extra/22776.dart b/tests/compiler/dart2js_extra/22776.dart
new file mode 100644
index 0000000..e9f12ea
--- /dev/null
+++ b/tests/compiler/dart2js_extra/22776.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for http://dartbug.com/22776/
+
+import "package:expect/expect.dart";
+
+class A {}
+
+main() {
+  try {
+    print(id(new Duration(milliseconds: 10)));
+    print(id(3) ~/ new A());
+  } catch (e) {
+    print("Error '$e' ${e.runtimeType}");
+  }
+}
+
+@AssumeDynamic()
+@NoInline()
+id(x) => x;
+
diff --git a/tests/compiler/dart2js_native/optimization_hints_test.dart b/tests/compiler/dart2js_native/optimization_hints_test.dart
index 8577f14..2539849 100644
--- a/tests/compiler/dart2js_native/optimization_hints_test.dart
+++ b/tests/compiler/dart2js_native/optimization_hints_test.dart
@@ -40,6 +40,39 @@
   throw 'in baz function';
 }
 
+@js.NoInline()
+geeNoInline() {
+ // Use `gee` several times, so `gee` isn't used only once (and thus inlinable
+ // independently of its size).
+ gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee();
+ gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee();
+ gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee();
+ gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee(); gee();
+}
+
+@js.ForceInline()
+// Big function that would normally not be inlinable.
+gee([c]) {
+  if (c != null) {
+    x = "in gee function";
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+    geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline(); geeNoInline();
+  }
+}
+
 main() {
   JS('', 'String("in main function")');
   var c;
@@ -58,6 +91,8 @@
   simple();
   noinline();
   baz(); // This call should be eliminated by the optimizer.
+  gee(new C());
+  print(x);
   check(JS('', 'arguments.callee'));
 }
 
@@ -82,6 +117,8 @@
                 "should contain r'\.c_field' exactly twice");
   Expect.isFalse(source.contains('.d_field'),
                  "should not contain r'\.d_field'");
+  Expect.isTrue(source.contains('"in gee function"'),
+                "must inline 'gee'");
 }
 
 simple() {
diff --git a/tests/corelib/apply2_test.dart b/tests/corelib/apply2_test.dart
index 021f415..5270949 100644
--- a/tests/corelib/apply2_test.dart
+++ b/tests/corelib/apply2_test.dart
@@ -3,23 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
-import "symbol_map_helper.dart";
 
-apply(Function function, ArgumentDescriptor args) {
-  return Function.apply(
-      function, args.positionalArguments,
-      symbolMapToStringMap(args.namedArguments));
+apply(Function function, List positional, Map<Symbol, dynamic> named) {
+  return Function.apply(function, positional, named);
 }
 
-class ArgumentDescriptor {
-  final List positionalArguments;
-  final Map<String, dynamic> namedArguments;
-
-  ArgumentDescriptor(this.positionalArguments, this.namedArguments);
-}
-
-void throwsNSME(function) {
-  Expect.throws(function, (e) => e is NoSuchMethodError);
+void throwsNSME(function, positional, named) {
+  Expect.throws(() => apply(function, positional, named),
+                (e) => e is NoSuchMethodError);
 }
 
 main() {
@@ -30,76 +21,76 @@
   var c5 = ({a: 1, b: 2}) => 'c5 $a $b';
   var c6 = ({b: 1, a: 2}) => 'c6 $a $b';
   var c7 = (x, {b: 1, a: 2}) => 'c7 $x $a $b';
+  var c8 = (x, y, [a = 2, b = 3]) => 'c8 $x $y $a $b';
 
-  Expect.equals('c1', apply(c1, new ArgumentDescriptor(null, null)));
-  Expect.equals('c1', apply(c1, new ArgumentDescriptor([], null)));
-  Expect.equals('c1', apply(c1, new ArgumentDescriptor([], {})));
-  Expect.equals('c1', apply(c1, new ArgumentDescriptor(null, {})));
-  throwsNSME(() => apply(c1, new ArgumentDescriptor([1], null)));
-  throwsNSME(() => apply(c1, new ArgumentDescriptor([1], {'a': 2})));
-  throwsNSME(() => apply(c1, new ArgumentDescriptor(null, {'a': 2})));
+  Expect.equals('c1', apply(c1, null, null));
+  Expect.equals('c1', apply(c1, [], null));
+  Expect.equals('c1', apply(c1, [], {}));
+  Expect.equals('c1', apply(c1, null, {}));
+  throwsNSME(c1, [1], null);
+  throwsNSME(c1, [1], {#a: 2});
+  throwsNSME(c1, null, {#a: 2});
 
-  Expect.equals('c2 1', apply(c2, new ArgumentDescriptor([1], null)));
-  Expect.equals('c2 1', apply(c2, new ArgumentDescriptor([1], {})));
-  throwsNSME(() => apply(c2, new ArgumentDescriptor(null, null)));
-  throwsNSME(() => apply(c2, new ArgumentDescriptor([], null)));
-  throwsNSME(() => apply(c2, new ArgumentDescriptor(null, {})));
-  throwsNSME(() => apply(c2, new ArgumentDescriptor(null, {'a': 1})));
+  Expect.equals('c2 1', apply(c2, [1], null));
+  Expect.equals('c2 1', apply(c2, [1], {}));
+  throwsNSME(c2, null, null);
+  throwsNSME(c2, [], null);
+  throwsNSME(c2, null, {});
+  throwsNSME(c2, null, {#a: 1});
+  throwsNSME(c2, [2], {#a: 1});
 
-  Expect.equals('c3 1', apply(c3, new ArgumentDescriptor([], null)));
-  Expect.equals('c3 2', apply(c3, new ArgumentDescriptor([2], {})));
-  throwsNSME(() => apply(c3, new ArgumentDescriptor([1, 2], null)));
-  throwsNSME(() => apply(c3, new ArgumentDescriptor(null, {'a': 1})));
+  Expect.equals('c3 1', apply(c3, null, null));
+  Expect.equals('c3 1', apply(c3, [], null));
+  Expect.equals('c3 2', apply(c3, [2], {}));
+  throwsNSME(c3, [1, 2], null);
+  throwsNSME(c3, null, {#a: 1});
 
-  Expect.equals('c4 1', apply(c4, new ArgumentDescriptor([], null)));
-  Expect.equals('c4 2', apply(c4, new ArgumentDescriptor([], {'a': 2})));
-  Expect.equals('c4 1', apply(c4, new ArgumentDescriptor(null, null)));
-  Expect.equals('c4 1', apply(c4, new ArgumentDescriptor([], {})));
-  throwsNSME(() => apply(c4, new ArgumentDescriptor([1], {'a': 1})));
-  throwsNSME(() => apply(c4, new ArgumentDescriptor([1], {})));
-  throwsNSME(() => apply(c4, new ArgumentDescriptor([], {'a': 1, 'b': 2})));
+  Expect.equals('c4 1', apply(c4, [], null));
+  Expect.equals('c4 2', apply(c4, [], {#a: 2}));
+  Expect.equals('c4 1', apply(c4, null, null));
+  Expect.equals('c4 1', apply(c4, [], {}));
+  throwsNSME(c4, [1], {#a: 1});
+  throwsNSME(c4, [1], {});
+  throwsNSME(c4, [], {#a: 1, #b: 2});
 
-  Expect.equals('c5 1 2', apply(c5, new ArgumentDescriptor([], null)));
-  Expect.equals('c5 3 2', apply(c5, new ArgumentDescriptor([], {'a': 3})));
-  Expect.equals('c5 1 2', apply(c5, new ArgumentDescriptor(null, null)));
-  Expect.equals('c5 1 2', apply(c5, new ArgumentDescriptor([], {})));
-  Expect.equals('c5 3 4',
-      apply(c5, new ArgumentDescriptor([], {'a': 3, 'b': 4})));
-  Expect.equals('c5 4 3',
-      apply(c5, new ArgumentDescriptor([], {'b': 3, 'a': 4})));
-  Expect.equals('c5 1 3',
-      apply(c5, new ArgumentDescriptor([], {'b': 3})));
-  throwsNSME(() => apply(c5, new ArgumentDescriptor([1], {'a': 1})));
-  throwsNSME(() => apply(c5, new ArgumentDescriptor([1], {})));
-  throwsNSME(() =>
-      apply(c5, new ArgumentDescriptor([], {'a': 1, 'b': 2, 'c': 3})));
+  Expect.equals('c5 1 2', apply(c5, [], null));
+  Expect.equals('c5 3 2', apply(c5, [], {#a: 3}));
+  Expect.equals('c5 1 2', apply(c5, null, null));
+  Expect.equals('c5 1 2', apply(c5, [], {}));
+  Expect.equals('c5 3 4', apply(c5, [], {#a: 3, #b: 4}));
+  Expect.equals('c5 4 3', apply(c5, [], {#b: 3, #a: 4}));
+  Expect.equals('c5 1 3', apply(c5, [], {#b: 3}));
+  throwsNSME(c5, [1], {#a: 1});
+  throwsNSME(c5, [1], {});
+  throwsNSME(c5, [], {#a: 1, #b: 2, #c: 3});
 
-  Expect.equals('c6 2 1', apply(c6, new ArgumentDescriptor([], null)));
-  Expect.equals('c6 3 1', apply(c6, new ArgumentDescriptor([], {'a': 3})));
-  Expect.equals('c6 2 1', apply(c6, new ArgumentDescriptor(null, null)));
-  Expect.equals('c6 2 1', apply(c6, new ArgumentDescriptor([], {})));
-  Expect.equals('c6 3 4',
-      apply(c6, new ArgumentDescriptor([], {'a': 3, 'b': 4})));
-  Expect.equals('c6 4 3',
-      apply(c6, new ArgumentDescriptor([], {'b': 3, 'a': 4})));
-  Expect.equals('c6 2 3',
-      apply(c6, new ArgumentDescriptor([], {'b': 3})));
-  throwsNSME(() => apply(c6, new ArgumentDescriptor([1], {'a': 1})));
-  throwsNSME(() => apply(c6, new ArgumentDescriptor([1], {})));
-  throwsNSME(() =>
-      apply(c6, new ArgumentDescriptor([], {'a': 1, 'b': 2, 'c': 3})));
+  Expect.equals('c6 2 1', apply(c6, [], null));
+  Expect.equals('c6 3 1', apply(c6, [], {#a: 3}));
+  Expect.equals('c6 2 1', apply(c6, null, null));
+  Expect.equals('c6 2 1', apply(c6, [], {}));
+  Expect.equals('c6 3 4', apply(c6, [], {#a: 3, #b: 4}));
+  Expect.equals('c6 4 3', apply(c6, [], {#b: 3, #a: 4}));
+  Expect.equals('c6 2 3', apply(c6, [], {#b: 3}));
+  throwsNSME(c6, [1], {#a: 1});
+  throwsNSME(c6, [1], {});
+  throwsNSME(c6, [], {#a: 1, #b: 2, #c: 3});
 
-  Expect.equals('c7 7 2 1', apply(c7, new ArgumentDescriptor([7], null)));
-  Expect.equals('c7 7 3 1', apply(c7, new ArgumentDescriptor([7], {'a': 3})));
-  Expect.equals('c7 7 2 1', apply(c7, new ArgumentDescriptor([7], {})));
-  Expect.equals('c7 7 3 4',
-      apply(c7, new ArgumentDescriptor([7], {'a': 3, 'b': 4})));
-  Expect.equals('c7 7 4 3',
-      apply(c7, new ArgumentDescriptor([7], {'b': 3, 'a': 4})));
-  Expect.equals('c7 7 2 3',
-      apply(c7, new ArgumentDescriptor([7], {'b': 3})));
-  throwsNSME(() => apply(c7, new ArgumentDescriptor([], {'a': 1})));
-  throwsNSME(() => apply(c7, new ArgumentDescriptor([], {})));
-  throwsNSME(() =>
-      apply(c7, new ArgumentDescriptor([7], {'a': 1, 'b': 2, 'c': 3})));
+  Expect.equals('c7 7 2 1', apply(c7, [7], null));
+  Expect.equals('c7 7 3 1', apply(c7, [7], {#a: 3}));
+  Expect.equals('c7 7 2 1', apply(c7, [7], {}));
+  Expect.equals('c7 7 3 4', apply(c7, [7], {#a: 3, #b: 4}));
+  Expect.equals('c7 7 4 3', apply(c7, [7], {#b: 3, #a: 4}));
+  Expect.equals('c7 7 2 3', apply(c7, [7], {#b: 3}));
+  throwsNSME(c7, [], {#a: 1});
+  throwsNSME(c7, [], {});
+  throwsNSME(c7, [7], {#a: 1, #b: 2, #c: 3});
+
+  Expect.equals('c8 7 8 2 3', apply(c8, [7, 8], null));
+  Expect.equals('c8 7 8 2 3', apply(c8, [7, 8], {}));
+  Expect.equals('c8 7 8 3 3', apply(c8, [7, 8, 3], null));
+  Expect.equals('c8 7 8 3 4', apply(c8, [7, 8, 3, 4], null));
+  throwsNSME(c8, [], null);
+  throwsNSME(c8, [], {});
+  throwsNSME(c8, [1], null);
+  throwsNSME(c8, [7, 8, 9, 10, 11], null);
 }
diff --git a/tests/corelib/apply4_test.dart b/tests/corelib/apply4_test.dart
index f617456..fba4b9d 100644
--- a/tests/corelib/apply4_test.dart
+++ b/tests/corelib/apply4_test.dart
@@ -16,5 +16,5 @@
   var a = new A();
   var clos = a.foo;
   Expect.equals(Function.apply(clos, ["well"]), "well 99");
-  Expect.equals(Function.apply(clos, ["well", 0, 1, 2, 3, 4, 5, 6]), "well 5");
+  Expect.equals(Function.apply(clos, ["well", 0, 2, 4, 3, 6, 9, 10]), "well 9");
 }
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index cfa07db..52283d6 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -103,7 +103,7 @@
 # IEEE-754 rounding algorithm.
 double_parse_test: Fail, OK
 
-[ $runtime == jsshell || $runtime == safari || $runtime == safarimobilesim ]
+[ $runtime == safari || $runtime == safarimobilesim ]
 double_round3_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
 double_round_to_double2_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
 
diff --git a/tests/corelib/double_parse_test.dart b/tests/corelib/double_parse_test.dart
index 1f26e8a..5fb6e76 100644
--- a/tests/corelib/double_parse_test.dart
+++ b/tests/corelib/double_parse_test.dart
@@ -114,6 +114,7 @@
       throw object;
     });
   }, (e) => identical(object, e), "Fail: '$source'");
+  Expect.equals(1.5, double.parse(source, (s) => 1.5));
 }
 
 void main() {
diff --git a/tests/corelib/hash_map2_test.dart b/tests/corelib/hash_map2_test.dart
index baaf143..848f449 100644
--- a/tests/corelib/hash_map2_test.dart
+++ b/tests/corelib/hash_map2_test.dart
@@ -3,8 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // VMOptions=
-// VMOptions=--use_compact_hash=false
-// VMOptions=--use_internal_hash_map --use_compact_hash=false 
+// VMOptions=--use_internal_hash_map
 
 // Tests of hash map behavior, with focus in iteration and concurrent
 // modification errors.
diff --git a/tests/corelib/hash_map_test.dart b/tests/corelib/hash_map_test.dart
index 76b1367..8f9ce30 100644
--- a/tests/corelib/hash_map_test.dart
+++ b/tests/corelib/hash_map_test.dart
@@ -3,8 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // VMOptions=
-// VMOptions=--use_compact_hash=false
-// VMOptions=--use_internal_hash_map --use_compact_hash=false
+// VMOptions=--use_internal_hash_map
 
 import "package:expect/expect.dart";
 
diff --git a/tests/corelib/hash_set_test.dart b/tests/corelib/hash_set_test.dart
index b0730e7..29b202d 100644
--- a/tests/corelib/hash_set_test.dart
+++ b/tests/corelib/hash_set_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 //
 // VMOptions=
-// VMOptions=--use_compact_hash=false
 
 // Tests of hash set behavior, with focus in iteration and concurrent
 // modification errors.
diff --git a/tests/corelib/int_parse_radix_test.dart b/tests/corelib/int_parse_radix_test.dart
index 9430e8f..ce68a79 100644
--- a/tests/corelib/int_parse_radix_test.dart
+++ b/tests/corelib/int_parse_radix_test.dart
@@ -94,7 +94,8 @@
     Expect.equals(-999, int.parse(source, radix: radix, onError: (s) => -999));
   }
   for (int i = 2; i < 36; i++) {
-    testFails(i.toRadixString(36), i);
+    testFails(i.toRadixString(36).toLowerCase(), i);
+    testFails(i.toRadixString(36).toUpperCase(), i);
   }
   testFails("", 2);
   testFails("+ 1", 2);  // No space between sign and digits.
diff --git a/tests/html/Ahem.ttf b/tests/html/Ahem.ttf
new file mode 100644
index 0000000..ac81cb0
--- /dev/null
+++ b/tests/html/Ahem.ttf
Binary files differ
diff --git a/tests/html/async_cancellingisolate.dart b/tests/html/async_cancellingisolate.dart
new file mode 100644
index 0000000..6278ebc
--- /dev/null
+++ b/tests/html/async_cancellingisolate.dart
@@ -0,0 +1,31 @@
+library async_cancellingisolate;
+
+import 'dart:async';
+import 'package:unittest/unittest.dart';
+
+main(message, replyTo) {
+  var command = message.first;
+  expect(command, 'START');
+  var shot = false;
+  var oneshot;
+  var periodic;
+  periodic = new Timer.periodic(const Duration(milliseconds: 10), (timer) {
+    expect(shot, isFalse);
+    shot = true;
+    expect(timer, same(periodic));
+    periodic.cancel();
+    oneshot.cancel();
+    // Wait some more time to be sure callbacks won't be invoked any
+    // more.
+    new Timer(const Duration(milliseconds: 50), () {
+      replyTo.send('DONE');
+    });
+  });
+  // We launch the oneshot timer after the periodic timer. Otherwise a
+  // (very long) context switch could make this test flaky: assume the
+  // oneshot timer is created first and then there is a 30ms context switch.
+  // when the periodic timer is scheduled it would execute after the oneshot.
+  oneshot = new Timer(const Duration(milliseconds: 30), () {
+    fail('Should never be invoked');
+  });
+}
\ No newline at end of file
diff --git a/tests/html/async_oneshot.dart b/tests/html/async_oneshot.dart
new file mode 100644
index 0000000..3ed24f1
--- /dev/null
+++ b/tests/html/async_oneshot.dart
@@ -0,0 +1,11 @@
+import 'dart:async';
+import 'package:unittest/unittest.dart';
+
+main(message, replyTo) {
+  var command = message.first;
+  expect(command, 'START');
+  new Timer(const Duration(milliseconds: 10), () {
+    replyTo.send('DONE');
+  });
+}
+
diff --git a/tests/html/async_periodictimer.dart b/tests/html/async_periodictimer.dart
new file mode 100644
index 0000000..4d647c5
--- /dev/null
+++ b/tests/html/async_periodictimer.dart
@@ -0,0 +1,24 @@
+library async_periodictimer;
+
+import 'dart:async';
+import 'package:unittest/unittest.dart';
+
+main(message, replyTo) {
+  var command = message.first;
+  expect(command, 'START');
+  int counter = 0;
+  new Timer.periodic(const Duration(milliseconds: 10), (timer) {
+    if (counter == 3) {
+      counter = 1024;
+      timer.cancel();
+      // Wait some more time to be sure callback won't be invoked any
+      // more.
+      new Timer(const Duration(milliseconds: 30), () {
+        replyTo.send('DONE');
+      });
+      return;
+    }
+    assert(counter < 3);
+    counter++;
+  });
+}
\ No newline at end of file
diff --git a/tests/html/async_spawnuri_test.dart b/tests/html/async_spawnuri_test.dart
new file mode 100644
index 0000000..0c6e287
--- /dev/null
+++ b/tests/html/async_spawnuri_test.dart
@@ -0,0 +1,37 @@
+library async_spawnuri_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+
+import 'dart:async';
+import 'dart:isolate';
+import 'dart:html';
+
+// OtherScripts=async_oneshot.dart async_periodictimer.dart async_cancellingisolate.dart
+main() {
+  useHtmlConfiguration();
+
+  test('one shot timer in pure isolate', () {
+    var response = new ReceivePort();
+    var remote = Isolate.spawnUri(Uri.parse('async_oneshot.dart'), 
+                               ['START'], response.sendPort);
+    remote.catchError((x) => expect("Error in oneshot isolate", x));
+    expect(remote.then((_) => response.first), completion('DONE'));
+  });
+
+  test('periodic timer in pure isolate', () {
+    var response = new ReceivePort();
+    var remote = Isolate.spawnUri(Uri.parse('async_periodictimer.dart'), 
+                               ['START'], response.sendPort);
+    remote.catchError((x) => expect("Error in periodic timer isolate", x));
+    expect(remote.then((_) => response.first), completion('DONE'));
+  });
+
+  test('cancellation in pure isolate', () {
+    var response = new ReceivePort();
+    var remote = Isolate.spawnUri(Uri.parse('async_cancellingisolate.dart'), 
+                               ['START'], response.sendPort);
+    remote.catchError((x) => expect("Error in cancelling isolate", x));
+    expect(remote.then((_) => response.first), completion('DONE'));
+  });
+}
diff --git a/tests/html/async_test.dart b/tests/html/async_test.dart
index 4144098..7a19538 100644
--- a/tests/html/async_test.dart
+++ b/tests/html/async_test.dart
@@ -7,83 +7,36 @@
 import 'dart:isolate';
 import 'dart:html';
 
-oneshotTimerIsolate(message) {
-  var command = message[0];
-  var replyTo = message[1];
-  expect(command, 'START');
-  new Timer(const Duration(milliseconds: 10), () {
-    replyTo.send('DONE');
-  });
-}
+import 'async_oneshot.dart' as oneshot_test show main; 
+import 'async_periodictimer.dart' as periodictimer_test show main;
+import 'async_cancellingisolate.dart' as cancelling_test show main;
 
-periodicTimerIsolate(message) {
-  var command = message[0];
-  var replyTo = message[1];
-  expect(command, 'START');
-  int counter = 0;
-  new Timer.periodic(const Duration(milliseconds: 10), (timer) {
-    if (counter == 3) {
-      counter = 1024;
-      timer.cancel();
-      // Wait some more time to be sure callback won't be invoked any
-      // more.
-      new Timer(const Duration(milliseconds: 30), () {
-        replyTo.send('DONE');
-      });
-      return;
-    }
-    assert(counter < 3);
-    counter++;
-  });
-}
-
-cancellingIsolate(message) {
-  var command = message[0];
-  var replyTo = message[1];
-  expect(command, 'START');
-  bool shot = false;
-  var oneshot;
-  var periodic;
-  periodic = new Timer.periodic(const Duration(milliseconds: 10), (timer) {
-    expect(shot, isFalse);
-    shot = true;
-    expect(timer, same(periodic));
-    periodic.cancel();
-    oneshot.cancel();
-    // Wait some more time to be sure callbacks won't be invoked any
-    // more.
-    new Timer(const Duration(milliseconds: 50), () {
-      replyTo.send('DONE');
-    });
-  });
-  // We launch the oneshot timer after the periodic timer. Otherwise a
-  // (very long) context switch could make this test flaky: assume the
-  // oneshot timer is created first and then there is a 30ms context switch.
-  // when the periodic timer is scheduled it would execute after the oneshot.
-  oneshot = new Timer(const Duration(milliseconds: 30), () {
-    fail('Should never be invoked');
-  });
-}
+oneshot(message) => oneshot_test.main(message.first, message.last);
+periodicTimerIsolate(message) =>
+    periodictimer_test.main(message.first, message.last);
+cancellingIsolate(message) => cancelling_test.main(message.first, message.last);
 
 main() {
   useHtmlConfiguration();
 
   test('one shot timer in pure isolate', () {
     var response = new ReceivePort();
-    var remote = Isolate.spawn(oneshotTimerIsolate,
-                               ['START', response.sendPort]);
+    var remote = Isolate.spawn(oneshot,
+                               [['START'], response.sendPort]);
     expect(remote.then((_) => response.first), completion('DONE'));
   });
+
   test('periodic timer in pure isolate', () {
     var response = new ReceivePort();
     var remote = Isolate.spawn(periodicTimerIsolate,
-                               ['START', response.sendPort]);
+                               [['START'], response.sendPort]);
     expect(remote.then((_) => response.first), completion('DONE'));
   });
+  
   test('cancellation in pure isolate', () {
     var response = new ReceivePort();
     var remote = Isolate.spawn(cancellingIsolate,
-                               ['START', response.sendPort]);
+                               [['START'], response.sendPort]);
     expect(remote.then((_) => response.first), completion('DONE'));
   });
 }
diff --git a/tests/html/deferred_multi_app_htmltest.html b/tests/html/deferred_multi_app_htmltest.html
index f5db785..554adf8 100644
--- a/tests/html/deferred_multi_app_htmltest.html
+++ b/tests/html/deferred_multi_app_htmltest.html
@@ -8,7 +8,7 @@
 
 START_HTML_DART_TEST
 {
-  "scripts": ["deferred_multi_app.dart"],
+  "scripts": ["deferred_multi_app.dart", "deferred_multi_app_lib.dart"],
   "expectedMessages": ["one", "two"]
 }
 END_HTML_DART_TEST
diff --git a/tests/html/element_animate_test.dart b/tests/html/element_animate_test.dart
new file mode 100644
index 0000000..31becda
--- /dev/null
+++ b/tests/html/element_animate_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library element_animate_test;
+
+import 'dart:async';
+import 'dart:html';
+import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/unittest.dart';
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  group('animate_supported', () {
+    test('supported', () {
+      expect(AnimationPlayer.supported, true);
+    });
+  });
+
+  group('simple_timing', () {
+    test('simple timing', () {
+      var body = document.body;
+      var opacity = num.parse(body.getComputedStyle().opacity);
+      body.animate([{"opacity": 100}, {"opacity": 0}], 100);
+      var newOpacity = num.parse(body.getComputedStyle().opacity);
+      expect(newOpacity < opacity, isTrue);
+    });
+  });
+
+  group('timing_dict', () {
+    test('timing dict', () {
+      var body = document.body;
+      // Animate different characteristics so the tests can run concurrently.
+      var fontSize = body.getComputedStyle().fontSize;
+      var player = body.animate(
+          [{"font-size": "500px"}, {"font-size": fontSize}], {"duration": 100});
+      var newFontSize = body.getComputedStyle().fontSize;
+      // Don't bother to parse to numbers, as long as it's changed that
+      // indicates something is happening.
+      expect(newFontSize == fontSize, isFalse);
+      player.on['finish'].listen(expectAsync((_) => 'done'));
+    });
+  });
+
+  group('omit_timing', () {
+    test('omit timing', () {
+      var body = document.body;
+      var player = body.animate([
+        {"transform": "translate(100px, -100%)"},
+        {"transform": "translate(400px, 500px)"}
+      ]);
+      player.on['finish'].listen(expectAsync((_) => 'done'));
+    });
+  });
+}
diff --git a/tests/html/element_offset_test.dart b/tests/html/element_offset_test.dart
index 10102d3..e7129d0 100644
--- a/tests/html/element_offset_test.dart
+++ b/tests/html/element_offset_test.dart
@@ -81,7 +81,7 @@
 
       var point = itema.offsetTo(itemii);
       expect(point.x, 40);
-      expect(point.y, inInclusiveRange(17, 20));
+      expect(point.y, inInclusiveRange(16, 20));
 
       expect(baz.offsetTo(bar).x, 7000);
       expect(baz.offsetTo(bar).y, inInclusiveRange(599, 604));
@@ -92,13 +92,13 @@
 
       point = item1.offsetTo(itemb);
       expect(point.x, 40);
-      expect(point.y, inInclusiveRange(17, 20));
+      expect(point.y, inInclusiveRange(16, 20));
       point = itemb.offsetTo(itemii);
       expect(point.x, 190);
-      expect(point.y, inInclusiveRange(54, 60));
+      expect(point.y, inInclusiveRange(52, 60));
       point = item1.offsetTo(itemii);
       expect(point.x, 230);
-      expect(point.y, inInclusiveRange(74, 80));
+      expect(point.y, inInclusiveRange(68, 80));
     });
 
     test('documentOffset', () {
@@ -112,16 +112,16 @@
       var itemii = query('.item-ii');
 
       expect(itema.documentOffset.x, 88);
-      expect(itema.documentOffset.y, inInclusiveRange(119, 160));
+      expect(itema.documentOffset.y, inInclusiveRange(111, 160));
 
       expect(itemii.documentOffset.x, 48);
-      expect(itemii.documentOffset.y, inInclusiveRange(101, 145));
+      expect(itemii.documentOffset.y, inInclusiveRange(95, 145));
 
       expect(itemb.documentOffset.x, 238);
-      expect(itemb.documentOffset.y, inInclusiveRange(157, 205));
+      expect(itemb.documentOffset.y, inInclusiveRange(147, 205));
 
       expect(item1.documentOffset.x, 278);
-      expect(item1.documentOffset.y, inInclusiveRange(175, 222));
+      expect(item1.documentOffset.y, inInclusiveRange(163, 222));
 
       expect(bar.documentOffset.x, 90);
       expect(bar.documentOffset.y, 8);
@@ -130,10 +130,10 @@
       expect(baz.documentOffset.y, 608);
 
       expect(qux.documentOffset.x, 8);
-      expect(qux.documentOffset.y, inInclusiveRange(221, 240));
+      expect(qux.documentOffset.y, inInclusiveRange(203, 240));
 
       expect(quux.documentOffset.x, 8);
-      expect(quux.documentOffset.y, inInclusiveRange(221, 240));
+      expect(quux.documentOffset.y, inInclusiveRange(203, 240));
     });
   });
 }
diff --git a/tests/html/element_types_constructors1_test.dart b/tests/html/element_types_constructors1_test.dart
new file mode 100644
index 0000000..202556a
--- /dev/null
+++ b/tests/html/element_types_constructors1_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library element_types_constructors1_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'dart:html';
+
+main() {
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      var expectation = supported ? returnsNormally : throws;
+      expect(() {
+        expect(fn(), isTrue);
+      }, expectation);
+    });
+  }
+
+  group('constructors', () {
+    check('a', () => new AnchorElement() is AnchorElement);
+    check('area', () => new AreaElement() is AreaElement);
+    check('audio', () => new AudioElement() is AudioElement);
+    check('body', () => new BodyElement() is BodyElement);
+    check('br', () => new BRElement() is BRElement);
+    check('base', () => new BaseElement() is BaseElement);
+    check('button', () => new ButtonElement() is ButtonElement);
+    check('canvas', () => new CanvasElement() is CanvasElement);
+    check('caption', () => new TableCaptionElement() is TableCaptionElement);
+    check('content',
+        () => new ContentElement() is ContentElement, ContentElement.supported);
+    check('details', () => new DetailsElement() is DetailsElement,
+        DetailsElement.supported);
+    check('datalist', () => new DataListElement() is DataListElement,
+        DataListElement.supported);
+    check('dl', () => new DListElement() is DListElement);
+    check('div', () => new DivElement() is DivElement);
+    check('embed',
+        () => new EmbedElement() is EmbedElement, EmbedElement.supported);
+  });
+}
diff --git a/tests/html/element_types_constructors2_test.dart b/tests/html/element_types_constructors2_test.dart
new file mode 100644
index 0000000..07a5fc4
--- /dev/null
+++ b/tests/html/element_types_constructors2_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library element_types_constructors2_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'dart:html';
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      var expectation = supported ? returnsNormally : throws;
+      expect(() {
+        expect(fn(), isTrue);
+      }, expectation);
+    });
+  }
+
+  group('constructors', () {
+    check('fieldset', () => new FieldSetElement() is FieldSetElement);
+    check('form', () => new FormElement() is FormElement);
+    check('head', () => new HeadElement() is HeadElement);
+    check('hr', () => new HRElement() is HRElement);
+    check('html', () => new HtmlHtmlElement() is HtmlHtmlElement);
+    check('h1', () => new HeadingElement.h1() is HeadingElement);
+    check('h2', () => new HeadingElement.h2() is HeadingElement);
+    check('h3', () => new HeadingElement.h3() is HeadingElement);
+    check('h4', () => new HeadingElement.h4() is HeadingElement);
+    check('h5', () => new HeadingElement.h5() is HeadingElement);
+    check('h6', () => new HeadingElement.h6() is HeadingElement);
+    check('iframe', () => new IFrameElement() is IFrameElement);
+    check('img', () => new ImageElement() is ImageElement);
+    check('input', () => new InputElement() is InputElement);
+    check('keygen',
+        () => new KeygenElement() is KeygenElement, KeygenElement.supported);
+  });
+}
diff --git a/tests/html/element_types_constructors3_test.dart b/tests/html/element_types_constructors3_test.dart
new file mode 100644
index 0000000..54324a6
--- /dev/null
+++ b/tests/html/element_types_constructors3_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library element_types_constructors3_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'dart:html';
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      var expectation = supported ? returnsNormally : throws;
+      expect(() {
+        expect(fn(), isTrue);
+      }, expectation);
+    });
+  }
+
+  group('constructors', () {
+    check('li', () => new LIElement() is LIElement);
+    check('label', () => new LabelElement() is LabelElement);
+    check('legen', () => new LegendElement() is LegendElement);
+    check('link', () => new LinkElement() is LinkElement);
+    check('map', () => new MapElement() is MapElement);
+    check('menu', () => new MenuElement() is MenuElement);
+    check('meta', () => new MetaElement() is MetaElement);
+    check('meter',
+        () => new MeterElement() is MeterElement, MeterElement.supported);
+    check('del', () => new Element.tag('del') is ModElement);
+    check('ins', () => new Element.tag('ins') is ModElement);
+    check('object', () => new ObjectElement() is ObjectElement,
+        ObjectElement.supported);
+    check('ol', () => new OListElement() is OListElement);
+    check('optgroup', () => new OptGroupElement() is OptGroupElement);
+    check('option', () => new OptionElement() is OptionElement);
+    check('output',
+        () => new OutputElement() is OutputElement, OutputElement.supported);
+  });
+}
diff --git a/tests/html/element_types_constructors4_test.dart b/tests/html/element_types_constructors4_test.dart
new file mode 100644
index 0000000..38223c9
--- /dev/null
+++ b/tests/html/element_types_constructors4_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library element_types_constructors_test4;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'dart:html';
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      var expectation = supported ? returnsNormally : throws;
+      expect(() {
+        expect(fn(), isTrue);
+      }, expectation);
+    });
+  }
+
+  group('constructors', () {
+    check('p', () => new ParagraphElement() is ParagraphElement);
+    check('param', () => new ParamElement() is ParamElement);
+    check('pre', () => new PreElement() is PreElement);
+    check('progress', () => new ProgressElement() is ProgressElement,
+        ProgressElement.supported);
+    check('q', () => new QuoteElement() is QuoteElement);
+    check('script', () => new ScriptElement() is ScriptElement);
+    check('select', () => new SelectElement() is SelectElement);
+    check('shadow',
+        () => new ShadowElement() is ShadowElement, ShadowElement.supported);
+    check('source', () => new SourceElement() is SourceElement);
+    check('span', () => new SpanElement() is SpanElement);
+    check('style', () => new StyleElement() is StyleElement);
+  });
+}
diff --git a/tests/html/element_types_constructors5_test.dart b/tests/html/element_types_constructors5_test.dart
new file mode 100644
index 0000000..e930ac1
--- /dev/null
+++ b/tests/html/element_types_constructors5_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library element_types_constructors5_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'dart:html';
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      var expectation = supported ? returnsNormally : throws;
+      expect(() {
+        expect(fn(), isTrue);
+      }, expectation);
+    });
+  }
+
+  group('constructors', () {
+    check('table', () => new TableElement() is TableElement);
+    check('template', () => new TemplateElement() is TemplateElement,
+        TemplateElement.supported);
+    check('textarea', () => new TextAreaElement() is TextAreaElement);
+    check('title', () => new TitleElement() is TitleElement);
+    check('td', () => new TableCellElement() is TableCellElement);
+    check('col', () => new TableColElement() is TableColElement);
+    check('colgroup', () => new Element.tag('colgroup') is TableColElement);
+    check('tr', () => new TableRowElement() is TableRowElement);
+    check('tbody', () => new Element.tag('tbody') is TableSectionElement);
+    check('tfoot', () => new Element.tag('tfoot') is TableSectionElement);
+    check('thead', () => new Element.tag('thead') is TableSectionElement);
+    check('track', () => new TrackElement() is TrackElement,
+        TrackElement.supported);
+  });
+}
diff --git a/tests/html/element_types_constructors6_test.dart b/tests/html/element_types_constructors6_test.dart
new file mode 100644
index 0000000..6049ffc
--- /dev/null
+++ b/tests/html/element_types_constructors6_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library element_types_constructors6_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'dart:html';
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  check(String name, bool fn(), [bool supported = true]) {
+    test(name, () {
+      var expectation = supported ? returnsNormally : throws;
+      expect(() {
+        expect(fn(), isTrue);
+      }, expectation);
+    });
+  }
+
+  group('ul', () {
+    check('ul', () => new UListElement() is UListElement);
+
+    test('accepts li', () {
+      var ul = new UListElement();
+      var li = new LIElement();
+      ul.append(li);
+    });
+  });
+  group('constructors', () {
+    check('video', () => new VideoElement() is VideoElement);
+    check('unknown', () => new Element.tag('someunknown') is UnknownElement);
+  });
+}
diff --git a/tests/html/element_types_test.dart b/tests/html/element_types_test.dart
index df0c488..ab06012 100644
--- a/tests/html/element_types_test.dart
+++ b/tests/html/element_types_test.dart
@@ -81,108 +81,4 @@
       expect(TrackElement.supported, true);
     });
   });
-
-  check(String name, bool fn(), [bool supported = true]) {
-    test(name, () {
-      var expectation = supported ? returnsNormally : throws;
-      expect(() {
-        expect(fn(), isTrue);
-      }, expectation);
-    });
-
-  }
-
-  group('constructors', () {
-    check('a', () => new AnchorElement() is AnchorElement);
-    check('area', () => new AreaElement() is AreaElement);
-    check('audio', () => new AudioElement() is AudioElement);
-    check('body', () => new BodyElement() is BodyElement);
-    check('br', () => new BRElement() is BRElement);
-    check('base', () => new BaseElement() is BaseElement);
-    check('button', () => new ButtonElement() is ButtonElement);
-    check('canvas', () => new CanvasElement() is CanvasElement);
-    check('caption', () => new TableCaptionElement() is TableCaptionElement);
-    check('content', () => new ContentElement() is ContentElement,
-        ContentElement.supported);
-    check('details', () => new DetailsElement() is DetailsElement,
-        DetailsElement.supported);
-    check('datalist', () => new DataListElement() is DataListElement,
-        DataListElement.supported);
-    check('dl', () => new DListElement() is DListElement);
-    check('div', () => new DivElement() is DivElement);
-    check('embed', () => new EmbedElement() is EmbedElement,
-        EmbedElement.supported);
-    check('fieldset', () => new FieldSetElement() is FieldSetElement);
-    check('form', () => new FormElement() is FormElement);
-    check('head', () => new HeadElement() is HeadElement);
-    check('hr', () => new HRElement() is HRElement);
-    check('html', () => new HtmlHtmlElement() is HtmlHtmlElement);
-    check('h1', () => new HeadingElement.h1() is HeadingElement);
-    check('h2', () => new HeadingElement.h2() is HeadingElement);
-    check('h3', () => new HeadingElement.h3() is HeadingElement);
-    check('h4', () => new HeadingElement.h4() is HeadingElement);
-    check('h5', () => new HeadingElement.h5() is HeadingElement);
-    check('h6', () => new HeadingElement.h6() is HeadingElement);
-    check('iframe', () => new IFrameElement() is IFrameElement);
-    check('img', () => new ImageElement() is ImageElement);
-    check('input', () => new InputElement() is InputElement);
-    check('keygen', () => new KeygenElement() is KeygenElement,
-        KeygenElement.supported);
-    check('li', () => new LIElement() is LIElement);
-    check('label', () => new LabelElement() is LabelElement);
-    check('legen', () => new LegendElement() is LegendElement);
-    check('link', () => new LinkElement() is LinkElement);
-    check('map', () => new MapElement() is MapElement);
-    check('menu', () => new MenuElement() is MenuElement);
-    check('meta', () => new MetaElement() is MetaElement);
-    check('meter', () => new MeterElement() is MeterElement,
-        MeterElement.supported);
-    check('del', () => new Element.tag('del') is ModElement);
-    check('ins', () => new Element.tag('ins') is ModElement);
-    check('object', () => new ObjectElement() is ObjectElement,
-        ObjectElement.supported);
-    check('ol', () => new OListElement() is OListElement);
-    check('optgroup', () => new OptGroupElement() is OptGroupElement);
-    check('option', () => new OptionElement() is OptionElement);
-    check('output', () => new OutputElement() is OutputElement,
-        OutputElement.supported);
-    check('p', () => new ParagraphElement() is ParagraphElement);
-    check('param', () => new ParamElement() is ParamElement);
-    check('pre', () => new PreElement() is PreElement);
-    check('progress', () => new ProgressElement() is ProgressElement,
-        ProgressElement.supported);
-    check('q', () => new QuoteElement() is QuoteElement);
-    check('script', () => new ScriptElement() is ScriptElement);
-    check('select', () => new SelectElement() is SelectElement);
-    check('shadow', () => new ShadowElement() is ShadowElement,
-        ShadowElement.supported);
-    check('source', () => new SourceElement() is SourceElement);
-    check('span', () => new SpanElement() is SpanElement);
-    check('style', () => new StyleElement() is StyleElement);
-    check('table', () => new TableElement() is TableElement);
-    check('template', () => new TemplateElement() is TemplateElement,
-        TemplateElement.supported);
-    check('textarea', () => new TextAreaElement() is TextAreaElement);
-    check('title', () => new TitleElement() is TitleElement);
-    check('td', () => new TableCellElement() is TableCellElement);
-    check('col', () => new TableColElement() is TableColElement);
-    check('colgroup', () => new Element.tag('colgroup') is TableColElement);
-    check('tr', () => new TableRowElement() is TableRowElement);
-    check('tbody', () => new Element.tag('tbody') is TableSectionElement);
-    check('tfoot', () => new Element.tag('tfoot') is TableSectionElement);
-    check('thead', () => new Element.tag('thead') is TableSectionElement);
-    check('track', () => new TrackElement() is TrackElement,
-        TrackElement.supported);
-    group('ul', () {
-      check('ul', () => new UListElement() is UListElement);
-
-      test('accepts li', () {
-        var ul = new UListElement();
-        var li = new LIElement();
-        ul.append(li);
-      });
-    });
-    check('video', () => new VideoElement() is VideoElement);
-    check('unknown', () => new Element.tag('someunknown') is UnknownElement);
-  });
 }
diff --git a/tests/html/fontface_test.dart b/tests/html/fontface_test.dart
new file mode 100644
index 0000000..8247a8a
--- /dev/null
+++ b/tests/html/fontface_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fontface_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+
+import 'dart:html';
+
+main() {
+  useHtmlConfiguration();
+
+  test("Creation with parameters", () {
+    var font =
+        new FontFace('Ahem', 'url(Ahem.ttf)', {'variant': 'small-caps'});
+    expect(font is FontFace, isTrue);
+    expect(font.family, 'Ahem');
+    expect(font.variant, 'small-caps');
+  });
+}
diff --git a/tests/html/html.status b/tests/html/html.status
index 7255772..c367d6f 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -14,8 +14,10 @@
 indexeddb_4_test: Skip # Issue 19726
 mouse_event_test: Fail # Issue 20437
 worker_api_test: Fail # Issue 10223
-two_scripts_htmltest: Fail # Issue 16603
 media_stream_test/constructors: Pass, Crash # Issue 22267
+element_animate_test/simple_timing: Fail # Not supported on Dartium
+element_animate_test/omit_timing: Fail # Not supported on Dartium
+element_animate_test/timing_dict: Fail # Not supported on Dartium
 
 [ $compiler == none && $mode == debug && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 datalistelement_test: Skip # Issue 20540
@@ -34,6 +36,8 @@
 
 [ $compiler == dart2js && ($runtime == safari || $runtime == safarimobilesim || $runtime == ff  || $ie) ]
 custom/entered_left_view_test/viewless_document: Fail # Polyfill does not handle this
+fontface_test: Fail # Fontface not supported on these.
+element_animate_test: Fail # Element.animate not supported on these browsers.
 
 [ $compiler == none && $runtime == dartium && $system == macos]
 canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Pass,Fail # Issue 11834
@@ -56,6 +60,7 @@
 [ $compiler == none && $runtime == ContentShellOnAndroid ]
 canvasrenderingcontext2d_test/drawImage_video_element: RuntimeError # Issue 19127
 canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Pass, Fail # Issue 20524
+notification_test/constructors: Skip # Times out on Android Dartium. Issue 22835
 
 element_offset_test/offset: RuntimeError # Issue 17550
 request_animation_frame_test: Skip # Times out, and also passes while taking 4.00 minutes. Issue 19127.
@@ -65,7 +70,6 @@
 
 [ $compiler == none && $runtime == drt && $system == windows ]
 worker_test/functional: Pass, Crash # Issue 9929.
-touchevent_test/supported: Pass, Fail # Issue 17061
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 crypto_test/functional: Pass, Slow # TODO(dart2js-team): Please triage this failure.
@@ -94,18 +98,16 @@
 element_types_test/supported_meter: RuntimeError # Issue 18573
 
 [ $runtime == chrome ]
-touchevent_test/supported: Pass, Fail # Issue 17061
+touchevent_test/supported: Fail # Touch events are only supported on touch devices
 xhr_cross_origin_test: Pass, Fail # Issue 11884
 xhr_test: Pass, Fail # Issue 11884
-element_types_test/constructors: Skip # Times out. Issue 22050
 audiocontext_test/functional: Skip # Renderer crash. Issue 22327
+element_animate_test/omit_timing: Skip # Timing out inexplicably. Temporarily suppressing (alanknight)
+element_animate_test/timing_dict: Skip # Timing out inexplicably. Temporarily suppressing (alanknight)
 
 [$runtime == drt || $runtime == dartium || $runtime == chrome || $runtime == chromeOnAndroid || $runtime == ContentShellOnAndroid ]
 webgl_1_test: Pass, Fail # Issue 8219
 
-[ ($compiler == none || $compiler == dart2dart) ]
-deferred_multi_app_htmltest: Fail # Issue 16603
-
 [ $compiler == none && ($runtime == drt || $runtime == dartium) && $system == windows]
 websql_test: Skip # Issue 4941: stderr contains a backtrace.
 
@@ -113,10 +115,6 @@
 websql_test: Fail, Pass # Issue 4941: stderr contains a backtrace.
 native_gc_test: Pass, Slow
 
-[$runtime == chrome && $compiler == dart2js && $system == macos]
-transition_event_test/functional: Skip # Times out. Issue 
-request_animation_frame_test: Skip # Times out. Issue 
-
 [$runtime == ie10 || $runtime == ie11]
 indexeddb_5_test: Fail # Issue 12893
 js_test: Fail # Issue 14246
@@ -132,6 +130,7 @@
 localstorage_test: Pass, RuntimeError # Issue 22166
 storage_test: Pass, RuntimeError # Issue 22166
 postmessage_structured_test/more_primitives: Fail # Does not support the MessageEvent constructor.
+notification_test/supported_notification: Fail # Notification not supported on IE
 
 [$runtime == ie10 || $runtime == ie11 || ($runtime == chrome && $system == macos)]
 transition_event_test/functional: Skip # Times out. Issue 22167
@@ -163,6 +162,7 @@
 media_stream_test/supported_MediaStreamEvent: Fail
 media_stream_test/supported_MediaStreamTrackEvent: Fail
 media_stream_test/supported_media: Fail
+mediasource_test/supported: Fail
 mutationobserver_test/supported: Fail
 rtc_test/supported: Fail
 shadow_dom_test/supported: Fail
@@ -173,7 +173,7 @@
 svgelement_test/supported_animateTransform: Fail
 svgelement_test/supported_foreignObject: Fail
 svgelement_test/supported_set: Fail
-touchevent_test/supported: Fail
+touchevent_test/supported: Fail # IE does not support TouchEvents
 webgl_1_test/supported: Fail
 websql_test/supported: Fail
 xhr_test/json: Fail # IE10 returns string, not JSON object
@@ -219,6 +219,8 @@
 media_stream_test/supported_MediaStreamEvent: Fail
 media_stream_test/supported_MediaStreamTrackEvent: Fail
 media_stream_test/supported_media: Fail
+mediasource_test/supported: Pass, Fail # Should pass on Windows 8
+mediasource_test/functional: Pass, Fail # Fails on Windows 8
 rtc_test/supported: Fail
 shadow_dom_test/supported: Fail
 speechrecognition_test/supported: Fail
@@ -228,7 +230,7 @@
 svgelement_test/supported_animateTransform: Fail
 svgelement_test/supported_foreignObject: Fail
 svgelement_test/supported_set: Fail
-touchevent_test/supported: Fail
+touchevent_test/supported: Fail # IE does not support TouchEvents
 webgl_1_test/functional: Fail
 websql_test/supported: Fail
 xhr_test/json: Fail # IE10 returns string, not JSON object
@@ -248,6 +250,7 @@
 canvasrenderingcontext2d_test/drawImage_video_element: Fail # Safari does not support drawImage w/ video element
 canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Fail # Safari does not support drawImage w/ video element
 element_test: Pass, Fail # Issue 21434
+mediasource_test: Pass, Fail # MediaSource only available on Safari 8 desktop, we can't express that.
 
 # Safari Feature support statuses-
 # All changes should be accompanied by platform support annotation changes.
@@ -268,6 +271,8 @@
 indexeddb_1_test/supported: Fail
 element_types_test/supported_template: Fail
 xhr_test/json: Fail # Safari doesn't support JSON response type
+notification_test/constructors: Pass # Safari mobile will pass this test on the basis that notifications aren't supported at all.
+notification_test/supported_notification: RuntimeError # Issue 22869
 
 [ $runtime == safari ]
 input_element_test/supported_month: RuntimeError
@@ -275,7 +280,8 @@
 input_element_test/supported_week: RuntimeError
 input_element_test/supported_date: Fail
 input_element_test/supported_datetime-local: Fail
-touchevent_test/supported: Fail
+touchevent_test/supported: Fail # Safari does not support TouchEvents
+notification_test/constructors: Fail # Safari doesn't let us access the fields of the Notification to verify them.
 
 [ $runtime == safari ]
 indexeddb_1_test/functional: Skip # Times out. Issue 21433
@@ -345,6 +351,7 @@
 input_element_test/supported_week: Fail
 media_stream_test/supported_MediaStreamEvent: Fail
 media_stream_test/supported_MediaStreamTrackEvent: Fail
+mediasource_test/supported: Fail # Behind a flag as of FF 36
 shadow_dom_test/supported: Fail
 speechrecognition_test/supported: Fail
 touchevent_test/supported: Fail
@@ -377,8 +384,8 @@
 [ $compiler == dart2js &&  $runtime == chrome]
 svgelement_test/supported_altGlyph: RuntimeError # Issue 22154
 
-[ $runtime == dartium && ($system == macos || $system == windows || $system == linux)]
-# Desktop operation systems do not support touch events on chrome 34 dartium.
+[ ($runtime == dartium) && ($system == macos || $system == windows || $system == linux)]
+# Desktop operating systems do not support touch events on chrome 34 dartium.
 touchevent_test/supported: Fail
 
 [ (($runtime == dartium || $runtime == drt) && $system == macos) || $system == windows ]
@@ -387,9 +394,6 @@
 [ $compiler == none && $runtime == dartium ]
 element_offset_test/offset: Pass, Fail # Issue 13719, 13296
 
-[ $runtime == chrome && $system == macos && $compiler == dart2js]
-element_offset_test/offset: RuntimeError # Issue 22619
-
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 custom/document_register_basic_test: StaticWarning
 custom/element_upgrade_test: StaticWarning
diff --git a/tests/html/mediasource_test.dart b/tests/html/mediasource_test.dart
new file mode 100644
index 0000000..7db8af8
--- /dev/null
+++ b/tests/html/mediasource_test.dart
@@ -0,0 +1,42 @@
+library mediasource_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'dart:html';
+import 'dart:typed_data';
+import 'dart:async';
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  var isMediaSource = predicate((x) => x is MediaSource, 'is a MediaSource');
+
+  group('supported', () {
+    test('supported', () {
+      expect(MediaSource.supported, true);
+    });
+  });
+
+  // TODO(alanknight): Actually exercise this, right now the tests are trivial.
+  group('functional', () {
+    var source;
+    if (MediaSource.supported) {
+      source = new MediaSource();
+    }
+
+    test('constructorTest', () {
+      if (MediaSource.supported) {
+        expect(source, isNotNull);
+        expect(source, isMediaSource);
+      }
+    });
+
+    test('media types', () {
+      if (MediaSource.supported) {
+        expect(MediaSource.isTypeSupported('text/html'), false);
+        expect(MediaSource.isTypeSupported('video/webm;codecs="vp8,vorbis"'),
+            true);
+      }
+    });
+  });
+}
diff --git a/tests/html/notification_test.dart b/tests/html/notification_test.dart
new file mode 100644
index 0000000..077ea54
--- /dev/null
+++ b/tests/html/notification_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library notification_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_individual_config.dart';
+import 'dart:html';
+
+main() {
+  useHtmlIndividualConfiguration();
+
+  group('supported_notification', () {
+    test('supported', () {
+      expect(Notification.supported, true);
+    });
+  });
+
+  group('constructors', () {
+    // Test that we create the notification and that the parameters have
+    // the expected values. Note that these won't actually display, because
+    // we haven't asked for permission, which would have to be done
+    // interactively, so can't run on a bot.
+    test('Notification', () {
+      var expectation = Notification.supported ? returnsNormally : throws;
+      expect(() {
+        var allDefaults = new Notification("Hello world");
+        var allSpecified = new Notification("Deluxe notification",
+            dir: "rtl",
+            body: 'All parameters set',
+            icon: 'icon.png',
+            tag: 'tag',
+            lang: 'en_US');
+        expect(allDefaults is Notification, isTrue);
+        expect(allSpecified is Notification, isTrue);
+        expect(allDefaults.title, "Hello world");
+        expect(allSpecified.title, "Deluxe notification");
+        expect(allSpecified.dir, "rtl");
+        expect(allSpecified.body, "All parameters set");
+        var icon = allSpecified.icon;
+        var tail = Uri.parse(icon).pathSegments.last;
+        expect(tail, "icon.png");
+        expect(allSpecified.tag, "tag");
+        expect(allSpecified.lang, "en_US");
+      }, expectation);
+    });
+  });
+}
diff --git a/tests/language/async_await_test.dart b/tests/language/async_await_test.dart
new file mode 100644
index 0000000..8844777
--- /dev/null
+++ b/tests/language/async_await_test.dart
@@ -0,0 +1,2008 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library async_await_test;
+
+import "package:unittest/unittest.dart";
+import "dart:async";
+
+main() {
+  bool checkedMode = false;
+  assert((checkedMode = true));
+
+  group("basic", () {
+    test("async w/o await", () {
+      f() async { return id(42); }
+      return expect42(f());
+    });
+
+    test("async waits", () {
+      // Calling an "async" function won't do anything immediately.
+      var result = [];
+      f() async {
+        result.add(1);
+        return id(42);
+      };
+      var future = f();
+      result.add(0);
+      return future.whenComplete(() {
+        expect(result, equals([0, 1]));
+      });
+    });
+
+    test("async throws", () {
+      f() async {
+        throw "err";
+        return id(42);
+      }
+      return throwsErr(f());
+    });
+
+    test("await future", () {
+      f() async {
+        var v = await new Future.value(42);
+        return v;
+      };
+      return expect42(f());
+    });
+
+    test("await value", () {
+      f() async {
+        var v = await id(42);
+        return v;
+      };
+      return expect42(f());
+    });
+
+    test("await null", () {
+      f() async {
+        var v = await null;
+        expect(v, equals(null));
+      };
+      return f();
+    });
+
+    test("await await", () {
+      f() async {
+        return await await new Future.value(42);
+      }
+      return expect42(f());
+    });
+
+    test("await fake value future", () {
+      f() async {
+        return await new FakeValueFuture(42);
+      }
+      return expect42(f());
+    });
+
+    test("await fake error future", () {
+      f() async {
+        return await new FakeErrorFuture("err");
+      }
+      return throwsErr(f());
+    });
+
+    test("await value is delayed", () {
+      f() async {
+        bool x = false;
+        scheduleMicrotask(() { x = true; });
+        var y = await true;
+        expect(x, equals(y));
+      }
+      return f();
+    });
+
+    test("await throw", () {
+      f() async {
+        await (throw "err");  // Check grammar: Are parentheses necessary?
+        return id(42);
+      }
+      return throwsErr(f());
+    });
+
+    test("throw before await", () {
+      f() async {
+        var x = throw "err";
+        await x;  // Check grammar: Are parentheses necessary?
+        return id(42);
+      }
+      return throwsErr(f());
+    });
+
+    if (checkedMode) {
+      test("assert before await", () {
+        f(v) async {
+          assert(v == 87);
+          return await new Future.microtask(() => 42);
+        }
+        return f(42).then((_) {
+          fail("assert didn't throw");
+        }, onError: (e, s) {
+          expect(e is AssertionError, isTrue);
+        });
+      });
+
+      test("assert after await", () {
+        f(v) async {
+          var x = await new Future.microtask(() => 42);
+          assert(v == 87);
+          return x;
+        }
+        return f(42).then((_) {
+          fail("assert didn't throw");
+        }, onError: (e, s) {
+          expect(e is AssertionError, isTrue);
+        });
+      });
+    }
+
+    test("async await error", () {
+      f() async {
+        await new Future.error("err");
+        return id(42);
+      }
+      return throwsErr(f());
+    });
+
+    test("async flattens futures", () {
+      f() async {
+        return new Future.value(42);  // Not awaited.
+      };
+      return f().then((v) {
+        expect(v, equals(42));  // And not a Future with value 42.
+      });
+    });
+
+    test("async flattens futures, error", () {
+      f() async {
+        return new Future.error("err");  // Not awaited.
+      };
+      return throwsErr(f());
+    });
+
+    test("await for", () {
+      f(s) async {
+        int i = 0;
+        await for (int v in s) {
+          i += v;
+        }
+        return i;
+      }
+      return f(mkStream()).then((v) {
+        expect(v, equals(45));  // 0 + 1 + ... + 9
+      });
+    });
+
+    test("await for w/ await", () {
+      f(s) async {
+        int i = 0;
+        await for (int v in s) {
+          i += await new Future.value(v);
+        }
+        return i;
+      }
+      return f(mkStream()).then((v) {
+        expect(v, equals(45));  // 0 + 1 + ... + 9
+      });
+    });
+
+    test("await for empty", () {
+      f(s) async {
+        int v = 0;
+        await for (int i in s) {
+          v += i;
+        }
+        return v;
+      }
+      var s = (new StreamController()..close()).stream;
+      return f(s).then((v) {
+        expect(v, equals(0));
+      });
+    });
+
+    if (checkedMode) {
+      test("await for w/ await, asseert", () {
+        f(s) async {
+          int i = 0;
+          await for (int v in s) {
+            i += await new Future.microtask(() => v);
+            assert(v < 8);
+          }
+          return i;
+        }
+        return f(mkStream()).then((v) {
+          fail("assert didn't throw");
+        }, onError: (e, s) {
+          expect(e is AssertionError, isTrue);
+        });
+      });
+    }
+  });
+
+  group("for", () {
+    test("await in for-loop", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i < 10; i++) {
+          v += await new Future.value(42);
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(10 * id(42)));
+      });
+    });
+
+    test("await in for-init", () {
+      f() async {
+        int v = 0;
+        for (int i = await new Future.value(42); i >= 0; i -= 10) {
+          v += 10;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(10 * 5));
+      });
+    });
+
+    test("await in for-test", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i < await new Future.value(42); i += 10) {
+          v += 10;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(10 * 5));
+      });
+    });
+
+    test("await in for-incr", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i < 100; i += await new Future.value(42)) {
+          v += 10;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(10 * 3));
+      });
+    });
+
+    test("await err in for-loop", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i < 10; i++) {
+          v += await new Future.error("err");
+        }
+        return v;
+      }
+      return throwsErr(f());
+    });
+
+    test("await err in for-init", () {
+      f() async {
+        int v = 0;
+        for (int i = await new Future.error("err"); i >= 0; i -= 10) {
+          v += 10;
+        }
+        return v;
+      }
+      return throwsErr(f());
+    });
+
+    test("await err in for-test", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i < await new Future.error("err"); i += 10) {
+          v += 10;
+        }
+        return v;
+      }
+      return throwsErr(f());
+    });
+
+    test("await err in for-incr", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i < 100; i += await new Future.error("err")) {
+          v += 10;
+        }
+        return v;
+      }
+      return throwsErr(f());
+    });
+
+    test("await in empty for-loop", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i > 0; i += 1) {
+          v += await new Future.value(42);
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(0));
+      });
+    });
+
+    test("await in empty for-loop 2", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i > 0; i += await new Future.value(1)) {
+          v += 1;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(0));
+      });
+    });
+
+    test("break before await in for-loop", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i < 10; i += 1) {
+          if (i == 2) break;
+          v += await new Future.value(42);
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 2));
+      });
+    });
+
+    test("break before await in for-loop 2", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i < 10; i += await new Future.value(1)) {
+          if (i == 2) break;
+          v += id(42);
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 2));
+      });
+    });
+
+    test("continue before await", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i < 10; i += 1) {
+          if (i == 2) continue;
+          v += await new Future.value(42);
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 9));
+      });
+    });
+
+    test("continue after await", () {
+      f() async {
+        int v = 0;
+        for (int i = 0; i < 10; i += 1) {
+          var j = await new Future.value(42);
+          if (i == 2) continue;
+          v += j;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 9));
+      });
+    });
+  });
+
+  group("while", () {
+    test("await in while-loop", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        while (i < 10) {
+          v += await new Future.value(42);
+          i++;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(10 * id(42)));
+      });
+    });
+
+    test("await in while-test", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        while (i < await new Future.value(42)) {
+          v += 10;
+          i += 10;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(10 * 5));
+      });
+    });
+
+    test("await err in loop", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        while (i < 10) {
+          v += await new Future.error("err");
+          i++;
+        }
+        return v;
+      }
+      return throwsErr(f());
+    });
+
+    test("await err in test", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        while (i < await new Future.error("err")) {
+          v += 10;
+          i += 10;
+        }
+        return v;
+      }
+      return throwsErr(f());
+    });
+
+    test("break before await", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        while (i < 10) {
+          if (i == 2) break;
+          v += await new Future.value(42);
+          i += 1;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 2));
+      });
+    });
+
+    test("break after await", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        while (i < 10) {
+          v += await new Future.value(42);
+          if (i == 2) break;
+          i += 1;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 3));
+      });
+    });
+
+    test("continue before await", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        while (i < 10) {
+          i += 1;
+          if (i == 2) continue;
+          v += await new Future.value(42);
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 9));
+      });
+    });
+
+    test("continue after await", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        while (i < 10) {
+          i += 1;
+          int j = await new Future.value(42);
+          if (i == 2) continue;
+          v += j;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 9));
+      });
+    });
+  });
+
+  group("do-while", () {
+    test("await in loop", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        do {
+          v += await new Future.value(42);
+          i++;
+        } while (i < 10);
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(10 * id(42)));
+      });
+    });
+
+    test("await in test", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        do {
+          v += 10;
+          i += 10;
+        } while (i < await new Future.value(42));
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(10 * 5));
+      });
+    });
+
+    test("await err in loop", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        do {
+          v += await new Future.error("err");
+          i++;
+        } while (i < 10);
+        return v;
+      }
+      return f().then((v) { fail("didn't throw"); },
+                      onError: (e) { expect(e, equals("err")); });
+    });
+
+    test("await err in test", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        do {
+          v += 10;
+          i += 10;
+        } while (i < await new Future.error("err"));
+        return v;
+      }
+      return f().then((v) { fail("didn't throw"); },
+                      onError: (e) { expect(e, equals("err")); });
+    });
+
+    test("break before await", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        do {
+          if (i == 2) break;
+          v += await new Future.value(42);
+          i += 1;
+        } while (i < 10);
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 2));
+      });
+    });
+
+    test("break after await", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        do {
+          v += await new Future.value(42);
+          if (i == 2) break;
+          i += 1;
+        } while (i < 10);
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 3));
+      });
+    });
+
+    test("continue before await", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        do {
+          i += 1;
+          if (i == 2) continue;
+          v += await new Future.value(42);
+        } while (i < 10);
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 9));
+      });
+    });
+
+    test("continue after await", () {
+      f() async {
+        int v = 0;
+        int i = 0;
+        do {
+          i += 1;
+          int j = await new Future.value(42);
+          if (i == 2) continue;
+          v += j;
+        } while (i < 10);
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(42 * 9));
+      });
+    });
+  });
+
+  group("for-in", () {
+    test("await in for-in", () {
+      f() async {
+        var v = 0;
+        for (var fut in [1, 2, 3].map((v) => new Future.value(v))) {
+          v += await fut;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(6));
+      });
+    });
+
+    test("await in for-in iterable", () {
+      f() async {
+        var v = 0;
+        for (var i in await new Future.value([1, 2, 3])) {
+          v += i;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(6));
+      });
+    });
+
+    test("await err in for-in", () {
+      f() async {
+        var v = 0;
+        for (var fut in [1, 2, 3].map((v) => (v != 1)
+                                             ? new Future.value(v)
+                                             : new Future.error("err"))) {
+          v += await fut;
+        }
+        return v;
+      }
+      return f().then((v) { fail("didn't throw"); },
+                      onError: (e) { expect(e, equals("err")); });
+    });
+
+    test("await err in for-in iterable", () {
+      f() async {
+        var v = 0;
+        for (var i in await new Future.error("err")) {
+          v += i;
+        }
+        return v;
+      }
+      return f().then((v) { fail("didn't throw"); },
+                      onError: (e) { expect(e, equals("err")); });
+    });
+
+    test("break before await in for-in", () {
+      f() async {
+        var v = 0;
+        for (var fut in [1, 2, 3].map((v) => new Future.value(v))) {
+          if (v == 3) break;
+          v += await fut;
+        }
+        return v;
+      }
+      return f().then((v) {
+        expect(v, equals(3));
+      });
+    });
+  });
+
+  group("try-catch", () {
+    test("try-no-catch", () {
+      f() async {
+        try {
+          return await id(42);
+        } catch(e) {
+          return 37;
+        }
+      }
+      return expect42(f());
+    });
+
+    test("await in body", () {
+      f() async {
+        try {
+          await new Future.error(42);
+        } catch(e) {
+          return e;
+        }
+      }
+      return expect42(f());
+    });
+
+    test("throw before await in body", () {
+      int i = id(0);
+      f() async {
+        try {
+          if (i >= 0) throw id(42);
+          return await new Future.value(10);
+        } catch(e) {
+          return e;
+        }
+      }
+      return expect42(f());
+    });
+
+    test("try-catch await in catch", () {
+      f() async {
+        try {
+          throw id(42);
+        } catch(e) {
+          return await new Future.value(e);
+        }
+      }
+      return expect42(f());
+    });
+
+    test("try-catch await error in catch", () {
+      f() async {
+        try {
+          throw id(42);
+        } catch(e) {
+          await new Future.error("err");
+        }
+      }
+      return f().then((v) { fail("didn't throw"); },
+                      onError: (e) { expect(e, equals("err")); });
+    });
+
+    test("try-catch-rethrow", () {
+      f() async {
+        try {
+          await new Future.error("err");
+        } catch(e) {
+          if (e == id(42)) return;
+          rethrow;
+        }
+      }
+      return f().then((v) { fail("didn't throw"); },
+                      onError: (e) { expect(e, equals("err")); });
+    });
+  });
+
+  group("try-finally", () {
+    test("await in body", () {
+      f() async {
+        try {
+          return await new Future.value(42);
+        } finally {
+          // Don't do anything.
+        }
+      }
+      return expect42(f());
+    });
+
+    test("await in finally", () {
+      var x = 0;
+      f() async {
+        try {
+          return id(42);
+        } finally {
+          x = await new Future.value(37);
+        }
+      }
+      return f().then((v) {
+        expect(v, equals(42));
+        expect(x, equals(37));
+      });
+    });
+
+    test("await err in body", () {
+      f() async {
+        try {
+          return await new Future.error("err");
+        } finally {
+          // Don't do anything.
+        }
+      }
+      return f().then((v) { fail("didn't throw"); },
+                      onError: (e) { expect(e, equals("err")); });
+    });
+
+    test("await err in finally", () {
+      f() async {
+        try {
+          return id(42);
+        } finally {
+          await new Future.error("err");
+        }
+      }
+      return f().then((v) { fail("didn't throw"); },
+                      onError: (e) { expect(e, equals("err")); });
+    });
+
+    test("await err in both", () {
+      f() async {
+        try {
+          await new Future.error("not err");
+        } finally {
+          await new Future.error("err");
+        }
+      }
+      return f().then((v) { fail("didn't throw"); },
+                      onError: (e) { expect(e, equals("err")); });
+    });
+
+    test("await err in body, override in finally", () {
+      f() async {
+        try {
+          return await new Future.error("err");
+        } finally {
+          return id(42);
+        }
+      }
+      return expect42(f());
+    });
+
+    test("await in body, override in finally", () {
+      f() async {
+        label: try {
+          return await new Future.value(37);
+        } finally {
+          break label;
+        }
+        return id(42);
+      }
+      return expect42(f());
+    });
+
+    test("await, override in finally", () {
+      var x = 0;
+      f() async {
+        label: try {
+          return 87;
+        } finally {
+          x = await new Future.value(37);
+          break label;
+        }
+        return id(42);
+      }
+      return f().then((v) {
+        expect(v, equals(42));
+        expect(x, equals(37));
+      });
+    });
+
+    test("throw in body, await, override in finally 3", () {
+      var x = 0;
+      f() async {
+        label: try {
+          throw "err";
+        } finally {
+          x = await new Future.value(37);
+          break label;
+        }
+        return id(42);
+      }
+      return f().then((v) {
+        expect(v, equals(42));
+        expect(x, equals(37));
+      });
+    });
+
+    test("await err in body, override in finally 2", () {
+      f() async {
+        label: try {
+          return await new Future.error("err");
+        } finally {
+          break label;
+        }
+        return id(42);
+      }
+      return expect42(f());
+    });
+
+    test("await in body, no-exit in finally", () {
+      f() async {
+        for (int i = 0; i < 10; i++) {
+          try {
+            return await i;
+          } finally {
+            continue;
+          }
+        }
+        return id(42);
+      }
+      return expect42(f());
+    });
+
+    test("no-exit after await in finally", () {
+      f() async {
+        int i = 0;
+        for (; i < 10; i++) {
+          try {
+            break;
+          } finally {
+            await new Future.value(42);
+            continue;
+          }
+        }
+        return id(i);
+      }
+      return f().then((v) {
+        expect(v, equals(10));
+      });
+    });
+
+    test("exit after continue, await in finally", () {
+      f() async {
+        int i = 0;
+        for (; i < 10; i++) {
+          try {
+            continue;
+          } finally {
+            await new Future.value(42);
+            break;
+          }
+        }
+        return id(i);
+      }
+      return f().then((v) {
+        expect(v, equals(0));
+      });
+    });
+
+    test("no-exit before await in finally 2", () {
+      f() async {
+        for (int i = 0; i < 10; i++) {
+          try {
+            return i;
+          } finally {
+            if (i >= 0) continue;
+            await new Future.value(42);
+          }
+        }
+        return id(42);
+      }
+      return expect42(f());
+    });
+
+    test("no-exit after await in finally", () {
+      f() async {
+        for (int i = 0; i < 10; i++) {
+          try {
+            return i;
+          } finally {
+            await new Future.value(42);
+            continue;
+          }
+        }
+        return id(42);
+      }
+      return expect42(f());
+    });
+
+    test("nested finallies", () {
+      var x = 0;
+      f() async {
+        try {
+          try {
+            return 42;
+          } finally {
+            x = await new Future.value(37);
+          }
+        } finally {
+          x += await new Future.value(37);
+        }
+      }
+      return f().then((v) {
+        expect(v, equals(42));
+        expect(x, equals(74));
+      });
+    });
+
+    test("nested finallies 2", () {
+      var x = 0;
+      f() async {
+        label: try {
+          try {
+            break label;
+          } finally {
+            x = await new Future.value(37);
+          }
+        } finally {
+          x += await new Future.value(37);
+        }
+        return 42;
+      }
+      return f().then((v) {
+        expect(v, equals(42));
+        expect(x, equals(74));
+      });
+    });
+
+    test("nested finallies 3", () {
+      var x = 0;
+      f() async {
+        label: try {
+          try {
+            break label;
+          } finally {
+            return await new Future.value(42);
+          }
+        } finally {
+          break label;
+        }
+        return 42;
+      }
+      return expect42(f());
+    });
+
+    test("nested finallies, throw", () {
+      var x = 0;
+      f() async {
+        try {
+          try {
+            throw "err";
+          } finally {
+            x = await new Future.value(37);
+          }
+        } finally {
+          x += await new Future.value(37);
+        }
+      }
+      return f().then((v) { fail("didn't throw"); },
+                      onError: (e) {
+                        expect(e, equals("err"));
+                        expect(x, equals(2 * 37));
+                      });
+    });
+  });
+
+  group("try-catch-finally", () {
+    test("await in body", () {
+      f() async {
+        try {
+          return await new Future.value(42);
+        } catch (e) {
+          throw null;
+        } finally {
+          if (id(42) == id(10)) return 10;
+        }
+      }
+      return expect42(f());
+    });
+
+    test("await in catch, not hit", () {
+      f() async {
+        try {
+          return id(42);
+        } catch (e) {
+          await new Future.error("err");
+        } finally {
+          if (id(42) == id(10)) return 10;
+        }
+      }
+      return expect42(f());
+    });
+
+    test("await in catch, hit", () {
+      f() async {
+        try {
+          return throw id(42);
+        } catch (e) {
+          return await new Future.value(e);
+        } finally {
+          if (id(42) == id(10)) return 10;
+        }
+      }
+      return expect42(f());
+    });
+
+    test("await in finally", () {
+      var x = 0;
+      f() async {
+        try {
+          return id(42);
+        } catch (e) {
+          throw null;
+        } finally {
+          x = await new Future.value(37);
+          if (id(42) == id(10)) return 10;
+        }
+      }
+      return f().then((v) {
+        expect(v, equals(42));
+        expect(x, equals(37));
+      });
+    });
+  });
+
+  group("switch", () {
+    test("await in expression", () {
+      f(v) async {
+        switch (await new Future.value(v)) {
+          case 1: return 1;
+          case 2: return 42;
+          default: return 3;
+        }
+        return null;
+      }
+      return expect42(f(2));
+    });
+
+    test("await err in expression", () {
+      f(v) async {
+        switch (await new Future.error("err")) {
+          case 1: return 1;
+          case 2: return 42;
+          default: return 3;
+        }
+        return null;
+      }
+      return throwsErr(f(2));
+    });
+
+    test("await in case", () {
+      f(v) async {
+        switch (v) {
+          case 1: return 1;
+          case 2: return await new Future.value(42);
+          default: return 3;
+        }
+        return null;
+      }
+      return expect42(f(2));
+    });
+
+    test("await err in case", () {
+      f(v) async {
+        switch (v) {
+          case 1: return 1;
+          case 2: return await new Future.error("err");
+          default: return 3;
+        }
+        return null;
+      }
+      return throwsErr(f(2));
+    });
+
+    test("continue before await in case", () {
+      f(v) async {
+        switch (v) {
+          label:
+          case 1: return 42;
+          case 2:
+            if (v <= 2) continue label;
+            return await new Future.value(10);
+          default: return 3;
+        }
+        return null;
+      }
+      return expect42(f(2));
+    });
+
+    test("continue after await in case", () {
+      f(v) async {
+        switch (v) {
+          label:
+          case 1: return 42;
+          case 2:
+            await new Future.value(10);
+            continue label;
+          default: return 3;
+        }
+        return null;
+      }
+      return expect42(f(2));
+    });
+  });
+
+  group("if", () {
+    test("await in test", () {
+      f(v) async {
+        if (await new Future.value(v)) {
+          return 42;
+        } else {
+          return 37;
+        }
+      }
+      return expect42(f(true));
+    });
+
+    test("await err in test", () {
+      f(v) async {
+        if (await new Future.error("err")) {
+          return 42;
+        } else {
+          return 37;
+        }
+      }
+      return throwsErr(f(true));
+    });
+
+    test("await in then", () {
+      f(v) async {
+        if (v) {
+          return await new Future.value(42);
+        }
+        return 37;
+      }
+      return expect42(f(true));
+    });
+
+    test("await err in then", () {
+      f(v) async {
+        if (v) {
+          return await new Future.error("err");
+        }
+        return 37;
+      }
+      return throwsErr(f(true));
+    });
+
+    test("await in then with else", () {
+      f(v) async {
+        if (v) {
+          return await new Future.value(42);
+        } else {
+          return 87;
+        }
+        return 37;
+      }
+      return expect42(f(true));
+    });
+
+    test("await err in then with else", () {
+      f(v) async {
+        if (v) {
+          return await new Future.error("err");
+        } else {
+          return 87;
+        }
+        return 37;
+      }
+      return throwsErr(f(true));
+    });
+
+    test("await in else", () {
+      f(v) async {
+        if (v) {
+          return 37;
+        } else {
+          return await new Future.value(42);
+        }
+        return 87;
+      }
+      return expect42(f(false));
+    });
+
+    test("await err in else", () {
+      f(v) async {
+        if (v) {
+          return 37;
+        } else {
+          return await new Future.error("err");
+        }
+        return 87;
+      }
+      return throwsErr(f(false));
+    });
+
+    test("await in else-if test", () {
+      f(v) async {
+        if (v) {
+          return 37;
+        } else if (!await new Future.value(v)) {
+          return 42;
+        } else {
+          return 37;
+        }
+        return 87;
+      }
+      return expect42(f(false));
+    });
+
+    test("await in else-if then", () {
+      f(v) async {
+        if (v) {
+          return 37;
+        } else if (!v) {
+          return await new Future.value(42);
+        } else {
+          return 37;
+        }
+        return 87;
+      }
+      return expect42(f(false));
+    });
+  });
+
+  group("conditional operator", () {
+    test("await in test", () {
+      f(v) async {
+        return (await new Future.value(v)) ? 42 : 37;
+      }
+      return expect42(f(true));
+    });
+
+    test("await err in test", () {
+      f(v) async {
+        return (await new Future.error("err")) ? 42 : 37;
+      }
+      return throwsErr(f(true));
+    });
+
+    test("await in then", () {
+      f(v) async {
+        return v ? (await new Future.value(42)) : 37;
+      }
+      return expect42(f(true));
+    });
+
+    test("await err in then", () {
+      f(v) async {
+        return v ? (await new Future.error("err")) : 37;
+      }
+      return throwsErr(f(true));
+    });
+
+    test("await in else", () {
+      f(v) async {
+        return v ? 37 : (await new Future.value(42));
+      }
+      return expect42(f(false));
+    });
+
+    test("await err in else", () {
+      f(v) async {
+        return v ? 37 : (await new Future.error("err"));
+      }
+      return throwsErr(f(false));
+    });
+  });
+
+  group("async declarations", () {
+    var f42 = new Future.value(42);
+
+    // Top-level declarations or local declarations in top-level functions.
+    test("topMethod", () {
+      return expect42(topMethod(f42));
+    });
+
+    test("topArrowMethod", () {
+      return expect42(topArrowMethod(f42));
+    });
+
+    test("topGetter", () {
+      return expect42(topGetter);
+    });
+
+    test("topArrowGetter", () {
+      return expect42(topArrowGetter);
+    });
+
+    test("topLocal", () {
+      return expect42(topLocal(f42));
+    });
+
+    test("topArrowLocal", () {
+      return expect42(topArrowLocal(f42));
+    });
+
+    test("topExpression", () {
+      return expect42(topExpression(f42));
+    });
+
+    test("topArrowExpression", () {
+      return expect42(topArrowExpression(f42));
+    });
+
+    test("topVarExpression", () {
+      return expect42(topVarExpression(f42));
+    });
+
+    test("topVarArrowExpression", () {
+      return expect42(topVarArrowExpression(f42));
+    });
+
+    // Static declarations or local declarations in static functions.
+    test("staticMethod", () {
+      return expect42(Async.staticMethod(f42));
+    });
+
+    test("staticArrowMethod", () {
+      return expect42(Async.staticArrowMethod(f42));
+    });
+
+    test("staticGetter", () {
+      return expect42(Async.staticGetter);
+    });
+
+    test("staticArrowGetter", () {
+      return expect42(Async.staticArrowGetter);
+    });
+
+    test("staticLocal", () {
+      return expect42(Async.staticLocal(f42));
+    });
+
+    test("staticArrowLocal", () {
+      return expect42(Async.staticArrowLocal(f42));
+    });
+
+    test("staticExpression", () {
+      return expect42(Async.staticExpression(f42));
+    });
+
+    test("staticArrowExpression", () {
+      return expect42(Async.staticArrowExpression(f42));
+    });
+
+    test("staticVarExpression", () {
+      return expect42(Async.staticVarExpression(f42));
+    });
+
+    test("staticVarArrowExpression", () {
+      return expect42(Async.staticVarArrowExpression(f42));
+    });
+
+    // Instance declarations or local declarations in instance functions.
+    var async = new Async();
+
+    test("instanceMethod", () {
+      return expect42(async.instanceMethod(f42));
+    });
+
+    test("instanceArrowMethod", () {
+      return expect42(async.instanceArrowMethod(f42));
+    });
+
+    test("instanceGetter", () {
+      return expect42(async.instanceGetter);
+    });
+
+    test("instanceArrowGetter", () {
+      return expect42(async.instanceArrowGetter);
+    });
+
+    test("instanceLocal", () {
+      return expect42(async.instanceLocal(f42));
+    });
+
+    test("instanceArrowLocal", () {
+      return expect42(async.instanceArrowLocal(f42));
+    });
+
+    test("instanceExpression", () {
+      return expect42(async.instanceExpression(f42));
+    });
+
+    test("instanceArrowExpression", () {
+      return expect42(async.instanceArrowExpression(f42));
+    });
+
+    test("instanceVarExpression", () {
+      return expect42(async.instanceVarExpression(f42));
+    });
+
+    test("instanceVarArrowExpression", () {
+      return expect42(async.instanceVarArrowExpression(f42));
+    });
+
+    // Local functions in constructor initializer list.
+    test("initializerExpression", () {
+      var async = new Async.initializer(f42);
+      return expect42(async.initValue);
+    });
+
+    test("initializerArrowExpression", () {
+      var async = new Async.initializerArrow(f42);
+      return expect42(async.initValue);
+    });
+
+    test("async in async", () {
+      return expect42(asyncInAsync(f42));
+    });
+
+    test("sync in async", () {
+      return expect42(syncInAsync(f42));
+    });
+
+    test("async in sync", () {
+      return expect42(asyncInSync(f42));
+    });
+
+    // Equality and identity.
+    test("Identical and equals", () {
+      expect(async.instanceMethod, equals(async.instanceMethod));
+      expect(Async.staticMethod, same(Async.staticMethod));
+      expect(topMethod, same(topMethod));
+    });
+  });
+
+  group("await expression", () {
+    const c42 = 42;
+    final v42 = 42;
+
+    test("local variable", () {
+      var l42 = 42;
+      f() async {
+        return await l42;
+      }
+      return expect42(f());
+    });
+
+    test("parameter", () {
+      f(p) async {
+        return await p;
+      }
+      return expect42(f(42));
+    });
+
+    test("final local variable", () {
+      f() async {
+        return await v42;
+      }
+      return expect42(f());
+    });
+
+    test("const local variable", () {
+      f() async {
+        return await c42;
+      }
+      return expect42(f());
+    });
+
+    test("unary prefix operator", () {
+      f() async {
+        return -await -42;
+      }
+      return expect42(f());
+    });
+
+    test("suffix operator", () {
+      f() async {
+        var v = [42];
+        return await v[0];
+      }
+      return expect42(f());
+    });
+
+    test("unary postfix operator", () {
+      f() async {
+        var x = 42;
+        return await x++;
+      }
+      return expect42(f());
+    });
+
+    test("suffix operator + increment", () {
+      f() async {
+        var v = [42];
+        return await v[0]++;
+      }
+      return expect42(f());
+    });
+
+    test("suffix operator + increment 2", () {
+      f() async {
+        var v = [42];
+        return await v[await 0]++;
+      }
+      return expect42(f());
+    });
+
+    test("unary pre-increment operator", () {
+      f() async {
+        var x = 41;
+        return await ++x;
+      }
+      return expect42(f());
+    });
+
+    test("suffix operator + pre-increment", () {
+      f() async {
+        var v = [41];
+        return await ++v[0];
+      }
+      return expect42(f());
+    });
+
+    test("assignment operator", () {
+      f() async {
+        var x = 37;
+        return await (x = 42);
+      }
+      return expect42(f());
+    });
+
+    test("assignment-op operator", () {
+      f() async {
+        var x = 37;
+        return await (x += 5);
+      }
+      return expect42(f());
+    });
+
+    test("binary operator", () {
+      f() async {
+        return await (10 + 11) + await (10 + 11);
+      }
+      return expect42(f());
+    });
+
+    test("ternary operator", () {
+      f(v) async {
+        return await ((v == 10) ? new Future.value(42) : 37);
+      }
+      return expect42(f(10));
+    });
+
+    test("top-level function call", () {
+      f() async {
+        return await topMethod(42);
+      }
+      return expect42(f());
+    });
+
+    test("static function call", () {
+      f() async {
+        return await Async.staticMethod(42);
+      }
+      return expect42(f());
+    });
+
+    test("instance function call", () {
+      f() async {
+        var a = new Async();
+        return await a.instanceMethod(42);
+      }
+      return expect42(f());
+    });
+
+    test("top-level function call w/ await", () {
+      f() async {
+        return await topMethod(await 42);
+      }
+      return expect42(f());
+    });
+
+    test("static function call w/ await", () {
+      f() async {
+        return await Async.staticMethod(await 42);
+      }
+      return expect42(f());
+    });
+
+    test("instance function call w/ await", () {
+      f() async {
+        var a = new Async();
+        return await a.instanceMethod(await 42);
+      }
+      return expect42(f());
+    });
+
+    test("top-level getter call", () {
+      f() async {
+        return await topGetter;
+      }
+      return expect42(f());
+    });
+
+    test("static getter call", () {
+      f() async {
+        return await Async.staticGetter;
+      }
+      return expect42(f());
+    });
+
+    test("top-level getter call", () {
+      f() async {
+        var a = new Async();
+        return await a.instanceGetter;
+      }
+      return expect42(f());
+    });
+
+    if (!checkedMode) return;
+
+    test("inside assert, true", () {                       /// 03: ok
+      f() async {                                          /// 03: continued
+        assert(await new Future.microtask(() => true));    /// 03: continued
+        return 42;                                         /// 03: continued
+      }                                                    /// 03: continued
+      return expect42(f());                                /// 03: continued
+    });                                                    /// 03: continued
+
+    test("inside assert, false", () {                      /// 03: continued
+      f() async {                                          /// 03: continued
+        assert(await new Future.microtask(() => false));   /// 03: continued
+        return 42;                                         /// 03: continued
+      }                                                    /// 03: continued
+      return f().then((_) {                                /// 03: continued
+        fail("assert didn't throw");                       /// 03: continued
+      }, onError: (e, s) {                                 /// 03: continued
+        expect(e is AssertionError, isTrue);               /// 03: continued
+      });                                                  /// 03: continued
+    });                                                    /// 03: continued
+
+    test("inside assert, function -> false", () {          /// 03: continued
+      f() async {                                          /// 03: continued
+        assert(await new Future.microtask(() => false));   /// 03: continued
+        return 42;                                         /// 03: continued
+      }                                                    /// 03: continued
+      return f().then((_) {                                /// 03: continued
+        fail("assert didn't throw");                       /// 03: continued
+      }, onError: (e, s) {                                 /// 03: continued
+        expect(e is AssertionError, isTrue);               /// 03: continued
+      });                                                  /// 03: continued
+    });                                                    /// 03: continued
+
+  });
+
+  group("syntax", () {
+    test("async as variable", () {
+      // Valid identifiers outside of async function.
+      var async = 42;
+      expect(async, equals(42));
+    });
+
+    test("await as variable", () {                         /// 02: ok
+      // Valid identifiers outside of async function.      /// 02: continued
+      var await = 42;                                      /// 02: continued
+      expect(await, equals(42));                           /// 02: continued
+    });                                                    /// 02: continued
+
+    test("yield as variable", () {
+      // Valid identifiers outside of async function.
+      var yield = 42;
+      expect(yield, equals(42));
+    });
+  });
+}
+
+
+// Attempt to obfuscates value to avoid too much constant folding.
+id(v) {
+  try {
+    if (v != null) throw v;
+  } catch (e) {
+    return e;
+  }
+  return null;
+}
+
+// Create a stream for testing "async for-in".
+Stream mkStream() {
+  var c;
+  int i = 0;
+  next() {
+    c.add(i++);
+    if (i == 10) {
+      c.close();
+    } else {
+      scheduleMicrotask(next);
+    }
+  }
+  c = new StreamController(onListen: () {
+    scheduleMicrotask(next);
+  });
+  return c.stream;
+}
+
+// Check that future contains the error "err".
+Future throwsErr(Future future) {
+  return future.then((v) { fail("didn't throw"); },
+                onError: (e) { expect(e, equals("err")); });
+}
+
+// Check that future contains the value 42.
+Future expect42(Future future) {
+  return future.then((v) {
+    expect(v, equals(42));
+  });
+}
+
+
+// Various async declarations.
+
+Future topMethod(f) async { return await f; }
+
+Future topArrowMethod(f) async => await f;
+
+Future get topGetter async {
+  return await new Future.value(42);
+}
+
+Future get topArrowGetter async => await new Future.value(42);
+
+Future topLocal(f) {
+  local() async { return await f; }
+  return local();
+}
+
+Future topArrowLocal(f) {
+  local() async => await f;
+  return local();
+}
+
+Future topExpression(f) {
+  return () async { return await f; } ();
+}
+
+Future topArrowExpression(f) {
+  return (() async => await f) ();
+}
+
+var topVarExpression = (f) async { return await f; };
+
+var topVarArrowExpression = (f) async => await f;
+
+class Async {
+  var initValue;
+  Async();
+
+  Async.initializer(f) : initValue = (() async { return await f; } ());
+
+  Async.initializerArrow(f) : initValue = ((() async => await f) ());
+
+  /* static */
+  static Future staticMethod(f) async { return await f; }
+
+  static Future staticArrowMethod(f) async => await f;
+
+  static Future get staticGetter async {
+    return await new Future.value(42);
+  }
+
+  static Future get staticArrowGetter async => await new Future.value(42);
+
+  static Future staticLocal(f) {
+    local() async { return await f; }
+    return local();
+  }
+
+  static Future staticArrowLocal(f) {
+    local() async => await f;
+    return local();
+  }
+
+  static Future staticExpression(f) {
+    return () async { return await f; } ();
+  }
+
+  static Future staticArrowExpression(f) {
+    return (() async => await f) ();
+  }
+
+  static var staticVarExpression = (f) async { return await f; };
+
+  static var staticVarArrowExpression = (f) async => await f;
+
+  /* instance */
+  Future instanceMethod(f) async { return await f; }
+
+  Future instanceArrowMethod(f) async => await f;
+
+  Future get instanceGetter async {
+    return await new Future.value(42);
+  }
+
+  Future get instanceArrowGetter async => await new Future.value(42);
+
+  Future instanceLocal(f) {
+    local() async { return await f; }
+    return local();
+  }
+
+  Future instanceArrowLocal(f) {
+    local() async => await f;
+    return local();
+  }
+
+  Future instanceExpression(f) {
+    return () async { return await f; } ();
+  }
+
+  Future instanceArrowExpression(f) {
+    return (() async => await f) ();
+  }
+
+  var instanceVarExpression = (f) async { return await f; };
+
+  var instanceVarArrowExpression = (f) async => await f;
+}
+
+Future asyncInAsync(f) async {
+  inner(f) async {
+    return await f;
+  }
+  return await inner(f);
+}
+
+Future asyncInSync(f) {
+  inner(f) async {
+    return await f;
+  }
+  return inner(f);
+}
+
+Future syncInAsync(f) async {
+  inner(f) {
+    return f;
+  }
+  return await inner(f);
+}
+
+/**
+ * A non-standard implementation of Future with a value.
+ */
+class FakeValueFuture implements Future {
+  final _value;
+  FakeValueFuture(this._value);
+  Future then(callback(value), {Function onError}) {
+    return new Future.microtask(() => callback(_value));
+  }
+  Future whenComplete(callback()) {
+    return new Future.microtask(() { callback(); });
+  }
+  Future catchError(Function onError, {bool test(error)}) => this;
+  Stream asStream() => (new StreamController()..add(_value)..close()).stream;
+  Future timeout(Duration duration, {onTimeout}) => this;
+}
+
+typedef BinaryFunction(a, b);
+
+/**
+ * A non-standard implementation of Future with an error.
+ */
+class FakeErrorFuture implements Future {
+  final _error;
+  FakeErrorFuture(this._error);
+  Future then(callback(value), {Function onError}) {
+    if (onError != null) {
+      if (onError is BinaryFunction) {
+        return new Future.microtask(() => onError(_error, null));
+      }
+      return new Future.microtask(() => onError(_error));
+    }
+    return this;
+  }
+  Future whenComplete(callback()) {
+    return new Future.microtask(() { callback(); }).then((_) => this);
+  }
+  Future catchError(Function onError, {bool test(error)}) {
+    return new Future.microtask(() {
+      if (test != null && !test(_error)) return this;
+      if (onError is BinaryFunction) {
+        return onError(_error, null);
+      }
+      return onError(_error);
+    });
+  }
+  Stream asStream() =>
+      (new StreamController()..addError(_error)..close()).stream;
+  Future timeout(Duration duration, {onTimeout}) => this;
+}
diff --git a/tests/language/async_or_generator_return_type_stacktrace_test.dart b/tests/language/async_or_generator_return_type_stacktrace_test.dart
new file mode 100644
index 0000000..1fa3d93
--- /dev/null
+++ b/tests/language/async_or_generator_return_type_stacktrace_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+void badReturnTypeAsync() async {}  /// 01: static type warning
+void badReturnTypeAsyncStar() async* {}  /// 02: static type warning
+void badReturnTypeSyncStar() sync* {}  /// 03: static type warning
+
+main() {
+  try {
+    badReturnTypeAsync();  /// 01: continued
+  } catch(e, st) {
+    Expect.isTrue(e is TypeError, "wrong exception type");
+    Expect.isTrue(st.toString().contains("badReturnTypeAsync"),
+                  "missing frame");
+  }
+
+  try {
+    badReturnTypeAsyncStar();  /// 02: continued
+  } catch(e, st) {
+    Expect.isTrue(e is TypeError, "wrong exception type");
+    Expect.isTrue(st.toString().contains("badReturnTypeAsyncStar"),
+                  "missing frame");
+  }
+
+  try {
+    badReturnTypeSyncStar();  /// 03: continued
+  } catch(e, st) {
+    Expect.isTrue(e is TypeError, "wrong exception type");
+    Expect.isTrue(st.toString().contains("badReturnTypeSyncStar"),
+                  "missing frame");
+  }
+}
\ No newline at end of file
diff --git a/tests/language/async_star_cancel_and_throw_in_finally_test.dart b/tests/language/async_star_cancel_and_throw_in_finally_test.dart
new file mode 100644
index 0000000..1ca90f0
--- /dev/null
+++ b/tests/language/async_star_cancel_and_throw_in_finally_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import"dart:async";
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+// When an exception is thrown in the finally block cleaning up after a cancel,
+// the future returned from cancel should complete with an error.
+
+foo() async* {
+  try {
+    int i = 0;
+    while(true) {
+      yield i++;
+    }
+  } finally {
+    throw "Error";
+  }
+}
+
+test() async {
+  var completer = new Completer();
+  var s;
+  s = foo().listen((e) async {
+    Expect.equals(0, e);
+    try {
+      await s.cancel();
+      Expect.fail("Did not throw");
+    } catch(e) {
+      Expect.equals("Error", e);
+      completer.complete();
+    }
+  });
+  await completer.future;
+}
+
+main() {
+  asyncStart();
+  test().then((_) => asyncEnd());
+}
diff --git a/tests/language/async_star_test.dart b/tests/language/async_star_test.dart
new file mode 100644
index 0000000..94a7523
--- /dev/null
+++ b/tests/language/async_star_test.dart
@@ -0,0 +1,922 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library async_start_test;
+
+import "package:unittest/unittest.dart";
+import "dart:async";
+
+main() {
+  group("basic", () {
+    test("empty", () {
+      f() async* {}
+      return f().toList().then((v) {
+        expect(v, equals([]));
+      });
+    });
+
+    test("single", () {
+      f() async* { yield 42; }
+      return f().toList().then((v) {
+        expect(v, equals([42]));
+      });
+    });
+
+    test("call delays", () {
+      var list = [];
+      f() async* { list.add(1); yield 2; }
+      var res = f().forEach(list.add);
+      list.add(0);
+      return res.whenComplete(() {
+        expect(list, equals([0, 1, 2]));
+      });
+    });
+
+    test("throws", () {
+      f() async* { yield 1; throw 2; }
+      var completer = new Completer();
+      var list = [];
+      f().listen(list.add,
+                 onError: (v) => list.add("$v"),
+                 onDone: completer.complete);
+      return completer.future.whenComplete(() {
+        expect(list, equals([1, "2"]));
+      });
+    });
+
+    test("multiple", () {
+      f() async* {
+        for (int i = 0; i < 10; i++) {
+          yield i;
+        }
+      }
+      return expectList(f(), new List.generate(10, id));
+    });
+
+    test("allows await", () {
+      f() async* {
+        var x = await new Future.value(42);
+        yield x;
+        x = await new Future.value(42);
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("allows await in loop", () {
+      f() async* {
+        for (int i = 0; i < 10; i++) {
+          yield await i;
+        }
+      }
+      return expectList(f(), new List.generate(10, id));
+    });
+
+    test("allows yield*", () {
+      f() async* {
+        yield* new Stream.fromIterable([1, 2, 3]);
+      }
+      return expectList(f(), [1, 2, 3]);
+    });
+
+    test("allows yield* of async*", () {
+      f(n) async* {
+        yield n;
+        if (n == 0) return;
+        yield* f(n - 1);
+        yield n;
+      }
+      return expectList(f(3), [3, 2, 1, 0, 1, 2, 3]);
+    });
+
+    test("Cannot yield* non-stream", () {
+      f(s) async* {
+        yield* s;
+      }
+      return f(42).transform(getErrors).single.then((v) {
+        // Not implementing Stream.
+        expect(v is Error, isTrue);
+      });
+    });
+
+   test("Cannot yield* non-stream", () {
+      f(s) async* {
+        yield* s;
+      }
+      return f(new NotAStream()).transform(getErrors).single.then((v) {
+        // Not implementing Stream.
+        expect(v is Error, isTrue);
+      });
+    });
+  });
+
+  group("yield statement context", () {
+    test("plain", () {
+      f() async* {
+        yield 0;
+      }
+      return expectList(f(), [0]);
+    });
+
+    test("if-then-else", () {
+      f(b) async* {
+        if (b) yield 0; else yield 1;
+      }
+      return expectList(f(true), [0]).whenComplete(() {
+        expectList(f(false), [1]);
+      });
+    });
+
+    test("block", () {
+      f() async* {
+        yield 0;
+        { yield 1; }
+        yield 2;
+      }
+      return expectList(f(), [0, 1, 2]);
+    });
+
+    test("labeled", () {
+      f() async* {
+        label1: yield 0;
+      }
+      return expectList(f(), [0]);
+    });
+
+    // VM issue 2238
+    test("labeled 2", () {          /// 01: ok
+      f() async* {                  /// 01: continued
+        label1: label2: yield 0;    /// 01: continued
+      }                             /// 01: continued
+      return expectList(f(), [0]);  /// 01: continued
+    });                             /// 01: continued
+
+    test("for-loop", () {
+      f() async* {
+        for (int i = 0; i < 3; i++) yield i;
+      }
+      return expectList(f(), [0, 1, 2]);
+    });
+
+    test("for-in-loop", () {
+      f() async* {
+        for (var i in [0, 1, 2]) yield i;
+      }
+      return expectList(f(), [0, 1, 2]);
+    });
+
+    test("await for-in-loop", () {
+      f() async* {
+        await for (var i in new Stream.fromIterable([0, 1, 2])) yield i;
+      }
+      return expectList(f(), [0, 1, 2]);
+    });
+
+    test("while-loop", () {
+      f() async* {
+        int i = 0;
+        while (i < 3) yield i++;
+      }
+      return expectList(f(), [0, 1, 2]);
+    });
+
+    test("do-while-loop", () {
+      f() async* {
+        int i = 0;
+        do yield i++; while (i < 3);
+      }
+      return expectList(f(), [0, 1, 2]);
+    });
+
+    test("try-catch-finally", () {
+      f() async* {
+        try { yield 0; } catch (e) { yield 1; } finally { yield 2; }
+      }
+      return expectList(f(), [0, 2]);
+    });
+
+    test("try-catch-finally 2", () {
+      f() async* {
+        try { yield throw 0; } catch (e) { yield 1; } finally { yield 2; }
+      }
+      return expectList(f(), [1, 2]);
+    });
+
+    test("switch-case", () {
+      f(v) async* {
+        switch (v) {
+          case 0:
+            yield 0;
+            continue label1;
+          label1:
+          case 1:
+            yield 1;
+            break;
+          default:
+            yield 2;
+        }
+      }
+      return expectList(f(0), [0, 1]).whenComplete(() {
+        return expectList(f(1), [1]);
+      }).whenComplete(() {
+        return expectList(f(2), [2]);
+      });
+    });
+
+    test("dead-code return", () {
+      f() async* {
+        return;
+        yield 1;
+      }
+      return expectList(f(), []);
+    });
+
+    test("dead-code throw", () {
+      f() async* {
+        try {
+          throw 0;
+          yield 1;
+        } catch (_) {}
+      }
+      return expectList(f(), []);
+    });
+
+    test("dead-code break", () {
+      f() async* {
+        while (true) {
+          break;
+          yield 1;
+        }
+      }
+      return expectList(f(), []);
+    });
+
+    test("dead-code break 2", () {
+      f() async* {
+        label: {
+          break label;
+          yield 1;
+        }
+      }
+      return expectList(f(), []);
+    });
+
+    test("dead-code continue", () {
+      f() async* {
+        do {
+          continue;
+          yield 1;
+        } while (false);
+      }
+      return expectList(f(), []);
+    });
+  });
+
+  group("yield expressions", () {
+    test("local variable", () {
+      f() async* {
+        var x = 42;
+        yield x;
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("constant variable", () {
+      f() async* {
+        const x = 42;
+        yield x;
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("function call", () {
+      g() => 42;
+      f() async* {
+        yield g();
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("unary operator", () {
+      f() async* {
+        var x = -42;
+        yield -x;
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("binary operator", () {
+      f() async* {
+        var x = 21;
+        yield x + x;
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("ternary operator", () {
+      f() async* {
+        var x = 21;
+        yield x == 21 ? x + x : x;
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("suffix post-increment", () {
+      f() async* {
+        var x = 42;
+        yield x++;
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("suffix pre-increment", () {
+      f() async* {
+        var x = 41;
+        yield ++x;
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("assignment", () {
+      f() async* {
+        var x = 37;
+        yield x = 42;
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("assignment op", () {
+      f() async* {
+        var x = 41;
+        yield x += 1;
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("await", () {
+      f() async* {
+        yield await new Future.value(42);
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("index operator", () {
+      f() async* {
+        var x = [42];
+        yield x[0];
+      }
+      return expectList(f(), [42]);
+    });
+
+    test("function expression block", () {
+      var o = new Object();
+      f() async* {
+        yield () { return o; };
+      }
+      return f().first.then((v) {
+        expect(v(), same(o));
+      });
+    });
+
+    test("function expression arrow", () {
+      var o = new Object();
+      f() async* {
+        yield () => o;
+      }
+      return f().first.then((v) {
+        expect(v(), same(o));
+      });
+    });
+
+    test("function expression block async", () {
+      var o = new Object();
+      f() async* {
+        yield () async { return o; };
+      }
+      return f().first.then((v) => v()).then((v) {
+        expect(v, same(o));
+      });
+    });
+
+    test("function expression arrow async", () {
+      var o = new Object();
+      f() async* {
+        yield () async => o;
+      }
+      return f().first.then((v) => v()).then((v) {
+        expect(v, same(o));
+      });
+    });
+
+    test("function expression block async*", () {
+      var o = new Object();
+      f() async* {
+        yield () async* { yield o; };
+      }
+      return f().first.then((v) => v().first).then((v) {
+        expect(v, same(o));
+      });
+    });
+  });
+
+  group("loops", () {
+    test("simple yield", () {
+      f() async* {
+        for (int i = 0; i < 3; i++) {
+          yield i;
+        }
+      }
+      return expectList(f(), [0, 1, 2]);
+    });
+
+    test("yield in double loop", () {
+      f() async* {
+        for (int i = 0; i < 3; i++) {
+          for (int j = 0; j < 2; j++) {
+            yield i * 2 + j;
+          }
+        }
+      }
+      return expectList(f(), [0, 1, 2, 3, 4, 5]);
+    });
+
+    test("yield in try body", () {
+      var list = [];
+      f() async* {
+        for (int i = 0; i < 3; i++) {
+          try {
+            yield i;
+          } finally {
+            list.add("$i");
+          }
+        }
+      }
+      return expectList(f(), [0, 1, 2]).whenComplete(() {
+        expect(list, equals(["0", "1", "2"]));
+      });
+    });
+
+    test("yield in catch", () {
+      var list = [];
+      f() async* {
+        for (int i = 0; i < 3; i++) {
+          try {
+            throw i;
+          } catch (e) {
+            yield e;
+          } finally {
+            list.add("$i");
+          }
+        }
+      }
+      return expectList(f(), [0, 1, 2]).whenComplete(() {
+        expect(list, equals(["0", "1", "2"]));
+      });
+    });
+
+    test("yield in finally", () {
+      var list = [];
+      f() async* {
+        for (int i = 0; i < 3; i++) {
+          try {
+            throw i;
+          } finally {
+            yield i;
+            list.add("$i");
+            continue;
+          }
+        }
+      }
+      return expectList(f(), [0, 1, 2]).whenComplete(() {
+        expect(list, equals(["0", "1", "2"]));
+      });
+    });
+
+    test("keep yielding after cancel", () {
+      f() async* {
+        for (int i = 0; i < 10; i++) {
+          try {
+            yield i;
+          } finally {
+            continue;
+          }
+        }
+      }
+      return expectList(f().take(3), [0, 1, 2]);
+    });
+  });
+
+  group("canceling", () {
+    // Stream.take(n) automatically cancels after seeing the n'th value.
+
+    test("cancels at yield", () {
+      Completer exits = new Completer();
+      var list = [];
+      f() async* {
+        try {
+          list.add(0);
+          yield list.add(1);
+          list.add(2);
+        } finally {
+          exits.complete(3);
+        }
+      }
+      // No events must be fired synchronously in response to a listen.
+      var subscription = f().listen((v) { fail("Received event $v"); },
+                                   onDone: () { fail("Received done"); });
+      // No events must be delivered after a cancel.
+      subscription.cancel();
+      return exits.future.then((v) {
+        expect(v, equals(3));
+        expect(list, equals([0, 1]));
+      });
+    });
+
+    test("does cancel eventually", () {
+      var exits = new Completer();
+      var list = [];
+      f() async* {
+        int i = 0;
+        try {
+          while (true) yield i++;
+        } finally {
+          list.add("a");
+          exits.complete(i);
+        }
+      }
+      return expectList(f().take(5), [0, 1, 2, 3, 4])
+          .then((_) => exits.future)
+          .then((v) {
+            expect(v, greaterThan(4));
+            expect(list, ["a"]);
+          });
+    });
+
+    group("at index", () {
+      f() async* {
+        try {
+          yield await new Future.microtask(() => 1);
+        } finally {
+          try {
+            yield await new Future.microtask(() => 2);
+          } finally {
+            yield await new Future.microtask(() => 3);
+          }
+        }
+      }
+      test("- all, sanity check", () {
+        return expectList(f(), [1, 2, 3]);
+      });
+      test("after end", () {
+        return expectList(f().take(4), [1, 2, 3]);
+      });
+      test("at end", () {
+        return expectList(f().take(3), [1, 2, 3]);
+      });
+      test("before end", () {
+        return expectList(f().take(2), [1, 2]);
+      });
+      test("early", () {
+        return expectList(f().take(1), [1]);
+      });
+      test("at start", () {
+        return expectList(f().take(0), []);
+      });
+    });
+
+    // Crashes dart2js.
+    // test("regression-fugl/fisk", () {
+    //   var res = [];
+    //   fisk() async* {
+    //     res.add("+fisk");
+    //     try {
+    //       for (int i = 0; i < 2; i++) {
+    //         yield await new Future.microtask(() => i);
+    //       }
+    //     } finally {
+    //       res.add("-fisk");
+    //     }
+    //   }
+
+    //   fugl(int count) async {
+    //     res.add("fisk $count");
+    //     try {
+    //       await for(int i in fisk().take(count)) res.add(i);
+    //     } finally {
+    //       res.add("done");
+    //     }
+    //   }
+
+    //   return fugl(3).whenComplete(() => fugl(2))
+    //                 .whenComplete(() => fugl(1))
+    //                 .whenComplete(() {
+    //     expect(res, ["fisk 3", "+fisk", 0, 1, "-fisk", "done",
+    //                  "fisk 2", "+fisk", 0, 1, "-fisk", "done",
+    //                  "fisk 1", "+fisk", 0, "done", "-fisk", ]);
+    //   });
+    // });
+
+  });
+
+  group("pausing", () {
+    test("pauses execution at yield for at least a microtask", () {
+      var list = [];
+      f() async* {
+        list.add(1);
+        yield 2;
+        list.add(3);
+        yield 4;
+        list.add(5);
+      }
+      var done = new Completer();
+      var sub = f().listen((v) {
+        if (v == 2) {
+          expect(list, equals([1]));
+        } else if (v == 4) {
+          expect(list, equals([1, 3]));
+        } else {
+          fail("Unexpected value $v");
+        }
+      }, onDone: () {
+        expect(list, equals([1, 3, 5]));
+        done.complete();
+      });
+      return done.future;
+    });
+
+    test("pause stops execution at yield", () {
+      var list = [];
+      f() async* {
+        list.add(1);
+        yield 2;
+        list.add(3);
+        yield 4;
+        list.add(5);
+      }
+      var done = new Completer();
+      var sub;
+      sub = f().listen((v) {
+        if (v == 2) {
+          expect(list, equals([1]));
+          sub.pause();
+          new Timer(MS * 300, () {
+            expect(list.length, lessThan(3));
+            sub.resume();
+          });
+        } else if (v == 4) {
+          expect(list, equals([1, 3]));
+        } else {
+          fail("Unexpected value $v");
+        }
+      }, onDone: () {
+        expect(list, equals([1, 3, 5]));
+        done.complete();
+      });
+      return done.future;
+    });
+
+    test("pause stops execution at yield 2", () {
+      var list = [];
+      f() async* {
+        int i = 0;
+        while (true) {
+          yield i;
+          list.add(i);
+          i++;
+        }
+      }
+      int expected = 0;
+      var done = new Completer();
+      var sub;
+      sub = f().listen((v) {
+        expect(v, equals(expected++));
+        if (v % 5 == 0) {
+          sub.pause(new Future.delayed(MS * 300));
+        } else if (v == 17) {
+          sub.cancel();
+          done.complete();
+        }
+      }, onDone: () {
+        fail("Unexpected done!");
+      });
+      return done.future.whenComplete(() {
+        expect(list.length == 18 || list.length == 19, isTrue);
+      });
+    });
+
+    test("canceling while paused at yield", () {                  /// 02: ok
+      var list = [];                                              /// 02: continued
+      var sync = new Sync();                                      /// 02: continued
+      f() async* {                                                /// 02: continued
+        list.add("*1");                                           /// 02: continued
+        yield 1;                                                  /// 02: continued
+        await sync.wait();                                        /// 02: continued
+        sync.release();                                           /// 02: continued
+        list.add("*2");                                           /// 02: continued
+        yield 2;                                                  /// 02: continued
+        list.add("*3");                                           /// 02: continued
+      };                                                          /// 02: continued
+      var stream = f();                                           /// 02: continued
+      var sub = stream.listen(list.add);                          /// 02: continued
+      return sync.wait().whenComplete(() {                        /// 02: continued
+        expect(list, equals(["*1", 1]));                          /// 02: continued
+        sub.pause();                                              /// 02: continued
+        return sync.wait();                                       /// 02: continued
+      }).whenComplete(() {                                        /// 02: continued
+        expect(list, equals(["*1", 1, "*2"]));                    /// 02: continued
+        sub.cancel();                                             /// 02: continued
+        return new Future.delayed(MS * 200, () {                  /// 02: continued
+          // Should not have yielded 2 or added *3 while paused.  /// 02: continued
+          expect(list, equals(["*1", 1, "*2"]));                  /// 02: continued
+        });                                                       /// 02: continued
+      });                                                         /// 02: continued
+    });                                                           /// 02: continued
+  });
+
+  group("await for", () {
+    mkStream(int n) async* {
+      for (int i = 0; i < n; i++) yield i;
+    }
+
+    test("simple stream", () {
+      f(s) async {
+        var r = 0;
+        await for(var v in s) r += v;
+        return r;
+      }
+      return f(mkStream(5)).then((v) {
+        expect(v, equals(10));
+      });
+    });
+
+    test("simple stream, await", () {
+      f(s) async {
+        var r = 0;
+        await for(var v in s) r += await new Future.microtask(() => v);
+        return r;
+      }
+      return f(mkStream(5)).then((v) {
+        expect(v, equals(10));
+      });
+    });
+
+    test("simple stream - take", () {           /// 03: ok
+      f(s) async {                              /// 03: continued
+        var r = 0;                              /// 03: continued
+        await for(var v in s.take(5)) r += v;   /// 03: continued
+        return r;                               /// 03: continued
+      }                                         /// 03: continued
+      return f(mkStream(10)).then((v) {         /// 03: continued
+        expect(v, equals(10));                  /// 03: continued
+      });                                       /// 03: continued
+    });                                         /// 03: continued
+
+    test("simple stream reyield", () {
+      f(s) async* {
+        var r = 0;
+        await for(var v in s) yield r += v;
+      }
+      return expectList(f(mkStream(5)), [0, 1, 3, 6, 10]);
+    });
+
+    test("simple stream, await, reyield", () {
+      f(s) async* {
+        var r = 0;
+        await for(var v in s) yield r += await new Future.microtask(() => v);
+      }
+      return expectList(f(mkStream(5)), [0, 1, 3, 6, 10]);
+    });
+
+    test("simple stream - take, reyield", () {                /// 04: ok
+      f(s) async* {                                           /// 04: continued
+        var r = 0;                                            /// 04: continued
+        await for(var v in s.take(5)) yield r += v;           /// 04: continued
+      }                                                       /// 04: continued
+      return expectList(f(mkStream(10)), [0, 1, 3, 6, 10]);   /// 04: continued
+    });                                                       /// 04: continued
+
+    test("nested", () {
+      f() async {
+        var r = 0;
+        await for (var i in mkStream(5)) {
+          await for (var j in mkStream(3)) {
+            r += i * j;
+          }
+        }
+        return r;
+      }
+      return f().then((v) {
+        expect(v, equals((1 + 2 + 3 + 4) * (1 + 2)));
+      });
+    });
+
+    test("nested, await", () {
+      f() async {
+        var r = 0;
+        await for (var i in mkStream(5)) {
+          await for (var j in mkStream(3)) {
+            r += await new Future.microtask(() => i * j);
+          }
+        }
+        return r;
+      }
+      return f().then((v) {
+        expect(v, equals((1 + 2 + 3 + 4) * (1 + 2)));
+      });
+    });
+
+    test("nested, await * 2", () {
+      f() async {
+        var r = 0;
+        await for (var i in mkStream(5)) {
+          var ai = await new Future.microtask(() => i);
+          await for (var j in mkStream(3)) {
+            r += await new Future.microtask(() => ai * j);
+          }
+        }
+        return r;
+      }
+      return f().then((v) {
+        expect(v, equals((1 + 2 + 3 + 4) * (1 + 2)));
+      });
+    });
+
+    test("await pauses loop", () {                                   /// 05: ok
+      var sc;                                                        /// 05: continued
+      var i = 0;                                                     /// 05: continued
+      void send() {                                                  /// 05: continued
+        if (i == 5) {                                                /// 05: continued
+          sc.close();                                                /// 05: continued
+        } else {                                                     /// 05: continued
+          sc.add(i++);                                               /// 05: continued
+        }                                                            /// 05: continued
+      }                                                              /// 05: continued
+      sc = new StreamController(onListen: send, onResume: send);     /// 05: continued
+      f(s) async {                                                   /// 05: continued
+        var r = 0;                                                   /// 05: continued
+        await for (var i in s) {                                     /// 05: continued
+          r += await new Future.delayed(MS * 10, () => i);           /// 05: continued
+        }                                                            /// 05: continued
+        return r;                                                    /// 05: continued
+      }                                                              /// 05: continued
+      return f(sc.stream).then((v) {                                 /// 05: continued
+        expect(v, equals(10));                                       /// 05: continued
+      });                                                            /// 05: continued
+    });                                                              /// 05: continued
+  });
+}
+
+// Obscuring identity function.
+id(x) {
+  try {
+    if (x != null) throw x;
+  } catch (e) {
+    return e;
+  }
+  return null;
+}
+
+expectList(stream, list) {
+  return stream.toList().then((v) {
+    expect(v, equals(list));
+  });
+}
+
+const MS = const Duration(milliseconds: 1);
+
+var getErrors = new StreamTransformer.fromHandlers(
+  handleData:(data, sink) { fail("Unexpected value"); },
+  handleError: (e, s, sink) { sink.add(e); },
+  handleDone: (sink) { sink.close(); });
+
+class NotAStream {
+  listen(oData, {onError, onDone, cancelOnError}) {
+    fail("Not implementing Stream.");
+  }
+}
+
+/**
+ * Allows two asynchronous executions to synchronize.
+ *
+ * Calling [wait] and waiting for the returned future to complete will
+ * wait for the other executions to call [wait] again. At that point,
+ * the waiting execution is allowed to continue (the returned future completes),
+ * and the more resent call to [wait] is now the waiting execution.
+ */
+class Sync {
+  Completer _completer = null;
+  // Release whoever is currently waiting and start waiting yourself.
+  Future wait([v]) {
+    if (_completer != null) _completer.complete(v);
+    _completer = new Completer();
+    return _completer.future;
+  }
+
+  // Release whoever is currently waiting.
+  void release([v]) {
+    if (_completer != null) {
+      _completer.complete(v);
+      _completer = null;
+    }
+  }
+}
diff --git a/tests/language/deferred_load_constants.dart b/tests/language/deferred_load_constants.dart
new file mode 100644
index 0000000..be5a93f
--- /dev/null
+++ b/tests/language/deferred_load_constants.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart version of two-argument Ackermann-Peter function.
+
+library deferred_load_constants;
+
+// Constant declaration.
+const c = const C();
+// Class declaration (`C` is a constant expression).
+class C {
+  const C();
+  static int staticfun(int x) => x;
+}
+// Function type definition.
+typedef int funtype(int x);
+// Top-level function.
+int toplevel(int x) => x;
diff --git a/tests/language/deferred_load_constants_test.dart b/tests/language/deferred_load_constants_test.dart
new file mode 100644
index 0000000..860e66c
--- /dev/null
+++ b/tests/language/deferred_load_constants_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// Dart version of two-argument Ackermann-Peter function.
+
+library deferred_load_constants;
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "deferred_load_constants.dart" deferred as foo;
+import "deferred_load_constants.dart";
+
+main() {
+  asyncStart();
+  Expect.throws(() => foo.c);
+  Expect.throws(() => foo.C);
+  Expect.throws(() => foo.funtype);
+  Expect.throws(() => foo.toplevel);
+  foo.loadLibrary().whenComplete(() {
+    // Reading constant declarations through deferred prefix works.
+    Expect.identical(c, foo.c);
+    Expect.identical(C, foo.C);
+    Expect.identical(funtype, foo.funtype);
+    Expect.identical(toplevel, foo.toplevel);
+    Expect.identical(C.staticfun, foo.C.staticfun);
+    // Access through deferred prefix is not a constant expression.
+    Expect.throws(() => const [foo.c]);            /// 01: compile-time error
+    Expect.throws(() => const [foo.C]);            /// 02: compile-time error
+    Expect.throws(() => const [foo.funtype]);      /// 03: compile-time error
+    Expect.throws(() => const [foo.toplevel]);     /// 04: compile-time error
+    Expect.throws(() => const [foo.C.staticfun]);  /// 05: compile-time error
+
+    asyncEnd();
+  });
+}
diff --git a/tests/language/flatten_test.dart b/tests/language/flatten_test.dart
new file mode 100644
index 0000000..eeb3880
--- /dev/null
+++ b/tests/language/flatten_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+class Derived<T> implements Future<T> {
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+class FixedPoint<T> implements Future<FixedPoint<T>> {
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+class Divergent<T> implements Future<Divergent<Divergent<T>>> {
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+test() async {
+  // flatten(Derived<int>) = int
+  int x = await new Derived<int>(); /// 01: runtime error
+  Future<int> f() async => new Derived<int>(); /// 02: ok
+  Future<int> f() async { return new Derived<int>(); } /// 03: ok
+  Future<int> x = (() async => new Derived<int>())(); /// 04: runtime error
+
+  // flatten(FixedPoint<int>) = FixedPoint<int>
+  FixedPoint<int> x = await new FixedPoint<int>(); /// 05: runtime error
+  Future<FixedPoint<int>> f() async => new FixedPoint<int>(); /// 06: ok
+  Future<FixedPoint<int>> f() async { return new FixedPoint<int>(); } /// 07: ok
+  Future<FixedPoint<int>> x = (() async => new FixedPoint<int>())(); /// 08: runtime error
+
+  // flatten(Divergent<int>) = Divergent<Divergent<int>>
+  Divergent<Divergent<int>> x = await new Divergent<int>(); /// 09: runtime error
+  Future<Divergent<Divergent<int>>> f() async => new Divergent<int>(); /// 10: ok
+  Future<Divergent<Divergent<int>>> f() async { return new Divergent<int>(); } /// 11: ok
+  Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())(); /// 12: runtime error
+}
+
+main() {
+  test();
+}
\ No newline at end of file
diff --git a/tests/language/implicit_super_constructor_call_test.dart b/tests/language/implicit_super_constructor_call_test.dart
index 16e41b2..70a34af 100644
--- a/tests/language/implicit_super_constructor_call_test.dart
+++ b/tests/language/implicit_super_constructor_call_test.dart
@@ -12,7 +12,6 @@
   @NoInline()
   A({this.x: "foo"}) {
     Expect.equals("foo", x.toString());
-    try {} catch (_) {}; // Make sure it really does not get inlined.
   }
 }
 
diff --git a/tests/language/language.status b/tests/language/language.status
index 60eafb7..0d182a6 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -7,7 +7,6 @@
 
 [ $compiler == none ]
 built_in_identifier_prefix_test: Fail # Issue 6970
-await_for_cancel_test: RuntimeError # Issue 21404
 
 # These bugs refer currently ongoing language discussions.
 constructor_initializer_test/none: Fail # Issue 12633
@@ -19,7 +18,6 @@
 duplicate_export_negative_test: Fail # Issue 6134
 
 [ $compiler == dart2dart ]
-
 deferred_load_library_wrong_args_test/none: Fail # Issue 17523
 deferred_load_inval_code_test: Fail # Issue 17523
 deferred_not_loaded_check_test: Fail # Issue 17523
@@ -41,6 +39,12 @@
 cyclic_type2_test: Fail, OK
 least_upper_bound_expansive_test/*: Fail, OK
 
+async_star_test/01: CompileTimeError, RuntimeError # drt only runtime-errs.
+async_star_test/02: RuntimeError
+async_star_test/05: Timeout, RuntimeError
+
+[ $compiler == none && ($runtime == drt || $runtime == dartium|| $runtime == ContentShellOnAndroid) ]
+
 [ $compiler == none && $runtime == vm ]
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
 unicode_bom_test: Fail # Issue 16067
@@ -51,7 +55,7 @@
 [ $compiler == none ]
 dynamic_prefix_core_test/01: RuntimeError # Issue 12478
 
-[ $compiler == none && ($runtime == vm || $runtime == drt || $runtime == dartium|| $runtime == ContentShellOnAndroid) ]
+[ $compiler == none && ($runtime == vm || $runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 dynamic_prefix_core_test/none: Fail # Issue 12478
 export_ambiguous_main_negative_test: Fail # Issue 14763
 
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index cc4d7a4..b381c07 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -5,9 +5,12 @@
 [ $compiler == dartanalyzer ]
 async_return_types_test/wrongTypeParameter: MissingStaticWarning # Issue 22410
 async_return_types_test/wrongReturnType: MissingStaticWarning # Issue 22410
+async_or_generator_return_type_stacktrace_test/01: MissingStaticWarning # Issue 22410
+async_or_generator_return_type_stacktrace_test/02: MissingStaticWarning # Issue 22410
 async_return_types_test/nestedFuture: MissingStaticWarning # Issue 22410
 await_backwards_compatibility_test/none: CompileTimeError # Issue 22052
 await_test: CompileTimeError # Issue 22052
+async_await_test/02: CompileTimeError # Issue 22052
 
 issue13179_test: CompileTimeError # Issue 13179
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 567fdbd..272ba36 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -10,8 +10,14 @@
 async_star_test/02: RuntimeError # 22853
 async_star_test/05: RuntimeError, Timeout
 
+try_catch_on_syntax_test/10: Fail # Issue 19823
+try_catch_on_syntax_test/11: Fail # Issue 19823
+
+deferred_load_constants_test/none: CompileTimeError # issue 22893
+
 [ $compiler == dart2js && $runtime == jsshell ]
 await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
+async_star_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728
 
 [ $compiler == dart2js || $compiler == dart2dart ]
 regress_22700_test: CompileTimeError # Issue 22700
@@ -162,8 +168,11 @@
 
 [ $compiler == dart2js && $runtime == chrome && $system == macos ]
 await_future_test: Pass, Timeout # Issue 22695.
+async_await_test/none: Pass, Timeout # Issue 22695.
+async_await_test/02: Pass, Timeout # Issue 22695.
+async_await_test/03: Pass, Timeout # Issue 22695.
 
-[ $compiler == dart2js && ($runtime == jsshell || $runtime == safari || $runtime == safarimobilesim)]
+[ $compiler == dart2js && ($runtime == safari || $runtime == safarimobilesim)]
 round_test: Fail, OK # Common JavaScript engine Math.round bug.
 
 [ $compiler == dart2js && $runtime == ff ]
@@ -177,33 +186,18 @@
 override_field_test/02: Pass, Slow # TODO(kasperl): Please triage.
 
 [ $compiler == dart2dart && $builder_tag == new_backend ]
-async_await_syntax_test/a03a: CompileTimeError # Issue 21404
-async_await_syntax_test/a03b: CompileTimeError # Issue 21404
-async_await_syntax_test/a11d: CompileTimeError # Issue 21404
-async_await_syntax_test/b03a: CompileTimeError # Issue 21404
-async_await_syntax_test/b11d: CompileTimeError # Issue 21404
-async_await_syntax_test/c03a: CompileTimeError # Issue 21404
-async_await_syntax_test/d03a: CompileTimeError # Issue 21404
 regress_13494_test: Pass # Issue 22370, passes for the wrong reason
 
-[ $compiler == dart2dart && $builder_tag == new_backend && $minified == true ]
-# This test fails in minified, because the type-argument is
-# renamed, but the symbol naming it it is not.
-type_variable_conflict2_test/01: RuntimeError # Issue 16180
+[ $compiler == dart2dart && $builder_tag == new_backend && $host_checked ]
+large_implicit_getter_test: Crash # Stack overflow
 
-[ $compiler == dart2dart && $builder_tag == new_backend && $minified == false ]
-# This test happens not to fail in minified, because the type-argument is
-# renamed, but the unresolved reference to it is not.
-type_variable_conflict2_test/04: Fail # Issue 19725
-
-[ $compiler == dart2dart && $minified && $builder_tag != new_backend ]
+[ $compiler == dart2dart && ($minified == true || $builder_tag == new_backend) ]
 type_variable_conflict2_test/01: RuntimeError # Issue 16180
 
 [ $compiler == dart2dart ]
 sync_generator2_test/07: MissingCompileTimeError # Issue 22324
 sync_generator2_test/08: MissingCompileTimeError # Issue 22324
 sync_generator2_test/10: MissingCompileTimeError # Issue 22324
-await_for_cancel_test: RuntimeError # Issue 21404
 
 regress_13494_test: Fail # Issue 22370
 
diff --git a/tests/language/parameter_initializer_test.dart b/tests/language/parameter_initializer_test.dart
index 23d1bc8..e81ff97 100644
--- a/tests/language/parameter_initializer_test.dart
+++ b/tests/language/parameter_initializer_test.dart
@@ -7,6 +7,7 @@
 class ParameterInitializerTest {
 
   static testMain() {
+
     var obj = new Foo.untyped(1);
     Expect.equals(1, obj.x);
 
diff --git a/tests/language/regress_22936_test.dart b/tests/language/regress_22936_test.dart
new file mode 100644
index 0000000..bd9950b
--- /dev/null
+++ b/tests/language/regress_22936_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test for issue 22936.
+
+import 'package:expect/expect.dart';
+
+bool fooCalled = false;
+
+foo() {
+  fooCalled = true;
+  return null;
+}
+
+main() {
+  final x = null;
+  try {
+    x =    /// 01: static type warning
+        foo();
+  } on NoSuchMethodError {
+  }
+  Expect.isTrue(fooCalled);
+}
\ No newline at end of file
diff --git a/tests/language/try_catch_on_syntax_test.dart b/tests/language/try_catch_on_syntax_test.dart
index 1b5e4a5..8828252 100644
--- a/tests/language/try_catch_on_syntax_test.dart
+++ b/tests/language/try_catch_on_syntax_test.dart
@@ -10,34 +10,39 @@
 
 class MyException2 extends MyException { }
 
-class TryCatchTest {
-  static void test1() {
-    var foo = 0;
-    try {
-      throw new MyException1();
-    }
-    on on MyException2 catch (e) { } /// 02: compile-time error
-    catch MyException2 catch (e) { } /// 03: compile-time error
-    catch catch catch (e) { } /// 04: compile-time error
-    on (e) { } /// 05: compile-time error
-    catch MyException2 catch (e) { } /// 06: compile-time error
-    on MyException2 catch (e) {
-      foo = 1;
-    } on MyException1 catch (e) {
-      foo = 2;
-    } on MyException catch (e) {
-      foo = 3;
-    }
-    on UndefinedClass /// 07: static type warning
-    catch(e) { foo = 4; }
-    Expect.equals(2, foo);
+void test1() {
+  var foo = 0;
+  try {
+    throw new MyException1();
   }
+  on on MyException2 catch (e) { } /// 02: compile-time error
+  catch MyException2 catch (e) { } /// 03: compile-time error
+  catch catch catch (e) { } /// 04: compile-time error
+  on (e) { } /// 05: compile-time error
+  catch MyException2 catch (e) { } /// 06: compile-time error
+  on MyException2 catch (e) {
+    foo = 1;
+  } on MyException1 catch (e) {
+    foo = 2;
+  } on MyException catch (e) {
+    foo = 3;
+  }
+  on UndefinedClass /// 07: static type warning
+  catch(e) { foo = 4; }
+  Expect.equals(2, foo);
+}
 
-  static void testMain() {
-    test1();
-  }
+testFinal() {
+  try {
+    throw "catch this!";
+    } catch (e, s) {
+      // Test that the error and stack trace variables are final.
+      e = null;  /// 10: runtime error
+      s = null;  /// 11: runtime error
+    }
 }
 
 main() {
-  TryCatchTest.testMain();
+  test1();
+  testFinal();
 }
diff --git a/tests/lib/async/future_test.dart b/tests/lib/async/future_test.dart
index 108cbcd..900eea6 100644
--- a/tests/lib/async/future_test.dart
+++ b/tests/lib/async/future_test.dart
@@ -876,6 +876,26 @@
   });
 }
 
+void testBadFuture() {
+  var bad = new BadFuture();
+  // Completing with bad future (then call throws) puts error in result.
+  asyncStart();
+  Completer completer = new Completer();
+  completer.complete(bad);
+  completer.future.then((_) { fail("unreachable"); },
+                        onError: (e, s) {
+                          Expect.isTrue(completer.isCompleted);
+                          asyncEnd();
+                        });
+
+  asyncStart();
+  var f = new Future.value().then((_) => bad);
+  f.then((_) { fail("unreachable"); },
+         onError: (e, s) {
+           asyncEnd();
+         });
+}
+
 main() {
   asyncStart();
 
@@ -935,6 +955,8 @@
   testWaitCleanUp();
   testWaitCleanUpError();
 
+  testBadFuture();
+
   asyncEnd();
 }
 
@@ -953,3 +975,15 @@
   String toString() => "CustomFuture@${_realFuture.hashCode}";
   int get hashCode => _realFuture.hashCode;
 }
+
+class BadFuture<T> implements Future<T> {
+  Future then(action(result)) {
+    throw "then GOTCHA!";
+  }
+  Future catchError(Function onError) {
+    throw "catch GOTCHA!";
+  }
+  Future whenComplete(action()) {
+    throw "finally GOTCHA!";
+  }
+}
diff --git a/tests/lib/async/timer_isActive_test.dart b/tests/lib/async/timer_isActive_test.dart
index 8df8a04b..7a7b8f2 100644
--- a/tests/lib/async/timer_isActive_test.dart
+++ b/tests/lib/async/timer_isActive_test.dart
@@ -34,7 +34,7 @@
   });
 
   test("timer cancel test", () {
-    Timer timer = new Timer(const Duration(seconds: 1),
+    Timer timer = new Timer(const Duration(seconds: 15),
                             () => fail("Should not be reached."));
     Timer.run(expectAsync(() {
       expect(timer.isActive, equals(true));
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 30cd46f..6e59d60 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -19,6 +19,7 @@
 mirrors/abstract_class_test: RuntimeError # Issue 12826
 mirrors/class_declarations_test/none: RuntimeError # Issue 13440
 mirrors/class_mirror_location_test: RuntimeError # Issue 6490
+mirrors/closurization_equivalence_test: RuntimeError # Issue 6490
 mirrors/constructor_kinds_test: RuntimeError # Issue 13799
 mirrors/constructor_private_name_test: CompileTimeError # Issue 13597
 mirrors/enum_test: RuntimeError # Issue 6490
@@ -176,7 +177,7 @@
 async/stream_asyncmap_test: RuntimeError # Timer interface not supported: Issue 7728.
 async/stream_transformation_broadcast_test: RuntimeError # Timer interface not supported: Issue 7728.
 async/stream_controller_test: Fail # Timer interface not supported: Issue 7728.
-mirrors/mirrors_reader_test: Slow, RuntimeError, Crash # Issue 16589 - RuntimeError.  Issue 22130 - Crash (out of memory).
+mirrors/mirrors_reader_test: Skip # Running in v8 suffices. Issue 16589 - RuntimeError.  Issue 22130 - Crash (out of memory).
 
 [ $compiler == dart2js && $checked ]
 convert/utf85_test: Pass, Slow # Issue 12029.
@@ -215,7 +216,7 @@
 mirrors/mirrors_reader_test: Timeout, Slow, RuntimeError # Issue 16589
 
 [ $runtime == chrome && $system == macos ]
-async/timer_isActive_test: Pass, Timeout # Issue 22696
+async/timer_isActive_test: Fail, Pass, Timeout # Issue 22696
 async/slow_consumer_test: Pass, Timeout # Issue 22696
 async/catch_errors11_test: Pass, Timeout # Issue 22696
 
@@ -312,6 +313,8 @@
 profiler/metrics_test: Fail # Issue 20309
 profiler/metrics_num_test: Fail # Issue 20309
 
+async/future_test: StaticWarning, OK # Deliberately broken implementation.
+
 [ ($compiler == dartanalyzer || $compiler == dart2analyzer) && $checked ]
 mirrors/regress_16321_test/01: MissingCompileTimeError # Issue 16391
 
diff --git a/tests/lib/mirrors/closurization_equivalence_test.dart b/tests/lib/mirrors/closurization_equivalence_test.dart
new file mode 100644
index 0000000..0701fc7
--- /dev/null
+++ b/tests/lib/mirrors/closurization_equivalence_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:mirrors';
+import 'package:expect/expect.dart';
+
+topLevelMethod() {}
+class C {
+  static staticMethod() {}
+  instanceMethod() {}
+}
+
+main() {
+  LibraryMirror thisLibrary = reflectClass(C).owner;
+  Expect.equals(thisLibrary.declarations[#topLevelMethod],
+                (reflect(topLevelMethod) as ClosureMirror).function,
+                "topLevel");
+
+  Expect.equals(reflectClass(C).declarations[#staticMethod],
+                (reflect(C.staticMethod) as ClosureMirror).function,
+                "static");
+
+  Expect.equals(reflectClass(C).declarations[#instanceMethod],
+                (reflect(new C().instanceMethod) as ClosureMirror).function,
+                "instance");
+}
diff --git a/tests/lib/mirrors/typedef_deferred_library_test.dart b/tests/lib/mirrors/typedef_deferred_library_test.dart
new file mode 100644
index 0000000..7dd6c2e
--- /dev/null
+++ b/tests/lib/mirrors/typedef_deferred_library_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library foo;
+
+@MirrorsUsed(targets: const ["foo", "bar"])
+import 'dart:mirrors';
+import 'typedef_library.dart' deferred as def;
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+main() {
+  asyncStart();
+  def.loadLibrary().then((_) {
+    var barLibrary = currentMirrorSystem().findLibrary(new Symbol("bar"));
+    var gTypedef = barLibrary.declarations[new Symbol("G")];
+    Expect.equals("G", MirrorSystem.getName(gTypedef.simpleName));
+    asyncEnd();
+  });
+}
diff --git a/tests/lib/mirrors/typedef_library.dart b/tests/lib/mirrors/typedef_library.dart
new file mode 100644
index 0000000..fcb3231
--- /dev/null
+++ b/tests/lib/mirrors/typedef_library.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library bar;
+
+typedef G();
diff --git a/tests/lib/mirrors/typedef_library_test.dart b/tests/lib/mirrors/typedef_library_test.dart
new file mode 100644
index 0000000..6549797
--- /dev/null
+++ b/tests/lib/mirrors/typedef_library_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library foo;
+
+@MirrorsUsed(targets: const ["foo", "bar"])
+import 'dart:mirrors';
+import 'typedef_library.dart';
+
+import 'package:expect/expect.dart';
+
+main() {
+  var barLibrary = currentMirrorSystem().findLibrary(new Symbol("bar"));
+  var gTypedef = barLibrary.declarations[new Symbol("G")];
+  Expect.equals("G", MirrorSystem.getName(gTypedef.simpleName));
+}
diff --git a/tests/standalone/full_coverage_test.dart b/tests/standalone/full_coverage_test.dart
index 04cd94e..05a2645 100644
--- a/tests/standalone/full_coverage_test.dart
+++ b/tests/standalone/full_coverage_test.dart
@@ -49,7 +49,7 @@
   }
 }
 ''',
-    'expectedHits': [-1, 0, 0, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1,
+    'expectedHits': [-1, 0, 0, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1,
                      0, -1, 1, -1, -1]
   },{
     'name': 'closures',
@@ -64,7 +64,7 @@
   });
 }
 ''',
-    'expectedHits': [-1, -1, 1, -1, -1, 1, 1, -1, -1]
+    'expectedHits': [1, -1, 1, -1, -1, 1, 1, -1, -1]
   }
 ];
 
diff --git a/tests/standalone/io/http_detach_socket_test.dart b/tests/standalone/io/http_detach_socket_test.dart
index a9d18b0..7a6c8f2 100644
--- a/tests/standalone/io/http_detach_socket_test.dart
+++ b/tests/standalone/io/http_detach_socket_test.dart
@@ -105,6 +105,7 @@
 void testClientDetachSocket() {
   ServerSocket.bind("127.0.0.1", 0).then((server) {
     server.listen((socket) {
+      int port = server.port;
       socket.write("HTTP/1.1 200 OK\r\n"
                        "\r\n"
                        "Test!");
@@ -120,7 +121,7 @@
           lines.sort();  // Lines 1-3 becomes 3-5 in a fixed order.
           Expect.equals("accept-encoding: gzip", lines[3]);
           Expect.equals("content-length: 0", lines[4]);
-          Expect.equals("host: 127.0.0.1:${server.port}", lines[5]);
+          Expect.equals("host: 127.0.0.1:${port}", lines[5]);
           socket.close();
         });
       server.close();
diff --git a/tests/standalone/io/issue_22636_test.dart b/tests/standalone/io/issue_22636_test.dart
new file mode 100644
index 0000000..d18ebac
--- /dev/null
+++ b/tests/standalone/io/issue_22636_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This test checks that setting writeEventsEnabled on a socket that is
+// closed for read (the other end has closed for write) does not send
+// an additional READ_CLOSED event.
+
+import "dart:io";
+import "dart:async";
+import "package:expect/expect.dart";
+
+final Duration delay = new Duration(milliseconds: 100);
+final List data = new List.generate(100, (i) => i % 20 + 65);
+RawServerSocket server;
+RawSocket client;
+bool serverReadClosedReceived = false;
+bool serverFirstWrite = true;
+
+void serverListen(RawSocket serverSide) {
+  void serveData(RawSocketEvent event) {
+    switch (event) {
+      case RawSocketEvent.WRITE:
+        serverSide.write(data);
+        if (serverFirstWrite) {
+          serverFirstWrite = false;
+          new Future.delayed(delay, () {
+            serverSide.writeEventsEnabled = true;
+          });
+        } else {
+          new Future.delayed(delay, () {
+            Expect.isTrue(serverReadClosedReceived);
+            serverSide.shutdown(SocketDirection.SEND);
+            server.close();
+          });
+        }
+        break;
+      case RawSocketEvent.READ_CLOSED:
+        Expect.isFalse(serverReadClosedReceived);
+        serverReadClosedReceived = true;
+        break;
+    }
+  }
+  serverSide.listen(serveData);
+}
+
+
+test() async {
+  server = await RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0);
+  server.listen(serverListen);
+  client = await RawSocket.connect(InternetAddress.LOOPBACK_IP_V4, server.port);
+  client.shutdown(SocketDirection.SEND);
+  client.listen((RawSocketEvent event) {
+    if (event == RawSocketEvent.READ) {
+      client.read();
+    }
+  });
+}
+
+
+void main() {
+  test();
+}
diff --git a/tests/standalone/io/issue_22637_test.dart b/tests/standalone/io/issue_22637_test.dart
new file mode 100644
index 0000000..50aeb39
--- /dev/null
+++ b/tests/standalone/io/issue_22637_test.dart
@@ -0,0 +1,68 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// This test checks that a shutdown(SocketDirection.SEND) of a socket,
+// when the other end is already closed, does not discard unread data
+// that remains in the connection.
+
+import "dart:io";
+import "dart:async";
+import "package:expect/expect.dart";
+
+RawServerSocket server;
+RawSocket client;
+Duration delay = new Duration(milliseconds: 100);
+
+void serverListen(RawSocket serverSide) {
+  var data = new List.generate(200, (i) => i % 20 + 65);
+  var offset = 0;
+  void serveData(RawSocketEvent event) {
+    if (event == RawSocketEvent.WRITE) {
+      while (offset < data.length) {
+        var written = serverSide.write(data, offset);
+        offset += written;
+        if (written == 0) {
+          serverSide.writeEventsEnabled = true;
+          return;
+        }
+      }
+      serverSide.close();
+      server.close();
+    }
+  }
+  serverSide.listen(serveData);
+}
+
+
+void clientListen(RawSocketEvent event) {
+  if (event == RawSocketEvent.READ) {
+    client.readEventsEnabled = false;
+    new Future.delayed(delay, () {
+      var data = client.read(100);
+      if (data == null) {
+        // If there is no data ready to read, wait until there is data
+        // that can be read, before running the rest of the test.
+        client.readEventsEnabled = true;
+        return;
+      }
+      client.shutdown(SocketDirection.SEND);
+      data = client.read(100);
+      Expect.isNotNull(data);
+      client.close();
+    });      
+  }
+}
+
+
+test() async {
+  server = await RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0);
+  server.listen(serverListen);
+  client = await RawSocket.connect(InternetAddress.LOOPBACK_IP_V4, server.port);
+  client.listen(clientListen);
+}
+
+
+void main() {
+  test();
+}
diff --git a/tests/standalone/io/raw_socket_test.dart b/tests/standalone/io/raw_socket_test.dart
index 4acc6ee..eefdb0c 100644
--- a/tests/standalone/io/raw_socket_test.dart
+++ b/tests/standalone/io/raw_socket_test.dart
@@ -442,6 +442,20 @@
   });
 }
 
+void testClosedError() {
+  asyncStart();
+  RawServerSocket.bind(InternetAddress.LOOPBACK_IP_V4, 0).then((server) {
+    server.listen((socket) { socket.close(); });
+    RawSocket.connect("127.0.0.1", server.port).then((socket) {
+      server.close();
+      socket.close();
+      Expect.throws(() => socket.remotePort, (e) => e is SocketException);
+      Expect.throws(() => socket.remoteAddress, (e) => e is SocketException);
+      asyncEnd();
+    });
+  });
+}
+
 main() {
   asyncStart();
   testArguments();
@@ -457,5 +471,6 @@
   testPauseSocket();
   testSocketZone();
   testSocketZoneError();
+  testClosedError();
   asyncEnd();
 }
diff --git a/tests/standalone/io/socket_exception_test.dart b/tests/standalone/io/socket_exception_test.dart
index 40a5851..d5d4e0e 100644
--- a/tests/standalone/io/socket_exception_test.dart
+++ b/tests/standalone/io/socket_exception_test.dart
@@ -71,8 +71,9 @@
       Expect.isNotNull(server);
      int port = server.port;
       Socket.connect("127.0.0.1", port).then((client) {
-       Expect.isNotNull(client);
+        Expect.isNotNull(client);
         client.close();
+        // First calls for which exceptions are note expected.
         try {
           client.close();
         } on SocketException catch(ex) {
@@ -87,7 +88,6 @@
         } on SocketException catch(ex) {
           exceptionCaught = true;
         } catch (ex) {
-          print(ex);
           wrongExceptionCaught = true;
         }
         Expect.isFalse(exceptionCaught);
@@ -103,6 +103,48 @@
         Expect.isFalse(exceptionCaught);
         Expect.isFalse(wrongExceptionCaught);
 
+        // From here exceptions are expected.
+        exceptionCaught = false;
+        try {
+          client.port;
+        } on SocketException catch(ex) {
+          exceptionCaught = true;
+        } catch (ex) {
+          wrongExceptionCaught = true;
+        }
+        Expect.isTrue(exceptionCaught);
+        Expect.isFalse(wrongExceptionCaught);
+        exceptionCaught = false;
+        try {
+          client.remotePort;
+        } on SocketException catch(ex) {
+          exceptionCaught = true;
+        } catch (ex) {
+          wrongExceptionCaught = true;
+        }
+        Expect.isTrue(exceptionCaught);
+        Expect.isFalse(wrongExceptionCaught);
+        exceptionCaught = false;
+        try {
+          client.address;
+        } on SocketException catch(ex) {
+          exceptionCaught = true;
+        } catch (ex) {
+          wrongExceptionCaught = true;
+        }
+        Expect.isTrue(exceptionCaught);
+        Expect.isFalse(wrongExceptionCaught);
+        exceptionCaught = false;
+        try {
+          client.remoteAddress;
+        } on SocketException catch(ex) {
+          exceptionCaught = true;
+        } catch (ex) {
+          wrongExceptionCaught = true;
+        }
+        Expect.isTrue(exceptionCaught);
+        Expect.isFalse(wrongExceptionCaught);
+
         server.close();
       });
     });
diff --git a/tests/standalone/map_literal_oom_test.dart b/tests/standalone/map_literal_oom_test.dart
new file mode 100644
index 0000000..fb23497
--- /dev/null
+++ b/tests/standalone/map_literal_oom_test.dart
Binary files differ
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index 8f8e406..d6c60ad 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -2,6 +2,9 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+[ $compiler == dart2js && $host_checked ]
+dummy_compiler_test: Crash # Issue 22809
+
 [ $compiler == dart2js ]
 dummy_compiler_test: Slow, Pass
 recursive_import_test: Slow, Pass
@@ -24,3 +27,7 @@
 dummy_compiler_test: Pass, RuntimeError # Issue 17662
 recursive_import_test: Pass, RuntimeError # Issue 17662
 source_mirrors_test: Pass, RuntimeError # Issue 17662
+
+[ $compiler == dart2dart && $builder_tag != new_backend ]
+source_mirrors_test: Slow, Pass
+dummy_compiler_test: Slow, Pass
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS
index ea70c5e..9645a59 100644
--- a/tools/FAKE_COMMITS
+++ b/tools/FAKE_COMMITS
@@ -9,3 +9,4 @@
 Testing svn server
 CIT outage
 Testing update steps
+Testing bots after GOLO <> gcs failures
diff --git a/tools/VERSION b/tools/VERSION
index 1000622..d33a387 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -25,7 +25,7 @@
 #
 CHANNEL dev
 MAJOR 1
-MINOR 9
+MINOR 10
 PATCH 0
-PRERELEASE 10
-PRERELEASE_PATCH 13
+PRERELEASE 0
+PRERELEASE_PATCH 0
diff --git a/tools/dart2js/angular2_testing_deps/CURRENT_ANGULAR_DEPS b/tools/dart2js/angular2_testing_deps/CURRENT_ANGULAR_DEPS
new file mode 100644
index 0000000..561545a
--- /dev/null
+++ b/tools/dart2js/angular2_testing_deps/CURRENT_ANGULAR_DEPS
@@ -0,0 +1 @@
+dd3e6271c259d1fb3e150a4a43bf2f3dac1413e8
diff --git a/tools/dart2js/angular2_testing_deps/README b/tools/dart2js/angular2_testing_deps/README
new file mode 100644
index 0000000..5f070a3
--- /dev/null
+++ b/tools/dart2js/angular2_testing_deps/README
@@ -0,0 +1,3 @@
+This directory contains a single file, CURRENT_ANGULAR_DEPS that we
+use to validate that benchmarks running against angular2 repository is
+using the correct version.
diff --git a/tools/dom/dom.json b/tools/dom/dom.json
index 26b9805..14555cc 100644
--- a/tools/dom/dom.json
+++ b/tools/dom/dom.json
@@ -8259,17 +8259,6 @@
     },
     "support_level": "experimental"
   },
-  "NotificationCenter": {
-    "comment": "http://www.w3.org/TR/notifications/#showing-a-notification",
-    "dart_action": "suppress",
-    "members": {
-      "checkPermission": {},
-      "createHTMLNotification": {},
-      "createNotification": {},
-      "requestPermission": {}
-    },
-    "support_level": "deprecated"
-  },
   "NotificationPermissionCallback": {
     "comment": "http://www.w3.org/TR/notifications/#notificationpermissioncallback",
     "members": {
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index 520404c..f63ad18 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -410,11 +410,6 @@
 };
 
 [DartSupplemental]
-interface WorkerGlobalScope {
-    [DartSuppress] readonly attribute NotificationCenter webkitNotifications;
-};
-
-[DartSupplemental]
 interface AudioBuffer {
     [DartSuppress] attribute float gain;
 };
diff --git a/tools/dom/scripts/dartdomgenerator.py b/tools/dom/scripts/dartdomgenerator.py
index a3fcece..a2fef65 100755
--- a/tools/dom/scripts/dartdomgenerator.py
+++ b/tools/dom/scripts/dartdomgenerator.py
@@ -233,6 +233,9 @@
   parser.add_option('--verbose', dest='logging_level',
                     action='store_false', default=logging.WARNING,
                     help='Output all informational messages')
+  parser.add_option('--examine', dest='examine_idls',
+                    action='store_true', default=None,
+                    help='Analyze IDL files')
   parser.add_option('--logging', dest='logging', type='int',
                     action='store', default=logging.NOTSET,
                     help='Level of logging 20 is Info, 30 is Warnings, 40 is Errors')
@@ -263,7 +266,7 @@
   UpdateCssProperties()
 
   # Parse the IDL and create the database.
-  database = fremontcutbuilder.main(options.parallel, logging_level=logging_level)
+  database = fremontcutbuilder.main(options.parallel, logging_level=logging_level, examine_idls=options.examine_idls)
 
   GenerateFromDatabase(database, dart2js_output_dir, dartium_output_dir,
       options.update_dom_metadata, logging_level)
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index 2f1ad82..5d11efb 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -519,13 +519,19 @@
   'MediaStreamEvent': _rtc_annotations,
   'MediaStreamTrack': _rtc_annotations,
   'MediaStreamTrackEvent': _rtc_annotations,
+  'MediaSource': [
+    # TODO(alanknight): This works on Firefox 33 behind a flag and in Safari
+    # desktop, but not mobile. On theory that static false positives are worse
+    # than negatives, leave those out for now. Update once they're available.
+    "@SupportedBrowser(SupportedBrowser.CHROME)",
+    "@SupportedBrowser(SupportedBrowser.IE, '11')",
+  ],
   'MutationObserver': [
     "@SupportedBrowser(SupportedBrowser.CHROME)",
     "@SupportedBrowser(SupportedBrowser.FIREFOX)",
     "@SupportedBrowser(SupportedBrowser.SAFARI)",
     "@Experimental()",
   ],
-  'NotificationCenter': _webkit_experimental_annotations,
   'Performance': _performance_annotations,
   'PopStateEvent': _history_annotations,
   'RTCIceCandidate': _rtc_annotations,
diff --git a/tools/dom/scripts/database.py b/tools/dom/scripts/database.py
index 951a341..fc8b659 100755
--- a/tools/dom/scripts/database.py
+++ b/tools/dom/scripts/database.py
@@ -275,6 +275,13 @@
       raise RuntimeError('Dictionary %s already exists' % dictionary_name)
     self._all_dictionaries[dictionary_name] = dictionary
 
+  def GetDictionaries(self):
+    """Returns a list of all loaded dictionaries."""
+    res = []
+    for _, dictionary in sorted(self._all_dictionaries.items()):
+      res.append(dictionary)
+    return res
+
   def TransitiveSecondaryParents(self, interface, propagate_event_target):
     """Returns a list of all non-primary parents.
 
diff --git a/tools/dom/scripts/databasebuilder.py b/tools/dom/scripts/databasebuilder.py
index 46c82a8..f61b81b 100755
--- a/tools/dom/scripts/databasebuilder.py
+++ b/tools/dom/scripts/databasebuilder.py
@@ -753,6 +753,7 @@
 
     for interface in self._database.GetInterfaces():
       map(all_types, interface.all(IDLExtAttrFunctionValue))
+      map(all_types, interface.attributes)
       map(all_types, interface.operations)
 
   def fetch_constructor_data(self, options):
@@ -772,3 +773,244 @@
       if 'V8EnabledAtRuntime' in attr.ext_attrs:
         interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \
             attr.ext_attrs['V8EnabledAtRuntime'] or attr.id
+
+  # Iterate of the database looking for relationships between dictionaries and
+  # interfaces marked with NoInterfaceObject.  This mechanism can be used for
+  # other IDL analysis.
+  def examine_database(self):
+    # Contains list of dictionary structure: {'dictionary': dictionary, 'usages': []}
+    self._diag_dictionaries = [];
+    self._dictionaries_used_types = [];
+
+    # Record any dictionary.
+    for dictionary in self._database.GetDictionaries():
+      self._diag_dictionaries.append({'dictionary': dictionary, 'usages': []});
+
+    # Contains list of NoInterfaceObject structures: {'no_interface_object': dictionary, 'usages': []}
+    self._diag_no_interfaces = [];
+    self._no_interfaces_used_types = [];
+
+    # Record any interface with Blink IDL Extended Attribute 'NoInterfaceObject'.
+    for interface in self._database.GetInterfaces():
+      if interface.is_no_interface_object:
+        self._diag_no_interfaces.append({'no_interface_object': interface, 'usages': []});
+
+    for interface in self._database.GetInterfaces():
+      self._constructors(interface)
+      self._constructors(interface, check_dictionaries=False)
+
+      for attribute in interface.attributes:
+        self._attribute_operation(interface, attribute)
+        self._attribute_operation(interface, attribute, check_dictionaries=False)
+
+      for operation in interface.operations:
+        self._attribute_operation(interface, operation)
+        self._attribute_operation(interface, operation, check_dictionaries=False)
+
+    # Report all dictionaries and their usage.
+    self._output_examination()
+    # Report all interface marked with NoInterfaceObject and their usage.
+    self._output_examination(check_dictionaries=False)
+
+    print '\nKey:'
+    print '  (READ-ONLY) - read-only attribute has relationship'
+    print '  (GET/SET)   - attribute has relationship'
+    print '  RETURN      - operation\'s returned value has relationship'
+    print '  (ARGUMENT)  - operation\'s argument(s) has relationship'
+    print ''
+    print '  (New)       - After dictionary name if constructor(s) exist'
+    print '  (Ops,Props,New) after a NoInterfaceObject name is defined as:'
+    print '    Ops       - number of operations for a NoInterfaceObject'
+    print '    Props     - number of properties for a NoInterfaceObject'
+    print '    New       - T(#) number constructors for a NoInterfaceObject'
+    print '                F no constructors for a NoInterfaceObject'
+    print '                e.g., an interface 5 operations, 3 properties and 2'
+    print '                      constructors would display (5,3,T(2))'
+
+    print '\n\nExamination Complete\n'
+
+  def _output_examination(self, check_dictionaries=True):
+    # Output diagnostics. First columns is Dictionary or NoInterfaceObject e.g.,
+    # |  Dictionary  |  Used In Interface  |  Usage Operation/Attribute  |
+    print '\n\n'
+    title_bar = ['Dictionary', 'Used In Interface', 'Usage Operation/Attribute'] if check_dictionaries \
+                else ['NoInterfaceObject (Ops,Props,New)', 'Used In Interface', 'Usage Operation/Attribute']
+    self._tabulate_title(title_bar)
+    diags = self._diag_dictionaries if check_dictionaries else self._diag_no_interfaces
+    for diag in diags:
+      if not(check_dictionaries):
+        interface = diag['no_interface_object']
+        ops_count = len(interface.operations)
+        properties_count = len(interface.attributes)
+        any_constructors = 'Constructor' in interface.ext_attrs
+        constructors = 'T(%s)' % len(interface.ext_attrs['Constructor']) if any_constructors else 'F'
+        interface_detail = '%s (%s,%s,%s)' % \
+            (diag['no_interface_object'].id,
+             ops_count,
+             properties_count,
+             constructors)
+        self._tabulate([interface_detail, '', ''])
+      else:
+        dictionary = diag['dictionary']
+        any_constructors = 'Constructor' in dictionary.ext_attrs
+        self._tabulate(['%s%s' % (dictionary.id, ' (New)' if any_constructors else ''), '', ''])
+      for usage in diag['usages']:
+        detail = ''
+        if 'attribute' in usage:
+          attribute_type = 'READ-ONLY' if not usage['argument'] else 'GET/SET'
+          detail = '(%s) %s' % (attribute_type, usage['attribute'])
+        elif 'operation' in usage:
+          detail = '%s %s%s' % ('RETURN' if usage['result'] else '',
+                                         usage['operation'],
+                                         '(ARGUMENT)' if usage['argument'] else '')
+        self._tabulate([None, usage['interface'], detail])
+      self._tabulate_break()
+
+  # operation_or_attribute either IDLOperation or IDLAttribute if None then
+  # its a constructor (IDLExtAttrFunctionValue).
+  def _mark_usage(self, interface, operation_or_attribute = None, check_dictionaries=True):
+    for diag in self._diag_dictionaries if check_dictionaries else self._diag_no_interfaces:
+      for usage in diag['usages']:
+        if not usage['interface']:
+          usage['interface'] = interface.id
+          if isinstance(operation_or_attribute, IDLOperation):
+            usage['operation'] = operation_or_attribute.id
+            if check_dictionaries:
+              usage['result'] = hasattr(operation_or_attribute.type, 'dictionary') and \
+                operation_or_attribute.type.dictionary == diag['dictionary'].id
+            else:
+              usage['result'] = operation_or_attribute.type.id == diag['no_interface_object'].id
+            usage['argument'] = False
+            for argument in operation_or_attribute.arguments:
+              if check_dictionaries:
+                arg = hasattr(argument.type, 'dictionary') and argument.type.dictionary == diag['dictionary'].id
+              else:
+                arg = argument.type.id == diag['no_interface_object'].id
+              if arg:
+                usage['argument'] = arg
+          elif isinstance(operation_or_attribute, IDLAttribute):
+            usage['attribute'] = operation_or_attribute.id
+            usage['result'] = True
+            usage['argument'] = not operation_or_attribute.is_read_only
+          elif not operation_or_attribute:
+            # Its a constructor only argument is dictionary or interface with NoInterfaceObject.
+            usage['operation'] = 'constructor'
+            usage['result'] = False
+            usage['argument'] = True
+
+  def _remember_usage(self, node, check_dictionaries=True):
+    if check_dictionaries:
+      used_types = self._dictionaries_used_types
+      diag_list = self._diag_dictionaries
+      diag_name = 'dictionary'
+    else:
+      used_types = self._no_interfaces_used_types
+      diag_list = self._diag_no_interfaces
+      diag_name = 'no_interface_object'
+
+    if len(used_types) > 0:
+      normalized_used = list(set(used_types))
+      for recorded_id in normalized_used:
+        for diag in diag_list:
+          if diag[diag_name].id == recorded_id:
+            diag['usages'].append({'interface': None, 'node': node})
+
+  # Iterator function to look for any IDLType that is a dictionary then remember
+  # that dictionary.
+  def _dictionary_used(self, type_node):
+    if hasattr(type_node, 'dictionary'):
+      dictionary_id = type_node.dictionary
+      if self._database.HasDictionary(dictionary_id):
+        for diag_dictionary in self._diag_dictionaries:
+          if diag_dictionary['dictionary'].id == dictionary_id:
+            # Record the dictionary that was referenced.
+            self._dictionaries_used_types.append(dictionary_id)
+            return
+
+      # If we get to this point, the IDL dictionary was never defined ... oops.
+      print 'DIAGNOSE_ERROR: IDL Dictionary %s doesn\'t exist.' % dictionary_id
+
+  # Iterator function to look for any IDLType that is an interface marked with
+  # NoInterfaceObject then remember that interface.
+  def _no_interface_used(self, type_node):
+    if hasattr(type_node, 'id'):
+      no_interface_id = type_node.id
+      if self._database.HasInterface(no_interface_id):
+        no_interface = self._database.GetInterface(no_interface_id)
+        if no_interface.is_no_interface_object:
+          for diag_no_interface in self._diag_no_interfaces:
+            if diag_no_interface['no_interface_object'].id == no_interface_id:
+              # Record the interface marked with NoInterfaceObject.
+              self._no_interfaces_used_types.append(no_interface_id)
+              return
+
+  def _constructors(self, interface, check_dictionaries=True):
+    if check_dictionaries:
+      self._dictionaries_used_types = []
+      constructor_function = self._dictionary_constructor_types
+    else:
+      self._no_interfaces_used_types = [];
+      constructor_function = self._no_interface_constructor_types
+
+    map(constructor_function, interface.all(IDLExtAttrFunctionValue))
+
+    self._mark_usage(interface, check_dictionaries=check_dictionaries)
+
+  # Scan an attribute or operation for a dictionary or interface with NoInterfaceObject
+  # reference.  
+  def _attribute_operation(self, interface, operation_attribute, check_dictionaries=True):
+    if check_dictionaries:
+      self._dictionaries_used_types = []
+      used = self._dictionary_used
+    else:
+      self._no_interfaces_used_types = [];
+      used = self._no_interface_used
+
+    map(used, operation_attribute.all(IDLType))
+
+    self._remember_usage(operation_attribute, check_dictionaries=check_dictionaries)
+    self._mark_usage(interface, operation_attribute, check_dictionaries=check_dictionaries)
+
+  # Iterator function for map to iterate over all constructor types
+  # (IDLExtAttrFunctionValue) that have a dictionary reference.
+  def _dictionary_constructor_types(self, node):
+    self._dictionaries_used_types = []
+    map(self._dictionary_used, node.all(IDLType))
+    self._remember_usage(node)
+
+  # Iterator function for map to iterate over all constructor types
+  # (IDLExtAttrFunctionValue) that reference an interface with NoInterfaceObject.
+  def _no_interface_constructor_types(self, node):
+    self._no_interfaces_used_types = [];
+    map(self._no_interface_used, node.all(IDLType))
+    self._remember_usage(node, check_dictionaries=False)
+
+  # Maximum width of each column.
+  def _TABULATE_WIDTH(self):
+    return 45
+
+  def _tabulate_title(self, row_title):
+    title_separator = "=" * self._TABULATE_WIDTH()
+    self._tabulate([title_separator, title_separator, title_separator])
+    self._tabulate(row_title)
+    self._tabulate([title_separator, title_separator, title_separator])
+
+  def _tabulate_break(self):
+    break_separator = "-" * self._TABULATE_WIDTH()
+    self._tabulate([break_separator, break_separator, break_separator])
+
+  def _tabulate(self, columns):
+    """Tabulate a list of columns for a row.  Each item in columns is a column
+       value each column will be padded up to _TABULATE_WIDTH.  Each
+       column starts/ends with a vertical bar '|' the format a row:
+
+           | columns[0] | columns[1] | columns[2] | ... |
+    """
+    if len(columns) > 0:
+      for column in columns:
+        value = '' if not column else column
+        sys.stdout.write('|{0:^{1}}'.format(value, self._TABULATE_WIDTH()))
+    else:
+      sys.stdout.write('|{0:^{1}}'.format('', self._TABULATE_WIDTH()))
+
+    sys.stdout.write('|\n')
diff --git a/tools/dom/scripts/fremontcutbuilder.py b/tools/dom/scripts/fremontcutbuilder.py
index b8c80a6..ed11625 100755
--- a/tools/dom/scripts/fremontcutbuilder.py
+++ b/tools/dom/scripts/fremontcutbuilder.py
@@ -36,7 +36,7 @@
 ]
 
 def build_database(idl_files, database_dir, feature_defines=None,
-                   logging_level=logging.WARNING):
+                   logging_level=logging.WARNING, examine_idls=False):
   """This code reconstructs the FremontCut IDL database from W3C,
   WebKit and Dart IDL files."""
   current_dir = os.path.dirname(__file__)
@@ -98,6 +98,11 @@
   # Map any IDL defined dictionaries to Dictionary.
   builder.map_dictionaries()
 
+  # Examine all IDL and produce a diagnoses of areas (e.g., list dictionaries
+  # declared and usage, etc.)
+  if examine_idls:
+    builder.examine_database()
+
   conditionals_met = set(
       'ENABLE_' + conditional for conditional in builder.conditionals_met)
   known_conditionals = set(FEATURE_DEFINES + FEATURE_DISABLED)
@@ -116,12 +121,9 @@
 
   print 'Merging interfaces %s seconds' % round(time.time() - start_time, 2)
 
-# TODO(terry): Don't generate the database cache.
-#  db.Save()
-
   return db
 
-def main(parallel=False, logging_level=logging.WARNING):
+def main(parallel=False, logging_level=logging.WARNING, examine_idls=False):
   current_dir = os.path.dirname(__file__)
 
   idl_files = []
@@ -167,7 +169,7 @@
 
   database_dir = os.path.join(current_dir, '..', 'database')
 
-  return build_database(idl_files, database_dir, logging_level=logging_level)
+  return build_database(idl_files, database_dir, logging_level=logging_level, examine_idls=examine_idls)
 
 if __name__ == '__main__':
   sys.exit(main())
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 6699fd3..860d7e1 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -542,6 +542,14 @@
     else:
       factory_parameters = ', '.join(constructor_info.factory_parameters)
 
+    def InputType(type_name):
+      conversion = self._InputConversion(
+          type_name, constructor_info.declared_name)
+      if conversion:
+        return conversion.input_type
+      else:
+        return self._NarrowInputType(type_name) if type_name else 'dynamic'
+
     if constructor_info.pure_dart_constructor:
       # TODO(antonm): use common dispatcher generation for this case as well.
       has_optional = any(param_info.is_optional
@@ -553,7 +561,7 @@
             'factory $CTOR($PARAMS) => '
             '$FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n',
             CTOR=constructor_info._ConstructorFullName(self._DartType),
-            PARAMS=constructor_info.ParametersAsDeclaration(self._DartType),
+            PARAMS=constructor_info.ParametersAsDeclaration(InputType),
             FACTORY=factory_name,
             METADATA=metadata,
             CTOR_FACTORY_NAME=factory_constructor_name,
@@ -570,7 +578,7 @@
             METADATA=metadata,
             FACTORY=factory_name,
             CTOR_FACTORY_NAME=factory_constructor_name,
-            PARAMS=constructor_info.ParametersAsDeclaration(self._DartType),
+            PARAMS=constructor_info.ParametersAsDeclaration(InputType),
             FACTORY_PARAMS=factory_parameters)
 
         for index, param_info in enumerate(constructor_info.param_infos):
@@ -586,6 +594,7 @@
           version, signature_index, argument_count):
         name = emitter.Format('_create_$VERSION', VERSION=version)
         arguments = constructor_info.idl_args[signature_index][:argument_count]
+        args = None
         if self._dart_use_blink:
             type_ids = [p.type.id for p in arguments]
             base_name, rs = \
@@ -593,15 +602,18 @@
             qualified_name = \
                 self.DeriveQualifiedBlinkName(self._interface.id,
                                               base_name)
+            args = constructor_info.ParametersAsArgumentList(argument_count)
         else:
             qualified_name = emitter.Format(
                 '$FACTORY.$NAME',
                 FACTORY=factory_name,
                 NAME=name)
+            (factory_params, converted_arguments) = self._ConvertArgumentTypes(
+                stmts_emitter, arguments, argument_count, constructor_info)
+            args = ', '.join(converted_arguments)
         call_emitter.Emit('$FACTORY_NAME($FACTORY_PARAMS)',
             FACTORY_NAME=qualified_name,
-            FACTORY_PARAMS= \
-                constructor_info.ParametersAsArgumentList(argument_count))
+            FACTORY_PARAMS=args)
         self.EmitStaticFactoryOverload(constructor_info, name, arguments)
 
       def IsOptional(signature_index, argument):
@@ -614,7 +626,7 @@
           CTOR=(('' if not custom_factory_ctr else '_factory')
                 + constructor_full_name),
           METADATA=metadata,
-          PARAMS=constructor_info.ParametersAsDeclaration(self._DartType))
+          PARAMS=constructor_info.ParametersAsDeclaration(InputType))
 
       overload_emitter = self._members_emitter
       overload_declaration = entry_declaration
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index ab07a81..d7b1b86 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -98,7 +98,6 @@
   'IDBAny',
   'MutationEvent',
   'Notation',
-  'NotificationCenter',
   'PagePopupController',
   'RGBColor',
   'RadioNodeList',  # Folded onto NodeList in dart2js.
@@ -163,7 +162,6 @@
   'FontLoader.notifyWhenFontsReady',
   'MediaStreamTrack.getSources',
   'Notification.requestPermission',
-  'NotificationCenter.requestPermission',
   'RTCPeerConnection.setLocalDescription',
   'RTCPeerConnection.setRemoteDescription',
   'StorageInfo.requestQuota',
diff --git a/tools/dom/scripts/idlnode.py b/tools/dom/scripts/idlnode.py
index 5d94ab6..e09c8c8 100755
--- a/tools/dom/scripts/idlnode.py
+++ b/tools/dom/scripts/idlnode.py
@@ -508,6 +508,7 @@
     return self.values()
 
 
+# IDLExtAttrFunctionValue is used for constructors defined in the IDL.
 class IDLExtAttrFunctionValue(IDLNode):
   """IDLExtAttrFunctionValue."""
   def __init__(self, func_value_ast, arg_list_ast, is_blink=False):
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index b747154..d81c614 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -58,6 +58,7 @@
     'Document.createTreeWalker',
     'DOMException.name',
     'DOMException.toString',
+    'Element.animate',
     'Element.createShadowRoot',
     'Element.insertAdjacentElement',
     'Element.insertAdjacentHTML',
@@ -407,6 +408,7 @@
 ]
 
 js_support_checks = dict({
+    'AnimationPlayer': "JS('bool', '!!(document.body.animate)')",
     'AudioContext': "JS('bool', '!!(window.AudioContext ||"
         " window.webkitAudioContext)')",
     'Crypto':
@@ -421,7 +423,8 @@
     'HTMLTemplateElement': ElemSupportStr('template'),
     'MediaStreamEvent': "Device.isEventTypeSupported('MediaStreamEvent')",
     'MediaStreamTrackEvent': "Device.isEventTypeSupported('MediaStreamTrackEvent')",
-    'NotificationCenter': "JS('bool', '!!(window.webkitNotifications)')",
+    'MediaSource': "JS('bool', '!!(window.MediaSource)')",
+    'Notification': "JS('bool', '!!(window.Notification)')",
     'Performance': "JS('bool', '!!(window.performance)')",
     'SpeechRecognition': "JS('bool', '!!(window.SpeechRecognition || "
         "window.webkitSpeechRecognition)')",
@@ -996,6 +999,53 @@
         NAME=html_name,
         PARAMS=info.ParametersAsDeclaration(self._NarrowInputType))
 
+  def _ConvertArgumentTypes(
+          self, stmts_emitter, arguments, argument_count, info):
+    temp_version = [0]
+    converted_arguments = []  
+    target_parameters = []
+    for position, arg in enumerate(arguments[:argument_count]):
+      conversion = self._InputConversion(arg.type.id, info.declared_name)
+      param_name = arguments[position].id
+      if conversion:
+        temp_version[0] += 1
+        temp_name = '%s_%s' % (param_name, temp_version[0])
+        temp_type = conversion.output_type
+        stmts_emitter.Emit(
+            '$(INDENT)$TYPE $NAME = $CONVERT($ARG);\n',
+            TYPE=TypeOrVar(temp_type),
+            NAME=temp_name,
+            CONVERT=conversion.function_name,
+            ARG=info.param_infos[position].name)
+        converted_arguments.append(temp_name)
+        param_type = temp_type
+        verified_type = temp_type  # verified by assignment in checked mode.
+      else:
+        converted_arguments.append(info.param_infos[position].name)
+        param_type = self._NarrowInputType(arg.type.id)
+        # Verified by argument checking on entry to the dispatcher.
+
+        verified_type = self._InputType(
+            info.param_infos[position].type_id, info)
+        # The native method does not need an argument type if we know the type.
+        # But we do need the native methods to have correct function types, so
+        # be conservative.
+        if param_type == verified_type:
+          if param_type in ['String', 'num', 'int', 'double', 'bool', 'Object']:
+            param_type = 'dynamic'
+
+      target_parameters.append(
+          '%s%s' % (TypeOrNothing(param_type), param_name))
+
+    return target_parameters, converted_arguments
+
+  def _InputType(self, type_name, info):
+    conversion = self._InputConversion(type_name, info.declared_name)
+    if conversion:
+      return conversion.input_type
+    else:
+      return self._NarrowInputType(type_name) if type_name else 'dynamic'
+
   def _AddOperationWithConversions(self, info, html_name):
     # Assert all operations have same return type.
     assert len(set([op.type.id for op in info.operations])) == 1
@@ -1008,57 +1058,21 @@
       return_type = self._NarrowInputType(info.type_name)
       native_return_type = return_type
 
-    def InputType(type_name):
-      conversion = self._InputConversion(type_name, info.declared_name)
-      if conversion:
-        return conversion.input_type
-      else:
-        return self._NarrowInputType(type_name) if type_name else 'dynamic'
-
     parameter_names = [param_info.name for param_info in info.param_infos]
-    parameter_types = [InputType(param_info.type_id)
+    parameter_types = [self._InputType(param_info.type_id, info)
                        for param_info in info.param_infos]
     operations = info.operations
 
-    temp_version = [0]
+    def InputType(type_name):
+        return self._InputType(type_name, info)
 
     def GenerateCall(
         stmts_emitter, call_emitter, version, operation, argument_count):
       target = '_%s_%d' % (
           html_name[1:] if html_name.startswith('_') else html_name, version);
-      arguments = []
-      target_parameters = []
-      for position, arg in enumerate(operation.arguments[:argument_count]):
-        conversion = self._InputConversion(arg.type.id, operation.id)
-        param_name = operation.arguments[position].id
-        if conversion:
-          temp_version[0] += 1
-          temp_name = '%s_%s' % (param_name, temp_version[0])
-          temp_type = conversion.output_type
-          stmts_emitter.Emit(
-              '$(INDENT)$TYPE $NAME = $CONVERT($ARG);\n',
-              TYPE=TypeOrVar(temp_type),
-              NAME=temp_name,
-              CONVERT=conversion.function_name,
-              ARG=parameter_names[position])
-          arguments.append(temp_name)
-          param_type = temp_type
-          verified_type = temp_type  # verified by assignment in checked mode.
-        else:
-          arguments.append(parameter_names[position])
-          param_type = self._NarrowInputType(arg.type.id)
-          # Verified by argument checking on entry to the dispatcher.
 
-          verified_type = InputType(info.param_infos[position].type_id)
-          # The native method does not need an argument type if we know the type.
-          # But we do need the native methods to have correct function types, so
-          # be conservative.
-          if param_type == verified_type:
-            if param_type in ['String', 'num', 'int', 'double', 'bool', 'Object']:
-              param_type = 'dynamic'
-
-        target_parameters.append(
-            '%s%s' % (TypeOrNothing(param_type), param_name))
+      (target_parameters, arguments) = self._ConvertArgumentTypes(
+          stmts_emitter, operation.arguments, argument_count, info)
 
       argument_list = ', '.join(arguments)
       # TODO(sra): If the native method has zero type checks, we can 'inline' is
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index dd2cdbd..541b5ba 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -393,6 +393,9 @@
   def CustomJSMembers(self):
     return {}
 
+  def _InputConversion(self, type_name, info):
+    return None
+
   def GenerateCallback(self, info):
     if IsPureInterface(self._interface.id) or IsCustomType(self._interface.id):
       return
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 38209ae..a41c6a6 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -779,6 +779,57 @@
   @deprecated
   void leftView() {}
 
+$if DART2JS
+  /**
+   * Creates a new AnimationEffect object whose target element is the object
+   * on which the method is called, and calls the play() method of the
+   * AnimationTimeline object of the document timeline of the node document
+   * of the element, passing the newly created AnimationEffect as the argument
+   * to the method. Returns an AnimationPlayer for the effect.
+   *
+   * Examples
+   *
+   *     var animation = elem.animate([{"opacity": 75}, {"opacity": 0}], 200);
+   *
+   *     var animation = elem.animate([
+   *       {"transform": "translate(100px, -100%)"},
+   *       {"transform" : "translate(400px, 500px)"}
+   *     ], 1500);  
+   *
+   * The [frames] parameter is an Iterable<Map>, where the
+   * map entries specify CSS animation effects. The
+   * [timing] paramter can be a double, representing the number of milliseconds
+   * for the transition, or a Map with fields corresponding to those
+   * of the [Timing] object.
+   *
+   * This is not yet supported in Dartium.
+  **/
+// TODO(alanknight): Correct above comment once it works in Dartium.
+  @Experimental
+  @SupportedBrowser(SupportedBrowser.CHROME, '36')
+  AnimationPlayer animate(Iterable<Map<String, dynamic>> frames, [timing]) {
+    if (frames is! Iterable || !(frames.every((x) => x is Map))) {
+      throw new ArgumentError("The frames parameter should be a List of Maps "
+          "with frame information");
+    }
+    var convertedFrames = frames;
+    if (convertedFrames is Iterable) {
+      convertedFrames = frames.map(convertDartToNative_Dictionary).toList();
+    }
+    var convertedTiming = timing;
+    if (convertedTiming is Map) {
+      convertedTiming = convertDartToNative_Dictionary(convertedTiming);
+    }
+    return convertedTiming == null
+      ? _animate(convertedFrames)
+      : _animate(convertedFrames, convertedTiming);
+  }
+
+  @DomName('Element.animate')
+  @JSName('animate')
+  @Experimental() // untriaged
+  AnimationPlayer _animate(Object effect, [timing]) native;
+$endif
   /**
    * Called by the DOM whenever an attribute on this has been changed.
    */
diff --git a/tools/dom/templates/html/impl/impl_Notification.darttemplate b/tools/dom/templates/html/impl/impl_Notification.darttemplate
index 03efd63..5a3a5e1 100644
--- a/tools/dom/templates/html/impl/impl_Notification.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Notification.darttemplate
@@ -6,16 +6,15 @@
 
 $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
 
-  factory $CLASSNAME(String title, {String titleDir: null, String body: null,
-      String bodyDir: null, String tag: null, String iconUrl: null}) {
+  factory $CLASSNAME(String title, {String dir: null, String body: null,
+      String lang: null, String tag: null, String icon: null}) {
 
     var parsedOptions = {};
-    if (titleDir != null) parsedOptions['titleDir'] = titleDir;
+    if (dir != null) parsedOptions['dir'] = dir;
     if (body != null) parsedOptions['body'] = body;
-    if (bodyDir != null) parsedOptions['bodyDir'] = bodyDir;
+    if (lang != null) parsedOptions['lang'] = lang;
     if (tag != null) parsedOptions['tag'] = tag;
-    if (iconUrl != null) parsedOptions['iconUrl'] = iconUrl;
-
+    if (icon != null) parsedOptions['icon'] = icon;
     return $CLASSNAME._factory$CLASSNAME(title, parsedOptions);
   }
 $!MEMBERS
diff --git a/tools/gyp_dart.py b/tools/gyp_dart.py
index 8bc3984..cce1b34 100644
--- a/tools/gyp_dart.py
+++ b/tools/gyp_dart.py
@@ -12,8 +12,11 @@
 import subprocess
 import sys
 
+SCRIPT_DIR = os.path.dirname(sys.argv[0])
+DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
+
 def execute(args):
-  process = subprocess.Popen(args)
+  process = subprocess.Popen(args, cwd=DART_ROOT)
   process.wait()
   return process.returncode
 
@@ -23,11 +26,11 @@
     component = sys.argv[1]
 
   component_gyp_files = {
-    'all' : 'dart/dart.gyp',
-    'runtime' : 'dart/runtime/dart-runtime.gyp',
+    'all' : 'dart.gyp',
+    'runtime' : 'runtime/dart-runtime.gyp',
   }
-  args = ['python', 'dart/third_party/gyp/gyp_main.py',
-          '--depth=dart', '-Idart/tools/gyp/all.gypi',
+  args = ['python', '-S', 'third_party/gyp/gyp_main.py',
+          '--depth=.', '-Itools/gyp/all.gypi',
           component_gyp_files[component]]
 
   if sys.platform == 'win32':
diff --git a/tools/testing/dart/multitest.dart b/tools/testing/dart/multitest.dart
index 3aed790..005cdc0 100644
--- a/tools/testing/dart/multitest.dart
+++ b/tools/testing/dart/multitest.dart
@@ -83,25 +83,27 @@
        'static type warning', 'dynamic type error',
        'checked mode compile-time error']);
 
-  List<String> testTemplate = new List<String>();
-  testTemplate.add(
-      '// Test created from multitest named ${filePath.toNativePath()}.');
   // Create the set of multitests, which will have a new test added each
   // time we see a multitest line with a new key.
   Map<String, List<String>> testsAsLines = new Map<String, List<String>>();
 
+  // Add the default case with key "none".
+  testsAsLines['none'] = new List<String>();
+  outcomes['none'] = new Set<String>();
+
   int lineCount = 0;
   for (String line in lines) {
     lineCount++;
     var annotation = new _Annotation.from(line);
     if (annotation != null) {
       testsAsLines.putIfAbsent(annotation.key,
-          () => new List<String>.from(testTemplate)).add(line);
-      outcomes.putIfAbsent(annotation.key,
-          () => new Set<String>());
-      if (annotation.rest == 'continued') {
-        continue;
-      } else {
+          () => new List<String>.from(testsAsLines["none"]));
+      // Add line to test with annotation.key as key, empty line to the rest.
+      for (var key in testsAsLines.keys) {
+        testsAsLines[key].add(annotation.key == key ? line : "");
+      }
+      outcomes.putIfAbsent(annotation.key, () => new Set<String>());
+      if (annotation.rest != 'continued') {
         for (String nextOutcome in annotation.outcomesList) {
           if (validMultitestOutcomes.contains(nextOutcome)) {
             outcomes[annotation.key].add(nextOutcome);
@@ -113,10 +115,15 @@
         }
       }
     } else {
-      testTemplate.add(line);
       for (var test in testsAsLines.values) test.add(line);
     }
   }
+  // End marker, has a final line separator so we don't need to add it after
+  // joining the lines.
+  var marker =
+      '// Test created from multitest named ${filePath.toNativePath()}.'
+      '$line_separator';
+  for (var test in testsAsLines.values) test.add(marker);
 
   var keysToDelete = [];
   // Check that every key (other than the none case) has at least one outcome
@@ -131,16 +138,12 @@
     }
   }
   // If a key/multitest was marked for deletion, do the necessary cleanup.
-  keysToDelete.forEach((key) => outcomes.remove(key));
-  keysToDelete.forEach((key) => testsAsLines.remove(key));
-
-  // Add the template, with no multitest lines, as a test with key 'none'.
-  testsAsLines['none'] = testTemplate;
-  outcomes['none'] = new Set<String>();
+  keysToDelete.forEach(outcomes.remove);
+  keysToDelete.forEach(testsAsLines.remove);
 
   // Copy all the tests into the output map tests, as multiline strings.
   for (String key in testsAsLines.keys) {
-    tests[key] = testsAsLines[key].join(line_separator) + line_separator;
+    tests[key] = testsAsLines[key].join(line_separator);
   }
 }
 
@@ -185,7 +188,7 @@
       '^(?:@.*\\s+)?' // Allow for a meta-data annotation.
       '(import|part)'
       '\\s+["\']'
-      '(?!(dart:|dart-ext:|package:|/))' // Look-ahead: not in package.
+      '(?!(dart:|dart-ext:|data:|package:|/))' // Look-ahead: not in package.
       '([^"\']*)' // The path to the imported file.
       '["\']');
   while (!toSearch.isEmpty) {
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 40d238d..2fb96b4 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -1350,7 +1350,7 @@
         // we will have more information and can remove this warning.
         stderr = "This test has not notified test.py that it started running. "
                  "This could be a bug in test.py! "
-                 "Please contact ricow/kustermann";
+                 "Please contact ricow/whesse";
       }
     }
 
@@ -2828,7 +2828,7 @@
         cancelDebugTimer();
         _debugTimer = new Timer(debugTimerDuration, () {
           print("The debug timer of test.dart expired. Please report this issue"
-                " to ricow/kustermann and provide the following information:");
+                " to ricow/whesse and provide the following information:");
           print("");
           print("Graph is sealed: ${_graph.isSealed}");
           print("");
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 0689ad7..2e97c05 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -1416,9 +1416,13 @@
           new File.fromUri(copiedScript).writeAsStringSync(
               new File.fromUri(script).readAsStringSync());
         } else {
+          var destination = copiedScript.toFilePath();
+          if (compileToJS) {
+            destination = destination.replaceFirst(dartExtension, '.js');
+          }
           commands.add(_compileCommand(
               script.toFilePath(),
-              copiedScript.toFilePath().replaceFirst(dartExtension, '.js'),
+              destination,
               compiler,
               tempDir,
               info.optionsFromFile));
@@ -1465,7 +1469,6 @@
       packageRootArgument(optionsFromFile['packageRoot']);
     if (packageRoot != null) args.add(packageRoot);
     args.add('--out=$outputFile');
-    if (configuration['csp']) args.add('--csp');
     args.add(inputFile);
     List<String> options = optionsFromFile['sharedOptions'];
     if (options != null) args.addAll(options);
@@ -2216,6 +2219,9 @@
         configuration["minified"]) {
       args.add("--minify");
     }
+    if (compiler == "dart2js" && configuration["csp"]) {
+      args.add("--csp");
+    }
     if (compiler == "dartanalyzer" || compiler == "dart2analyzer") {
       args.add("--show-package-warnings");
       args.add("--enable-async");