Version 1.6.0-dev.3.0

svn merge -r 38082:38144 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@38145 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 9cbebf7..d301b07 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -5,7 +5,7 @@
 \usepackage{hyperref}
 \newcommand{\code}[1]{{\sf #1}}
 \title{Dart Programming Language  Specification \\
-{\large Version 1.4}}
+{\large Version 1.6}}
 %\author{The Dart Team}
 \begin{document}
 \maketitle
@@ -1253,7 +1253,7 @@
 Default values specified in $k$ would be ignored, since it is the {\em actual} parameters that are passed to $k^\prime$. Hence, default values are disallowed.
 }
 
-It is a compile-time error if a redirecting factory constructor redirects to itself, either directly or indirectly via a sequence of redirections. %does not redirect to a non-redirecting factory constructor or to a generative constructor in a finite number of steps.
+It is a run-time error if a redirecting factory constructor redirects to itself, either directly or indirectly via a sequence of redirections. %does not redirect to a non-redirecting factory constructor or to a generative constructor in a finite number of steps.
 
 % Make this a runtime error so deferred loading works
 
@@ -1332,12 +1332,18 @@
 
 \commentary{All the work of a constant constructor must be handled via its initializers.}
 
-It is a compile-time error if a constant constructor is declared by a class that has a non-final instance variable. 
+It is a compile-time error if a constant constructor is declared by a class that has a non-final instance variable.  
 
 \commentary{
 The above refers to both locally declared and inherited instance variables.
 }
 
+It is a compile-time error if a constant constructor is declared by a class $C$ if any instance variable declared in $C$ is initialized with an expression that is not a constant expression.
+
+\commentary {
+A superclass of $C$ cannot declare such an initializer either, because it must necessarily declare constant constructor as well (unless it is \code{Object}, which declares no instance variables).
+}
+
 The superinitializer that appears, explicitly or implicitly, in the initializer list of a constant constructor must specify a constant constructor of the superclass of the immediately enclosing class or a compile-time error occurs.
 
 Any expression that appears within the initializer list of a constant constructor must be a potentially constant expression, or a compile-time error occurs. 
@@ -1345,7 +1351,7 @@
 A {\em potentially constant expression} is an expression $e$ that would be a valid constant expression if all formal parameters of $e$'s immediately enclosing constant constructor were treated as compile-time constants that were guaranteed to evaluate to an integer, boolean or string value as required by their immediately enclosing superexpression.
 
 \commentary{
-Note that a parameter that is not used in an superexpression that is restricted to certain types can be a constant of any type. For example}
+Note that a parameter that is not used in a superexpression that is restricted to certain types can be a constant of any type. For example}
 
 \begin{dartCode}
 \CLASS{} A \{
@@ -1479,7 +1485,7 @@
 \subsection{Superclasses}
 \label{superclasses}
 
-The superclass of a class $C$ that has a with clause \code{\WITH{} $M_1, \ldots, M_k$} and an extends clause \code{\EXTENDS{} S} is the application of mixin (\ref{mixins}) $M_k* \cdots * M_1$  to S.  If no with clause is specified then  the \EXTENDS{} clause of a class $C$ specifies its superclass. If no \EXTENDS{} clause is specified, then either:
+The superclass of a class $C$ that has a with clause \code{\WITH{} $M_1, \ldots, M_k$} and an extends clause \code{\EXTENDS{} S} is the application of mixin (\ref{mixins}) $M_k* \cdots * M_1$  to S.  If no \WITH{} clause is specified then  the \EXTENDS{} clause of a class $C$ specifies its superclass. If no \EXTENDS{} clause is specified, then either:
 \begin{itemize}
 \item $C$ is \code{Object}, which has no superclass. OR
 \item Class $C$ is  deemed to have an \EXTENDS{} clause of the form \code{\EXTENDS{} Object}, and the rules above apply. 
@@ -1499,7 +1505,7 @@
 %} 
 
 %It is a compile-time error if  the \EXTENDS{} clause of a class $C$ includes a type expression that does not denote a class available in the lexical scope of $C$. 
-It is a compile-time error if  the \EXTENDS{} clause of a class $C$ specifies a malformed  type as a superclass.
+It is a compile-time error if  the \EXTENDS{} clause of a class $C$ specifies a malformed  type or a deferred type (\ref{staticTypes}) as a superclass.
 % too strict? Do we e want extends List<Undeclared> to work as List<dynamic>? 
 
 \commentary{ The type parameters of a generic class are available in the lexical scope of the superclass clause, potentially shadowing classes in the surrounding scope. The following code is therefore illegal and should cause a compile-time error:
@@ -1622,7 +1628,7 @@
     .
 \end{grammar}
 
-It is a compile-time error if  the \IMPLEMENTS{}  clause of a class $C$ specifies a type variable as a superinterface. It is a compile-time error if  the  \IMPLEMENTS{} clause of a class $C$ specifies  a malformed type as a superinterface  It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies type \DYNAMIC{} as a superinterface. It is a compile-time error if  the  \IMPLEMENTS{} clause of a class $C$ specifies  a type $T$ as a superinterface more than once.
+It is a compile-time error if  the \IMPLEMENTS{}  clause of a class $C$ specifies a type variable as a superinterface. It is a compile-time error if  the  \IMPLEMENTS{} clause of a class $C$ specifies  a malformed type or deferred type (\ref{staticTypes}) as a superinterface  It is a compile-time error if the \IMPLEMENTS{} clause of a class $C$ specifies type \DYNAMIC{} as a superinterface. It is a compile-time error if  the  \IMPLEMENTS{} clause of a class $C$ specifies  a type $T$ as a superinterface more than once.
 It is a compile-time error if the superclass of a class $C$ is specified as a superinterface of $C$.
 
 \rationale{
@@ -1788,7 +1794,8 @@
 \subsection{Mixin Application}
 \label{mixinApplication}
 
-A mixin may be applied to a superclass, yielding a new class. Mixin application occurs when a mixin is mixed into a class declaration via its \WITH{} clause.  The mixin application may be used to extend a class per section (\ref{classes}); alternately, a class may be defined as a mixin application as described in this section.
+A mixin may be applied to a superclass, yielding a new class. Mixin application occurs when a mixin is mixed into a class declaration via its \WITH{} clause.  The mixin application may be used to extend a class per section (\ref{classes}); alternately, a class may be defined as a mixin application as described in this section.   It is a compile-time error if the \WITH{} clause of a mixin application $C$ includes a deferred type expression.
+
 
 \begin{grammar}
 {\bf  mixinApplicationClass:}
@@ -2112,17 +2119,17 @@
 \rationale{It would be tempting to allow string interpolation where the interpolated value is any compile-time constant.  However, this would require running the \code{toString()} method for constant objects, which could contain arbitrary code.}
 \item A literal symbol (\ref{symbols}).
 \item \NULL{} (\ref{null}).
-\item A qualified reference to a static constant variable (\ref{variables}). 
-\commentary {For example, If class C declares a constant static variable v, C.v is a constant. The same is true if C is accessed via a prefix p; p.C.v is a constant.
+\item A qualified reference to a static constant variable (\ref{variables}) that is not qualified by a deferred prefix. 
+\commentary {For example, If class C declares a constant static variable v, C.v is a constant. The same is true if C is accessed via a prefix p; p.C.v is a constant  unless p is a deferred prefix.
 }
 \item An identifier expression that denotes a constant variable. %CHANGE in googledoc
 \item A simple or qualified identifier denoting a class or a type alias. 
 \commentary {For example, if C is a class or typedef C is a constant, and if C is imported with a prefix p,  p.C is a constant.
 }
-\item A constant constructor invocation (\ref{const}).  
+\item A constant constructor invocation (\ref{const}) that is not qualified by a deferred prefix.  
 \item A constant list literal (\ref{lists}).
 \item A constant map literal (\ref{maps}).
-\item A simple or qualified identifier denoting a top-level function (\ref{functions}) or a static method (\ref{staticMethods}).
+\item A simple or qualified identifier denoting a top-level function (\ref{functions}) or a static method (\ref{staticMethods}) that is not qualified by a deferred prefix.
 \item A parenthesized expression \code{($e$)} where $e$ is a constant expression.
 \item An expression of the form \code{identical($e_1$, $e_2$)} where $e_1$ and $e_2$ are constant expressions  and \code{identical()} is statically bound to the predefined dart function   \code{identical()} discussed above (\ref{objectIdentity}).
 \item An expression of one of the forms  \code{$e_1$ == $e_2$} or  \code{$e_1$ != $e_2$} where $e_1$ and $e_2$ are constant expressions that evaluate to a numeric, string or boolean value or to \NULL{}.
@@ -2817,6 +2824,8 @@
 
 First, the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is evaluated. 
 
+If $T$ is a deferred type with prefix $p$, then if $p$ has not been successfully loaded, a dynamic error occurs.
+
 Then, if $q$ is a non-factory constructor of an abstract class then an \code{AbstractClassInstantiationError} is thrown.
 
 If $T$  is malformed or if $T$ is a type variable a dynamic error occurs. In checked mode, if $T$ or any of its superclasses is malbounded a dynamic error occurs.
@@ -2838,7 +2847,8 @@
 
 If $q$ is a redirecting factory constructor of the form $T(p_1, \ldots, p_{n+k}) = c;$ or of the form  $T.id(p_1, \ldots, p_{n+k}) = c;$ then the result of the evaluation of $e$ is equivalent to evaluating the expression 
 
-$[V_1,  \ldots, V_m/T_1,  \ldots, T_m]($\code{\NEW{} $c(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k}))$}.
+$[V_1,  \ldots, V_m/T_1,  \ldots, T_m]($\code{\NEW{} $c(a_1, \ldots, a_n, x_{n+1}: a_{n+1}, \ldots, x_{n+k}: a_{n+k}))$}.  If evaluation of $q$ causes $q$ to be re-evaluated cyclically, a runtime error occurs.
+
 
 Otherwise, the body of $q$ is executed with respect to the bindings that resulted from the evaluation of the argument list and the type parameters (if any) of $q$ bound to the actual type arguments $V_1, \ldots, V_l$ resulting in an object $i$. The result of the evaluation of $e$ is $i$.
 
@@ -2879,7 +2889,7 @@
 
 \CONST{} $T.id(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ 
 
-or the form  \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. It is a compile-time error if $T$ does not denote a class accessible in the current scope. 
+or the form  \CONST{} $T(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. It is a compile-time error if $T$ does not denote a class accessible in the current scope.  It is a compile-time error if $T$ is a deferred type (\ref{staticTypes}).
 
 \commentary{In particular, $T$ may not be a type variable.}
 
@@ -3148,6 +3158,14 @@
 
 where $id$ is an identifier or an identifier qualified with a library prefix. 
 
+If $id$ is qualified with a deferred prefix $p$ and $p$ has not been successfully loaded, then:
+\begin{itemize}
+\item
+If the invocation has the form $p$\code{.loadLibrary()} then an attempt to load the library represented by the prefix $p$ is initiated as discussed in section \ref{imports}. 
+\item
+ Otherwise, a \code{NoSuchMethodError} is thrown.
+ \end{itemize}
+
 If there exists a lexically visible declaration named $id$, let $f_{id}$ be the innermost such declaration. Then:
 \begin{itemize}
 \item
@@ -3305,7 +3323,8 @@
 
 Evaluation of $i$ proceeds as follows:
 
-If $C$ does not declare a static method or getter $m$ then the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is evaluated, after which a \code{NoSuchMethodError} is thrown. 
+If $C$ is a deferred type  (\ref{staticTypes}) with prefix $p$, and $p$ has not been successfully loaded, or
+if $C$ does not declare a static method or getter $m$ then the argument list $(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ is evaluated, after which a \code{NoSuchMethodError} is thrown. 
 
 Otherwise, evaluation proceeds as follows:
 \begin{itemize}
@@ -3431,8 +3450,18 @@
 \end{itemize}
 Then the method \code{noSuchMethod()} is looked up in $S$ and invoked  with argument $im$, and the result of this invocation is the result of evaluating $i$.
 
+
+
 It is a static type warning if $S$ does not have a getter named $m$.  The static type of $i$ is the declared return type of $S.m$, if $S.m$ exists; otherwise the static type of $i$  is  \DYNAMIC{}. 
 
+Evaluation of a getter invocation of the form $p.C.v$, where $p$ is a deferred prefix, proceeds as follows:
+
+If $p$ has been successfully loaded, the assignment is evaluated exactly like the invocation $K.v$, where $K$ denotes the top level member $C$ of the library represented by $p$. Otherwise a \code{NoSuchMethodError} is thrown.
+
+
+Evaluation of a top-level getter invocation $i$ of the form $p.m$, where $p$ is a deferred prefix and  $m$ is an identifier, proceeds as follows:
+
+If $p$ has been successfully loaded, the invocation is evaluated exactly like the invocation $w$, where $w$ denotes the top level member named $m$ of the library represented by $p$. Otherwise a \code{NoSuchMethodError} is thrown.
  
 
 
@@ -3507,6 +3536,14 @@
 
 Then the method \code{noSuchMethod()} is looked up in $o_1$ and invoked  with argument $im$. The value of the assignment expression is $o_2$ irrespective of whether setter lookup has failed or succeeded.
 
+Evaluation of an assignment of the form $p.v \code{=} e$, where $p$ is a deferred prefix, proceeds as follows:
+
+If $p$ has been successfully loaded, the assignment is evaluated exactly like the assignment $w \code{=} e$, where $w$ denotes the top level member named $v$ of the library represented by $p$. Otherwise, $e$ is evaluated and then a \code{NoSuchMethodError} is thrown.
+
+Evaluation of an assignment of the form $p.C.v \code{=} e$, where $p$ is a deferred prefix, proceeds as follows:
+
+If $p$ has been successfully loaded, the assignment is evaluated exactly like the assignment $K.v = e$, where $K$ denotes the top level member $C$ of the library represented by $p$. Otherwise $e$ is evaluated and then a \code{NoSuchMethodError} is thrown.
+
 In checked mode, it is a dynamic type error if $o_2$ is not \NULL{} and the interface of the class of $o_2$ is not a subtype of the actual type of $e_1.v$.
 
 Let $T$ be the static type of $e_1$. It is a static type warning if $T$ does not have an accessible instance setter named $v=$ unless $T$ or a superinterface of $T$ is annotated with an annotation denoting a constant identical to the constant \code{@proxy} defined in \code{dart:core}. It is a static type warning if the static type of $e_2$ may not be assigned to $T$.   The static type of the expression $e_1v$ \code{=} $e_2$ is the static type of $e_2$.
@@ -3523,7 +3560,8 @@
 \label{compoundAssignment}
 
 A compound assignment of the form $v$ $op\code{=} e$ is equivalent to $v \code{=} v$ $op$ $e$. A compound assignment of the form $C.v$ $op \code{=} e$ is equivalent to $C.v \code{=} C.v$ $op$ $e$. A compound assignment of the form $e_1.v$ $op = e_2$ is equivalent to \code{((x) $=>$ x.v = x.v $op$ $e_2$)($e_1$)} where $x$ is a variable that is not used in $e_2$. A compound assignment of the form  $e_1[e_2]$ $op\code{=} e_3$ is equivalent to 
-\code{((a, i) $=>$ a[i] = a[i] $op$ $e_3$)($e_1, e_2$)} where $a$ and $i$ are a variables that are not used in $e_3$. 
+\code{((a, i) $=>$ a[i] = a[i] $op$ $e_3$)($e_1, e_2$)} where $a$ and $i$ are a variables that are not used in $e_3$. A compound assignment of the form $p.v$ $op\code{=} e$, where $p$ is a deferred prefix,  is equivalent to $p.v \code{=} p.v$ $op$ $e$. A compound assignment of the form $p.C.v$ $op\code{=} e$, where $p$ is a deferred prefix,  is equivalent to $p.C.v \code{=} p.C.v$ $op$ $e$.
+
 
 \begin{grammar}
 {\bf compoundAssignmentOperator:}`*=';
@@ -4072,7 +4110,7 @@
  
  Evaluation of the is-expression \code{$e$ \IS{} $T$} proceeds as follows:
 
-The expression $e$ is evaluated to a value $v$. Then, if $T$ is malformed, a dynamic error occurs. Otherwise, if the interface of the class of $v$ is a subtype of $T$, the is-expression evaluates to true. Otherwise it evaluates to false.
+The expression $e$ is evaluated to a value $v$. Then, if $T$ is a malformed or deferred type (\ref{staticTypes}), a dynamic error occurs. Otherwise, if the interface of the class of $v$ is a subtype of $T$, the is-expression evaluates to true. Otherwise it evaluates to false.
 
 \commentary{It follows that \code{$e$ \IS{} Object} is always true. This makes sense in a language where everything is an object. 
 
@@ -4117,7 +4155,7 @@
  
  Evaluation of the cast expression \code{$e$ \AS{} $T$} proceeds as follows:
 
-The expression $e$ is evaluated to a value $v$. Then, if $T$ is malformed, a dynamic error occurs. Otherwise, if the interface of the class of $v$ is a subtype of $T$, the cast expression evaluates to $v$. Otherwise, if $v$ is \NULL{}, the cast expression evaluates to $v$. 
+The expression $e$ is evaluated to a value $v$. Then, if $T$ is a malformed or deferred type (\ref{staticTypes}), a dynamic error occurs. Otherwise, if the interface of the class of $v$ is a subtype of $T$, the cast expression evaluates to $v$. Otherwise, if $v$ is \NULL{}, the cast expression evaluates to $v$. 
 In all other cases,  a \code{CastError} is thrown.
  
 The static type of a cast expression  \code{$e$ \AS{} $T$}  is $T$. 
@@ -4505,7 +4543,7 @@
 \commentary{In other words,  all the expressions in the cases evaluate to constants of the exact same user defined class or are of certain known types.  Note that the values of the expressions are known at compile-time, and are independent of any static type annotations.
 }
 
-It is a compile-time error if the class $C$ has an implementation of the operator $==$ other than the one inherited from \code{Object} unless the value of the expression is a string, an integer, literal symbol or the result of invoking a constant constructor class \cd{Symbol}.
+It is a compile-time error if the class $C$ has an implementation of the operator $==$ other than the one inherited from \code{Object} unless the value of the expression is a string, an integer, literal symbol or the result of invoking a constant constructor of class \cd{Symbol}.
  
  \rationale{
  The prohibition on user defined equality allows us to implement the switch efficiently for user defined types. We could formulate matching in terms of identity instead with the same efficiency. However, if a type defines an equality operator, programmers would find it quite surprising that equal objects did not match.
@@ -4664,10 +4702,10 @@
 The syntax is designed to be upward compatible with existing Javascript programs. The \ON{} clause can be omitted, leaving what looks like a Javascript catch clause.
 }
 
-An \ON{}-\CATCH{} clause of the form   \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$}  {\em matches} an object $o$  if the type of $o$ is a subtype of $T$.  If $T$ is a malformed type, then performing a match causes a run time error.
+An \ON{}-\CATCH{} clause of the form   \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$}  {\em matches} an object $o$  if the type of $o$ is a subtype of $T$.  If $T$ is a malformed or deferred type  (\ref{staticTypes}), then performing a match causes a run time error.
 
 \commentary {
-It is of course a static warning if $T$ is a malformed type (\ref{staticTypes}).
+It is of course a static warning if $T$ is a deferred or malformed type.
 }
 
 An \ON{}-\CATCH{} clause of the form   \code{\ON{} $T$ \CATCH{} ($p_1, p_2$) $s$} introduces a new scope $CS$ in which local variables specified by $p_1$ and $p_2$ are defined. The statement $s$ is enclosed within $CS$.
@@ -5002,9 +5040,14 @@
 An {\em import} specifies a library to be used in the scope of another library. 
 \begin{grammar}
 {\bf libraryImport:}
-   metadata \IMPORT{}  uri (\AS{} identifier)?  combinator* `{\escapegrammar ;}'
+   metadata importSpecification
     .
-    
+ 
+ {\bf importSpecification:}
+    \IMPORT{}  uri (\AS{} identifier)?  combinator* `{\escapegrammar ;}';
+     \IMPORT{}  uri \DEFERRED{} \AS{} identifier  combinator* `{\escapegrammar ;}'
+    .
+       
 {\bf combinator:}\SHOW{} identifierList;
 \HIDE{} identifierList
     .
@@ -5014,19 +5057,61 @@
  \end{grammar}
  
 
-An import specifies a URI $x$ where the declaration of an imported library is to be found. It is a compile-time error if  the specified URI does not refer to a library declaration.  The interpretation of URIs is described in section \ref{uris} below.
+An import specifies a URI $x$ where the declaration of an imported library is to be found. 
+
+Imports may be {\em deferred} or {\em immediate}. A deferred import is distinguished by the appearance of the built-in identifier \DEFERRED{} after the URI. Any import that is not deferred is immediate.
+
+It is a compile-time error if  the specified URI of an immediate import does not refer to a library declaration.  The interpretation of URIs is described in section \ref{uris} below.
+
+It is a static warning if the specified URI of a deferred import does not refer to a library declaration.
+
+\rationale{
+ One cannot detect the problem at compile time because compilation often occurs during execution and  one does not know what the URI refers to.  However the development environment should detect the problem.
+ }
+
  
 The {\em current library} is the library currently being compiled. The import modifies the  namespace of the current library in a manner that is determined by the imported library and by the optional elements of  the import.
      
-An import directive $I$ may optionally include:
-\begin{itemize}
-\item A prefix clause of the form \AS{} \code{Id} used to prefix names imported by $I$.
-\item Namespace combinator clauses used to restrict the set of names imported by $I$. Currently, two namespace combinators are supported: \HIDE{} and \SHOW{}.
-\end{itemize}
+An immediate import directive $I$ may optionally include a prefix clause of the form \AS{} \code{Id} used to prefix names imported by $I$. A deferred import must include a prefix clause or a compile time error occurs. It is a compile-time error if a prefix used in a deferred import is used in another import clause.
+
+An import directive $I$ may optionally include a namespace combinator clauses used to restrict the set of names imported by $I$. Currently, two namespace combinators are supported: \HIDE{} and \SHOW{}.
 
 Let $I$ be an import directive that refers to a URI via the string $s_1$. Evaluation of $I$  proceeds as follows:
 
-First,
+If $I$ is a deferred import, no evaluation takes place. Instead, the following names are added to the scope of $L$:
+\begin{itemize}
+\item
+The name of the prefix, $p$ denoting a deferred prefix declaration.
+\item
+The name \code{$p$.loadLibrary}, denoting a top level function with no arguments, whose semantics are described below.
+\end{itemize}
+ 
+A deferred prefix $p$ may be loaded explicitly via the function call \code{$p$.loadLibrary}, which returns a future $f$. The effect of the call is to cause an immediate import $IÕ$ to be executed at some future time, where $IÕ$ is is derived from $I$ by eliding the word \DEFERRED{} and adding a \HIDE{} \code{loadLibrary}  combinator clause. When $IÕ$ executes without error, $f$ completes successfully. If $IÕ$ executes without error, we say that the call to \code{$p$.loadLibrary} has succeeded, otherwise we say the call has failed.
+
+After a call succeeds, the names $p$ and \code{$p$.loadLibrary} remain in the top-level scope of $L$, and so it is possible to call \code{loadLibrary} again. If a call fails, nothing happens, and one again has the option to call \code{loadLibrary} again. Whether a repeated call to \code{loadLibrary} succeeds will vary as described below.
+
+The effect of a repeated call to \code{$p$.loadLibrary} is as follows:
+\begin{itemize}
+\item
+If another call to \code{$p$.loadLibrary} has already succeeded, the repeated call also succeeds. 
+Otherwise,
+\item
+If another call to  to \code{$p$.loadLibrary} has failed:
+\begin{itemize}
+\item
+If the failure is due to a compilation error, the repeated call fails for the same reason.
+\item
+If the failure is due to other causes, the repeated call behaves as if no previous call had been made.
+\end{itemize}
+\end{itemize}
+
+\commentary{
+In other words, one can retry a deferred load after a network failure or because a file is absent, but once one finds some content and loads it, one can no longer reload.
+
+We do not specify what value the future returned resolves to.
+}
+
+If $I$ is an immediate import then, first
 
  \begin{itemize}
  \item
@@ -5338,8 +5423,11 @@
 This ensures that the developer is spared a series of cascading warnings as the malformed type interacts with other types.
 }
 
+A type $T$ is {\em deferred} iff it is of the form $p.T$ where $p$ is a deferred prefix.
+It is a static warning to use a deferred type in a type annotation, type test, type cast or as a type parameter. However, all other static warnings must be issued under the assumption that all deferred libraries have successfully been loaded.
 
-\subsubsection{Type Promotion}
+
+\subsubsection{Type Promotion}   
 \label{typePromotion}
 
 The static type system ascribes a static type to every expression.  In some cases, the types of local variables and formal parameters may be promoted from their declared types based on control flow. 
@@ -5354,10 +5442,19 @@
 
 A Dart implementation must support execution in both {\em production mode} and {\em checked mode}.  Those dynamic checks specified as occurring specifically in checked mode must be performed iff the code is executed in checked mode.
 
+\commentary{
+Note that this is the case even if the deferred type belongs to a prefix that has already been loaded. This is regrettable, since it strongly discourages the use of type annotations that involve deferred types because Dart programmers use checked mode much of the time.
+
+In practice, many scenarios involving deferred loading involve deferred loading of classes that implement eagerly loaded interfaces, so the situation is often less onerous than it seems. The current semantics were adopted based on considerations of ease of implementation.
+
+Clearly, if a deferred type has not yet been loaded, it is impossible to do a correct subtype test involving it, and one would expect a dynamic failure, as is the case with type tests and casts. By the same token, one would expect checked mode to work seamlessly once a type had been loaded. We hope to adopt these semantics in the future; such a change would be upwardly compatible.
+
+}
+
 %It is a run-time type error to access an undeclared type outside .
 
 %It is a dynamic type error if a malformed type is used in a subtype test.  
-In checked mode, it is a dynamic type error if a malformed or malbounded (\ref{parameterizedTypes}) 
+In checked mode, it is a dynamic type error if a deferred, malformed or malbounded (\ref{parameterizedTypes}) 
 type is used in a subtype test.  
 
 %In production mode, an undeclared type is treated as an instance of type \DYNAMIC{}. 
diff --git a/pkg/analysis_services/lib/search/search_engine.dart b/pkg/analysis_services/lib/search/search_engine.dart
index a2579dd..3aac8ba 100644
--- a/pkg/analysis_services/lib/search/search_engine.dart
+++ b/pkg/analysis_services/lib/search/search_engine.dart
@@ -9,6 +9,8 @@
 
 import 'dart:async';
 
+import 'package:analysis_services/index/index.dart';
+import 'package:analysis_services/src/search/search_engine.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -27,278 +29,271 @@
 
 
 /**
+ * Returns a new [SearchEngine] instance based on the given [Index].
+ */
+SearchEngine createSearchEngine(Index index) {
+  return new SearchEngineImpl(index);
+}
+
+
+/**
  * Instances of the enum [MatchKind] represent the kind of reference that was
  * found when a match represents a reference to an element.
  */
-class MatchKind extends Enum<MatchKind> {
+class MatchKind {
   /**
    * A reference to an Angular element.
    */
-  static const MatchKind ANGULAR_REFERENCE = const MatchKind(
-      'ANGULAR_REFERENCE', 0);
+  static const MatchKind ANGULAR_REFERENCE =
+      const MatchKind('ANGULAR_REFERENCE');
 
   /**
    * A reference to an Angular element.
    */
-  static const MatchKind ANGULAR_CLOSING_TAG_REFERENCE = const MatchKind(
-      'ANGULAR_CLOSING_TAG_REFERENCE', 1);
+  static const MatchKind ANGULAR_CLOSING_TAG_REFERENCE =
+      const MatchKind('ANGULAR_CLOSING_TAG_REFERENCE');
 
   /**
    * A declaration of a class.
    */
-  static const MatchKind CLASS_DECLARATION = const MatchKind(
-      'CLASS_DECLARATION', 2);
+  static const MatchKind CLASS_DECLARATION =
+      const MatchKind('CLASS_DECLARATION');
 
   /**
    * A declaration of a class alias.
    */
-  static const MatchKind CLASS_ALIAS_DECLARATION = const MatchKind(
-      'CLASS_ALIAS_DECLARATION', 3);
+  static const MatchKind CLASS_ALIAS_DECLARATION =
+      const MatchKind('CLASS_ALIAS_DECLARATION');
 
   /**
    * A declaration of a constructor.
    */
-  static const MatchKind CONSTRUCTOR_DECLARATION = const MatchKind(
-      'CONSTRUCTOR_DECLARATION', 4);
+  static const MatchKind CONSTRUCTOR_DECLARATION =
+      const MatchKind('CONSTRUCTOR_DECLARATION');
 
   /**
    * A reference to a constructor in which the constructor is being referenced.
    */
-  static const MatchKind CONSTRUCTOR_REFERENCE = const MatchKind(
-      'CONSTRUCTOR_REFERENCE', 5);
+  static const MatchKind CONSTRUCTOR_REFERENCE =
+      const MatchKind('CONSTRUCTOR_REFERENCE');
 
   /**
    * A reference to a type in which the type was extended.
    */
-  static const MatchKind EXTENDS_REFERENCE = const MatchKind(
-      'EXTENDS_REFERENCE', 6);
+  static const MatchKind EXTENDS_REFERENCE =
+      const MatchKind('EXTENDS_REFERENCE');
 
   /**
    * A reference to a field in which the field's value is being invoked.
    */
-  static const MatchKind FIELD_INVOCATION = const MatchKind('FIELD_INVOCATION',
-      7);
+  static const MatchKind FIELD_INVOCATION = const MatchKind('FIELD_INVOCATION');
 
   /**
    * A reference to a field (from field formal parameter).
    */
-  static const MatchKind FIELD_REFERENCE = const MatchKind('FIELD_REFERENCE',
-      8);
+  static const MatchKind FIELD_REFERENCE = const MatchKind('FIELD_REFERENCE');
 
   /**
    * A reference to a field in which the field's value is being read.
    */
-  static const MatchKind FIELD_READ = const MatchKind('FIELD_READ', 9);
+  static const MatchKind FIELD_READ = const MatchKind('FIELD_READ');
 
   /**
    * A reference to a field in which the field's value is being written.
    */
-  static const MatchKind FIELD_WRITE = const MatchKind('FIELD_WRITE', 10);
+  static const MatchKind FIELD_WRITE = const MatchKind('FIELD_WRITE');
 
   /**
    * A declaration of a function.
    */
-  static const MatchKind FUNCTION_DECLARATION = const MatchKind(
-      'FUNCTION_DECLARATION', 11);
+  static const MatchKind FUNCTION_DECLARATION =
+      const MatchKind('FUNCTION_DECLARATION');
 
   /**
    * A reference to a function in which the function is being executed.
    */
-  static const MatchKind FUNCTION_EXECUTION = const MatchKind(
-      'FUNCTION_EXECUTION', 12);
+  static const MatchKind FUNCTION_EXECUTION =
+      const MatchKind('FUNCTION_EXECUTION');
 
   /**
    * A reference to a function in which the function is being referenced.
    */
-  static const MatchKind FUNCTION_REFERENCE = const MatchKind(
-      'FUNCTION_REFERENCE', 13);
+  static const MatchKind FUNCTION_REFERENCE =
+      const MatchKind('FUNCTION_REFERENCE');
 
   /**
    * A declaration of a function type.
    */
-  static const MatchKind FUNCTION_TYPE_DECLARATION = const MatchKind(
-      'FUNCTION_TYPE_DECLARATION', 14);
+  static const MatchKind FUNCTION_TYPE_DECLARATION =
+      const MatchKind('FUNCTION_TYPE_DECLARATION');
 
   /**
    * A reference to a function type.
    */
-  static const MatchKind FUNCTION_TYPE_REFERENCE = const MatchKind(
-      'FUNCTION_TYPE_REFERENCE', 15);
+  static const MatchKind FUNCTION_TYPE_REFERENCE =
+      const MatchKind('FUNCTION_TYPE_REFERENCE');
 
   /**
    * A reference to a type in which the type was implemented.
    */
-  static const MatchKind IMPLEMENTS_REFERENCE = const MatchKind(
-      'IMPLEMENTS_REFERENCE', 16);
+  static const MatchKind IMPLEMENTS_REFERENCE =
+      const MatchKind('IMPLEMENTS_REFERENCE');
 
   /**
    * A reference to a [ImportElement].
    */
-  static const MatchKind IMPORT_REFERENCE = const MatchKind('IMPORT_REFERENCE',
-      17);
+  static const MatchKind IMPORT_REFERENCE = const MatchKind('IMPORT_REFERENCE');
 
   /**
    * A reference to a class that is implementing a specified type.
    */
-  static const MatchKind INTERFACE_IMPLEMENTED = const MatchKind(
-      'INTERFACE_IMPLEMENTED', 18);
+  static const MatchKind INTERFACE_IMPLEMENTED =
+      const MatchKind('INTERFACE_IMPLEMENTED');
 
   /**
    * A reference to a [LibraryElement].
    */
-  static const MatchKind LIBRARY_REFERENCE = const MatchKind(
-      'LIBRARY_REFERENCE', 19);
+  static const MatchKind LIBRARY_REFERENCE =
+      const MatchKind('LIBRARY_REFERENCE');
 
   /**
    * A reference to a method in which the method is being invoked.
    */
-  static const MatchKind METHOD_INVOCATION = const MatchKind(
-      'METHOD_INVOCATION', 20);
+  static const MatchKind METHOD_INVOCATION =
+      const MatchKind('METHOD_INVOCATION');
 
   /**
    * A reference to a method in which the method is being referenced.
    */
-  static const MatchKind METHOD_REFERENCE = const MatchKind('METHOD_REFERENCE',
-      21);
+  static const MatchKind METHOD_REFERENCE = const MatchKind('METHOD_REFERENCE');
 
   /**
    * A declaration of a name.
    */
-  static const MatchKind NAME_DECLARATION = const MatchKind('NAME_DECLARATION',
-      22);
+  static const MatchKind NAME_DECLARATION = const MatchKind('NAME_DECLARATION');
 
   /**
    * A reference to a name, resolved.
    */
-  static const MatchKind NAME_REFERENCE_RESOLVED = const MatchKind(
-      'NAME_REFERENCE_RESOLVED', 23);
+  static const MatchKind NAME_REFERENCE_RESOLVED =
+      const MatchKind('NAME_REFERENCE_RESOLVED');
 
   /**
    * An invocation of a name, resolved.
    */
-  static const MatchKind NAME_INVOCATION_RESOLVED = const MatchKind(
-      'NAME_INVOCATION_RESOLVED', 24);
+  static const MatchKind NAME_INVOCATION_RESOLVED =
+      const MatchKind('NAME_INVOCATION_RESOLVED');
 
   /**
    * A reference to a name in which the name's value is being read.
    */
-  static const MatchKind NAME_READ_RESOLVED = const MatchKind(
-      'NAME_READ_RESOLVED', 25);
+  static const MatchKind NAME_READ_RESOLVED =
+      const MatchKind('NAME_READ_RESOLVED');
 
   /**
    * A reference to a name in which the name's value is being read and written.
    */
-  static const MatchKind NAME_READ_WRITE_RESOLVED = const MatchKind(
-      'NAME_READ_WRITE_RESOLVED', 26);
+  static const MatchKind NAME_READ_WRITE_RESOLVED =
+      const MatchKind('NAME_READ_WRITE_RESOLVED');
 
   /**
    * A reference to a name in which the name's value is being written.
    */
-  static const MatchKind NAME_WRITE_RESOLVED = const MatchKind(
-      'NAME_WRITE_RESOLVED', 27);
+  static const MatchKind NAME_WRITE_RESOLVED =
+      const MatchKind('NAME_WRITE_RESOLVED');
 
   /**
    * An invocation of a name, unresolved.
    */
-  static const MatchKind NAME_INVOCATION_UNRESOLVED = const MatchKind(
-      'NAME_INVOCATION_UNRESOLVED', 28);
+  static const MatchKind NAME_INVOCATION_UNRESOLVED =
+      const MatchKind('NAME_INVOCATION_UNRESOLVED');
 
   /**
    * A reference to a name in which the name's value is being read.
    */
-  static const MatchKind NAME_READ_UNRESOLVED = const MatchKind(
-      'NAME_READ_UNRESOLVED', 29);
+  static const MatchKind NAME_READ_UNRESOLVED =
+      const MatchKind('NAME_READ_UNRESOLVED');
 
   /**
    * A reference to a name in which the name's value is being read and written.
    */
-  static const MatchKind NAME_READ_WRITE_UNRESOLVED = const MatchKind(
-      'NAME_READ_WRITE_UNRESOLVED', 30);
+  static const MatchKind NAME_READ_WRITE_UNRESOLVED =
+      const MatchKind('NAME_READ_WRITE_UNRESOLVED');
 
   /**
    * A reference to a name in which the name's value is being written.
    */
-  static const MatchKind NAME_WRITE_UNRESOLVED = const MatchKind(
-      'NAME_WRITE_UNRESOLVED', 31);
+  static const MatchKind NAME_WRITE_UNRESOLVED =
+      const MatchKind('NAME_WRITE_UNRESOLVED');
 
   /**
    * A reference to a name, unresolved.
    */
-  static const MatchKind NAME_REFERENCE_UNRESOLVED = const MatchKind(
-      'NAME_REFERENCE_UNRESOLVED', 32);
+  static const MatchKind NAME_REFERENCE_UNRESOLVED =
+      const MatchKind('NAME_REFERENCE_UNRESOLVED');
 
   /**
    * A reference to a named parameter in invocation.
    */
-  static const MatchKind NAMED_PARAMETER_REFERENCE = const MatchKind(
-      'NAMED_PARAMETER_REFERENCE', 33);
+  static const MatchKind NAMED_PARAMETER_REFERENCE =
+      const MatchKind('NAMED_PARAMETER_REFERENCE');
 
   /**
    * A reference to a property accessor.
    */
-  static const MatchKind PROPERTY_ACCESSOR_REFERENCE = const MatchKind(
-      'PROPERTY_ACCESSOR_REFERENCE', 34);
+  static const MatchKind PROPERTY_ACCESSOR_REFERENCE =
+      const MatchKind('PROPERTY_ACCESSOR_REFERENCE');
 
   /**
    * A reference to a type.
    */
-  static const MatchKind TYPE_REFERENCE = const MatchKind('TYPE_REFERENCE', 35);
+  static const MatchKind TYPE_REFERENCE = const MatchKind('TYPE_REFERENCE');
 
   /**
    * A reference to a type parameter.
    */
-  static const MatchKind TYPE_PARAMETER_REFERENCE = const MatchKind(
-      'TYPE_PARAMETER_REFERENCE', 36);
+  static const MatchKind TYPE_PARAMETER_REFERENCE =
+      const MatchKind('TYPE_PARAMETER_REFERENCE');
 
   /**
    * A reference to a [CompilationUnitElement].
    */
-  static const MatchKind UNIT_REFERENCE = const MatchKind('UNIT_REFERENCE', 37);
+  static const MatchKind UNIT_REFERENCE = const MatchKind('UNIT_REFERENCE');
 
   /**
    * A declaration of a variable.
    */
-  static const MatchKind VARIABLE_DECLARATION = const MatchKind(
-      'VARIABLE_DECLARATION', 38);
+  static const MatchKind VARIABLE_DECLARATION =
+      const MatchKind('VARIABLE_DECLARATION');
 
   /**
    * A reference to a variable in which the variable's value is being read.
    */
-  static const MatchKind VARIABLE_READ = const MatchKind('VARIABLE_READ', 39);
+  static const MatchKind VARIABLE_READ = const MatchKind('VARIABLE_READ');
 
   /**
    * A reference to a variable in which the variable's value is being both read
    * and write.
    */
-  static const MatchKind VARIABLE_READ_WRITE = const MatchKind(
-      'VARIABLE_READ_WRITE', 40);
+  static const MatchKind VARIABLE_READ_WRITE =
+      const MatchKind('VARIABLE_READ_WRITE');
 
   /**
    * A reference to a variable in which the variables's value is being written.
    */
-  static const MatchKind VARIABLE_WRITE = const MatchKind('VARIABLE_WRITE', 41);
+  static const MatchKind VARIABLE_WRITE = const MatchKind('VARIABLE_WRITE');
 
   /**
    * A reference to a type in which the type was mixed in.
    */
-  static const MatchKind WITH_REFERENCE = const MatchKind('WITH_REFERENCE', 42);
+  static const MatchKind WITH_REFERENCE = const MatchKind('WITH_REFERENCE');
 
-  static const List<MatchKind> values = const [ANGULAR_REFERENCE,
-      ANGULAR_CLOSING_TAG_REFERENCE, CLASS_DECLARATION, CLASS_ALIAS_DECLARATION,
-      CONSTRUCTOR_DECLARATION, CONSTRUCTOR_REFERENCE, EXTENDS_REFERENCE,
-      FIELD_INVOCATION, FIELD_REFERENCE, FIELD_READ, FIELD_WRITE,
-      FUNCTION_DECLARATION, FUNCTION_EXECUTION, FUNCTION_REFERENCE,
-      FUNCTION_TYPE_DECLARATION, FUNCTION_TYPE_REFERENCE, IMPLEMENTS_REFERENCE,
-      IMPORT_REFERENCE, INTERFACE_IMPLEMENTED, LIBRARY_REFERENCE, METHOD_INVOCATION,
-      METHOD_REFERENCE, NAME_DECLARATION, NAME_REFERENCE_RESOLVED,
-      NAME_INVOCATION_RESOLVED, NAME_READ_RESOLVED, NAME_READ_WRITE_RESOLVED,
-      NAME_WRITE_RESOLVED, NAME_INVOCATION_UNRESOLVED, NAME_READ_UNRESOLVED,
-      NAME_READ_WRITE_UNRESOLVED, NAME_WRITE_UNRESOLVED, NAME_REFERENCE_UNRESOLVED,
-      NAMED_PARAMETER_REFERENCE, PROPERTY_ACCESSOR_REFERENCE, TYPE_REFERENCE,
-      TYPE_PARAMETER_REFERENCE, UNIT_REFERENCE, VARIABLE_DECLARATION, VARIABLE_READ,
-      VARIABLE_READ_WRITE, VARIABLE_WRITE, WITH_REFERENCE];
+  final String name;
 
-  const MatchKind(String name, int ordinal) : super(name, ordinal);
+  const MatchKind(this.name);
+
+  @override
+  String toString() => name;
 }
 
 
@@ -307,13 +302,6 @@
  * to search for various pieces of information.
  */
 abstract class SearchEngine {
-//  /**
-//   * Returns types assigned to the given field or top-level variable.
-//   *
-//   * [variable] - the field or top-level variable to find assigned types for.
-//   */
-//  Future<Set<DartType>> searchAssignedTypes(PropertyInducingElement variable);
-
   /**
    * Returns declarations of class members with the given name.
    *
@@ -380,9 +368,10 @@
   /**
    * Is `true` if field or method access is done using qualifier.
    */
-  bool qualified = false;
+  final bool isQualified;
 
-  SearchMatch(this.kind, this.element, this.sourceRange, this.isResolved);
+  SearchMatch(this.kind, this.element, this.sourceRange, this.isResolved,
+      this.isQualified);
 
   @override
   int get hashCode => JavaArrays.makeHashCode([element, sourceRange, kind]);
@@ -393,9 +382,11 @@
       return true;
     }
     if (object is SearchMatch) {
-      return kind == object.kind && isResolved == object.isResolved && qualified
-          == object.qualified && sourceRange == object.sourceRange && element ==
-          object.element;
+      return kind == object.kind &&
+          isResolved == object.isResolved &&
+          isQualified == object.isQualified &&
+          sourceRange == object.sourceRange &&
+          element == object.element;
     }
     return false;
   }
@@ -405,14 +396,14 @@
     StringBuffer buffer = new StringBuffer();
     buffer.write("SearchMatch(kind=");
     buffer.write(kind);
-    buffer.write(", isResolved=");
-    buffer.write(isResolved);
     buffer.write(", element=");
     buffer.write(element.displayName);
     buffer.write(", range=");
     buffer.write(sourceRange);
-    buffer.write(", qualified=");
-    buffer.write(qualified);
+    buffer.write(", isResolved=");
+    buffer.write(isResolved);
+    buffer.write(", isQualified=");
+    buffer.write(isQualified);
     buffer.write(")");
     return buffer.toString();
   }
diff --git a/pkg/analysis_services/lib/src/index/index_contributor.dart b/pkg/analysis_services/lib/src/index/index_contributor.dart
index 0444183..3a1c97e 100644
--- a/pkg/analysis_services/lib/src/index/index_contributor.dart
+++ b/pkg/analysis_services/lib/src/index/index_contributor.dart
@@ -656,6 +656,10 @@
     }
     // prepare information
     Element element = node.bestElement;
+    // TODO(scheglov) fix resolver to resolve to Field, not an accessor
+    if (node.parent is Combinator && element is PropertyAccessorElement) {
+      element = (element as PropertyAccessorElement).variable;
+    }
     // qualified name reference
     _recordQualifiedMemberReference(node, element, nameElement, location);
     // stop if already handled
@@ -688,9 +692,11 @@
         FunctionTypeAliasElement || element is LabelElement || element is
         TypeParameterElement) {
       recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
-    } else if (element is FieldElement) {
+    } else if (element is PropertyInducingElement) {
       location = _getLocationWithInitializerType(node, location);
-      recordRelationship(element, IndexConstants.IS_REFERENCED_BY, location);
+      recordRelationship(element,
+          IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+          location);
     } else if (element is FieldFormalParameterElement) {
       FieldFormalParameterElement fieldParameter = element;
       FieldElement field = fieldParameter.field;
diff --git a/pkg/analysis_services/lib/src/index/store/codec.dart b/pkg/analysis_services/lib/src/index/store/codec.dart
index 9153e69..108f936 100644
--- a/pkg/analysis_services/lib/src/index/store/codec.dart
+++ b/pkg/analysis_services/lib/src/index/store/codec.dart
@@ -19,14 +19,14 @@
   /**
    * A table mapping contexts to their unique indices.
    */
-  Map<AnalysisContext, int> _contextToIndex = new HashMap<AnalysisContext, int>(
-      );
+  Map<AnalysisContext, int> _contextToIndex =
+      new HashMap<AnalysisContext, int>();
 
   /**
    * A table mapping indices to the corresponding contexts.
    */
-  Map<int, AnalysisContext> _indexToContext = new HashMap<int, AnalysisContext>(
-      );
+  Map<int, AnalysisContext> _indexToContext =
+      new HashMap<int, AnalysisContext>();
 
   /**
    * The next id to assign.
@@ -92,7 +92,8 @@
     List<int> path = _indexToPath[index];
     List<String> components = _getLocationComponents(path);
     ElementLocation location = new ElementLocationImpl.con3(components);
-    return context.getElement(location);
+    Element element = context.getElement(location);
+    return element;
   }
 
   /**
diff --git a/pkg/analysis_services/lib/src/search/search_engine.dart b/pkg/analysis_services/lib/src/search/search_engine.dart
index b9419b9..def5e32 100644
--- a/pkg/analysis_services/lib/src/search/search_engine.dart
+++ b/pkg/analysis_services/lib/src/search/search_engine.dart
@@ -7,1222 +7,451 @@
 
 library services.src.search.search_engine;
 
-///**
-// * Instances of the class <code>AndSearchPattern</code> implement a search pattern that matches
-// * elements that match all of several other search patterns.
-// */
-//class AndSearchPattern implements SearchPattern {
-//  /**
-//   * The patterns used to determine whether this pattern matches an element.
-//   */
-//  final List<SearchPattern> _patterns;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements that match all of several other
-//   * search patterns.
-//   *
-//   * @param patterns the patterns used to determine whether this pattern matches an element
-//   */
-//  AndSearchPattern(this._patterns);
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    MatchQuality highestQuality = null;
-//    for (SearchPattern pattern in _patterns) {
-//      MatchQuality quality = pattern.matches(element);
-//      if (quality == null) {
-//        return null;
-//      }
-//      if (highestQuality == null) {
-//        highestQuality = quality;
-//      } else {
-//        highestQuality = highestQuality.max(quality);
-//      }
-//    }
-//    return highestQuality;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>CamelCaseSearchPattern</code> implement a search pattern that
-// * matches elements whose name matches a partial identifier where camel case conventions are used to
-// * perform what is essentially multiple prefix matches.
-// */
-//class CamelCaseSearchPattern implements SearchPattern {
-//  /**
-//   * The pattern that matching elements must match.
-//   */
-//  List<int> _pattern;
-//
-//  /**
-//   * A flag indicating whether the pattern and the name being matched must have exactly the same
-//   * number of parts (i.e. the same number of uppercase characters).
-//   */
-//  final bool _samePartCount;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements whose names match the given
-//   * camel-case pattern.
-//   *
-//   * @param pattern the pattern that matching elements must match
-//   * @param samePartCount `true` if the pattern and the name being matched must have
-//   *          exactly the same number of parts (i.e. the same number of uppercase characters)
-//   */
-//  CamelCaseSearchPattern(String pattern, this._samePartCount) {
-//    this._pattern = pattern.toCharArray();
-//  }
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    String name = element.displayName;
-//    if (name == null) {
-//      return null;
-//    }
-//    if (CharOperation.camelCaseMatch(_pattern, name.toCharArray(), _samePartCount)) {
-//      return MatchQuality.EXACT;
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Instances of the class `CountingSearchListener` listen for search results, passing those
-// * results on to a wrapped listener, but ensure that the wrapped search listener receives only one
-// * notification that the search is complete.
-// */
-//class CountingSearchListener implements SearchListener {
-//  /**
-//   * The number of times that this listener expects to be told that the search is complete before
-//   * passing the information along to the wrapped listener.
-//   */
-//  int _completionCount = 0;
-//
-//  /**
-//   * The listener that will be notified as results are received and when the given number of search
-//   * complete notifications have been received.
-//   */
-//  final SearchListener _wrappedListener;
-//
-//  /**
-//   * Initialize a newly created search listener to pass search results on to the given listener and
-//   * to notify the given listener that the search is complete after getting the given number of
-//   * notifications.
-//   *
-//   * @param completionCount the number of times that this listener expects to be told that the
-//   *          search is complete
-//   * @param wrappedListener the listener that will be notified as results are received
-//   */
-//  CountingSearchListener(int completionCount, this._wrappedListener) {
-//    this._completionCount = completionCount;
-//    if (completionCount == 0) {
-//      _wrappedListener.searchComplete();
-//    }
-//  }
-//
-//  @override
-//  void matchFound(SearchMatch match) {
-//    _wrappedListener.matchFound(match);
-//  }
-//
-//  @override
-//  void searchComplete() {
-//    _completionCount--;
-//    if (_completionCount <= 0) {
-//      _wrappedListener.searchComplete();
-//    }
-//  }
-//}
-//
-///**
-// * Instances of the class <code>ExactSearchPattern</code> implement a search pattern that matches
-// * elements whose name matches a specified identifier exactly.
-// */
-//class ExactSearchPattern implements SearchPattern {
-//  /**
-//   * The identifier that matching elements must be equal to.
-//   */
-//  final String _identifier;
-//
-//  /**
-//   * A flag indicating whether a case sensitive match is to be performed.
-//   */
-//  final bool _caseSensitive;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements whose names begin with the given
-//   * prefix.
-//   *
-//   * @param identifier the identifier that matching elements must be equal to
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   */
-//  ExactSearchPattern(this._identifier, this._caseSensitive);
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    String name = element.displayName;
-//    if (name == null) {
-//      return null;
-//    }
-//    if (_caseSensitive && name == _identifier) {
-//      return MatchQuality.EXACT;
-//    }
-//    if (!_caseSensitive && javaStringEqualsIgnoreCase(name, _identifier)) {
-//      return MatchQuality.EXACT;
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>FilteredSearchListener</code> implement a search listener that
-// * delegates to another search listener after removing matches that do not pass a given filter.
-// */
-//class FilteredSearchListener extends WrappedSearchListener {
-//  /**
-//   * The filter used to filter the matches.
-//   */
-//  final SearchFilter _filter;
-//
-//  /**
-//   * Initialize a newly created search listener to pass on any matches that pass the given filter to
-//   * the given listener.
-//   *
-//   * @param filter the filter used to filter the matches
-//   * @param listener the search listener being wrapped
-//   */
-//  FilteredSearchListener(this._filter, SearchListener listener) : super(listener);
-//
-//  @override
-//  void matchFound(SearchMatch match) {
-//    if (_filter.passes(match)) {
-//      propagateMatch(match);
-//    }
-//  }
-//}
-//
-///**
-// * [SearchListener] used by [SearchEngineImpl] internally to gather asynchronous results
-// * and return them synchronously.
-// */
-//class GatheringSearchListener implements SearchListener {
-//  /**
-//   * A list containing the matches that have been found so far.
-//   */
-//  List<SearchMatch> _matches = [];
-//
-//  /**
-//   * A flag indicating whether the search is complete.
-//   */
-//  bool _isComplete = false;
-//
-//  /**
-//   * @return the the matches that have been found.
-//   */
-//  List<SearchMatch> get matches {
-//    _matches.sort(SearchMatch.SORT_BY_ELEMENT_NAME);
-//    return _matches;
-//  }
-//
-//  /**
-//   * Return `true` if the search is complete.
-//   *
-//   * @return `true` if the search is complete
-//   */
-//  bool get isComplete => _isComplete;
-//
-//  @override
-//  void matchFound(SearchMatch match) {
-//    _matches.add(match);
-//  }
-//
-//  @override
-//  void searchComplete() {
-//    _isComplete = true;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>LibrarySearchScope</code> implement a search scope that encompasses
-// * everything in a given collection of libraries.
-// */
-//class LibrarySearchScope implements SearchScope {
-//  /**
-//   * The libraries defining which elements are included in the scope.
-//   */
-//  final List<LibraryElement> libraries;
-//
-//  /**
-//   * Create a search scope that encompasses everything in the given libraries.
-//   *
-//   * @param libraries the libraries defining which elements are included in the scope
-//   */
-//  LibrarySearchScope.con1(Iterable<LibraryElement> libraries) : this.con2(new List.from(libraries));
-//
-//  /**
-//   * Create a search scope that encompasses everything in the given libraries.
-//   *
-//   * @param libraries the libraries defining which elements are included in the scope
-//   */
-//  LibrarySearchScope.con2(this.libraries);
-//
-//  @override
-//  bool encloses(Element element) {
-//    LibraryElement elementLibrary = element.getAncestor((element) => element is LibraryElement);
-//    return ArrayUtils.contains(libraries, elementLibrary);
-//  }
-//}
-//
-///**
-// * Instances of the class <code>NameMatchingSearchListener</code> implement a search listener that
-// * delegates to another search listener after removing matches that do not match a given pattern.
-// */
-//class NameMatchingSearchListener extends WrappedSearchListener {
-//  /**
-//   * The pattern used to filter the matches.
-//   */
-//  final SearchPattern _pattern;
-//
-//  /**
-//   * Initialize a newly created search listener to pass on any matches that match the given pattern
-//   * to the given listener.
-//   *
-//   * @param pattern the pattern used to filter the matches
-//   * @param listener the search listener being wrapped
-//   */
-//  NameMatchingSearchListener(this._pattern, SearchListener listener) : super(listener);
-//
-//  @override
-//  void matchFound(SearchMatch match) {
-//    if (_pattern.matches(match.element) != null) {
-//      propagateMatch(match);
-//    }
-//  }
-//}
-//
-///**
-// * Instances of the class <code>OrSearchPattern</code> implement a search pattern that matches
-// * elements that match any one of several other search patterns.
-// */
-//class OrSearchPattern implements SearchPattern {
-//  /**
-//   * The patterns used to determine whether this pattern matches an element.
-//   */
-//  final List<SearchPattern> _patterns;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements that match any one of several other
-//   * search patterns.
-//   *
-//   * @param patterns the patterns used to determine whether this pattern matches an element
-//   */
-//  OrSearchPattern(this._patterns);
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    // Do we want to return the highest quality of match rather than stopping
-//    // after the first match? Doing so would be more accurate, but slower.
-//    for (SearchPattern pattern in _patterns) {
-//      MatchQuality quality = pattern.matches(element);
-//      if (quality != null) {
-//        return quality;
-//      }
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>PrefixSearchPattern</code> implement a search pattern that matches
-// * elements whose name has a given prefix.
-// */
-//class PrefixSearchPattern implements SearchPattern {
-//  /**
-//   * The prefix that matching elements must start with.
-//   */
-//  final String _prefix;
-//
-//  /**
-//   * A flag indicating whether a case sensitive match is to be performed.
-//   */
-//  final bool _caseSensitive;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements whose names begin with the given
-//   * prefix.
-//   *
-//   * @param prefix the prefix that matching elements must start with
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   */
-//  PrefixSearchPattern(this._prefix, this._caseSensitive);
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    if (element == null) {
-//      return null;
-//    }
-//    String name = element.displayName;
-//    if (name == null) {
-//      return null;
-//    }
-//    if (_caseSensitive && startsWith(name, _prefix)) {
-//      return MatchQuality.EXACT;
-//    }
-//    if (!_caseSensitive && startsWithIgnoreCase(name, _prefix)) {
-//      return MatchQuality.EXACT;
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>RegularExpressionSearchPattern</code> implement a search pattern
-// * that matches elements whose name matches a given regular expression.
-// */
-//class RegularExpressionSearchPattern implements SearchPattern {
-//  /**
-//   * The regular expression pattern that matching elements must match.
-//   */
-//  RegExp _pattern;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements whose names begin with the given
-//   * prefix.
-//   *
-//   * @param regularExpression the regular expression that matching elements must match
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   */
-//  RegularExpressionSearchPattern(String regularExpression, bool caseSensitive) {
-//    _pattern = new RegExp(regularExpression);
-//  }
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    if (element == null) {
-//      return null;
-//    }
-//    String name = element.displayName;
-//    if (name == null) {
-//      return null;
-//    }
-//    if (new JavaPatternMatcher(_pattern, name).matches()) {
-//      return MatchQuality.EXACT;
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Factory for [SearchEngine].
-// */
-//class SearchEngineFactory {
-//  /**
-//   * @return the new [SearchEngine] instance based on the given [Index].
-//   */
-//  static SearchEngine createSearchEngine(Index index) => new SearchEngineImpl(index);
-//}
+import 'dart:async';
 
-///**
-// * Implementation of [SearchEngine].
-// */
-//class SearchEngineImpl implements SearchEngine {
-//  /**
-//   * Apply the given filter to the given listener.
-//   *
-//   * @param filter the filter to be used before passing matches on to the listener, or `null`
-//   *          if all matches should be passed on
-//   * @param listener the listener that will only be given matches that pass the filter
-//   * @return a search listener that will pass to the given listener any matches that pass the given
-//   *         filter
-//   */
-//  static SearchListener _applyFilter(SearchFilter filter, SearchListener listener) {
-//    if (filter == null) {
-//      return listener;
-//    }
-//    return new FilteredSearchListener(filter, listener);
-//  }
-//
-//  /**
-//   * Apply the given pattern to the given listener.
-//   *
-//   * @param pattern the pattern to be used before passing matches on to the listener, or
-//   *          `null` if all matches should be passed on
-//   * @param listener the listener that will only be given matches that match the pattern
-//   * @return a search listener that will pass to the given listener any matches that match the given
-//   *         pattern
-//   */
-//  static SearchListener _applyPattern(SearchPattern pattern, SearchListener listener) {
-//    if (pattern == null) {
-//      return listener;
-//    }
-//    return new NameMatchingSearchListener(pattern, listener);
-//  }
-//
-//  static List<Element> _createElements(SearchScope scope) {
-//    if (scope is LibrarySearchScope) {
-//      return scope.libraries;
-//    }
-//    return <Element> [IndexConstants.UNIVERSE];
-//  }
-//
-//  static RelationshipCallback _newCallback(MatchKind matchKind, SearchScope scope, SearchListener listener) => new SearchEngineImpl_RelationshipCallbackImpl(scope, matchKind, listener);
-//
-//  /**
-//   * The index used to respond to the search requests.
-//   */
-//  final Index _index;
-//
-//  /**
-//   * Initialize a newly created search engine to use the given index.
-//   *
-//   * @param index the index used to respond to the search requests
-//   */
-//  SearchEngineImpl(this._index);
-//
-//  @override
-//  Set<DartType> searchAssignedTypes(PropertyInducingElement variable, SearchScope scope) {
-//    PropertyAccessorElement setter = variable.setter;
-//    int numRequests = (setter != null ? 2 : 0) + 2;
-//    // find locations
-//    List<Location> locations = [];
-//    CountDownLatch latch = new CountDownLatch(numRequests);
-//    if (setter != null) {
-//      _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, new Callback());
-//      _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, new Callback());
-//    }
-//    _index.getRelationships(variable, IndexConstants.IS_REFERENCED_BY, new Callback());
-//    _index.getRelationships(variable, IndexConstants.IS_DEFINED_BY, new Callback());
-//    Uninterruptibles.awaitUninterruptibly(latch);
-//    // get types from locations
-//    Set<DartType> types = new Set();
-//    for (Location location in locations) {
-//      // check scope
-//      if (scope != null) {
-//        Element targetElement = location.element;
-//        if (!scope.encloses(targetElement)) {
-//          continue;
-//        }
-//      }
-//      // we need data
-//      if (location is! LocationWithData) {
-//        continue;
-//      }
-//      LocationWithData locationWithData = location as LocationWithData;
-//      // add type
-//      Object data = locationWithData.data;
-//      if (data is DartType) {
-//        DartType type = data as DartType;
-//        types.add(type);
-//      }
-//    }
-//    // done
-//    return types;
-//  }
-//
-//  @override
-//  List<SearchMatch> searchDeclarations(String name, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchDeclarations(this, name, scope, filter));
-//
-//  @override
-//  void searchDeclarations2(String name, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.IS_DEFINED_BY, _newCallback(MatchKind.NAME_DECLARATION, scope, listener));
-//  }
-//
-//  @override
-//  List<SearchMatch> searchFunctionDeclarations(SearchScope scope, SearchPattern pattern, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchFunctionDeclarations(this, scope, pattern, filter));
-//
-//  @override
-//  void searchFunctionDeclarations2(SearchScope scope, SearchPattern pattern, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    List<Element> elements = _createElements(scope);
-//    listener = _applyPattern(pattern, listener);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(elements.length, listener);
-//    for (Element element in elements) {
-//      _index.getRelationships(element, IndexConstants.DEFINES_FUNCTION, _newCallback(MatchKind.FUNCTION_DECLARATION, scope, listener));
-//    }
-//  }
-//
-//  @override
-//  List<SearchMatch> searchQualifiedMemberReferences(String name, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchQualifiedMemberReferences(this, name, scope, filter));
-//
-//  @override
-//  void searchQualifiedMemberReferences2(String name, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(10, listener);
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _newCallback(MatchKind.NAME_REFERENCE_RESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _newCallback(MatchKind.NAME_REFERENCE_UNRESOLVED, scope, listener));
-//    // granular resolved operations
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_INVOKED_BY_RESOLVED, _newCallback(MatchKind.NAME_INVOCATION_RESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_BY_RESOLVED, _newCallback(MatchKind.NAME_READ_RESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED, _newCallback(MatchKind.NAME_READ_WRITE_RESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED, _newCallback(MatchKind.NAME_WRITE_RESOLVED, scope, listener));
-//    // granular unresolved operations
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED, _newCallback(MatchKind.NAME_INVOCATION_UNRESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_BY_UNRESOLVED, _newCallback(MatchKind.NAME_READ_UNRESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED, _newCallback(MatchKind.NAME_READ_WRITE_UNRESOLVED, scope, listener));
-//    _index.getRelationships(new NameElementImpl(name), IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED, _newCallback(MatchKind.NAME_WRITE_UNRESOLVED, scope, listener));
-//  }
-//
-//  @override
-//  List<SearchMatch> searchReferences(Element element, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchReferences(this, element, scope, filter));
-//
-//  @override
-//  void searchReferences2(Element element, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    if (element == null) {
-//      listener.searchComplete();
-//      return;
-//    }
-//    if (element is Member) {
-//      element = (element as Member).baseElement;
-//    }
-//    while (true) {
-//      if (element.kind == ElementKind.ANGULAR_COMPONENT || element.kind == ElementKind.ANGULAR_CONTROLLER || element.kind == ElementKind.ANGULAR_FORMATTER || element.kind == ElementKind.ANGULAR_PROPERTY || element.kind == ElementKind.ANGULAR_SCOPE_PROPERTY || element.kind == ElementKind.ANGULAR_SELECTOR) {
-//        _searchReferences(element as AngularElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.CLASS) {
-//        _searchReferences2(element as ClassElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.COMPILATION_UNIT) {
-//        _searchReferences3(element as CompilationUnitElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.CONSTRUCTOR) {
-//        _searchReferences4(element as ConstructorElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.FIELD || element.kind == ElementKind.TOP_LEVEL_VARIABLE) {
-//        _searchReferences12(element as PropertyInducingElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.FUNCTION) {
-//        _searchReferences5(element as FunctionElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.GETTER || element.kind == ElementKind.SETTER) {
-//        _searchReferences11(element as PropertyAccessorElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.IMPORT) {
-//        _searchReferences7(element as ImportElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.LIBRARY) {
-//        _searchReferences8(element as LibraryElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.LOCAL_VARIABLE) {
-//        _searchReferences14(element as LocalVariableElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.METHOD) {
-//        _searchReferences9(element as MethodElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.PARAMETER) {
-//        _searchReferences10(element as ParameterElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) {
-//        _searchReferences6(element as FunctionTypeAliasElement, scope, filter, listener);
-//        return;
-//      } else if (element.kind == ElementKind.TYPE_PARAMETER) {
-//        _searchReferences13(element as TypeParameterElement, scope, filter, listener);
-//        return;
-//      } else {
-//        listener.searchComplete();
-//        return;
-//      }
-//      break;
-//    }
-//  }
-//
-//  @override
-//  List<SearchMatch> searchSubtypes(ClassElement type, SearchScope scope, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchSubtypes(this, type, scope, filter));
-//
-//  @override
-//  void searchSubtypes2(ClassElement type, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(3, listener);
-//    _index.getRelationships(type, IndexConstants.IS_EXTENDED_BY, _newCallback(MatchKind.EXTENDS_REFERENCE, scope, listener));
-//    _index.getRelationships(type, IndexConstants.IS_MIXED_IN_BY, _newCallback(MatchKind.WITH_REFERENCE, scope, listener));
-//    _index.getRelationships(type, IndexConstants.IS_IMPLEMENTED_BY, _newCallback(MatchKind.IMPLEMENTS_REFERENCE, scope, listener));
-//  }
-//
-//  @override
-//  List<SearchMatch> searchTypeDeclarations(SearchScope scope, SearchPattern pattern, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchTypeDeclarations(this, scope, pattern, filter));
-//
-//  @override
-//  void searchTypeDeclarations2(SearchScope scope, SearchPattern pattern, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    List<Element> elements = _createElements(scope);
-//    listener = _applyPattern(pattern, listener);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(elements.length * 3, listener);
-//    for (Element element in elements) {
-//      _index.getRelationships(element, IndexConstants.DEFINES_CLASS, _newCallback(MatchKind.CLASS_DECLARATION, scope, listener));
-//      _index.getRelationships(element, IndexConstants.DEFINES_CLASS_ALIAS, _newCallback(MatchKind.CLASS_ALIAS_DECLARATION, scope, listener));
-//      _index.getRelationships(element, IndexConstants.DEFINES_FUNCTION_TYPE, _newCallback(MatchKind.FUNCTION_TYPE_DECLARATION, scope, listener));
-//    }
-//  }
-//
-//  @override
-//  List<SearchMatch> searchVariableDeclarations(SearchScope scope, SearchPattern pattern, SearchFilter filter) => _gatherResults(new SearchRunner_SearchEngineImpl_searchVariableDeclarations(this, scope, pattern, filter));
-//
-//  @override
-//  void searchVariableDeclarations2(SearchScope scope, SearchPattern pattern, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    List<Element> elements = _createElements(scope);
-//    listener = _applyPattern(pattern, listener);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(elements.length, listener);
-//    for (Element element in elements) {
-//      _index.getRelationships(element, IndexConstants.DEFINES_VARIABLE, _newCallback(MatchKind.VARIABLE_DECLARATION, scope, listener));
-//    }
-//  }
-//
-//  /**
-//   * Use the given runner to perform the given number of asynchronous searches, then wait until the
-//   * search has completed and return the results that were produced.
-//   *
-//   * @param runner the runner used to perform an asynchronous search
-//   * @return the results that were produced @ if the results of at least one of the searched could
-//   *         not be computed
-//   */
-//  List<SearchMatch> _gatherResults(SearchEngineImpl_SearchRunner runner) {
-//    GatheringSearchListener listener = new GatheringSearchListener();
-//    runner.performSearch(listener);
-//    while (!listener.isComplete) {
-//      Thread.yield();
-//    }
-//    return listener.matches;
-//  }
-//
-//  void _searchReferences(AngularElement element, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(2, listener);
-//    _index.getRelationships(element, IndexConstants.ANGULAR_REFERENCE, _newCallback(MatchKind.ANGULAR_REFERENCE, scope, listener));
-//    _index.getRelationships(element, IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE, _newCallback(MatchKind.ANGULAR_CLOSING_TAG_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences2(ClassElement type, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(type, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.TYPE_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences3(CompilationUnitElement unit, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(unit, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.UNIT_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences4(ConstructorElement constructor, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(2, listener);
-//    _index.getRelationships(constructor, IndexConstants.IS_DEFINED_BY, _newCallback(MatchKind.CONSTRUCTOR_DECLARATION, scope, listener));
-//    _index.getRelationships(constructor, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.CONSTRUCTOR_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences5(FunctionElement function, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(2, listener);
-//    _index.getRelationships(function, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.FUNCTION_REFERENCE, scope, listener));
-//    _index.getRelationships(function, IndexConstants.IS_INVOKED_BY, _newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener));
-//  }
-//
-//  void _searchReferences6(FunctionTypeAliasElement alias, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(alias, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.FUNCTION_TYPE_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences7(ImportElement imp, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(imp, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.IMPORT_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences8(LibraryElement library, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(library, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.LIBRARY_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences9(MethodElement method, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    // TODO(scheglov) use "5" when add named matches
-//    listener = new CountingSearchListener(4, listener);
-//    // exact matches
-//    _index.getRelationships(method, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, _newCallback(MatchKind.METHOD_INVOCATION, scope, listener));
-//    _index.getRelationships(method, IndexConstants.IS_INVOKED_BY_QUALIFIED, _newCallback(MatchKind.METHOD_INVOCATION, scope, listener));
-//    _index.getRelationships(method, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.METHOD_REFERENCE, scope, listener));
-//    _index.getRelationships(method, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.METHOD_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences10(ParameterElement parameter, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(5, listener);
-//    _index.getRelationships(parameter, IndexConstants.IS_READ_BY, _newCallback(MatchKind.VARIABLE_READ, scope, listener));
-//    _index.getRelationships(parameter, IndexConstants.IS_READ_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_READ_WRITE, scope, listener));
-//    _index.getRelationships(parameter, IndexConstants.IS_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_WRITE, scope, listener));
-//    _index.getRelationships(parameter, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.NAMED_PARAMETER_REFERENCE, scope, listener));
-//    _index.getRelationships(parameter, IndexConstants.IS_INVOKED_BY, _newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener));
-//  }
-//
-//  void _searchReferences11(PropertyAccessorElement accessor, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(2, listener);
-//    _index.getRelationships(accessor, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.PROPERTY_ACCESSOR_REFERENCE, scope, listener));
-//    _index.getRelationships(accessor, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.PROPERTY_ACCESSOR_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences12(PropertyInducingElement field, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    PropertyAccessorElement getter = field.getter;
-//    PropertyAccessorElement setter = field.setter;
-//    int numRequests = (getter != null ? 4 : 0) + (setter != null ? 2 : 0) + 2;
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(numRequests, listener);
-//    if (getter != null) {
-//      _index.getRelationships(getter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_READ, scope, listener));
-//      _index.getRelationships(getter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.FIELD_READ, scope, listener));
-//      _index.getRelationships(getter, IndexConstants.IS_INVOKED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_INVOCATION, scope, listener));
-//      _index.getRelationships(getter, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, _newCallback(MatchKind.FIELD_INVOCATION, scope, listener));
-//    }
-//    if (setter != null) {
-//      _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_WRITE, scope, listener));
-//      _index.getRelationships(setter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _newCallback(MatchKind.FIELD_WRITE, scope, listener));
-//    }
-//    _index.getRelationships(field, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.FIELD_REFERENCE, scope, listener));
-//    _index.getRelationships(field, IndexConstants.IS_REFERENCED_BY_QUALIFIED, _newCallback(MatchKind.FIELD_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences13(TypeParameterElement typeParameter, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    _index.getRelationships(typeParameter, IndexConstants.IS_REFERENCED_BY, _newCallback(MatchKind.TYPE_PARAMETER_REFERENCE, scope, listener));
-//  }
-//
-//  void _searchReferences14(VariableElement variable, SearchScope scope, SearchFilter filter, SearchListener listener) {
-//    assert(listener != null);
-//    listener = _applyFilter(filter, listener);
-//    listener = new CountingSearchListener(4, listener);
-//    _index.getRelationships(variable, IndexConstants.IS_READ_BY, _newCallback(MatchKind.VARIABLE_READ, scope, listener));
-//    _index.getRelationships(variable, IndexConstants.IS_READ_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_READ_WRITE, scope, listener));
-//    _index.getRelationships(variable, IndexConstants.IS_WRITTEN_BY, _newCallback(MatchKind.VARIABLE_WRITE, scope, listener));
-//    _index.getRelationships(variable, IndexConstants.IS_INVOKED_BY, _newCallback(MatchKind.FUNCTION_EXECUTION, scope, listener));
-//  }
-//}
-//
-///**
-// * Instances of the class <code>RelationshipCallbackImpl</code> implement a callback that can be
-// * used to report results to a search listener.
-// */
-//class SearchEngineImpl_RelationshipCallbackImpl implements RelationshipCallback {
-//  final SearchScope _scope;
-//
-//  /**
-//   * The kind of matches that are represented by the results that will be provided to this
-//   * callback.
-//   */
-//  final MatchKind _matchKind;
-//
-//  /**
-//   * The search listener that should be notified when results are found.
-//   */
-//  final SearchListener _listener;
-//
-//  /**
-//   * Initialize a newly created callback to report matches of the given kind to the given listener
-//   * when results are found.
-//   *
-//   * @param scope the [SearchScope] to return matches from, may be `null` to return
-//   *          all matches
-//   * @param matchKind the kind of matches that are represented by the results
-//   * @param listener the search listener that should be notified when results are found
-//   */
-//  SearchEngineImpl_RelationshipCallbackImpl(this._scope, this._matchKind, this._listener);
-//
-//  @override
-//  void hasRelationships(Element element, Relationship relationship, List<Location> locations) {
-//    for (Location location in locations) {
-//      Element targetElement = location.element;
-//      // check scope
-//      if (_scope != null && !_scope.encloses(targetElement)) {
-//        continue;
-//      }
-//      SourceRange range = new SourceRange(location.offset, location.length);
-//      // TODO(scheglov) IndexConstants.DYNAMIC for MatchQuality.NAME
-//      MatchQuality quality = MatchQuality.EXACT;
-//      //          MatchQuality quality = element.getResource() != IndexConstants.DYNAMIC
-//      //              ? MatchQuality.EXACT : MatchQuality.NAME;
-//      SearchMatch match = new SearchMatch(quality, _matchKind, targetElement, range);
-//      match.qualified = identical(relationship, IndexConstants.IS_REFERENCED_BY_QUALIFIED) || identical(relationship, IndexConstants.IS_INVOKED_BY_QUALIFIED);
-//      _listener.matchFound(match);
-//    }
-//    _listener.searchComplete();
-//  }
-//}
-//
-///**
-// * The interface <code>SearchRunner</code> defines the behavior of objects that can be used to
-// * perform an asynchronous search.
-// */
-//abstract class SearchEngineImpl_SearchRunner {
-//  /**
-//   * Perform an asynchronous search, passing the results to the given listener.
-//   *
-//   * @param listener the listener to which search results should be passed @ if the results could
-//   *          not be computed
-//   */
-//  void performSearch(SearchListener listener);
-//}
-//
-///**
-// * The interface <code>SearchListener</code> defines the behavior of objects that are listening for
-// * the results of a search.
-// */
-//abstract class SearchListener {
-//  /**
-//   * Record the fact that the given match was found.
-//   *
-//   * @param match the match that was found
-//   */
-//  void matchFound(SearchMatch match);
-//
-//  /**
-//   * This method is invoked when the search is complete and no additional matches will be found.
-//   */
-//  void searchComplete();
-//}
+import 'package:analysis_services/index/index.dart';
+import 'package:analysis_services/search/search_engine.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/source.dart';
 
-///**
-// * The class <code>SearchPatternFactory</code> defines utility methods that can be used to create
-// * search patterns.
-// */
-//class SearchPatternFactory {
-//  /**
-//   * Create a pattern that will match any element that is matched by all of the given patterns. If
-//   * no patterns are given, then the resulting pattern will not match any elements.
-//   *
-//   * @param patterns the patterns that must all be matched in order for the new pattern to be
-//   *          matched
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createAndPattern(List<SearchPattern> patterns) {
-//    if (patterns.length == 1) {
-//      return patterns[0];
-//    }
-//    return new AndSearchPattern(patterns);
-//  }
-//
-//  /**
-//   * Create a pattern that will match any element whose name matches a partial identifier where
-//   * camel case conventions are used to perform what is essentially multiple prefix matches.
-//   *
-//   * @param pattern the pattern that matching elements must match
-//   * @param samePartCount `true` if the pattern and the name being matched must have
-//   *          exactly the same number of parts (i.e. the same number of uppercase characters)
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createCamelCasePattern(String prefix, bool samePartCount) => new CamelCaseSearchPattern(prefix, samePartCount);
-//
-//  /**
-//   * Create a pattern that will match any element whose name matches a specified identifier exactly.
-//   *
-//   * @param identifier the identifier that matching elements must be equal to
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createExactPattern(String identifier, bool caseSensitive) => new ExactSearchPattern(identifier, caseSensitive);
-//
-//  /**
-//   * Create a pattern that will match any element that is matched by at least one of the given
-//   * patterns. If no patterns are given, then the resulting pattern will not match any elements.
-//   *
-//   * @param patterns the patterns used to determine whether the new pattern is matched
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createOrPattern(List<SearchPattern> patterns) {
-//    if (patterns.length == 1) {
-//      return patterns[0];
-//    }
-//    return new OrSearchPattern(patterns);
-//  }
-//
-//  /**
-//   * Create a pattern that will match any element whose name starts with the given prefix.
-//   *
-//   * @param prefix the prefix of names that match the pattern
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createPrefixPattern(String prefix, bool caseSensitive) => new PrefixSearchPattern(prefix, caseSensitive);
-//
-//  /**
-//   * Create a pattern that will match any element whose name matches a regular expression.
-//   *
-//   * @param regularExpression the regular expression that matching elements must match
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createRegularExpressionPattern(String regularExpression, bool caseSensitive) => new RegularExpressionSearchPattern(regularExpression, caseSensitive);
-//
-//  /**
-//   * Create a pattern that will match any element whose name matches a pattern containing wildcard
-//   * characters. The wildcard characters that are currently supported are '?' (to match any single
-//   * character) and '*' (to match zero or more characters).
-//   *
-//   * @param pattern the pattern that matching elements must match
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   * @return the pattern that was created
-//   */
-//  static SearchPattern createWildcardPattern(String pattern, bool caseSensitive) => new WildcardSearchPattern(pattern, caseSensitive);
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchDeclarations implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  String name;
-//
-//  SearchScope scope;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchDeclarations(this.SearchEngineImpl_this, this.name, this.scope, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchDeclarations2(name, scope, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchFunctionDeclarations implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  SearchScope scope;
-//
-//  SearchPattern pattern;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchFunctionDeclarations(this.SearchEngineImpl_this, this.scope, this.pattern, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchFunctionDeclarations2(scope, pattern, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchQualifiedMemberReferences implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  String name;
-//
-//  SearchScope scope;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchQualifiedMemberReferences(this.SearchEngineImpl_this, this.name, this.scope, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchQualifiedMemberReferences2(name, scope, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchReferences implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  Element element;
-//
-//  SearchScope scope;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchReferences(this.SearchEngineImpl_this, this.element, this.scope, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchReferences2(element, scope, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchSubtypes implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  ClassElement type;
-//
-//  SearchScope scope;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchSubtypes(this.SearchEngineImpl_this, this.type, this.scope, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchSubtypes2(type, scope, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchTypeDeclarations implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  SearchScope scope;
-//
-//  SearchPattern pattern;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchTypeDeclarations(this.SearchEngineImpl_this, this.scope, this.pattern, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchTypeDeclarations2(scope, pattern, filter, listener);
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImpl_searchVariableDeclarations implements SearchEngineImpl_SearchRunner {
-//  final SearchEngineImpl SearchEngineImpl_this;
-//
-//  SearchScope scope;
-//
-//  SearchPattern pattern;
-//
-//  SearchFilter filter;
-//
-//  SearchRunner_SearchEngineImpl_searchVariableDeclarations(this.SearchEngineImpl_this, this.scope, this.pattern, this.filter);
-//
-//  @override
-//  void performSearch(SearchListener listener) {
-//    SearchEngineImpl_this.searchVariableDeclarations2(scope, pattern, filter, listener);
-//  }
-//}
-//
-///**
-// * The class <code>SearchScopeFactory</code> defines utility methods that can be used to create
-// * search scopes.
-// */
-//class SearchScopeFactory {
-//  /**
-//   * A search scope that encompasses everything in the "universe". Because it does not hold any
-//   * state there is no reason not to share a single instance.
-//   */
-//  static SearchScope _UNIVERSE_SCOPE = new UniverseSearchScope();
-//
-//  /**
-//   * Create a search scope that encompasses everything in the given library.
-//   *
-//   * @param library the library defining which elements are included in the scope
-//   * @return the search scope that was created
-//   */
-//  static SearchScope createLibraryScope(Iterable<LibraryElement> libraries) => new LibrarySearchScope.con1(libraries);
-//
-//  /**
-//   * Create a search scope that encompasses everything in the given libraries.
-//   *
-//   * @param libraries the libraries defining which elements are included in the scope
-//   * @return the search scope that was created
-//   */
-//  static SearchScope createLibraryScope2(List<LibraryElement> libraries) => new LibrarySearchScope.con2(libraries);
-//
-//  /**
-//   * Create a search scope that encompasses everything in the given library.
-//   *
-//   * @param library the library defining which elements are included in the scope
-//   * @return the search scope that was created
-//   */
-//  static SearchScope createLibraryScope3(LibraryElement library) => new LibrarySearchScope.con2([library]);
-//
-//  /**
-//   * Create a search scope that encompasses everything in the universe.
-//   *
-//   * @return the search scope that was created
-//   */
-//  static SearchScope createUniverseScope() => _UNIVERSE_SCOPE;
-//}
-//
-///**
-// * The [SearchScope] that encompasses everything in the universe.
-// */
-//class UniverseSearchScope implements SearchScope {
-//  @override
-//  bool encloses(Element element) => true;
-//}
-//
-///**
-// * Instances of the class <code>WildcardSearchPattern</code> implement a search pattern that matches
-// * elements whose name matches a pattern with wildcard characters. The wildcard characters that are
-// * currently supported are '?' (to match any single character) and '*' (to match zero or more
-// * characters).
-// */
-//class WildcardSearchPattern implements SearchPattern {
-//  /**
-//   * The pattern that matching elements must match.
-//   */
-//  List<int> _pattern;
-//
-//  /**
-//   * A flag indicating whether a case sensitive match is to be performed.
-//   */
-//  final bool _caseSensitive;
-//
-//  /**
-//   * Initialize a newly created search pattern to match elements whose names begin with the given
-//   * prefix.
-//   *
-//   * @param pattern the pattern that matching elements must match
-//   * @param caseSensitive `true` if a case sensitive match is to be performed
-//   */
-//  WildcardSearchPattern(String pattern, this._caseSensitive) {
-//    this._pattern = _caseSensitive ? pattern.toCharArray() : pattern.toLowerCase().toCharArray();
-//  }
-//
-//  @override
-//  MatchQuality matches(Element element) {
-//    if (element == null) {
-//      return null;
-//    }
-//    String name = element.displayName;
-//    if (name == null) {
-//      return null;
-//    }
-//    if (CharOperation.match(_pattern, name.toCharArray(), _caseSensitive)) {
-//      return MatchQuality.EXACT;
-//    }
-//    return null;
-//  }
-//}
-//
-///**
-// * Instances of the class <code>ScopedSearchListener</code> implement a search listener that
-// * delegates to another search listener after removing matches that are outside a given scope.
-// */
-//abstract class WrappedSearchListener implements SearchListener {
-//  /**
-//   * The listener being wrapped.
-//   */
-//  SearchListener _baseListener;
-//
-//  /**
-//   * Initialize a newly created search listener to wrap the given listener.
-//   *
-//   * @param listener the search listener being wrapped
-//   */
-//  WrappedSearchListener(SearchListener listener) {
-//    _baseListener = listener;
-//  }
-//
-//  @override
-//  void searchComplete() {
-//    _baseListener.searchComplete();
-//  }
-//
-//  /**
-//   * Pass the given match on to the wrapped listener.
-//   *
-//   * @param match the match to be propagated
-//   */
-//  void propagateMatch(SearchMatch match) {
-//    _baseListener.matchFound(match);
-//  }
-//}
+
+/**
+ * A [SearchEngine] implementation.
+ */
+class SearchEngineImpl implements SearchEngine {
+  final Index _index;
+
+  SearchEngineImpl(this._index);
+
+  @override
+  Future<List<SearchMatch>> searchMemberDeclarations(String name) {
+    NameElement element = new NameElement(name);
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        element,
+        IndexConstants.IS_DEFINED_BY,
+        MatchKind.NAME_DECLARATION);
+    return requestor.merge().then((matches) {
+      return matches.where((match) {
+        return match.element.enclosingElement is ClassElement;
+      }).toList();
+    });
+  }
+
+  @override
+  Future<List<SearchMatch>> searchMemberReferences(String name) {
+    NameElement element = new NameElement(name);
+    _Requestor requestor = new _Requestor(_index);
+    // rought
+//    requestor.add(
+//        element,
+//        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+//        MatchKind.NAME_REFERENCE_RESOLVED);
+//    requestor.add(
+//        element,
+//        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+//        MatchKind.NAME_REFERENCE_UNRESOLVED,
+//        isResolved: false);
+    // granular resolved operations
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_INVOKED_BY_RESOLVED,
+        MatchKind.NAME_INVOCATION_RESOLVED);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_READ_BY_RESOLVED,
+        MatchKind.NAME_READ_RESOLVED);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED,
+        MatchKind.NAME_READ_WRITE_RESOLVED);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED,
+        MatchKind.NAME_WRITE_RESOLVED);
+    // granular unresolved operations
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED,
+        MatchKind.NAME_INVOCATION_UNRESOLVED,
+        isResolved: false);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_READ_BY_UNRESOLVED,
+        MatchKind.NAME_READ_UNRESOLVED,
+        isResolved: false);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED,
+        MatchKind.NAME_READ_WRITE_UNRESOLVED,
+        isResolved: false);
+    requestor.add(
+        element,
+        IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED,
+        MatchKind.NAME_WRITE_UNRESOLVED,
+        isResolved: false);
+    // done
+    return requestor.merge();
+  }
+
+  @override
+  Future<List<SearchMatch>> searchReferences(Element element) {
+    if (element.kind == ElementKind.ANGULAR_COMPONENT ||
+        element.kind == ElementKind.ANGULAR_CONTROLLER ||
+        element.kind == ElementKind.ANGULAR_FORMATTER ||
+        element.kind == ElementKind.ANGULAR_PROPERTY ||
+        element.kind == ElementKind.ANGULAR_SCOPE_PROPERTY ||
+        element.kind == ElementKind.ANGULAR_SELECTOR) {
+      return _searchReferences_Angular(element as AngularElement);
+    } else if (element.kind == ElementKind.CLASS) {
+      return _searchReferences_Class(element as ClassElement);
+    } else if (element.kind == ElementKind.COMPILATION_UNIT) {
+      return _searchReferences_CompilationUnit(
+          element as CompilationUnitElement);
+    } else if (element.kind == ElementKind.CONSTRUCTOR) {
+      return _searchReferences_Constructor(element as ConstructorElement);
+    } else if (element.kind == ElementKind.FIELD ||
+        element.kind == ElementKind.TOP_LEVEL_VARIABLE) {
+      return _searchReferences_Field(element as PropertyInducingElement);
+    } else if (element.kind == ElementKind.FUNCTION) {
+      return _searchReferences_Function(element as FunctionElement);
+    } else if (element.kind == ElementKind.GETTER ||
+        element.kind == ElementKind.SETTER) {
+      return _searchReferences_PropertyAccessor(
+          element as PropertyAccessorElement);
+    } else if (element.kind == ElementKind.IMPORT) {
+      return _searchReferences_Import(element as ImportElement);
+    } else if (element.kind == ElementKind.LIBRARY) {
+      return _searchReferences_Library(element as LibraryElement);
+    } else if (element.kind == ElementKind.LOCAL_VARIABLE) {
+      return _searchReferences_LocalVariable(element as LocalVariableElement);
+    } else if (element.kind == ElementKind.METHOD) {
+      return _searchReferences_Method(element as MethodElement);
+    } else if (element.kind == ElementKind.PARAMETER) {
+      return _searchReferences_Parameter(element as ParameterElement);
+    } else if (element.kind == ElementKind.FUNCTION_TYPE_ALIAS) {
+      return _searchReferences_FunctionTypeAlias(
+          element as FunctionTypeAliasElement);
+    } else if (element.kind == ElementKind.TYPE_PARAMETER) {
+      return _searchReferences_TypeParameter(element as TypeParameterElement);
+    }
+    return new Future.value(<SearchMatch>[]);
+  }
+
+  @override
+  Future<List<SearchMatch>> searchSubtypes(ClassElement type) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        type,
+        IndexConstants.IS_EXTENDED_BY,
+        MatchKind.EXTENDS_REFERENCE);
+    requestor.add(
+        type,
+        IndexConstants.IS_MIXED_IN_BY,
+        MatchKind.WITH_REFERENCE);
+    requestor.add(
+        type,
+        IndexConstants.IS_IMPLEMENTED_BY,
+        MatchKind.IMPLEMENTS_REFERENCE);
+    return requestor.merge();
+  }
+
+  @override
+  Future<List<SearchMatch>> searchTopLevelDeclarations(String pattern) {
+    UniverseElement universe = UniverseElement.INSTANCE;
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        universe,
+        IndexConstants.DEFINES_CLASS,
+        MatchKind.CLASS_DECLARATION);
+    requestor.add(
+        universe,
+        IndexConstants.DEFINES_CLASS_ALIAS,
+        MatchKind.CLASS_ALIAS_DECLARATION);
+    requestor.add(
+        universe,
+        IndexConstants.DEFINES_FUNCTION_TYPE,
+        MatchKind.FUNCTION_TYPE_DECLARATION);
+    requestor.add(
+        universe,
+        IndexConstants.DEFINES_FUNCTION,
+        MatchKind.FUNCTION_DECLARATION);
+    requestor.add(
+        universe,
+        IndexConstants.DEFINES_VARIABLE,
+        MatchKind.VARIABLE_DECLARATION);
+    RegExp regExp = new RegExp(pattern);
+    return requestor.merge().then((List<SearchMatch> matches) {
+      return matches.where((SearchMatch match) {
+        String name = match.element.displayName;
+        return regExp.hasMatch(name);
+      }).toList();
+    });
+  }
+
+  Future<List<SearchMatch>> _searchReferences_Angular(AngularElement element) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        element,
+        IndexConstants.ANGULAR_REFERENCE,
+        MatchKind.ANGULAR_REFERENCE);
+    requestor.add(
+        element,
+        IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE,
+        MatchKind.ANGULAR_CLOSING_TAG_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>> _searchReferences_Class(ClassElement clazz) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        clazz,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.TYPE_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_CompilationUnit(CompilationUnitElement unit) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        unit,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.UNIT_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_Constructor(ConstructorElement constructor) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        constructor,
+        IndexConstants.IS_DEFINED_BY,
+        MatchKind.CONSTRUCTOR_DECLARATION);
+    requestor.add(
+        constructor,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.CONSTRUCTOR_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_Field(PropertyInducingElement field) {
+    PropertyAccessorElement getter = field.getter;
+    PropertyAccessorElement setter = field.setter;
+    _Requestor requestor = new _Requestor(_index);
+    // field itself
+    requestor.add(
+        field,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.FIELD_REFERENCE);
+    requestor.add(
+        field,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        MatchKind.FIELD_REFERENCE);
+    // getter
+    if (getter != null) {
+      requestor.add(
+          getter,
+          IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+          MatchKind.FIELD_READ);
+      requestor.add(
+          getter,
+          IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+          MatchKind.FIELD_READ);
+      requestor.add(
+          getter,
+          IndexConstants.IS_INVOKED_BY_QUALIFIED,
+          MatchKind.FIELD_INVOCATION);
+      requestor.add(
+          getter,
+          IndexConstants.IS_INVOKED_BY_UNQUALIFIED,
+          MatchKind.FIELD_INVOCATION);
+    }
+    // setter
+    if (setter != null) {
+      requestor.add(
+          setter,
+          IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+          MatchKind.FIELD_WRITE);
+      requestor.add(
+          setter,
+          IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+          MatchKind.FIELD_WRITE);
+    }
+    // done
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_Function(FunctionElement function) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        function,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.FUNCTION_REFERENCE);
+    requestor.add(
+        function,
+        IndexConstants.IS_INVOKED_BY,
+        MatchKind.FUNCTION_EXECUTION);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_FunctionTypeAlias(FunctionTypeAliasElement alias) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        alias,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.FUNCTION_TYPE_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>> _searchReferences_Import(ImportElement imp) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        imp,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.IMPORT_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>> _searchReferences_Library(LibraryElement library) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        library,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.LIBRARY_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_LocalVariable(LocalVariableElement variable) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(variable, IndexConstants.IS_READ_BY, MatchKind.VARIABLE_READ);
+    requestor.add(
+        variable,
+        IndexConstants.IS_READ_WRITTEN_BY,
+        MatchKind.VARIABLE_READ_WRITE);
+    requestor.add(
+        variable,
+        IndexConstants.IS_WRITTEN_BY,
+        MatchKind.VARIABLE_WRITE);
+    requestor.add(
+        variable,
+        IndexConstants.IS_INVOKED_BY,
+        MatchKind.FUNCTION_EXECUTION);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>> _searchReferences_Method(MethodElement method) {
+    _Requestor requestor = new _Requestor(_index);
+    if (method is MethodMember) {
+      method = (method as MethodMember).baseElement;
+    }
+    requestor.add(
+        method,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        MatchKind.METHOD_REFERENCE);
+    requestor.add(
+        method,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        MatchKind.METHOD_REFERENCE);
+    requestor.add(
+        method,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
+        MatchKind.METHOD_INVOCATION);
+    requestor.add(
+        method,
+        IndexConstants.IS_INVOKED_BY_UNQUALIFIED,
+        MatchKind.METHOD_INVOCATION);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_Parameter(ParameterElement parameter) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        parameter,
+        IndexConstants.IS_READ_BY,
+        MatchKind.VARIABLE_READ);
+    requestor.add(
+        parameter,
+        IndexConstants.IS_READ_WRITTEN_BY,
+        MatchKind.VARIABLE_READ_WRITE);
+    requestor.add(
+        parameter,
+        IndexConstants.IS_WRITTEN_BY,
+        MatchKind.VARIABLE_WRITE);
+    requestor.add(
+        parameter,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.NAMED_PARAMETER_REFERENCE);
+    requestor.add(
+        parameter,
+        IndexConstants.IS_INVOKED_BY,
+        MatchKind.FUNCTION_EXECUTION);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_PropertyAccessor(PropertyAccessorElement accessor) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        accessor,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        MatchKind.PROPERTY_ACCESSOR_REFERENCE);
+    requestor.add(
+        accessor,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        MatchKind.PROPERTY_ACCESSOR_REFERENCE);
+    return requestor.merge();
+  }
+
+  Future<List<SearchMatch>>
+      _searchReferences_TypeParameter(TypeParameterElement typeParameter) {
+    _Requestor requestor = new _Requestor(_index);
+    requestor.add(
+        typeParameter,
+        IndexConstants.IS_REFERENCED_BY,
+        MatchKind.TYPE_PARAMETER_REFERENCE);
+    return requestor.merge();
+  }
+}
+
+
+class _Requestor {
+  final List<Future<List<SearchMatch>>> futures = <Future<List<SearchMatch>>>[];
+  final Index index;
+
+  _Requestor(this.index);
+
+  void add(Element element2, Relationship relationship, MatchKind kind,
+      {bool isResolved: true}) {
+    Future relationsFuture = index.getRelationships(element2, relationship);
+    Future matchesFuture = relationsFuture.then((List<Location> locations) {
+      bool isQualified =
+          relationship == IndexConstants.IS_REFERENCED_BY_QUALIFIED ||
+          relationship == IndexConstants.IS_INVOKED_BY_QUALIFIED;
+      List<SearchMatch> matches = <SearchMatch>[];
+      for (Location location in locations) {
+        Element element = location.element;
+        matches.add(
+            new SearchMatch(
+                kind,
+                element,
+                new SourceRange(location.offset, location.length),
+                isResolved,
+                isQualified));
+      }
+      return matches;
+    });
+    futures.add(matchesFuture);
+  }
+
+  Future<List<SearchMatch>> merge() {
+    return Future.wait(futures).then((List<List<SearchMatch>> matchesList) {
+      return matchesList.expand((matches) => matches).toList();
+    });
+  }
+}
diff --git a/pkg/analysis_services/pubspec.yaml b/pkg/analysis_services/pubspec.yaml
index 66e9ac2..194caf2 100644
--- a/pkg/analysis_services/pubspec.yaml
+++ b/pkg/analysis_services/pubspec.yaml
@@ -1,12 +1,12 @@
 name: analysis_services
-version: 0.1.0
+version: 0.2.0
 author: Dart Team <misc@dartlang.org>
 description: A set of services on top of Analysis Engine
 homepage: http://www.dartlang.org
 environment:
   sdk: '>=1.0.0 <2.0.0'
 dependencies:
-  analyzer: '>=0.21.0 <1.0.0'
+  analyzer: '>=0.21.1 <1.0.0'
 dev_dependencies:
-  analysis_testing: '>=0.2.0 <1.0.0'
+  analysis_testing: '>=0.3.0 <1.0.0'
   unittest: '>=0.10.0 <0.12.0'
diff --git a/pkg/analysis_services/test/index/abstract_single_unit.dart b/pkg/analysis_services/test/index/abstract_single_unit.dart
new file mode 100644
index 0000000..7dc112d
--- /dev/null
+++ b/pkg/analysis_services/test/index/abstract_single_unit.dart
@@ -0,0 +1,93 @@
+// 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.services.src.index.abstract_single_file;
+
+import 'package:analysis_testing/abstract_context.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:unittest/unittest.dart';
+
+
+class AbstractSingleUnitTest extends AbstractContextTest {
+  bool verifyNoTestUnitErrors = true;
+
+  String testCode;
+  Source testSource;
+  CompilationUnit testUnit;
+  CompilationUnitElement testUnitElement;
+  LibraryElement testLibraryElement;
+
+  void assertNoErrorsInSource(Source source) {
+    List<AnalysisError> errors = context.getErrors(source).errors;
+    expect(errors, isEmpty);
+  }
+
+  Element findElement(String name, [ElementKind kind]) {
+    return findChildElement(testUnitElement, name, kind);
+  }
+
+  AstNode findNodeAtOffset(int offset, [Predicate<AstNode> predicate]) {
+    AstNode result = new NodeLocator.con1(offset).searchWithin(testUnit);
+    if (result != null && predicate != null) {
+      result = result.getAncestor(predicate);
+    }
+    return result;
+  }
+
+  AstNode findNodeAtString(String search, [Predicate<AstNode> predicate]) {
+    int offset = findOffset(search);
+    return findNodeAtOffset(offset, predicate);
+  }
+
+  Element findNodeElementAtString(String search,
+      [Predicate<AstNode> predicate]) {
+    AstNode node = findNodeAtString(search, predicate);
+    if (node == null) {
+      return null;
+    }
+    return ElementLocator.locate(node);
+  }
+
+  int findOffset(String search) {
+    int offset = testCode.indexOf(search);
+    expect(offset, isNonNegative, reason: "Not found '$search' in\n$testCode");
+    return offset;
+  }
+
+  int getLeadingIdentifierLength(String search) {
+    int length = 0;
+    while (length < search.length) {
+      int c = search.codeUnitAt(length);
+      if (c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0)) {
+        length++;
+        continue;
+      }
+      if (c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0)) {
+        length++;
+        continue;
+      }
+      if (c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0)) {
+        length++;
+        continue;
+      }
+      break;
+    }
+    return length;
+  }
+
+  void resolveTestUnit(String code) {
+    testCode = code;
+    testSource = addSource('/test.dart', code);
+    testUnit = resolveLibraryUnit(testSource);
+    if (verifyNoTestUnitErrors) {
+      assertNoErrorsInSource(testSource);
+    }
+    testUnitElement = testUnit.element;
+    testLibraryElement = testUnitElement.library;
+  }
+}
diff --git a/pkg/analysis_services/test/index/dart_index_contributor_test.dart b/pkg/analysis_services/test/index/dart_index_contributor_test.dart
index 3892d5d..b5087b6 100644
--- a/pkg/analysis_services/test/index/dart_index_contributor_test.dart
+++ b/pkg/analysis_services/test/index/dart_index_contributor_test.dart
@@ -7,16 +7,15 @@
 import 'package:analysis_services/index/index.dart';
 import 'package:analysis_services/index/index_store.dart';
 import 'package:analysis_services/src/index/index_contributor.dart';
-import 'package:analysis_testing/abstract_context.dart';
 import 'package:analysis_testing/reflective_tests.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
 
+import 'abstract_single_unit.dart';
+
 
 main() {
   groupSep = ' | ';
@@ -30,7 +29,10 @@
  * Returns `true` if the [actual] location the same properties as [expected].
  */
 bool _equalsLocation(Location actual, ExpectedLocation expected) {
-  return _equalsLocationProperties(actual, expected.element, expected.offset,
+  return _equalsLocationProperties(
+      actual,
+      expected.element,
+      expected.offset,
       expected.length);
 }
 
@@ -40,7 +42,8 @@
  */
 bool _equalsLocationProperties(Location actual, Element expectedElement,
     int expectedOffset, int expectedLength) {
-  return expectedElement == actual.element && expectedOffset == actual.offset &&
+  return expectedElement == actual.element &&
+      expectedOffset == actual.offset &&
       expectedLength == actual.length;
 }
 
@@ -48,53 +51,29 @@
 bool _equalsRecordedRelation(RecordedRelation recordedRelation,
     Element expectedElement, Relationship expectedRelationship,
     ExpectedLocation expectedLocation) {
-  return expectedElement == recordedRelation.element && expectedRelationship ==
-      recordedRelation.relationship && (expectedLocation == null || _equalsLocation(
-      recordedRelation.location, expectedLocation));
+  return expectedElement == recordedRelation.element &&
+      expectedRelationship == recordedRelation.relationship &&
+      (expectedLocation == null ||
+          _equalsLocation(recordedRelation.location, expectedLocation));
 }
 
 
-int _getLeadingIdentifierLength(String search) {
-  int length = 0;
-  while (length < search.length) {
-    int c = search.codeUnitAt(length);
-    if (c >= 'a'.codeUnitAt(0) && c <= 'z'.codeUnitAt(0)) {
-      length++;
-      continue;
-    }
-    if (c >= 'A'.codeUnitAt(0) && c <= 'Z'.codeUnitAt(0)) {
-      length++;
-      continue;
-    }
-    if (c >= '0'.codeUnitAt(0) && c <= '9'.codeUnitAt(0)) {
-      length++;
-      continue;
-    }
-    break;
-  }
-  return length;
-}
-
 @ReflectiveTestCase()
-class DartUnitContributorTest extends AbstractContextTest {
+class DartUnitContributorTest extends AbstractSingleUnitTest {
   IndexStore store = new MockIndexStore();
   List<RecordedRelation> recordedRelations = <RecordedRelation>[];
 
-  bool verifyNoTestUnitErrors = true;
-
-  String testCode;
-  Source testSource;
-  CompilationUnit testUnit;
-  CompilationUnitElement testUnitElement;
-  LibraryElement testLibraryElement;
-
   void setUp() {
     super.setUp();
     when(store.aboutToIndexDart(context, anyObject)).thenReturn(true);
-    when(store.recordRelationship(anyObject, anyObject, anyObject)).thenInvoke(
-        (Element element, Relationship relationship, Location location) {
-      recordedRelations.add(new RecordedRelation(element, relationship,
-          location));
+    when(
+        store.recordRelationship(
+            anyObject,
+            anyObject,
+            anyObject)).thenInvoke(
+                (Element element, Relationship relationship, Location location) {
+      recordedRelations.add(
+          new RecordedRelation(element, relationship, location));
     });
   }
 
@@ -107,21 +86,23 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    FieldElement fieldElement = _findElement("myField");
+    Element mainElement = findElement("main");
+    FieldElement fieldElement = findElement("myField");
     PropertyAccessorElement getterElement = fieldElement.getter;
     // verify
-    _assertRecordedRelation(getterElement,
-        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _expectedLocation(mainElement,
-        'myField);'));
+    _assertRecordedRelation(
+        getterElement,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        _expectedLocation(mainElement, 'myField);'));
   }
 
   void test_definesClass() {
     _indexTestUnit('class A {}');
     // prepare elements
-    ClassElement classElement = _findElement("A");
+    ClassElement classElement = findElement("A");
     // verify
-    _assertDefinesTopLevelElement(IndexConstants.DEFINES_CLASS,
+    _assertDefinesTopLevelElement(
+        IndexConstants.DEFINES_CLASS,
         _expectedLocation(classElement, 'A {}'));
   }
 
@@ -130,27 +111,30 @@
 class Mix {}
 class MyClass = Object with Mix;''');
     // prepare elements
-    Element classElement = _findElement("MyClass");
+    Element classElement = findElement("MyClass");
     // verify
-    _assertDefinesTopLevelElement(IndexConstants.DEFINES_CLASS_ALIAS,
+    _assertDefinesTopLevelElement(
+        IndexConstants.DEFINES_CLASS_ALIAS,
         _expectedLocation(classElement, 'MyClass ='));
   }
 
   void test_definesFunction() {
     _indexTestUnit('myFunction() {}');
     // prepare elements
-    FunctionElement functionElement = _findElement("myFunction");
+    FunctionElement functionElement = findElement("myFunction");
     // verify
-    _assertDefinesTopLevelElement(IndexConstants.DEFINES_FUNCTION,
+    _assertDefinesTopLevelElement(
+        IndexConstants.DEFINES_FUNCTION,
         _expectedLocation(functionElement, 'myFunction() {}'));
   }
 
   void test_definesFunctionType() {
     _indexTestUnit('typedef MyFunction(int p);');
     // prepare elements
-    FunctionTypeAliasElement typeAliasElement = _findElement("MyFunction");
+    FunctionTypeAliasElement typeAliasElement = findElement("MyFunction");
     // verify
-    _assertDefinesTopLevelElement(IndexConstants.DEFINES_FUNCTION_TYPE,
+    _assertDefinesTopLevelElement(
+        IndexConstants.DEFINES_FUNCTION_TYPE,
         _expectedLocation(typeAliasElement, 'MyFunction(int p);'));
   }
 
@@ -158,9 +142,10 @@
   void test_definesVariable() {
     _indexTestUnit('var myVar = 42;');
     // prepare elements
-    VariableElement varElement = _findElement("myVar");
+    VariableElement varElement = findElement("myVar");
     // verify
-    _assertDefinesTopLevelElement(IndexConstants.DEFINES_VARIABLE,
+    _assertDefinesTopLevelElement(
+        IndexConstants.DEFINES_VARIABLE,
         _expectedLocation(varElement, 'myVar = 42;'));
   }
 
@@ -171,10 +156,12 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    VariableElement variableElement = _findElement("v");
+    Element mainElement = findElement("main");
+    VariableElement variableElement = findElement("v");
     // verify
-    _assertNoRecordedRelation(variableElement, IndexConstants.IS_READ_BY,
+    _assertNoRecordedRelation(
+        variableElement,
+        IndexConstants.IS_READ_BY,
         _expectedLocation(mainElement, 'v in []'));
   }
 
@@ -185,15 +172,19 @@
   A.foo() {}
 }''');
     // prepare elements
-    ClassElement classA = _findElement("A");
-    ConstructorElement consA = _findNodeElementAtString("A()", (node) => node is
-        ConstructorDeclaration);
-    ConstructorElement consA_foo = _findNodeElementAtString("A.foo()", (node) =>
-        node is ConstructorDeclaration);
+    ClassElement classA = findElement("A");
+    ConstructorElement consA =
+        findNodeElementAtString("A()", (node) => node is ConstructorDeclaration);
+    ConstructorElement consA_foo =
+        findNodeElementAtString("A.foo()", (node) => node is ConstructorDeclaration);
     // verify
-    _assertRecordedRelation(consA, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        consA,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(classA, '() {}'));
-    _assertRecordedRelation(consA_foo, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        consA_foo,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(classA, '.foo() {}', '.foo'.length));
   }
 
@@ -203,10 +194,12 @@
   m() {}
 }''');
     // prepare elements
-    Element methodElement = _findElement("m");
+    Element methodElement = findElement("m");
     Element nameElement = new NameElement("m");
     // verify
-    _assertRecordedRelation(nameElement, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(methodElement, 'm() {}'));
   }
 
@@ -217,10 +210,12 @@
   operator +(o) {}
 }''');
     // prepare elements
-    Element methodElement = _findElement("+");
+    Element methodElement = findElement("+");
     Element nameElement = new NameElement("+");
     // verify
-    _assertRecordedRelation(nameElement, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(methodElement, '+(o) {}', 1));
   }
 
@@ -230,10 +225,12 @@
 class B extends A {} // 2
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
-    ClassElement classElementB = _findElement("B");
+    ClassElement classElementA = findElement("A");
+    ClassElement classElementB = findElement("B");
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_EXTENDED_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_EXTENDED_BY,
         _expectedLocation(classElementB, 'A {} // 2'));
   }
 
@@ -242,10 +239,12 @@
 class A {} // 1
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
+    ClassElement classElementA = findElement("A");
     ClassElement classElementObject = classElementA.supertype.element;
     // verify
-    _assertRecordedRelation(classElementObject, IndexConstants.IS_EXTENDED_BY,
+    _assertRecordedRelation(
+        classElementObject,
+        IndexConstants.IS_EXTENDED_BY,
         _expectedLocation(classElementA, 'A {}', 0));
   }
 
@@ -256,10 +255,12 @@
 class C = A with B; // 3
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
-    ClassElement classElementC = _findElement("C");
+    ClassElement classElementA = findElement("A");
+    ClassElement classElementC = findElement("C");
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_EXTENDED_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_EXTENDED_BY,
         _expectedLocation(classElementC, 'A with'));
   }
 
@@ -269,10 +270,12 @@
 class B implements A {} // 2
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
-    ClassElement classElementB = _findElement("B");
+    ClassElement classElementA = findElement("A");
+    ClassElement classElementB = findElement("B");
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_IMPLEMENTED_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_IMPLEMENTED_BY,
         _expectedLocation(classElementB, 'A {} // 2'));
   }
 
@@ -283,10 +286,12 @@
 class C = Object with A implements B; // 3
 ''');
     // prepare elements
-    ClassElement classElementB = _findElement("B");
-    ClassElement classElementC = _findElement("C");
+    ClassElement classElementB = findElement("B");
+    ClassElement classElementC = findElement("C");
     // verify
-    _assertRecordedRelation(classElementB, IndexConstants.IS_IMPLEMENTED_BY,
+    _assertRecordedRelation(
+        classElementB,
+        IndexConstants.IS_IMPLEMENTED_BY,
         _expectedLocation(classElementC, 'B; // 3'));
   }
 
@@ -300,13 +305,14 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    FieldElement fieldElement = _findElement("field");
+    Element mainElement = findElement("main");
+    FieldElement fieldElement = findElement("field");
     PropertyAccessorElement getterElement = fieldElement.getter;
     // verify
-    _assertRecordedRelation(getterElement,
-        IndexConstants.IS_INVOKED_BY_QUALIFIED, _expectedLocation(mainElement,
-        'field();'));
+    _assertRecordedRelation(
+        getterElement,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
+        _expectedLocation(mainElement, 'field();'));
   }
 
 
@@ -319,14 +325,18 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element methodElement = _findElement("foo");
+    Element mainElement = findElement("main");
+    Element methodElement = findElement("foo");
     // verify
     var location = _expectedLocation(mainElement, 'foo();');
-    _assertRecordedRelation(methodElement,
-        IndexConstants.IS_INVOKED_BY_QUALIFIED, location);
-    _assertNoRecordedRelation(methodElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
+    _assertRecordedRelation(
+        methodElement,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
+        location);
+    _assertNoRecordedRelation(
+        methodElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        location);
   }
 
   void test_isInvokedByQualified_MethodElement_propagatedType() {
@@ -340,12 +350,13 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element methodElement = _findElement("foo");
+    Element mainElement = findElement("main");
+    Element methodElement = findElement("foo");
     // verify
-    _assertRecordedRelation(methodElement,
-        IndexConstants.IS_INVOKED_BY_QUALIFIED, _expectedLocation(mainElement,
-        'foo();'));
+    _assertRecordedRelation(
+        methodElement,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
+        _expectedLocation(mainElement, 'foo();'));
   }
 
   void test_isInvokedByUnqualified_MethodElement() {
@@ -357,12 +368,13 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element methodElement = _findElement("foo");
+    Element mainElement = findElement("main");
+    Element methodElement = findElement("foo");
     // verify
-    _assertRecordedRelation(methodElement,
-        IndexConstants.IS_INVOKED_BY_UNQUALIFIED, _expectedLocation(mainElement,
-        'foo();'));
+    _assertRecordedRelation(
+        methodElement,
+        IndexConstants.IS_INVOKED_BY_UNQUALIFIED,
+        _expectedLocation(mainElement, 'foo();'));
   }
 
   void test_isInvokedBy_FunctionElement() {
@@ -372,10 +384,12 @@
   foo();
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    FunctionElement functionElement = _findElement("foo");
+    Element mainElement = findElement("main");
+    FunctionElement functionElement = findElement("foo");
     // verify
-    _assertRecordedRelation(functionElement, IndexConstants.IS_INVOKED_BY,
+    _assertRecordedRelation(
+        functionElement,
+        IndexConstants.IS_INVOKED_BY,
         _expectedLocation(mainElement, 'foo();'));
   }
 
@@ -386,10 +400,12 @@
   v();
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element element = _findElement("v");
+    Element mainElement = findElement("main");
+    Element element = findElement("v");
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY,
         _expectedLocation(mainElement, 'v();'));
   }
 
@@ -399,10 +415,12 @@
   p();
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element element = _findElement("p");
+    Element mainElement = findElement("main");
+    Element element = findElement("p");
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY,
         _expectedLocation(mainElement, 'p();'));
   }
 
@@ -412,10 +430,12 @@
 class B extends Object with A {} // 2
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
-    ClassElement classElementB = _findElement("B");
+    ClassElement classElementA = findElement("A");
+    ClassElement classElementB = findElement("B");
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_MIXED_IN_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_MIXED_IN_BY,
         _expectedLocation(classElementB, 'A {} // 2'));
   }
 
@@ -425,10 +445,12 @@
 class B = Object with A; // 2
 ''');
     // prepare elements
-    ClassElement classElementA = _findElement("A");
-    ClassElement classElementB = _findElement("B");
+    ClassElement classElementA = findElement("A");
+    ClassElement classElementB = findElement("B");
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_MIXED_IN_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_MIXED_IN_BY,
         _expectedLocation(classElementB, 'A; // 2'));
   }
 
@@ -439,10 +461,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element parameterElement = _findElement("p");
+    Element mainElement = findElement("main");
+    Element parameterElement = findElement("p");
     // verify
-    _assertRecordedRelation(parameterElement, IndexConstants.IS_READ_BY,
+    _assertRecordedRelation(
+        parameterElement,
+        IndexConstants.IS_READ_BY,
         _expectedLocation(mainElement, 'p);'));
   }
 
@@ -454,10 +478,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element variableElement = _findElement("v");
+    Element mainElement = findElement("main");
+    Element variableElement = findElement("v");
     // verify
-    _assertRecordedRelation(variableElement, IndexConstants.IS_READ_BY,
+    _assertRecordedRelation(
+        variableElement,
+        IndexConstants.IS_READ_BY,
         _expectedLocation(mainElement, 'v);'));
   }
 
@@ -468,10 +494,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element parameterElement = _findElement("p");
+    Element mainElement = findElement("main");
+    Element parameterElement = findElement("p");
     // verify
-    _assertRecordedRelation(parameterElement, IndexConstants.IS_READ_WRITTEN_BY,
+    _assertRecordedRelation(
+        parameterElement,
+        IndexConstants.IS_READ_WRITTEN_BY,
         _expectedLocation(mainElement, 'p += 1'));
   }
 
@@ -483,10 +511,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    Element variableElement = _findElement("v");
+    Element mainElement = findElement("main");
+    Element variableElement = findElement("v");
     // verify
-    _assertRecordedRelation(variableElement, IndexConstants.IS_READ_WRITTEN_BY,
+    _assertRecordedRelation(
+        variableElement,
+        IndexConstants.IS_READ_WRITTEN_BY,
         _expectedLocation(mainElement, 'v += 1'));
   }
 
@@ -500,12 +530,13 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     Element nameElement = new NameElement('field');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, 'field);'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, 'field);'));
   }
 
   void test_isReferencedByQualifiedResolved_NameElement_method() {
@@ -518,12 +549,13 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     Element nameElement = new NameElement('method');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, 'method();'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, 'method();'));
   }
 
   void test_isReferencedByQualifiedResolved_NameElement_operator() {
@@ -546,34 +578,42 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // binary
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '+ 5', '+'.length));
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '+= 5', '+='.length));
-    _assertRecordedRelation(new NameElement('=='),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '== 5', '=='.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '+ 5', '+'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '+= 5', '+='.length));
+    _assertRecordedRelation(
+        new NameElement('=='),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '== 5', '=='.length));
     // prefix
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '++a', '++'.length));
-    _assertRecordedRelation(new NameElement('-'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '--a', '--'.length));
-    _assertRecordedRelation(new NameElement('~'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '~a', '~'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '++a', '++'.length));
+    _assertRecordedRelation(
+        new NameElement('-'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '--a', '--'.length));
+    _assertRecordedRelation(
+        new NameElement('~'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '~a', '~'.length));
     // postfix
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '++;', '++'.length));
-    _assertRecordedRelation(new NameElement('-'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, _expectedLocation(
-        mainElement, '--;', '--'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '++;', '++'.length));
+    _assertRecordedRelation(
+        new NameElement('-'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED,
+        _expectedLocation(mainElement, '--;', '--'.length));
   }
 
   void test_isReferencedByQualifiedUnresolved_NameElement_field() {
@@ -586,15 +626,18 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
-    FieldElement fieldElement = _findElement('field');
+    Element mainElement = findElement('main');
+    FieldElement fieldElement = findElement('field');
     Element nameElement = new NameElement('field');
     // verify
-    _assertRecordedRelation(nameElement, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(fieldElement, 'field;'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, 'field);'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, 'field);'));
   }
 
   void test_isReferencedByQualifiedUnresolved_NameElement_method() {
@@ -607,15 +650,18 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
-    MethodElement methodElement = _findElement('method');
+    Element mainElement = findElement('main');
+    MethodElement methodElement = findElement('method');
     Element nameElement = new NameElement('method');
     // verify
-    _assertRecordedRelation(nameElement, IndexConstants.IS_DEFINED_BY,
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_DEFINED_BY,
         _expectedLocation(methodElement, 'method() {}'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, 'method();'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, 'method();'));
   }
 
   void test_isReferencedByQualifiedUnresolved_NameElement_operator() {
@@ -638,34 +684,42 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // binary
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '+ 5', '+'.length));
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '+= 5', '+='.length));
-    _assertRecordedRelation(new NameElement('=='),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '== 5', '=='.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '+ 5', '+'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '+= 5', '+='.length));
+    _assertRecordedRelation(
+        new NameElement('=='),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '== 5', '=='.length));
     // prefix
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '++a', '++'.length));
-    _assertRecordedRelation(new NameElement('-'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '--a', '--'.length));
-    _assertRecordedRelation(new NameElement('~'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '~a', '~'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '++a', '++'.length));
+    _assertRecordedRelation(
+        new NameElement('-'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '--a', '--'.length));
+    _assertRecordedRelation(
+        new NameElement('~'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '~a', '~'.length));
     // postfix
-    _assertRecordedRelation(new NameElement('+'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '++;', '++'.length));
-    _assertRecordedRelation(new NameElement('-'),
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, _expectedLocation(
-        mainElement, '--;', '--'.length));
+    _assertRecordedRelation(
+        new NameElement('+'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '++;', '++'.length));
+    _assertRecordedRelation(
+        new NameElement('-'),
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED,
+        _expectedLocation(mainElement, '--;', '--'.length));
   }
 
   void test_isReferencedByQualified_ConstructorElement() {
@@ -685,27 +739,37 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     var isConstructor = (node) => node is ConstructorDeclaration;
-    ConstructorElement consA = _findNodeElementAtString("A()", isConstructor);
-    ConstructorElement consA_foo = _findNodeElementAtString("A.foo()",
-        isConstructor);
-    ConstructorElement consB = _findNodeElementAtString("B()", isConstructor);
-    ConstructorElement consB_foo = _findNodeElementAtString("B.foo()",
-        isConstructor);
-    ConstructorElement consB_bar = _findNodeElementAtString("B.bar()",
-        isConstructor);
+    ConstructorElement consA = findNodeElementAtString("A()", isConstructor);
+    ConstructorElement consA_foo =
+        findNodeElementAtString("A.foo()", isConstructor);
+    ConstructorElement consB = findNodeElementAtString("B()", isConstructor);
+    ConstructorElement consB_foo =
+        findNodeElementAtString("B.foo()", isConstructor);
+    ConstructorElement consB_bar =
+        findNodeElementAtString("B.bar()", isConstructor);
     // A()
-    _assertRecordedRelation(consA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(consB, '(); // marker-1', 0));
-    _assertRecordedRelation(consA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, '(); // marker-main-1', 0));
     // A.foo()
-    _assertRecordedRelation(consA_foo, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA_foo,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(consB_foo, '.foo(); // marker-2', '.foo'.length));
-    _assertRecordedRelation(consA_foo, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA_foo,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(consB_bar, '.foo; // marker-3', '.foo'.length));
-    _assertRecordedRelation(consA_foo, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA_foo,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, '.foo(); // marker-main-2', '.foo'.length));
   }
 
@@ -723,15 +787,19 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     var isConstructor = (node) => node is ConstructorDeclaration;
-    ConstructorElement consA = _findNodeElementAtString("A()", isConstructor);
-    ConstructorElement consA_named = _findNodeElementAtString("A.named()",
-        isConstructor);
+    ConstructorElement consA = findNodeElementAtString("A()", isConstructor);
+    ConstructorElement consA_named =
+        findNodeElementAtString("A.named()", isConstructor);
     // verify
-    _assertRecordedRelation(consA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, '(); // marker-main-1', 0));
-    _assertRecordedRelation(consA_named, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        consA_named,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, '.named(); // marker-main-2', '.named'.length));
   }
 
@@ -745,13 +813,14 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
-    FieldElement fieldElement = _findElement('field');
+    Element mainElement = findElement('main');
+    FieldElement fieldElement = findElement('field');
     PropertyAccessorElement setterElement = fieldElement.setter;
     // verify
-    _assertRecordedRelation(setterElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED, _expectedLocation(mainElement,
-        'field = 1'));
+    _assertRecordedRelation(
+        setterElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        _expectedLocation(mainElement, 'field = 1'));
   }
 
   void test_isReferencedByQualified_MethodElement() {
@@ -764,12 +833,13 @@
 }
 ''');
     // prepare elements
-    Element fooElement = _findElement('foo');
-    Element mainElement = _findElement('main');
+    Element fooElement = findElement('foo');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(fooElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED, _expectedLocation(mainElement,
-        'foo);'));
+    _assertRecordedRelation(
+        fooElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        _expectedLocation(mainElement, 'foo);'));
   }
 
   void test_isReferencedByQualified_MethodElement_operator_binary() {
@@ -785,16 +855,24 @@
 }
 ''');
     // prepare elements
-    Element element = _findElement('+');
-    Element mainElement = _findElement('main');
+    Element element = findElement('+');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '+ 1', "+".length));
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '+= 2', "+=".length));
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '++a;', "++".length));
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '++;', "++".length));
   }
 
@@ -810,15 +888,18 @@
 }
 ''');
     // prepare elements
-    MethodElement readElement = _findElement("[]");
-    MethodElement writeElement = _findElement("[]=");
-    Element mainElement = _findElement('main');
+    MethodElement readElement = findElement("[]");
+    MethodElement writeElement = findElement("[]=");
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(readElement, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        readElement,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '[0]', "[".length));
-    _assertRecordedRelation(writeElement,
-        IndexConstants.IS_INVOKED_BY_QUALIFIED, _expectedLocation(mainElement, '[1] =',
-        "[".length));
+    _assertRecordedRelation(
+        writeElement,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
+        _expectedLocation(mainElement, '[1] =', "[".length));
   }
 
   void test_isReferencedByQualified_MethodElement_operator_prefix() {
@@ -831,10 +912,12 @@
 }
 ''');
     // prepare elements
-    MethodElement element = _findElement("~");
-    Element mainElement = _findElement('main');
+    MethodElement element = findElement("~");
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_INVOKED_BY_QUALIFIED,
         _expectedLocation(mainElement, '~a', "~".length));
   }
 
@@ -848,10 +931,12 @@
 }
 ''');
     // prepare elements
-    PropertyAccessorElement element = _findNodeElementAtString('foo =>');
-    Element mainElement = _findElement('main');
+    PropertyAccessorElement element = findNodeElementAtString('foo =>');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
         _expectedLocation(mainElement, 'foo);'));
     _assertNoRecordedRelation(element, IndexConstants.IS_REFERENCED_BY, null);
   }
@@ -866,10 +951,12 @@
 }
 ''');
     // prepare elements
-    PropertyAccessorElement element = _findNodeElementAtString('foo(x)');
-    Element mainElement = _findElement('main');
+    PropertyAccessorElement element = findNodeElementAtString('foo(x)');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
         _expectedLocation(mainElement, 'foo = 42;'));
     _assertNoRecordedRelation(element, IndexConstants.IS_REFERENCED_BY, null);
   }
@@ -887,7 +974,7 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     ImportElement importElement = testLibraryElement.imports[0];
     CompilationUnitElement impUnit =
         importElement.importedLibrary.definingCompilationUnit;
@@ -895,9 +982,13 @@
     PropertyAccessorElement getter = myVar.getter;
     PropertyAccessorElement setter = myVar.setter;
     // verify
-    _assertRecordedRelation(setter, IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        setter,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
         _expectedLocation(mainElement, 'myVar = 1'));
-    _assertRecordedRelation(getter, IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+    _assertRecordedRelation(
+        getter,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
         _expectedLocation(mainElement, 'myVar);'));
   }
 
@@ -911,14 +1002,18 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    FieldElement fieldElement = _findElement("field");
+    Element mainElement = findElement("main");
+    FieldElement fieldElement = findElement("field");
     PropertyAccessorElement getter = fieldElement.getter;
     PropertyAccessorElement setter = fieldElement.setter;
     // verify
-    _assertRecordedRelation(setter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+    _assertRecordedRelation(
+        setter,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
         _expectedLocation(mainElement, 'field = 5'));
-    _assertRecordedRelation(getter, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+    _assertRecordedRelation(
+        getter,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
         _expectedLocation(mainElement, 'field);'));
   }
 
@@ -931,13 +1026,16 @@
   }
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    MethodElement methodElement = _findElement("method");
+    Element mainElement = findElement("main");
+    MethodElement methodElement = findElement("method");
     // verify
-    _assertRecordedRelation(methodElement,
-        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _expectedLocation(mainElement,
-        'method);'));
-    _assertNoRecordedRelation(methodElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        methodElement,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        _expectedLocation(mainElement, 'method);'));
+    _assertNoRecordedRelation(
+        methodElement,
+        IndexConstants.IS_REFERENCED_BY,
         null);
   }
 
@@ -949,15 +1047,17 @@
   print(topVariable);
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    TopLevelVariableElement variableElement = _findElement("topVariable");
+    Element mainElement = findElement("main");
+    TopLevelVariableElement variableElement = findElement("topVariable");
     // verify
-    _assertRecordedRelation(variableElement.setter,
-        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _expectedLocation(mainElement,
-        'topVariable = 5'));
-    _assertRecordedRelation(variableElement.getter,
-        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, _expectedLocation(mainElement,
-        'topVariable);'));
+    _assertRecordedRelation(
+        variableElement.setter,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        _expectedLocation(mainElement, 'topVariable = 5'));
+    _assertRecordedRelation(
+        variableElement.getter,
+        IndexConstants.IS_REFERENCED_BY_UNQUALIFIED,
+        _expectedLocation(mainElement, 'topVariable);'));
   }
 
   void test_isReferencedBy_ClassElement() {
@@ -973,20 +1073,30 @@
 }
 ''');
     // prepare elements
-    ClassElement aElement = _findElement("A");
-    Element mainElement = _findElement("main");
-    ParameterElement pElement = _findElement("p");
-    VariableElement vElement = _findElement("v");
+    ClassElement aElement = findElement("A");
+    Element mainElement = findElement("main");
+    ParameterElement pElement = findElement("p");
+    VariableElement vElement = findElement("v");
     // verify
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(pElement, 'A p) {'));
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(vElement, 'A v;'));
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'A(); // 2'));
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'A.field = 1;'));
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'A.field); // 3'));
   }
 
@@ -999,13 +1109,17 @@
 }
 ''');
     // prepare elements
-    ClassElement bElement = _findElement("B");
-    ParameterElement pElement = _findElement("p");
-    VariableElement vElement = _findElement("v");
+    ClassElement bElement = findElement("B");
+    ParameterElement pElement = findElement("p");
+    VariableElement vElement = findElement("v");
     // verify
-    _assertRecordedRelation(bElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        bElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(pElement, 'B p) {'));
-    _assertRecordedRelation(bElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        bElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(vElement, 'B v;'));
   }
 
@@ -1018,7 +1132,9 @@
     // prepare elements
     CompilationUnitElement myUnitElement = testLibraryElement.parts[0];
     // verify
-    _assertRecordedRelation(myUnitElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        myUnitElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, "'my_unit.dart';", "'my_unit.dart'".length));
   }
 
@@ -1030,11 +1146,13 @@
 }
 ''');
     // prepare elements
-    ConstructorElement constructorElement = _findNodeElementAtString("A()",
-        (node) => node is ConstructorDeclaration);
-    FieldElement fieldElement = _findElement("field");
+    ConstructorElement constructorElement =
+        findNodeElementAtString("A()", (node) => node is ConstructorDeclaration);
+    FieldElement fieldElement = findElement("field");
     // verify
-    _assertRecordedRelation(fieldElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        fieldElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
         _expectedLocation(constructorElement, 'field = 5'));
   }
 
@@ -1046,12 +1164,32 @@
 }
 ''');
     // prepare elements
-    FieldElement fieldElement = _findElement("field");
-    Element fieldParameterElement = _findNodeElementAtString("field);");
+    FieldElement fieldElement = findElement("field");
+    Element fieldParameterElement = findNodeElementAtString("field);");
     // verify
-    _assertRecordedRelation(fieldElement,
-        IndexConstants.IS_REFERENCED_BY_QUALIFIED, _expectedLocation(
-        fieldParameterElement, 'field);'));
+    _assertRecordedRelation(
+        fieldElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        _expectedLocation(fieldParameterElement, 'field);'));
+  }
+
+  void test_isReferencedBy_TopLevelVariableElement() {
+    addSource('/lib.dart', '''
+library lib;
+var V;
+''');
+    _indexTestUnit('''
+import 'lib.dart' show V; // imp
+''');
+    // prepare elements
+    var libElement = testLibraryElement.imports[0].importedLibrary;
+    var libUnit = libElement.definingCompilationUnit;
+    TopLevelVariableElement fieldElement = libUnit.topLevelVariables[0];
+    // verify
+    _assertRecordedRelation(
+        fieldElement,
+        IndexConstants.IS_REFERENCED_BY_QUALIFIED,
+        _expectedLocation(testUnitElement, 'V; // imp'));
   }
 
   void test_isReferencedBy_FunctionElement() {
@@ -1063,16 +1201,22 @@
 }
 ''');
     // prepare elements
-    FunctionElement element = _findElement("foo");
-    Element mainElement = _findElement("main");
+    FunctionElement element = findElement("foo");
+    Element mainElement = findElement("main");
     // "referenced" here
-    _assertRecordedRelation(element, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'foo);'));
     // only "invoked", but not "referenced"
     {
-      _assertRecordedRelation(element, IndexConstants.IS_INVOKED_BY,
+      _assertRecordedRelation(
+          element,
+          IndexConstants.IS_INVOKED_BY,
           _expectedLocation(mainElement, 'foo());'));
-      _assertNoRecordedRelation(element, IndexConstants.IS_REFERENCED_BY,
+      _assertNoRecordedRelation(
+          element,
+          IndexConstants.IS_REFERENCED_BY,
           _expectedLocation(mainElement, 'foo());'));
     }
   }
@@ -1084,10 +1228,12 @@
 }
 ''');
     // prepare elements
-    Element aElement = _findElement('A');
-    Element pElement = _findElement('p');
+    Element aElement = findElement('A');
+    Element pElement = findElement('p');
     // verify
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(pElement, 'A p) {'));
   }
 
@@ -1108,20 +1254,32 @@
 ''');
     // prepare elements
     ImportElement importElement = testLibraryElement.imports[0];
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'myVar = 1;', 0));
-    _assertRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'myFunction();', 0));
-    _assertNoRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertNoRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'print(0);', 0));
     // no references from import combinators
-    _assertNoRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertNoRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, 'myVar, ', 0));
-    _assertNoRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertNoRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, 'myFunction hide', 0));
-    _assertNoRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertNoRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, 'myToHide;', 0));
   }
 
@@ -1145,11 +1303,15 @@
     // prepare elements
     ImportElement importElementA = testLibraryElement.imports[0];
     ImportElement importElementB = testLibraryElement.imports[1];
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(importElementA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElementA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.myVar = 1;', 'pref.'.length));
-    _assertRecordedRelation(importElementB, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElementB,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.MyClass();', 'pref.'.length));
   }
 
@@ -1172,11 +1334,15 @@
     // prepare elements
     ImportElement importElementA = testLibraryElement.imports[0];
     ImportElement importElementB = testLibraryElement.imports[1];
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(importElementA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElementA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.A();', 'pref.'.length));
-    _assertRecordedRelation(importElementB, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElementB,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.B();', 'pref.'.length));
   }
 
@@ -1193,9 +1359,11 @@
 ''');
     // prepare elements
     ImportElement importElement = testLibraryElement.imports[0];
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.myFunc();', 'pref.'.length));
   }
 
@@ -1213,9 +1381,11 @@
 ''');
     // prepare elements
     ImportElement importElement = testLibraryElement.imports[0];
-    Element mainElement = _findElement('main');
+    Element mainElement = findElement('main');
     // verify
-    _assertRecordedRelation(importElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        importElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'pref.A();', 'pref.'.length));
   }
 
@@ -1260,10 +1430,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
-    Element element = _findElement('L');
+    Element mainElement = findElement('main');
+    Element element = findElement('L');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'L;'));
   }
 
@@ -1278,7 +1450,9 @@
     LibraryElement libElement = testLibraryElement.exportedLibraries[0];
     CompilationUnitElement libUnitElement = libElement.definingCompilationUnit;
     // verify
-    _assertRecordedRelation(libUnitElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        libUnitElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, "'lib.dart'", "'lib.dart'".length));
   }
 
@@ -1293,7 +1467,9 @@
     LibraryElement libElement = testLibraryElement.imports[0].importedLibrary;
     CompilationUnitElement libUnitElement = libElement.definingCompilationUnit;
     // verify
-    _assertRecordedRelation(libUnitElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        libUnitElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, "'lib.dart'", "'lib.dart'".length));
   }
 
@@ -1305,10 +1481,12 @@
 }
 ''');
     // prepare elements
-    Element mainElement = _findElement('main');
-    Element element = _findElement('p');
+    Element mainElement = findElement('main');
+    Element element = findElement('p');
     // verify
-    _assertRecordedRelation(element, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        element,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(mainElement, 'p: 1'));
   }
 
@@ -1322,17 +1500,23 @@
 }
 ''');
     // prepare elements
-    Element typeParameterElement = _findElement('T');
-    Element fieldElement = _findElement('f');
-    Element parameterElement = _findElement('p');
-    Element variableElement = _findElement('v');
+    Element typeParameterElement = findElement('T');
+    Element fieldElement = findElement('f');
+    Element parameterElement = findElement('p');
+    Element variableElement = findElement('v');
     // verify
-    _assertRecordedRelation(typeParameterElement,
-        IndexConstants.IS_REFERENCED_BY, _expectedLocation(fieldElement, 'T f'));
-    _assertRecordedRelation(typeParameterElement,
-        IndexConstants.IS_REFERENCED_BY, _expectedLocation(parameterElement, 'T p'));
-    _assertRecordedRelation(typeParameterElement,
-        IndexConstants.IS_REFERENCED_BY, _expectedLocation(variableElement, 'T v'));
+    _assertRecordedRelation(
+        typeParameterElement,
+        IndexConstants.IS_REFERENCED_BY,
+        _expectedLocation(fieldElement, 'T f'));
+    _assertRecordedRelation(
+        typeParameterElement,
+        IndexConstants.IS_REFERENCED_BY,
+        _expectedLocation(parameterElement, 'T p'));
+    _assertRecordedRelation(
+        typeParameterElement,
+        IndexConstants.IS_REFERENCED_BY,
+        _expectedLocation(variableElement, 'T v'));
   }
 
   /**
@@ -1349,12 +1533,16 @@
 var myVariable = null;
 ''');
     // prepare elements
-    Element aElement = _findElement('A');
-    Element variableElement = _findElement('myVariable');
+    Element aElement = findElement('A');
+    Element variableElement = findElement('myVariable');
     // verify
-    _assertRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, 'A] text'));
-    _assertNoRecordedRelation(aElement, IndexConstants.IS_REFERENCED_BY,
+    _assertNoRecordedRelation(
+        aElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(variableElement, 'A] text'));
   }
 
@@ -1370,7 +1558,9 @@
     testLibraryElement = testUnitElement.library;
     indexDartUnit(store, context, testUnit);
     // verify
-    _assertRecordedRelation(testLibraryElement, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        testLibraryElement,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(testUnitElement, "lib;"));
   }
 
@@ -1380,10 +1570,12 @@
 A myVariable = null;
 ''');
     // prepare elements
-    Element classElementA = _findElement('A');
-    Element variableElement = _findElement('myVariable');
+    Element classElementA = findElement('A');
+    Element variableElement = findElement('myVariable');
     // verify
-    _assertRecordedRelation(classElementA, IndexConstants.IS_REFERENCED_BY,
+    _assertRecordedRelation(
+        classElementA,
+        IndexConstants.IS_REFERENCED_BY,
         _expectedLocation(variableElement, 'A myVariable'));
   }
 
@@ -1393,10 +1585,12 @@
   p = 1;
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    ParameterElement pElement = _findElement("p");
+    Element mainElement = findElement("main");
+    ParameterElement pElement = findElement("p");
     // verify
-    _assertRecordedRelation(pElement, IndexConstants.IS_WRITTEN_BY,
+    _assertRecordedRelation(
+        pElement,
+        IndexConstants.IS_WRITTEN_BY,
         _expectedLocation(mainElement, 'p = 1'));
   }
 
@@ -1407,10 +1601,12 @@
   v = 1;
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
-    LocalVariableElement vElement = _findElement("v");
+    Element mainElement = findElement("main");
+    LocalVariableElement vElement = findElement("v");
     // verify
-    _assertRecordedRelation(vElement, IndexConstants.IS_WRITTEN_BY,
+    _assertRecordedRelation(
+        vElement,
+        IndexConstants.IS_WRITTEN_BY,
         _expectedLocation(mainElement, 'v = 1'));
   }
 
@@ -1424,18 +1620,21 @@
   p.test(2);
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
+    Element mainElement = findElement("main");
     Element nameElement = new NameElement('test');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_INVOKED_BY_RESOLVED, _expectedLocation(mainElement,
-        'test(1)'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED, _expectedLocation(mainElement,
-        'test(2)'));
-    _assertNoRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_READ_BY_UNRESOLVED, _expectedLocation(mainElement,
-        'test(2)'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_INVOKED_BY_RESOLVED,
+        _expectedLocation(mainElement, 'test(1)'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_INVOKED_BY_UNRESOLVED,
+        _expectedLocation(mainElement, 'test(2)'));
+    _assertNoRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_READ_BY_UNRESOLVED,
+        _expectedLocation(mainElement, 'test(2)'));
   }
 
   void test_nameIsReadBy() {
@@ -1448,15 +1647,17 @@
   print(p.test); // p
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
+    Element mainElement = findElement("main");
     Element nameElement = new NameElement('test');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_READ_BY_RESOLVED, _expectedLocation(mainElement,
-        'test); // a'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_READ_BY_UNRESOLVED, _expectedLocation(mainElement,
-        'test); // p'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_READ_BY_RESOLVED,
+        _expectedLocation(mainElement, 'test); // a'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_READ_BY_UNRESOLVED,
+        _expectedLocation(mainElement, 'test); // p'));
   }
 
   void test_nameIsReadWrittenBy() {
@@ -1469,15 +1670,17 @@
   p.test += 2;
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
+    Element mainElement = findElement("main");
     Element nameElement = new NameElement('test');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED, _expectedLocation(mainElement,
-        'test += 1'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED, _expectedLocation(
-        mainElement, 'test += 2'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_READ_WRITTEN_BY_RESOLVED,
+        _expectedLocation(mainElement, 'test += 1'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_READ_WRITTEN_BY_UNRESOLVED,
+        _expectedLocation(mainElement, 'test += 2'));
   }
 
   void test_nameIsWrittenBy() {
@@ -1490,15 +1693,17 @@
   p.test = 2;
 }''');
     // prepare elements
-    Element mainElement = _findElement("main");
+    Element mainElement = findElement("main");
     Element nameElement = new NameElement('test');
     // verify
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED, _expectedLocation(mainElement,
-        'test = 1'));
-    _assertRecordedRelation(nameElement,
-        IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED, _expectedLocation(mainElement,
-        'test = 2'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_WRITTEN_BY_RESOLVED,
+        _expectedLocation(mainElement, 'test = 1'));
+    _assertRecordedRelation(
+        nameElement,
+        IndexConstants.NAME_IS_WRITTEN_BY_UNRESOLVED,
+        _expectedLocation(mainElement, 'test = 2'));
   }
 
   void test_nullUnit() {
@@ -1513,25 +1718,25 @@
   void _assertDefinesTopLevelElement(Relationship relationship,
       ExpectedLocation expectedLocation) {
     _assertRecordedRelation(testLibraryElement, relationship, expectedLocation);
-    _assertRecordedRelation(UniverseElement.INSTANCE, relationship,
+    _assertRecordedRelation(
+        UniverseElement.INSTANCE,
+        relationship,
         expectedLocation);
   }
 
-  void _assertNoErrorsInSource() {
-    List<AnalysisError> errors = context.getErrors(testSource).errors;
-    expect(errors, isEmpty);
-  }
-
   /**
    * Asserts that [recordedRelations] has no item with the specified properties.
    */
   void _assertNoRecordedRelation(Element element, Relationship relationship,
       ExpectedLocation location) {
     for (RecordedRelation recordedRelation in recordedRelations) {
-      if (_equalsRecordedRelation(recordedRelation, element, relationship,
+      if (_equalsRecordedRelation(
+          recordedRelation,
+          element,
+          relationship,
           location)) {
-        fail('not expected: ${recordedRelation} in\n' + recordedRelations.join(
-            '\n'));
+        fail(
+            'not expected: ${recordedRelation} in\n' + recordedRelations.join('\n'));
       }
     }
   }
@@ -1542,66 +1747,32 @@
   Location _assertRecordedRelation(Element expectedElement,
       Relationship expectedRelationship, ExpectedLocation expectedLocation) {
     for (RecordedRelation recordedRelation in recordedRelations) {
-      if (_equalsRecordedRelation(recordedRelation, expectedElement,
-          expectedRelationship, expectedLocation)) {
+      if (_equalsRecordedRelation(
+          recordedRelation,
+          expectedElement,
+          expectedRelationship,
+          expectedLocation)) {
         return recordedRelation.location;
       }
     }
-    fail("not found\n$expectedElement $expectedRelationship "
-        "in $expectedLocation in\n" + recordedRelations.join('\n'));
+    fail(
+        "not found\n$expectedElement $expectedRelationship " "in $expectedLocation in\n"
+            +
+            recordedRelations.join('\n'));
     return null;
   }
 
   ExpectedLocation _expectedLocation(Element element, String search, [int length
       = -1]) {
-    int offset = _findOffset(search);
+    int offset = findOffset(search);
     if (length == -1) {
-      length = _getLeadingIdentifierLength(search);
+      length = getLeadingIdentifierLength(search);
     }
     return new ExpectedLocation(element, offset, length);
   }
 
-  Element _findElement(String name, [ElementKind kind]) {
-    return findChildElement(testUnitElement, name, kind);
-  }
-
-  AstNode _findNodeAtOffset(int offset, [Predicate<AstNode> predicate]) {
-    AstNode result = new NodeLocator.con1(offset).searchWithin(testUnit);
-    if (result != null && predicate != null) {
-      result = result.getAncestor(predicate);
-    }
-    return result;
-  }
-
-  AstNode _findNodeAtString(String search, [Predicate<AstNode> predicate]) {
-    int offset = _findOffset(search);
-    return _findNodeAtOffset(offset, predicate);
-  }
-
-  Element _findNodeElementAtString(String search,
-      [Predicate<AstNode> predicate]) {
-    AstNode node = _findNodeAtString(search, predicate);
-    if (node == null) {
-      return null;
-    }
-    return ElementLocator.locate(node);
-  }
-
-  int _findOffset(String search) {
-    int offset = testCode.indexOf(search);
-    expect(offset, isNonNegative, reason: "Not found '$search' in\n$testCode");
-    return offset;
-  }
-
   void _indexTestUnit(String code) {
-    testCode = code;
-    testSource = addSource('/test.dart', code);
-    testUnit = resolveLibraryUnit(testSource);
-    if (verifyNoTestUnitErrors) {
-      _assertNoErrorsInSource();
-    }
-    testUnitElement = testUnit.element;
-    testLibraryElement = testUnitElement.library;
+    resolveTestUnit(code);
     indexDartUnit(store, context, testUnit);
   }
 }
diff --git a/pkg/analysis_services/test/index/store/codec_test.dart b/pkg/analysis_services/test/index/store/codec_test.dart
index 1b4dc6a..c72cb60 100644
--- a/pkg/analysis_services/test/index/store/codec_test.dart
+++ b/pkg/analysis_services/test/index/store/codec_test.dart
@@ -10,9 +10,10 @@
 import 'package:analysis_testing/reflective_tests.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
 
+import '../abstract_single_unit.dart';
+
 
 main() {
   groupSep = ' | ';
@@ -71,78 +72,115 @@
 
 
 @ReflectiveTestCase()
-class _ElementCodecTest {
+class _ElementCodecTest extends AbstractSingleUnitTest {
   ElementCodec codec;
   AnalysisContext context = new MockAnalysisContext('context');
   StringCodec stringCodec = new StringCodec();
 
   void setUp() {
+    super.setUp();
     codec = new ElementCodec(stringCodec);
   }
 
+  void test_field() {
+    resolveTestUnit('''
+class A {
+  int field;
+}
+''');
+    FieldElement field = findElement('field', ElementKind.FIELD);
+    PropertyAccessorElement getter = field.getter;
+    PropertyAccessorElement setter = field.setter;
+    {
+      int id = codec.encode(getter);
+      expect(codec.decode(context, id), getter);
+    }
+    {
+      int id = codec.encode(setter);
+      expect(codec.decode(context, id), setter);
+    }
+    {
+      int id = codec.encode(field);
+      expect(codec.decode(context, id), field);
+    }
+  }
+
   void test_localLocalVariable() {
+    resolveTestUnit('''
+main() {
+  {
+    foo() {
+      int bar; // A
+    }
+  }
+  {
+    foo() {
+      int bar; // B
+    }
+  }
+}
+''');
     {
-      Element element = new MockElement();
-      ElementLocation location = new ElementLocationImpl.con3(['main', 'foo@1',
-          'bar@2']);
-      when(context.getElement(location)).thenReturn(element);
-      when(element.location).thenReturn(location);
+      LocalVariableElement element = findNodeElementAtString('bar; // A', null);
       int id = codec.encode(element);
       expect(codec.decode(context, id), element);
     }
     {
-      Element element = new MockElement();
-      ElementLocation location = new ElementLocationImpl.con3(['main', 'foo@10',
-          'bar@20']);
-      when(context.getElement(location)).thenReturn(element);
-      when(element.location).thenReturn(location);
+      LocalVariableElement element = findNodeElementAtString('bar; // B', null);
       int id = codec.encode(element);
       expect(codec.decode(context, id), element);
     }
-    // check strings, "foo" as a single string, no "foo@1" or "foo@10"
-    expect(stringCodec.nameToIndex, hasLength(3));
-    expect(stringCodec.nameToIndex, containsPair('main', 0));
-    expect(stringCodec.nameToIndex, containsPair('foo', 1));
-    expect(stringCodec.nameToIndex, containsPair('bar', 2));
+    // check strings, "foo" as a single string, no "foo@17" or "bar@35"
+    expect(stringCodec.nameToIndex, hasLength(4));
+    expect(stringCodec.nameToIndex, containsPair('f/test.dart', 0));
+    expect(stringCodec.nameToIndex, containsPair('main', 1));
+    expect(stringCodec.nameToIndex, containsPair('foo', 2));
+    expect(stringCodec.nameToIndex, containsPair('bar', 3));
   }
 
   void test_localVariable() {
+    resolveTestUnit('''
+main() {
+  {
+    int foo; // A
+  }
+  {
+    int foo; // B
+  }
+}
+''');
     {
-      Element element = new MockElement();
-      ElementLocation location = new ElementLocationImpl.con3(['main',
-          'foo@42']);
-      when(context.getElement(location)).thenReturn(element);
-      when(element.location).thenReturn(location);
+      LocalVariableElement element = findNodeElementAtString('foo; // A', null);
       int id = codec.encode(element);
       expect(codec.decode(context, id), element);
     }
     {
-      Element element = new MockElement();
-      ElementLocation location = new ElementLocationImpl.con3(['main',
-          'foo@4200']);
-      when(context.getElement(location)).thenReturn(element);
-      when(element.location).thenReturn(location);
+      LocalVariableElement element = findNodeElementAtString('foo; // B', null);
       int id = codec.encode(element);
       expect(codec.decode(context, id), element);
     }
-    // check strings, "foo" as a single string, no "foo@42" or "foo@4200"
-    expect(stringCodec.nameToIndex, hasLength(2));
-    expect(stringCodec.nameToIndex, containsPair('main', 0));
-    expect(stringCodec.nameToIndex, containsPair('foo', 1));
+    // check strings, "foo" as a single string, no "foo@21" or "foo@47"
+    expect(stringCodec.nameToIndex, hasLength(3));
+    expect(stringCodec.nameToIndex, containsPair('f/test.dart', 0));
+    expect(stringCodec.nameToIndex, containsPair('main', 1));
+    expect(stringCodec.nameToIndex, containsPair('foo', 2));
   }
 
   void test_notLocal() {
-    Element element = new MockElement();
-    ElementLocation location = new ElementLocationImpl.con3(['foo', 'bar']);
-    when(element.location).thenReturn(location);
-    when(context.getElement(location)).thenReturn(element);
+    resolveTestUnit('''
+main() {
+  int foo;
+}
+''');
+    LocalVariableElement element = findElement('foo');
     int id = codec.encode(element);
     expect(codec.encode(element), id);
     expect(codec.decode(context, id), element);
     // check strings
-    expect(stringCodec.nameToIndex, hasLength(2));
-    expect(stringCodec.nameToIndex, containsPair('foo', 0));
-    expect(stringCodec.nameToIndex, containsPair('bar', 1));
+    expect(stringCodec.nameToIndex, hasLength(3));
+    expect(stringCodec.nameToIndex, containsPair('f/test.dart', 0));
+    expect(stringCodec.nameToIndex, containsPair('main', 1));
+    expect(stringCodec.nameToIndex, containsPair('foo', 2));
   }
 }
 
diff --git a/pkg/analysis_services/test/search/search_engine_test.dart b/pkg/analysis_services/test/search/search_engine_test.dart
index db896c9..f6d02de9 100644
--- a/pkg/analysis_services/test/search/search_engine_test.dart
+++ b/pkg/analysis_services/test/search/search_engine_test.dart
@@ -5,2144 +5,659 @@
 // This code was auto-generated, is not intended to be edited, and is subject to
 // significant change. Please see the README file for more information.
 
-library engine.search_engine_test;
+library services.src.search.search_engine_test;
+
+import 'dart:async';
+
+import 'package:analysis_services/index/index.dart';
+import 'package:analysis_services/index/local_memory_index.dart';
+import 'package:analysis_services/search/search_engine.dart';
+import 'package:analysis_services/src/search/search_engine.dart';
+import 'package:analysis_testing/mocks.dart';
+import 'package:analysis_testing/reflective_tests.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:typed_mock/typed_mock.dart';
+import 'package:unittest/unittest.dart';
+
+import '../index/abstract_single_unit.dart';
 
 
 main() {
+  groupSep = ' | ';
+  group('SearchEngineImplTest', () {
+    runReflectiveTests(SearchEngineImplTest);
+  });
+}
+
+class ExpectedMatch {
+  final Element element;
+  final MatchKind kind;
+  SourceRange range;
+  final bool isResolved;
+  final bool isQualified;
+
+  ExpectedMatch(this.element, this.kind, int offset, int length,
+      {this.isResolved: true, this.isQualified: false}) {
+    this.range = new SourceRange(offset, length);
+  }
+
+  bool operator ==(SearchMatch match) {
+    return match.element == this.element &&
+        match.kind == this.kind &&
+        match.isResolved == this.isResolved &&
+        match.isQualified == this.isQualified &&
+        match.sourceRange == this.range;
+  }
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write("ExpectedMatch(kind=");
+    buffer.write(kind);
+    buffer.write(", element=");
+    buffer.write(element != null ? element.displayName : 'null');
+    buffer.write(", range=");
+    buffer.write(range);
+    buffer.write(", isResolved=");
+    buffer.write(isResolved);
+    buffer.write(", isQualified=");
+    buffer.write(isQualified);
+    buffer.write(")");
+    return buffer.toString();
+  }
 }
 
 
-//class AndSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  SearchPattern _patternA = mock(SearchPattern);
-//
-//  SearchPattern _patternB = mock(SearchPattern);
-//
-//  AndSearchPattern _pattern = new AndSearchPattern([_patternA, _patternB]);
-//
-//  void test_allExact() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, _pattern.matches(_element));
+class MockAngularComponentElement extends TypedMock implements
+    AngularComponentElement {
+  final kind = ElementKind.ANGULAR_COMPONENT;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockAngularControllerElement extends TypedMock implements
+    AngularControllerElement {
+  final kind = ElementKind.ANGULAR_CONTROLLER;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockAngularFormatterElement extends TypedMock implements
+    AngularFormatterElement {
+  final kind = ElementKind.ANGULAR_FORMATTER;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockIndex extends TypedMock implements Index {
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+@ReflectiveTestCase()
+class SearchEngineImplTest extends AbstractSingleUnitTest {
+  Index index;
+  SearchEngineImpl searchEngine;
+
+//  void mockLocation(Element element, Relationship relationship,
+//      Location location) {
+//    mockLocations(element, relationship, [location]);
 //  }
 //
-//  void test_ExactName() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.NAME);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, _pattern.matches(_element));
+//  void mockLocations(Element element, Relationship relationship,
+//      List<Location> locations) {
+//    index.getRelationships(element, relationship);
+//    when(null).thenReturn(new Future.value(locations));
 //  }
-//
-//  void test_NameExact() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.NAME);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, _pattern.matches(_element));
-//  }
-//
-//  void test_oneNull() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    when(_patternB.matches(_element)).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, _pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('AndSearchPatternTest', () {
-//      _ut.test('test_ExactName', () {
-//        final __test = new AndSearchPatternTest();
-//        runJUnitTest(__test, __test.test_ExactName);
-//      });
-//      _ut.test('test_NameExact', () {
-//        final __test = new AndSearchPatternTest();
-//        runJUnitTest(__test, __test.test_NameExact);
-//      });
-//      _ut.test('test_allExact', () {
-//        final __test = new AndSearchPatternTest();
-//        runJUnitTest(__test, __test.test_allExact);
-//      });
-//      _ut.test('test_oneNull', () {
-//        final __test = new AndSearchPatternTest();
-//        runJUnitTest(__test, __test.test_oneNull);
-//      });
-//    });
-//  }
-//}
-//
-//class CamelCaseSearchPatternTest extends EngineTestCase {
-//  void test_matchExact_samePartCount() {
-//    Element element = mock(Element);
-//    when(element.displayName).thenReturn("HashMap");
-//    //
-//    CamelCaseSearchPattern pattern = new CamelCaseSearchPattern("HM", true);
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(element));
-//  }
-//
-//  void test_matchExact_withLowerCase() {
-//    Element element = mock(Element);
-//    when(element.displayName).thenReturn("HashMap");
-//    //
-//    CamelCaseSearchPattern pattern = new CamelCaseSearchPattern("HaMa", true);
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(element));
-//  }
-//
-//  void test_matchNot_nullName() {
-//    Element element = mock(Element);
-//    when(element.displayName).thenReturn(null);
-//    //
-//    CamelCaseSearchPattern pattern = new CamelCaseSearchPattern("HM", true);
-//    JUnitTestCase.assertSame(null, pattern.matches(element));
-//  }
-//
-//  void test_matchNot_samePartCount() {
-//    Element element = mock(Element);
-//    when(element.displayName).thenReturn("LinkedHashMap");
-//    //
-//    CamelCaseSearchPattern pattern = new CamelCaseSearchPattern("LH", true);
-//    JUnitTestCase.assertSame(null, pattern.matches(element));
-//  }
-//
-//  void test_matchNot_withLowerCase() {
-//    Element element = mock(Element);
-//    when(element.displayName).thenReturn("HashMap");
-//    //
-//    CamelCaseSearchPattern pattern = new CamelCaseSearchPattern("HaMu", true);
-//    JUnitTestCase.assertSame(null, pattern.matches(element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('CamelCaseSearchPatternTest', () {
-//      _ut.test('test_matchExact_samePartCount', () {
-//        final __test = new CamelCaseSearchPatternTest();
-//        runJUnitTest(__test, __test.test_matchExact_samePartCount);
-//      });
-//      _ut.test('test_matchExact_withLowerCase', () {
-//        final __test = new CamelCaseSearchPatternTest();
-//        runJUnitTest(__test, __test.test_matchExact_withLowerCase);
-//      });
-//      _ut.test('test_matchNot_nullName', () {
-//        final __test = new CamelCaseSearchPatternTest();
-//        runJUnitTest(__test, __test.test_matchNot_nullName);
-//      });
-//      _ut.test('test_matchNot_samePartCount', () {
-//        final __test = new CamelCaseSearchPatternTest();
-//        runJUnitTest(__test, __test.test_matchNot_samePartCount);
-//      });
-//      _ut.test('test_matchNot_withLowerCase', () {
-//        final __test = new CamelCaseSearchPatternTest();
-//        runJUnitTest(__test, __test.test_matchNot_withLowerCase);
-//      });
-//    });
-//  }
-//}
-//
-//class CountingSearchListenerTest extends EngineTestCase {
-//  void test_matchFound() {
-//    SearchListener listener = mock(SearchListener);
-//    SearchMatch match = mock(SearchMatch);
-//    SearchListener countingListener = new CountingSearchListener(2, listener);
-//    // "match" should be passed to "listener"
-//    countingListener.matchFound(match);
-//    verify(listener).matchFound(match);
-//    verifyNoMoreInteractions(listener);
-//  }
-//
-//  void test_searchComplete() {
-//    SearchListener listener = mock(SearchListener);
-//    SearchListener countingListener = new CountingSearchListener(2, listener);
-//    // complete 2 -> 1
-//    countingListener.searchComplete();
-//    verifyZeroInteractions(listener);
-//    // complete 2 -> 0
-//    countingListener.searchComplete();
-//    verify(listener).searchComplete();
-//  }
-//
-//  void test_searchComplete_zero() {
-//    SearchListener listener = mock(SearchListener);
-//    new CountingSearchListener(0, listener);
-//    // complete at 0
-//    verify(listener).searchComplete();
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('CountingSearchListenerTest', () {
-//      _ut.test('test_matchFound', () {
-//        final __test = new CountingSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound);
-//      });
-//      _ut.test('test_searchComplete', () {
-//        final __test = new CountingSearchListenerTest();
-//        runJUnitTest(__test, __test.test_searchComplete);
-//      });
-//      _ut.test('test_searchComplete_zero', () {
-//        final __test = new CountingSearchListenerTest();
-//        runJUnitTest(__test, __test.test_searchComplete_zero);
-//      });
-//    });
-//  }
-//}
-//
-//class ExactSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  void test_caseInsensitive_false() {
-//    SearchPattern pattern = new ExactSearchPattern("HashMa", false);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseInsensitive_true() {
-//    SearchPattern pattern = new ExactSearchPattern("HashMap", false);
-//    when(_element.displayName).thenReturn("HashMaP");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_false() {
-//    SearchPattern pattern = new ExactSearchPattern("HashMa", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_true() {
-//    SearchPattern pattern = new ExactSearchPattern("HashMap", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_nullName() {
-//    SearchPattern pattern = new ExactSearchPattern("HashMap", true);
-//    when(_element.displayName).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('ExactSearchPatternTest', () {
-//      _ut.test('test_caseInsensitive_false', () {
-//        final __test = new ExactSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_false);
-//      });
-//      _ut.test('test_caseInsensitive_true', () {
-//        final __test = new ExactSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_true);
-//      });
-//      _ut.test('test_caseSensitive_false', () {
-//        final __test = new ExactSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_false);
-//      });
-//      _ut.test('test_caseSensitive_true', () {
-//        final __test = new ExactSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_true);
-//      });
-//      _ut.test('test_nullName', () {
-//        final __test = new ExactSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullName);
-//      });
-//    });
-//  }
-//}
-//
-//class FilterSearchListenerTest extends EngineTestCase {
-//  SearchListener _listener = mock(SearchListener);
-//
-//  SearchMatch _match = mock(SearchMatch);
-//
-//  SearchFilter _filter = mock(SearchFilter);
-//
-//  SearchListener _filteredListener = new FilteredSearchListener(_filter, _listener);
-//
-//  void test_matchFound_filterFalse() {
-//    when(_filter.passes(_match)).thenReturn(false);
-//    // "match" should be passed to "listener"
-//    _filteredListener.matchFound(_match);
-//    verifyNoMoreInteractions(_listener);
-//  }
-//
-//  void test_matchFound_filterTrue() {
-//    when(_filter.passes(_match)).thenReturn(true);
-//    // "match" should be passed to "listener"
-//    _filteredListener.matchFound(_match);
-//    verify(_listener).matchFound(_match);
-//    verifyNoMoreInteractions(_listener);
-//  }
-//
-//  void test_searchComplete() {
-//    _filteredListener.searchComplete();
-//    verify(_listener).searchComplete();
-//    verifyNoMoreInteractions(_listener);
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('FilterSearchListenerTest', () {
-//      _ut.test('test_matchFound_filterFalse', () {
-//        final __test = new FilterSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound_filterFalse);
-//      });
-//      _ut.test('test_matchFound_filterTrue', () {
-//        final __test = new FilterSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound_filterTrue);
-//      });
-//      _ut.test('test_searchComplete', () {
-//        final __test = new FilterSearchListenerTest();
-//        runJUnitTest(__test, __test.test_searchComplete);
-//      });
-//    });
-//  }
-//}
-//
-//class GatheringSearchListenerTest extends EngineTestCase {
-//  SearchMatch _matchA = mock(SearchMatch);
-//
-//  SearchMatch _matchB = mock(SearchMatch);
-//
-//  GatheringSearchListener _gatheringListener = new GatheringSearchListener();
-//
-//  void test_matchFound() {
-//    Element elementA = mock(Element);
-//    Element elementB = mock(Element);
-//    when(elementA.displayName).thenReturn("A");
-//    when(elementB.displayName).thenReturn("B");
-//    when(_matchA.element).thenReturn(elementA);
-//    when(_matchB.element).thenReturn(elementB);
-//    // matchB
-//    _gatheringListener.matchFound(_matchB);
-//    JUnitTestCase.assertFalse(_gatheringListener.isComplete);
-//    assertThat(_gatheringListener.matches).containsExactly(_matchB);
-//    // matchA
-//    _gatheringListener.matchFound(_matchA);
-//    JUnitTestCase.assertFalse(_gatheringListener.isComplete);
-//    assertThat(_gatheringListener.matches).containsExactly(_matchA, _matchB);
-//  }
-//
-//  void test_searchComplete() {
-//    JUnitTestCase.assertFalse(_gatheringListener.isComplete);
-//    // complete
-//    _gatheringListener.searchComplete();
-//    JUnitTestCase.assertTrue(_gatheringListener.isComplete);
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('GatheringSearchListenerTest', () {
-//      _ut.test('test_matchFound', () {
-//        final __test = new GatheringSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound);
-//      });
-//      _ut.test('test_searchComplete', () {
-//        final __test = new GatheringSearchListenerTest();
-//        runJUnitTest(__test, __test.test_searchComplete);
-//      });
-//    });
-//  }
-//}
-//
-//class LibrarySearchScopeTest extends EngineTestCase {
-//  LibraryElement _libraryA = mock(LibraryElement);
-//
-//  LibraryElement _libraryB = mock(LibraryElement);
-//
-//  Element _element = mock(Element);
-//
-//  void test_arrayConstructor_inA_false() {
-//    when(_element.getAncestor((element) => element is LibraryElement)).thenReturn(_libraryB);
-//    LibrarySearchScope scope = new LibrarySearchScope.con2([_libraryA]);
-//    assertThat(scope.libraries).containsOnly(_libraryA);
-//    JUnitTestCase.assertFalse(scope.encloses(_element));
-//  }
-//
-//  void test_arrayConstructor_inA_true() {
-//    when(_element.getAncestor((element) => element is LibraryElement)).thenReturn(_libraryA);
-//    LibrarySearchScope scope = new LibrarySearchScope.con2([_libraryA, _libraryB]);
-//    assertThat(scope.libraries).containsOnly(_libraryA, _libraryB);
-//    JUnitTestCase.assertTrue(scope.encloses(_element));
-//  }
-//
-//  void test_collectionConstructor_inB() {
-//    when(_element.getAncestor((element) => element is LibraryElement)).thenReturn(_libraryB);
-//    LibrarySearchScope scope = new LibrarySearchScope.con1(ImmutableSet.of(_libraryA, _libraryB));
-//    assertThat(scope.libraries).containsOnly(_libraryA, _libraryB);
-//    JUnitTestCase.assertTrue(scope.encloses(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('LibrarySearchScopeTest', () {
-//      _ut.test('test_arrayConstructor_inA_false', () {
-//        final __test = new LibrarySearchScopeTest();
-//        runJUnitTest(__test, __test.test_arrayConstructor_inA_false);
-//      });
-//      _ut.test('test_arrayConstructor_inA_true', () {
-//        final __test = new LibrarySearchScopeTest();
-//        runJUnitTest(__test, __test.test_arrayConstructor_inA_true);
-//      });
-//      _ut.test('test_collectionConstructor_inB', () {
-//        final __test = new LibrarySearchScopeTest();
-//        runJUnitTest(__test, __test.test_collectionConstructor_inB);
-//      });
-//    });
-//  }
-//}
-//
-//class NameMatchingSearchListenerTest extends EngineTestCase {
-//  SearchListener _listener = mock(SearchListener);
-//
-//  Element _element = mock(Element);
-//
-//  SearchMatch _match = mock(SearchMatch);
-//
-//  SearchPattern _pattern = mock(SearchPattern);
-//
-//  SearchListener _nameMatchingListener = new NameMatchingSearchListener(_pattern, _listener);
-//
-//  void test_matchFound_patternFalse() {
-//    when(_pattern.matches(_element)).thenReturn(null);
-//    // verify
-//    _nameMatchingListener.matchFound(_match);
-//    verifyNoMoreInteractions(_listener);
-//  }
-//
-//  void test_matchFound_patternTrue() {
-//    when(_pattern.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    // verify
-//    _nameMatchingListener.matchFound(_match);
-//    verify(_listener).matchFound(_match);
-//    verifyNoMoreInteractions(_listener);
-//  }
-//
-//  @override
-//  void setUp() {
-//    super.setUp();
-//    when(_match.element).thenReturn(_element);
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('NameMatchingSearchListenerTest', () {
-//      _ut.test('test_matchFound_patternFalse', () {
-//        final __test = new NameMatchingSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound_patternFalse);
-//      });
-//      _ut.test('test_matchFound_patternTrue', () {
-//        final __test = new NameMatchingSearchListenerTest();
-//        runJUnitTest(__test, __test.test_matchFound_patternTrue);
-//      });
-//    });
-//  }
-//}
-//
-//class OrSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  SearchPattern _patternA = mock(SearchPattern);
-//
-//  SearchPattern _patternB = mock(SearchPattern);
-//
-//  SearchPattern _pattern = new OrSearchPattern([_patternA, _patternB]);
-//
-//  void test_allExact() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, _pattern.matches(_element));
-//  }
-//
-//  void test_ExactName() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.NAME);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, _pattern.matches(_element));
-//  }
-//
-//  void test_NameExact() {
-//    when(_patternA.matches(_element)).thenReturn(MatchQuality.NAME);
-//    when(_patternB.matches(_element)).thenReturn(MatchQuality.EXACT);
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.NAME, _pattern.matches(_element));
-//  }
-//
-//  void test_NullNull() {
-//    when(_patternA.matches(_element)).thenReturn(null);
-//    when(_patternB.matches(_element)).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, _pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('OrSearchPatternTest', () {
-//      _ut.test('test_ExactName', () {
-//        final __test = new OrSearchPatternTest();
-//        runJUnitTest(__test, __test.test_ExactName);
-//      });
-//      _ut.test('test_NameExact', () {
-//        final __test = new OrSearchPatternTest();
-//        runJUnitTest(__test, __test.test_NameExact);
-//      });
-//      _ut.test('test_NullNull', () {
-//        final __test = new OrSearchPatternTest();
-//        runJUnitTest(__test, __test.test_NullNull);
-//      });
-//      _ut.test('test_allExact', () {
-//        final __test = new OrSearchPatternTest();
-//        runJUnitTest(__test, __test.test_allExact);
-//      });
-//    });
-//  }
-//}
-//
-//class PrefixSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  void test_caseInsensitive_contentMatch_caseMatch() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", false);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseInsensitive_contentMatch_caseMismatch() {
-//    SearchPattern pattern = new PrefixSearchPattern("HaSHMa", false);
-//    when(_element.displayName).thenReturn("hashMaP");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseInsensitive_contentMismatch() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", false);
-//    when(_element.displayName).thenReturn("HashTable");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_contentMatch() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_contentMismatch() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", true);
-//    when(_element.displayName).thenReturn("HashTable");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_nullElement() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", false);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(null));
-//  }
-//
-//  void test_nullName() {
-//    SearchPattern pattern = new PrefixSearchPattern("HashMa", false);
-//    when(_element.displayName).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('PrefixSearchPatternTest', () {
-//      _ut.test('test_caseInsensitive_contentMatch_caseMatch', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_contentMatch_caseMatch);
-//      });
-//      _ut.test('test_caseInsensitive_contentMatch_caseMismatch', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_contentMatch_caseMismatch);
-//      });
-//      _ut.test('test_caseInsensitive_contentMismatch', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_contentMismatch);
-//      });
-//      _ut.test('test_caseSensitive_contentMatch', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_contentMatch);
-//      });
-//      _ut.test('test_caseSensitive_contentMismatch', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_contentMismatch);
-//      });
-//      _ut.test('test_nullElement', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullElement);
-//      });
-//      _ut.test('test_nullName', () {
-//        final __test = new PrefixSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullName);
-//      });
-//    });
-//  }
-//}
-//
-//class RegularExpressionSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  void test_caseInsensitive_false_contentMismatch() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H[a-z]*Map", false);
-//    when(_element.displayName).thenReturn("Maps");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseInsensitive_true_caseMismatch() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H[a-z]*MaP", false);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_false_caseMismatch() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H[a-z]*MaP", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_false_contentMismatch() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H[a-z]*Map", true);
-//    when(_element.displayName).thenReturn("Maps");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_true() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H.*Map", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_nullElement() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H.*Map", true);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(null));
-//  }
-//
-//  void test_nullName() {
-//    SearchPattern pattern = new RegularExpressionSearchPattern("H.*Map", true);
-//    when(_element.displayName).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('RegularExpressionSearchPatternTest', () {
-//      _ut.test('test_caseInsensitive_false_contentMismatch', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_false_contentMismatch);
-//      });
-//      _ut.test('test_caseInsensitive_true_caseMismatch', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_true_caseMismatch);
-//      });
-//      _ut.test('test_caseSensitive_false_caseMismatch', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_false_caseMismatch);
-//      });
-//      _ut.test('test_caseSensitive_false_contentMismatch', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_false_contentMismatch);
-//      });
-//      _ut.test('test_caseSensitive_true', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_true);
-//      });
-//      _ut.test('test_nullElement', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullElement);
-//      });
-//      _ut.test('test_nullName', () {
-//        final __test = new RegularExpressionSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullName);
-//      });
-//    });
-//  }
-//}
-//
-//class SearchEngineImplTest extends EngineTestCase {
-//  static void _assertMatches(List<SearchMatch> matches, List<SearchEngineImplTest_ExpectedMatch> expectedMatches) {
-//    assertThat(matches).hasSize(expectedMatches.length);
-//    for (SearchMatch match in matches) {
-//      bool found = false;
-//      String msg = match.toString();
-//      for (SearchEngineImplTest_ExpectedMatch expectedMatch in expectedMatches) {
-//        if (match.element == expectedMatch._element && match.kind == expectedMatch._kind && match.quality == expectedMatch._quality && match.sourceRange == expectedMatch._range && match.isQualified == expectedMatch._qualified) {
-//          found = true;
-//          break;
-//        }
-//      }
-//      if (!found) {
-//        JUnitTestCase.fail("Not found: ${msg}");
-//      }
-//    }
-//  }
-//
-//  IndexStore _indexStore = IndexFactory.newSplitIndexStore(new MemoryNodeManager());
-//
-//  static AnalysisContext _CONTEXT = mock(AnalysisContext);
-//
-//  int _nextLocationId = 0;
-//
-//  SearchScope _scope;
-//
-//  SearchPattern _pattern = null;
-//
-//  SearchFilter _filter = null;
-//
-//  Source _source = mock(Source);
-//
-//  CompilationUnitElement _unitElement = mock(CompilationUnitElement);
-//
-//  LibraryElement _libraryElement = mock(LibraryElement);
-//
-//  Element _elementA = _mockElement(Element, ElementKind.CLASS);
-//
-//  Element _elementB = _mockElement(Element, ElementKind.CLASS);
-//
-//  Element _elementC = _mockElement(Element, ElementKind.CLASS);
-//
-//  Element _elementD = _mockElement(Element, ElementKind.CLASS);
-//
-//  Element _elementE = _mockElement(Element, ElementKind.CLASS);
-//
-//  void fail_searchAssignedTypes_assignments() {
-//    // TODO(scheglov) does not work - new split index store cannot store types (yet?)
-//    PropertyAccessorElement setterElement = _mockElement(PropertyAccessorElement, ElementKind.SETTER);
-//    FieldElement fieldElement = _mockElement(FieldElement, ElementKind.FIELD);
-//    when(fieldElement.setter).thenReturn(setterElement);
-//    DartType typeA = mock(DartType);
-//    DartType typeB = mock(DartType);
-//    DartType typeC = mock(DartType);
-//    _indexStore.aboutToIndexDart(_CONTEXT, _unitElement);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      location = new LocationWithData<DartType>.con1(location, typeA);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      location = new LocationWithData<DartType>.con1(location, typeB);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    // will be filtered by scope
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      location = new LocationWithData<DartType>.con1(location, typeC);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    // not LocationWithData
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // ask types
-//    Set<DartType> types = _runSearch(new SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_assignments(fieldElement));
-//    assertThat(types).containsOnly(typeA, typeB);
-//  }
-//
-//  void fail_searchAssignedTypes_initializers() {
-//    // TODO(scheglov) does not work - new split index store cannot store types (yet?)
-//    FieldElement fieldElement = _mockElement(FieldElement, ElementKind.FIELD);
-//    DartType typeA = mock(DartType);
-//    DartType typeB = mock(DartType);
-//    {
-//      Location location = new Location(_elementA, 10, 1);
-//      location = new LocationWithData<DartType>.con1(location, typeA);
-//      _indexStore.recordRelationship(fieldElement, IndexConstants.IS_DEFINED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 20, 1);
-//      location = new LocationWithData<DartType>.con1(location, typeB);
-//      _indexStore.recordRelationship(fieldElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // ask types
-//    Set<DartType> types = _runSearch(new SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_initializers(fieldElement));
-//    assertThat(types).containsOnly(typeA, typeB);
-//  }
-//
-//  void test_searchDeclarations_String() {
-//    Element referencedElement = new NameElementImpl("test");
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_DEFINED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_DEFINED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _runSearch(new SearchRunner_SearchEngineImplTest_test_searchDeclarations_String(this));
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.NAME_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.NAME_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchFunctionDeclarations() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineFunctionsAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchFunctionDeclarations_async() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineFunctionsAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchFunctionDeclarationsAsync();
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchFunctionDeclarations_inUniverse() {
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(IndexConstants.UNIVERSE, IndexConstants.DEFINES_FUNCTION, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(IndexConstants.UNIVERSE, IndexConstants.DEFINES_FUNCTION, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    _scope = SearchScopeFactory.createUniverseScope();
-//    // search matches
-//    List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchFunctionDeclarations_useFilter() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineFunctionsAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search "elementA"
-//    {
-//      _filter = new SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter_2(this);
-//      List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_DECLARATION, 1, 2)]);
-//    }
-//    // search "elementB"
-//    {
-//      _filter = new SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter(this);
-//      List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_DECLARATION, 10, 20)]);
-//    }
-//  }
-//
-//  void test_searchFunctionDeclarations_usePattern() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineFunctionsAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search "A"
-//    {
-//      _pattern = SearchPatternFactory.createExactPattern("A", true);
-//      List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_DECLARATION, 1, 2)]);
-//    }
-//    // search "B"
-//    {
-//      _pattern = SearchPatternFactory.createExactPattern("B", true);
-//      List<SearchMatch> matches = _searchFunctionDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_DECLARATION, 10, 20)]);
-//    }
-//  }
-//
-//  void test_searchReferences_AngularComponentElement() {
-//    AngularComponentElement referencedElement = _mockElement(AngularComponentElement, ElementKind.ANGULAR_COMPONENT);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_CLOSING_TAG_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_AngularControllerElement() {
-//    AngularControllerElement referencedElement = _mockElement(AngularControllerElement, ElementKind.ANGULAR_CONTROLLER);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_AngularFilterElement() {
-//    AngularFormatterElement referencedElement = _mockElement(AngularFormatterElement, ElementKind.ANGULAR_FORMATTER);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_AngularPropertyElement() {
-//    AngularPropertyElement referencedElement = _mockElement(AngularPropertyElement, ElementKind.ANGULAR_PROPERTY);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_AngularScopePropertyElement() {
-//    AngularScopePropertyElement referencedElement = _mockElement(AngularScopePropertyElement, ElementKind.ANGULAR_SCOPE_PROPERTY);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_AngularSelectorElement() {
-//    AngularSelectorElement referencedElement = _mockElement(AngularSelectorElement, ElementKind.ANGULAR_SELECTOR);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.ANGULAR_REFERENCE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.ANGULAR_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.ANGULAR_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_ClassElement() {
-//    ClassElement referencedElement = _mockElement(ClassElement, ElementKind.CLASS);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.TYPE_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.TYPE_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_ClassElement_useScope() {
-//    LibraryElement libraryA = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    LibraryElement libraryB = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    ClassElement referencedElement = _mockElement(ClassElement, ElementKind.CLASS);
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(libraryA);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationA);
-//    }
-//    {
-//      when(_elementB.getAncestor((element) => element is LibraryElement)).thenReturn(libraryB);
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches, in "libraryA"
-//    _scope = SearchScopeFactory.createLibraryScope3(libraryA);
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.TYPE_REFERENCE, 1, 2)]);
-//  }
-//
-//  void test_searchReferences_CompilationUnitElement() {
-//    CompilationUnitElement referencedElement = _mockElement(CompilationUnitElement, ElementKind.COMPILATION_UNIT);
-//    {
-//      Location location = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.UNIT_REFERENCE, 1, 2)]);
-//  }
-//
-//  void test_searchReferences_ConstructorElement() {
-//    ConstructorElement referencedElement = _mockElement(ConstructorElement, ElementKind.CONSTRUCTOR);
-//    {
-//      Location location = new Location(_elementA, 10, 1);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_DEFINED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 20, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 30, 3);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.CONSTRUCTOR_DECLARATION, 10, 1),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.CONSTRUCTOR_REFERENCE, 20, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementC, MatchKind.CONSTRUCTOR_REFERENCE, 30, 3)]);
-//  }
-//
-//  void test_searchReferences_Element_unknown() {
-//    List<SearchMatch> matches = _searchReferencesSync(Element, null);
-//    assertThat(matches).isEmpty();
-//  }
-//
-//  void test_searchReferences_FieldElement() {
-//    PropertyAccessorElement getterElement = _mockElement(PropertyAccessorElement, ElementKind.GETTER);
-//    PropertyAccessorElement setterElement = _mockElement(PropertyAccessorElement, ElementKind.SETTER);
-//    FieldElement fieldElement = _mockElement(FieldElement, ElementKind.FIELD);
-//    when(fieldElement.getter).thenReturn(getterElement);
-//    when(fieldElement.setter).thenReturn(setterElement);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(getterElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(getterElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, fieldElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.FIELD_READ, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.FIELD_READ, 2, 20, true),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementC, MatchKind.FIELD_WRITE, 3, 30, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementD, MatchKind.FIELD_WRITE, 4, 40, true)]);
-//  }
-//
-//  void test_searchReferences_FieldElement_invocation() {
-//    PropertyAccessorElement getterElement = _mockElement(PropertyAccessorElement, ElementKind.GETTER);
-//    FieldElement fieldElement = _mockElement(FieldElement, ElementKind.FIELD);
-//    when(fieldElement.getter).thenReturn(getterElement);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(getterElement, IndexConstants.IS_INVOKED_BY_QUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(getterElement, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, fieldElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.FIELD_INVOCATION, 1, 10, true),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.FIELD_INVOCATION, 2, 20, false)]);
-//  }
-//
-//  void test_searchReferences_FieldElement2() {
-//    FieldElement fieldElement = _mockElement(FieldElement, ElementKind.FIELD);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(fieldElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(fieldElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, fieldElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.FIELD_REFERENCE, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.FIELD_REFERENCE, 2, 20, true)]);
-//  }
-//
-//  void test_searchReferences_FunctionElement() {
-//    FunctionElement referencedElement = _mockElement(FunctionElement, ElementKind.FUNCTION);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_EXECUTION, 1, 10),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_REFERENCE, 2, 20)]);
-//  }
-//
-//  void test_searchReferences_ImportElement() {
-//    ImportElement referencedElement = _mockElement(ImportElement, ElementKind.IMPORT);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 0);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.IMPORT_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.IMPORT_REFERENCE, 10, 0)]);
-//  }
-//
-//  void test_searchReferences_LibraryElement() {
-//    LibraryElement referencedElement = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    {
-//      Location location = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.LIBRARY_REFERENCE, 1, 2)]);
-//  }
-//
-//  void test_searchReferences_MethodElement() {
-//    MethodElement referencedElement = _mockElement(MethodElement, ElementKind.METHOD);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY_QUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.METHOD_INVOCATION, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.METHOD_INVOCATION, 2, 20, true),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementC, MatchKind.METHOD_REFERENCE, 3, 30, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementD, MatchKind.METHOD_REFERENCE, 4, 40, true)]);
-//  }
-//
-//  void test_searchReferences_MethodMember() {
-//    MethodElement referencedElement = _mockElement(MethodElement, ElementKind.METHOD);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY_QUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    MethodMember referencedMember = new MethodMember(referencedElement, null);
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedMember);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.METHOD_INVOCATION, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.METHOD_INVOCATION, 2, 20, true),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementC, MatchKind.METHOD_REFERENCE, 3, 30, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementD, MatchKind.METHOD_REFERENCE, 4, 40, true)]);
-//  }
-//
-//  void test_searchReferences_notSupported() {
-//    Element referencedElement = _mockElement(Element, ElementKind.UNIVERSE);
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    assertThat(matches).isEmpty();
-//  }
-//
-//  void test_searchReferences_ParameterElement() {
-//    ParameterElement referencedElement = _mockElement(ParameterElement, ElementKind.PARAMETER);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_READ_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_WRITTEN_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_READ_WRITTEN_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 5, 50);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    // TODO(scheglov) why no MatchKind.FIELD_READ_WRITE ?
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.VARIABLE_READ, 1, 10),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.VARIABLE_WRITE, 2, 20),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementC, MatchKind.VARIABLE_READ_WRITE, 3, 30),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementD, MatchKind.NAMED_PARAMETER_REFERENCE, 4, 40),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementD, MatchKind.FUNCTION_EXECUTION, 5, 50)]);
-//  }
-//
-//  void test_searchReferences_PropertyAccessorElement_getter() {
-//    PropertyAccessorElement accessor = _mockElement(PropertyAccessorElement, ElementKind.GETTER);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(accessor, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(accessor, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, accessor);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 2, 20, true)]);
-//  }
-//
-//  void test_searchReferences_PropertyAccessorElement_setter() {
-//    PropertyAccessorElement accessor = _mockElement(PropertyAccessorElement, ElementKind.SETTER);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(accessor, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(accessor, IndexConstants.IS_REFERENCED_BY_QUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, accessor);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementB, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 2, 20, true)]);
-//  }
-//
-//  void test_searchReferences_TopLevelVariableElement() {
-//    PropertyAccessorElement getterElement = _mockElement(PropertyAccessorElement, ElementKind.GETTER);
-//    PropertyAccessorElement setterElement = _mockElement(PropertyAccessorElement, ElementKind.SETTER);
-//    TopLevelVariableElement topVariableElement = _mockElement(TopLevelVariableElement, ElementKind.TOP_LEVEL_VARIABLE);
-//    when(topVariableElement.getter).thenReturn(getterElement);
-//    when(topVariableElement.setter).thenReturn(setterElement);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(getterElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 2, 20);
-//      _indexStore.recordRelationship(setterElement, IndexConstants.IS_REFERENCED_BY_UNQUALIFIED, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, topVariableElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementA, MatchKind.FIELD_READ, 1, 10, false),
-//        new SearchEngineImplTest_ExpectedMatch.con2(_elementC, MatchKind.FIELD_WRITE, 2, 20, false)]);
-//  }
-//
-//  void test_searchReferences_TypeAliasElement() {
-//    FunctionTypeAliasElement referencedElement = _mockElement(FunctionTypeAliasElement, ElementKind.FUNCTION_TYPE_ALIAS);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_TYPE_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.FUNCTION_TYPE_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_TypeParameterElement() {
-//    TypeParameterElement referencedElement = _mockElement(TypeParameterElement, ElementKind.TYPE_PARAMETER);
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.TYPE_PARAMETER_REFERENCE, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.TYPE_PARAMETER_REFERENCE, 10, 20)]);
-//  }
-//
-//  void test_searchReferences_VariableElement() {
-//    LocalVariableElement referencedElement = _mockElement(LocalVariableElement, ElementKind.LOCAL_VARIABLE);
-//    {
-//      Location location = new Location(_elementA, 1, 10);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_READ_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementB, 2, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_WRITTEN_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementC, 3, 30);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_READ_WRITTEN_BY, location);
-//    }
-//    {
-//      Location location = new Location(_elementD, 4, 40);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_INVOKED_BY, location);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync(Element, referencedElement);
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.VARIABLE_READ, 1, 10),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.VARIABLE_WRITE, 2, 20),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementC, MatchKind.VARIABLE_READ_WRITE, 3, 30),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementD, MatchKind.FUNCTION_EXECUTION, 4, 40)]);
-//  }
-//
-//  void test_searchSubtypes() {
-//    ClassElement referencedElement = _mockElement(ClassElement, ElementKind.CLASS);
-//    {
-//      Location locationA = new Location(_elementA, 10, 1);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_EXTENDED_BY, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 20, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_MIXED_IN_BY, locationB);
-//    }
-//    {
-//      Location locationC = new Location(_elementC, 30, 3);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_IMPLEMENTED_BY, locationC);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _runSearch(new SearchRunner_SearchEngineImplTest_test_searchSubtypes(this, referencedElement));
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.EXTENDS_REFERENCE, 10, 1),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.WITH_REFERENCE, 20, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementC, MatchKind.IMPLEMENTS_REFERENCE, 30, 3)]);
-//  }
-//
-//  void test_searchTypeDeclarations_async() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_CLASS, locationA);
-//    }
-//    _indexStore.doneIndex();
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchTypeDeclarationsAsync();
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.CLASS_DECLARATION, 1, 2)]);
-//  }
-//
-//  void test_searchTypeDeclarations_class() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_CLASS, locationA);
-//    }
-//    _indexStore.doneIndex();
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchTypeDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.CLASS_DECLARATION, 1, 2)]);
-//  }
-//
-//  void test_searchTypeDeclarations_classAlias() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_CLASS_ALIAS, locationA);
-//    }
-//    _indexStore.doneIndex();
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchTypeDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.CLASS_ALIAS_DECLARATION, 1, 2)]);
-//  }
-//
-//  void test_searchTypeDeclarations_functionType() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_FUNCTION_TYPE, locationA);
-//    }
-//    _indexStore.doneIndex();
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchTypeDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.FUNCTION_TYPE_DECLARATION, 1, 2)]);
-//  }
-//
-//  void test_searchUnresolvedQualifiedReferences() {
-//    Element referencedElement = new NameElementImpl("test");
-//    {
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED_RESOLVED, locationA);
-//    }
-//    {
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(referencedElement, IndexConstants.IS_REFERENCED_BY_QUALIFIED_UNRESOLVED, locationB);
-//    }
-//    _indexStore.doneIndex();
-//    // search matches
-//    List<SearchMatch> matches = _searchReferencesSync2("searchQualifiedMemberReferences", String, "test");
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.NAME_REFERENCE_RESOLVED, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.NAME_REFERENCE_UNRESOLVED, 10, 20)]);
-//  }
-//
-//  void test_searchVariableDeclarations() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineVariablesAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchVariableDeclarationsSync();
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.VARIABLE_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.VARIABLE_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchVariableDeclarations_async() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineVariablesAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search matches
-//    List<SearchMatch> matches = _searchVariableDeclarationsAsync();
-//    // verify
-//    _assertMatches(matches, [
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.VARIABLE_DECLARATION, 1, 2),
-//        new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.VARIABLE_DECLARATION, 10, 20)]);
-//  }
-//
-//  void test_searchVariableDeclarations_usePattern() {
-//    LibraryElement library = _mockElement(LibraryElement, ElementKind.LIBRARY);
-//    _defineVariablesAB(library);
-//    _scope = new LibrarySearchScope.con2([library]);
-//    // search "A"
-//    {
-//      _pattern = SearchPatternFactory.createExactPattern("A", true);
-//      List<SearchMatch> matches = _searchVariableDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementA, MatchKind.VARIABLE_DECLARATION, 1, 2)]);
-//    }
-//    // search "B"
-//    {
-//      _pattern = SearchPatternFactory.createExactPattern("B", true);
-//      List<SearchMatch> matches = _searchVariableDeclarationsSync();
-//      _assertMatches(matches, [new SearchEngineImplTest_ExpectedMatch.con1(_elementB, MatchKind.VARIABLE_DECLARATION, 10, 20)]);
-//    }
-//  }
-//
-//  @override
-//  void setUp() {
-//    super.setUp();
-//    // library
-//    when(_unitElement.library).thenReturn(_libraryElement);
-//    when(_libraryElement.definingCompilationUnit).thenReturn(_unitElement);
-//    when(_unitElement.source).thenReturn(_source);
-//    when(_libraryElement.source).thenReturn(_source);
-//    when(_libraryElement.parts).thenReturn(new List<CompilationUnitElement>(0));
-//    // elements
-//    when(_elementA.toString()).thenReturn("A");
-//    when(_elementB.toString()).thenReturn("B");
-//    when(_elementC.toString()).thenReturn("C");
-//    when(_elementD.toString()).thenReturn("D");
-//    when(_elementE.toString()).thenReturn("E");
-//    when(_elementA.displayName).thenReturn("A");
-//    when(_elementB.displayName).thenReturn("B");
-//    when(_elementC.displayName).thenReturn("C");
-//    when(_elementD.displayName).thenReturn("D");
-//    when(_elementE.displayName).thenReturn("E");
-//    when(_elementA.source).thenReturn(_source);
-//    when(_elementB.source).thenReturn(_source);
-//    when(_elementC.source).thenReturn(_source);
-//    when(_elementD.source).thenReturn(_source);
-//    when(_elementE.source).thenReturn(_source);
-//    when(_elementA.context).thenReturn(_CONTEXT);
-//    when(_elementB.context).thenReturn(_CONTEXT);
-//    when(_elementC.context).thenReturn(_CONTEXT);
-//    when(_elementD.context).thenReturn(_CONTEXT);
-//    when(_elementE.context).thenReturn(_CONTEXT);
-//    when(_CONTEXT.getElement(_elementA.location)).thenReturn(_elementA);
-//    when(_CONTEXT.getElement(_elementB.location)).thenReturn(_elementB);
-//    when(_CONTEXT.getElement(_elementC.location)).thenReturn(_elementC);
-//    when(_CONTEXT.getElement(_elementD.location)).thenReturn(_elementD);
-//    when(_CONTEXT.getElement(_elementE.location)).thenReturn(_elementE);
-//    // start indexing
-//    JUnitTestCase.assertTrue(_indexStore.aboutToIndexDart(_CONTEXT, _unitElement));
-//  }
-//
-//  void _defineFunctionsAB(LibraryElement library) {
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_FUNCTION, locationA);
-//    }
-//    {
-//      when(_elementB.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_FUNCTION, locationB);
-//    }
-//    _indexStore.doneIndex();
-//  }
-//
-//  void _defineVariablesAB(LibraryElement library) {
-//    {
-//      when(_elementA.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationA = new Location(_elementA, 1, 2);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_VARIABLE, locationA);
-//    }
-//    {
-//      when(_elementB.getAncestor((element) => element is LibraryElement)).thenReturn(library);
-//      Location locationB = new Location(_elementB, 10, 20);
-//      _indexStore.recordRelationship(library, IndexConstants.DEFINES_VARIABLE, locationB);
-//    }
-//    _indexStore.doneIndex();
-//  }
-//
-//  Element _mockElement(Type clazz, ElementKind kind) {
-//    Element element = mock(clazz);
-//    when(element.context).thenReturn(_CONTEXT);
-//    when(element.source).thenReturn(_source);
-//    when(element.kind).thenReturn(kind);
-//    ElementLocation elementLocation = new ElementLocationImpl.con2("mockLocation${_nextLocationId++}");
-//    when(element.location).thenReturn(elementLocation);
-//    when(_CONTEXT.getElement(element.location)).thenReturn(element);
-//    return element;
-//  }
-//
-//  Object _runSearch(SearchEngineImplTest_SearchRunner runner) {
-//    OperationQueue queue = new OperationQueue();
-//    OperationProcessor processor = new OperationProcessor(queue);
-//    Index index = new IndexImpl(_indexStore, queue, processor);
-//    SearchEngine engine = SearchEngineFactory.createSearchEngine(index);
-//    try {
-//      new Thread_SearchEngineImplTest_runSearch(processor).start();
-//      processor.waitForRunning();
-//      return runner.run(queue, processor, index, engine);
-//    } finally {
-//      processor.stop(false);
-//    }
-//  }
-//
-//  List<SearchMatch> _searchDeclarationsAsync(String methodName) => _runSearch(new SearchRunner_SearchEngineImplTest_searchDeclarationsAsync(this, methodName, this, matches, latch));
-//
-//  List<SearchMatch> _searchDeclarationsSync(String methodName) => _runSearch(new SearchRunner_SearchEngineImplTest_searchDeclarationsSync(this, methodName));
-//
-//  List<SearchMatch> _searchFunctionDeclarationsAsync() => _searchDeclarationsAsync("searchFunctionDeclarations");
-//
-//  List<SearchMatch> _searchFunctionDeclarationsSync() => _searchDeclarationsSync("searchFunctionDeclarations");
-//
-//  List<SearchMatch> _searchReferencesSync(Type clazz, Object element) => _searchReferencesSync2("searchReferences", clazz, element);
-//
-//  List<SearchMatch> _searchReferencesSync2(String methodName, Type clazz, Object element) => _runSearch(new SearchRunner_SearchEngineImplTest_searchReferencesSync(this, methodName, clazz, element));
-//
-//  List<SearchMatch> _searchTypeDeclarationsAsync() => _searchDeclarationsAsync("searchTypeDeclarations");
-//
-//  List<SearchMatch> _searchTypeDeclarationsSync() => _searchDeclarationsSync("searchTypeDeclarations");
-//
-//  List<SearchMatch> _searchVariableDeclarationsAsync() => _searchDeclarationsAsync("searchVariableDeclarations");
-//
-//  List<SearchMatch> _searchVariableDeclarationsSync() => _searchDeclarationsSync("searchVariableDeclarations");
-//
-//  static dartSuite() {
-//    _ut.group('SearchEngineImplTest', () {
-//      _ut.test('test_searchDeclarations_String', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchDeclarations_String);
-//      });
-//      _ut.test('test_searchFunctionDeclarations', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchFunctionDeclarations);
-//      });
-//      _ut.test('test_searchFunctionDeclarations_async', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchFunctionDeclarations_async);
-//      });
-//      _ut.test('test_searchFunctionDeclarations_inUniverse', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchFunctionDeclarations_inUniverse);
-//      });
-//      _ut.test('test_searchFunctionDeclarations_useFilter', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchFunctionDeclarations_useFilter);
-//      });
-//      _ut.test('test_searchFunctionDeclarations_usePattern', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchFunctionDeclarations_usePattern);
-//      });
-//      _ut.test('test_searchReferences_AngularComponentElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularComponentElement);
-//      });
-//      _ut.test('test_searchReferences_AngularControllerElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularControllerElement);
-//      });
-//      _ut.test('test_searchReferences_AngularFilterElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularFilterElement);
-//      });
-//      _ut.test('test_searchReferences_AngularPropertyElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularPropertyElement);
-//      });
-//      _ut.test('test_searchReferences_AngularScopePropertyElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularScopePropertyElement);
-//      });
-//      _ut.test('test_searchReferences_AngularSelectorElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_AngularSelectorElement);
-//      });
-//      _ut.test('test_searchReferences_ClassElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_ClassElement);
-//      });
-//      _ut.test('test_searchReferences_ClassElement_useScope', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_ClassElement_useScope);
-//      });
-//      _ut.test('test_searchReferences_CompilationUnitElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_CompilationUnitElement);
-//      });
-//      _ut.test('test_searchReferences_ConstructorElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_ConstructorElement);
-//      });
-//      _ut.test('test_searchReferences_Element_unknown', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_Element_unknown);
-//      });
-//      _ut.test('test_searchReferences_FieldElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_FieldElement);
-//      });
-//      _ut.test('test_searchReferences_FieldElement2', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_FieldElement2);
-//      });
-//      _ut.test('test_searchReferences_FieldElement_invocation', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_FieldElement_invocation);
-//      });
-//      _ut.test('test_searchReferences_FunctionElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_FunctionElement);
-//      });
-//      _ut.test('test_searchReferences_ImportElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_ImportElement);
-//      });
-//      _ut.test('test_searchReferences_LibraryElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_LibraryElement);
-//      });
-//      _ut.test('test_searchReferences_MethodElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_MethodElement);
-//      });
-//      _ut.test('test_searchReferences_MethodMember', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_MethodMember);
-//      });
-//      _ut.test('test_searchReferences_ParameterElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_ParameterElement);
-//      });
-//      _ut.test('test_searchReferences_PropertyAccessorElement_getter', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_PropertyAccessorElement_getter);
-//      });
-//      _ut.test('test_searchReferences_PropertyAccessorElement_setter', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_PropertyAccessorElement_setter);
-//      });
-//      _ut.test('test_searchReferences_TopLevelVariableElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_TopLevelVariableElement);
-//      });
-//      _ut.test('test_searchReferences_TypeAliasElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_TypeAliasElement);
-//      });
-//      _ut.test('test_searchReferences_TypeParameterElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_TypeParameterElement);
-//      });
-//      _ut.test('test_searchReferences_VariableElement', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_VariableElement);
-//      });
-//      _ut.test('test_searchReferences_notSupported', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchReferences_notSupported);
-//      });
-//      _ut.test('test_searchSubtypes', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchSubtypes);
-//      });
-//      _ut.test('test_searchTypeDeclarations_async', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchTypeDeclarations_async);
-//      });
-//      _ut.test('test_searchTypeDeclarations_class', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchTypeDeclarations_class);
-//      });
-//      _ut.test('test_searchTypeDeclarations_classAlias', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchTypeDeclarations_classAlias);
-//      });
-//      _ut.test('test_searchTypeDeclarations_functionType', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchTypeDeclarations_functionType);
-//      });
-//      _ut.test('test_searchUnresolvedQualifiedReferences', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchUnresolvedQualifiedReferences);
-//      });
-//      _ut.test('test_searchVariableDeclarations', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchVariableDeclarations);
-//      });
-//      _ut.test('test_searchVariableDeclarations_async', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchVariableDeclarations_async);
-//      });
-//      _ut.test('test_searchVariableDeclarations_usePattern', () {
-//        final __test = new SearchEngineImplTest();
-//        runJUnitTest(__test, __test.test_searchVariableDeclarations_usePattern);
-//      });
-//    });
-//  }
-//}
-//
-//class SearchEngineImplTest_ExpectedMatch {
-//  final Element _element;
-//
-//  final MatchKind _kind;
-//
-//  final MatchQuality _quality;
-//
-//  SourceRange _range;
-//
-//  final bool _qualified;
-//
-//  SearchEngineImplTest_ExpectedMatch.con1(Element element, MatchKind kind, int offset, int length) : this.con3(element, kind, MatchQuality.EXACT, offset, length);
-//
-//  SearchEngineImplTest_ExpectedMatch.con2(Element element, MatchKind kind, int offset, int length, bool qualified) : this.con4(element, kind, MatchQuality.EXACT, offset, length, qualified);
-//
-//  SearchEngineImplTest_ExpectedMatch.con3(Element element, MatchKind kind, MatchQuality quality, int offset, int length) : this.con4(element, kind, quality, offset, length, false);
-//
-//  SearchEngineImplTest_ExpectedMatch.con4(this._element, this._kind, this._quality, int offset, int length, this._qualified) {
-//    this._range = new SourceRange(offset, length);
-//  }
-//}
-//
-//abstract class SearchEngineImplTest_SearchRunner<T> {
-//  T run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine);
-//}
-//
-//class SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter implements SearchFilter {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter(this.SearchEngineImplTest_this);
-//
-//  @override
-//  bool passes(SearchMatch match) => identical(match.element, SearchEngineImplTest_this._elementB);
-//}
-//
-//class SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter_2 implements SearchFilter {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  SearchFilter_SearchEngineImplTest_test_searchFunctionDeclarations_useFilter_2(this.SearchEngineImplTest_this);
-//
-//  @override
-//  bool passes(SearchMatch match) => identical(match.element, SearchEngineImplTest_this._elementA);
-//}
-//
-//class SearchListener_SearchRunner_117_run implements SearchListener {
-//  List<SearchMatch> matches;
-//
-//  CountDownLatch latch;
-//
-//  SearchListener_SearchRunner_117_run(this.matches, this.latch);
-//
-//  @override
-//  void matchFound(SearchMatch match) {
-//    matches.add(match);
-//  }
-//
-//  @override
-//  void searchComplete() {
-//    latch.countDown();
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_assignments implements SearchEngineImplTest_SearchRunner {
-//  FieldElement fieldElement;
-//
-//  SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_assignments(this.fieldElement, this.fieldElement);
-//
-//  @override
-//  Set<DartType> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) => engine.searchAssignedTypes(fieldElement, new SearchScope_SearchRunner_109_run());
-//}
-//
-//class SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_initializers implements SearchEngineImplTest_SearchRunner {
-//  FieldElement fieldElement;
-//
-//  SearchRunner_SearchEngineImplTest_fail_searchAssignedTypes_initializers(this.fieldElement);
-//
-//  @override
-//  Set<DartType> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) => engine.searchAssignedTypes(fieldElement, null);
-//}
-//
-//class SearchRunner_SearchEngineImplTest_searchDeclarationsAsync implements SearchEngineImplTest_SearchRunner {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  String methodName;
-//
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  List<SearchMatch> matches;
-//
-//  CountDownLatch latch;
-//
-//  SearchRunner_SearchEngineImplTest_searchDeclarationsAsync(this.SearchEngineImplTest_this, this.methodName, this.SearchEngineImplTest_this, this.matches, this.latch, this.SearchEngineImplTest_this, this.methodName, this.SearchEngineImplTest_this, this.matches, this.latch);
-//
-//  @override
-//  List<SearchMatch> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) {
-//    CountDownLatch latch = new CountDownLatch(1);
-//    List<SearchMatch> matches = [];
-//    engine.runtimeType.getMethod(methodName, [SearchScope, SearchPattern, SearchFilter, SearchListener]).invoke(engine, [
-//        SearchEngineImplTest_this._scope,
-//        SearchEngineImplTest_this._pattern,
-//        SearchEngineImplTest_this._filter,
-//        new SearchListener_SearchRunner_117_run(matches, latch)]);
-//    latch.await(30, TimeUnit.SECONDS);
-//    return matches;
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImplTest_searchDeclarationsSync implements SearchEngineImplTest_SearchRunner {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  String methodName;
-//
-//  SearchRunner_SearchEngineImplTest_searchDeclarationsSync(this.SearchEngineImplTest_this, this.methodName);
-//
-//  @override
-//  List<SearchMatch> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) => engine.runtimeType.getMethod(methodName, [SearchScope, SearchPattern, SearchFilter]).invoke(engine, [
-//      SearchEngineImplTest_this._scope,
-//      SearchEngineImplTest_this._pattern,
-//      SearchEngineImplTest_this._filter]) as List<SearchMatch>;
-//}
-//
-//class SearchRunner_SearchEngineImplTest_searchReferencesSync implements SearchEngineImplTest_SearchRunner {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  String methodName;
-//
-//  Type clazz;
-//
-//  Object element;
-//
-//  SearchRunner_SearchEngineImplTest_searchReferencesSync(this.SearchEngineImplTest_this, this.methodName, this.clazz, this.element);
-//
-//  @override
-//  List<SearchMatch> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) {
-//    // pass some operation to wait if search will not call processor
-//    queue.enqueue(mock(IndexOperation));
-//    // run actual search
-//    return engine.runtimeType.getMethod(methodName, [clazz, SearchScope, SearchFilter]).invoke(engine, [
-//        element,
-//        SearchEngineImplTest_this._scope,
-//        SearchEngineImplTest_this._filter]) as List<SearchMatch>;
-//  }
-//}
-//
-//class SearchRunner_SearchEngineImplTest_test_searchDeclarations_String implements SearchEngineImplTest_SearchRunner {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  SearchRunner_SearchEngineImplTest_test_searchDeclarations_String(this.SearchEngineImplTest_this);
-//
-//  @override
-//  List<SearchMatch> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) => engine.searchDeclarations("test", SearchEngineImplTest_this._scope, SearchEngineImplTest_this._filter);
-//}
-//
-//class SearchRunner_SearchEngineImplTest_test_searchSubtypes implements SearchEngineImplTest_SearchRunner {
-//  final SearchEngineImplTest SearchEngineImplTest_this;
-//
-//  ClassElement referencedElement;
-//
-//  SearchRunner_SearchEngineImplTest_test_searchSubtypes(this.SearchEngineImplTest_this, this.referencedElement);
-//
-//  @override
-//  List<SearchMatch> run(OperationQueue queue, OperationProcessor processor, Index index, SearchEngine engine) => engine.searchSubtypes(referencedElement, SearchEngineImplTest_this._scope, SearchEngineImplTest_this._filter);
-//}
-//
-//class SearchScope_SearchRunner_109_run implements SearchScope {
-//  @override
-//  bool encloses(Element element) => !identical(element, _elementC);
-//}
-//
-//class Thread_SearchEngineImplTest_runSearch extends Thread {
-//  OperationProcessor processor;
-//
-//  Thread_SearchEngineImplTest_runSearch(this.processor) : super();
-//
-//  @override
-//  void run() {
-//    processor.run();
-//  }
-//}
-//
-//class UniverseSearchScopeTest extends EngineTestCase {
-//  SearchScope _scope = new UniverseSearchScope();
-//
-//  Element _element = mock(Element);
-//
-//  void test_anyElement() {
-//    JUnitTestCase.assertTrue(_scope.encloses(_element));
-//  }
-//
-//  void test_nullElement() {
-//    JUnitTestCase.assertTrue(_scope.encloses(null));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('UniverseSearchScopeTest', () {
-//      _ut.test('test_anyElement', () {
-//        final __test = new UniverseSearchScopeTest();
-//        runJUnitTest(__test, __test.test_anyElement);
-//      });
-//      _ut.test('test_nullElement', () {
-//        final __test = new UniverseSearchScopeTest();
-//        runJUnitTest(__test, __test.test_nullElement);
-//      });
-//    });
-//  }
-//}
-//
-//class WildcardSearchPatternTest extends EngineTestCase {
-//  Element _element = mock(Element);
-//
-//  void test_caseInsensitive_false_contentMismatch() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*Map", false);
-//    when(_element.displayName).thenReturn("Maps");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseInsensitive_true_caseMismatch() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*MaP", false);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_false_caseMismatch() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*MaP", true);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_false_contentMismatch() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*Map", false);
-//    when(_element.displayName).thenReturn("Maps");
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  void test_caseSensitive_true() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*Ma?", false);
-//    when(_element.displayName).thenReturn("HashMap");
-//    // validate
-//    JUnitTestCase.assertSame(MatchQuality.EXACT, pattern.matches(_element));
-//  }
-//
-//  void test_nullElement() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*Map", false);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(null));
-//  }
-//
-//  void test_nullName() {
-//    SearchPattern pattern = new WildcardSearchPattern("H*Map", false);
-//    when(_element.displayName).thenReturn(null);
-//    // validate
-//    JUnitTestCase.assertSame(null, pattern.matches(_element));
-//  }
-//
-//  static dartSuite() {
-//    _ut.group('WildcardSearchPatternTest', () {
-//      _ut.test('test_caseInsensitive_false_contentMismatch', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_false_contentMismatch);
-//      });
-//      _ut.test('test_caseInsensitive_true_caseMismatch', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseInsensitive_true_caseMismatch);
-//      });
-//      _ut.test('test_caseSensitive_false_caseMismatch', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_false_caseMismatch);
-//      });
-//      _ut.test('test_caseSensitive_false_contentMismatch', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_false_contentMismatch);
-//      });
-//      _ut.test('test_caseSensitive_true', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_caseSensitive_true);
-//      });
-//      _ut.test('test_nullElement', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullElement);
-//      });
-//      _ut.test('test_nullName', () {
-//        final __test = new WildcardSearchPatternTest();
-//        runJUnitTest(__test, __test.test_nullName);
-//      });
-//    });
-//  }
-//}
-//
-//main() {
-//  CountingSearchListenerTest.dartSuite();
-//  FilterSearchListenerTest.dartSuite();
-//  GatheringSearchListenerTest.dartSuite();
-//  NameMatchingSearchListenerTest.dartSuite();
-//  LibrarySearchScopeTest.dartSuite();
-//  UniverseSearchScopeTest.dartSuite();
-//  SearchEngineImplTest.dartSuite();
-//  AndSearchPatternTest.dartSuite();
-//  CamelCaseSearchPatternTest.dartSuite();
-//  ExactSearchPatternTest.dartSuite();
-//  OrSearchPatternTest.dartSuite();
-//  PrefixSearchPatternTest.dartSuite();
-//  RegularExpressionSearchPatternTest.dartSuite();
-//  WildcardSearchPatternTest.dartSuite();
-//}
+
+  void setUp() {
+    super.setUp();
+    index = createLocalMemoryIndex();
+    searchEngine = new SearchEngineImpl(index);
+  }
+
+  Future test_searchMemberDeclarations() {
+    _indexTestUnit('''
+class A {
+  test() {}
+}
+class B {
+  int test = 42;
+}
+''');
+    NameElement element = new NameElement('test');
+    ClassElement elementA = findElement('A');
+    ClassElement elementB = findElement('B');
+    var expected = [
+        _expectId(elementA.methods[0], MatchKind.NAME_DECLARATION, 'test() {}'),
+        _expectId(elementB.fields[0], MatchKind.NAME_DECLARATION, 'test = 42;')];
+    return searchEngine.searchMemberDeclarations('test').then((matches) {
+      _assertMatches(matches, expected);
+    });
+  }
+
+  Future test_searchReferences_AngularComponentElement() {
+    // use mocks
+    index = new MockIndex();
+    searchEngine = new SearchEngineImpl(index);
+    Element elementA = new MockElement('A');
+    Element elementB = new MockElement('B');
+    // fill mocks
+    AngularComponentElement element = new MockAngularComponentElement();
+    void mockLocation(Element element, Relationship relationship,
+        Location location) {
+      index.getRelationships(element, relationship);
+      when(null).thenReturn(new Future.value([location]));
+    }
+    mockLocation(
+        element,
+        IndexConstants.ANGULAR_REFERENCE,
+        new Location(elementA, 1, 10));
+    mockLocation(
+        element,
+        IndexConstants.ANGULAR_CLOSING_TAG_REFERENCE,
+        new Location(elementB, 2, 20));
+    var expected = [
+        new ExpectedMatch(elementA, MatchKind.ANGULAR_REFERENCE, 1, 10),
+        new ExpectedMatch(elementB, MatchKind.ANGULAR_CLOSING_TAG_REFERENCE, 2, 20)];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_ClassElement() {
+    _indexTestUnit('''
+class A {}
+main(A p) {
+  A v;
+}
+''');
+    ClassElement element = findElement('A');
+    Element pElement = findElement('p');
+    Element vElement = findElement('v');
+    var expected = [
+        _expectId(pElement, MatchKind.TYPE_REFERENCE, 'A p'),
+        _expectId(vElement, MatchKind.TYPE_REFERENCE, 'A v')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_CompilationUnitElement() {
+    addSource('/my_part.dart', '''
+part of lib;
+''');
+    _indexTestUnit('''
+library lib;
+part 'my_part.dart';
+''');
+    CompilationUnitElement element = testLibraryElement.parts[0];
+    var expected = [
+        _expectId(
+            testUnitElement,
+            MatchKind.UNIT_REFERENCE,
+            "'my_part.dart'",
+            length: "'my_part.dart'".length)];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_ConstructorElement() {
+    _indexTestUnit('''
+class A {
+  A.named() {}
+}
+main() {
+  new A.named();
+}
+''');
+    ConstructorElement element = findElement('named');
+    ClassElement elementA = findElement('A');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(
+            elementA,
+            MatchKind.CONSTRUCTOR_DECLARATION,
+            '.named() {}',
+            length: 6),
+        _expectId(
+            mainElement,
+            MatchKind.CONSTRUCTOR_REFERENCE,
+            '.named();',
+            length: 6)];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_Element_unknown() {
+    return _verifyReferences(UniverseElement.INSTANCE, []);
+  }
+
+  Future test_searchReferences_FieldElement() {
+    _indexTestUnit('''
+class A {
+  var field;
+  A({this.field});
+  main() {
+    new A(field: 1);
+    // getter
+    print(field); // ref-nq
+    print(this.field); // ref-q
+    field(); // inv-nq
+    this.field(); // inv-q
+    // setter
+    field = 2; // ref-nq;
+    this.field = 3; // ref-q;
+  }
+}
+''');
+    FieldElement element = findElement('field');
+    Element main = findElement('main');
+    Element fieldParameter = findElement('field', ElementKind.PARAMETER);
+    var expected = [
+        _expectIdQ(fieldParameter, MatchKind.FIELD_REFERENCE, 'field}'),
+        _expectIdQ(main, MatchKind.FIELD_REFERENCE, 'field: 1'),
+        _expectId(main, MatchKind.FIELD_READ, 'field); // ref-nq'),
+        _expectIdQ(main, MatchKind.FIELD_READ, 'field); // ref-q'),
+        _expectId(main, MatchKind.FIELD_INVOCATION, 'field(); // inv-nq'),
+        _expectIdQ(main, MatchKind.FIELD_INVOCATION, 'field(); // inv-q'),
+        _expectId(main, MatchKind.FIELD_WRITE, 'field = 2; // ref-nq'),
+        _expectIdQ(main, MatchKind.FIELD_WRITE, 'field = 3; // ref-q')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_FunctionElement() {
+    _indexTestUnit('''
+test() {}
+main() {
+  test();
+  print(test);
+}
+''');
+    FunctionElement element = findElement('test');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(mainElement, MatchKind.FUNCTION_EXECUTION, 'test();'),
+        _expectId(mainElement, MatchKind.FUNCTION_REFERENCE, 'test);')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_FunctionTypeAliasElement() {
+    _indexTestUnit('''
+typedef Test();
+main() {
+  Test a;
+  Test b;
+}
+''');
+    FunctionTypeAliasElement element = findElement('Test');
+    Element aElement = findElement('a');
+    Element bElement = findElement('b');
+    var expected = [
+        _expectId(aElement, MatchKind.FUNCTION_TYPE_REFERENCE, 'Test a;'),
+        _expectId(bElement, MatchKind.FUNCTION_TYPE_REFERENCE, 'Test b;')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_ImportElement_noPrefix() {
+    _indexTestUnit('''
+import 'dart:math';
+main() {
+  print(E);
+}
+''');
+    ImportElement element = testLibraryElement.imports[0];
+    Element mainElement = findElement('main');
+    var kind = MatchKind.IMPORT_REFERENCE;
+    var expected = [_expectId(mainElement, kind, 'E);', length: 0)];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_ImportElement_withPrefix() {
+    _indexTestUnit('''
+import 'dart:math' as math;
+main() {
+  print(math.PI);
+}
+''');
+    ImportElement element = testLibraryElement.imports[0];
+    Element mainElement = findElement('main');
+    var kind = MatchKind.IMPORT_REFERENCE;
+    var expected = [
+        _expectId(mainElement, kind, 'math.PI);', length: 'math.'.length)];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_LibraryElement() {
+    var codeA = 'part of lib; // A';
+    var codeB = 'part of lib; // B';
+    var sourceA = addSource('/unitA.dart', codeA);
+    var sourceB = addSource('/unitB.dart', codeB);
+    _indexTestUnit('''
+library lib;
+part 'unitA.dart';
+part 'unitB.dart';
+''');
+    LibraryElement element = testLibraryElement;
+    CompilationUnitElement elementA = element.parts[0];
+    CompilationUnitElement elementB = element.parts[1];
+    index.indexUnit(context, elementA.node);
+    index.indexUnit(context, elementB.node);
+    Element mainElement = findElement('main');
+    var expected = [
+        new ExpectedMatch(
+            elementA,
+            MatchKind.LIBRARY_REFERENCE,
+            codeA.indexOf('lib; // A'),
+            'lib'.length),
+        new ExpectedMatch(
+            elementB,
+            MatchKind.LIBRARY_REFERENCE,
+            codeB.indexOf('lib; // B'),
+            'lib'.length),];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_LocalVariableElement() {
+    _indexTestUnit('''
+main() {
+  var v;
+  v = 1;
+  v += 2;
+  print(v);
+  v();
+}
+''');
+    LocalVariableElement element = findElement('v');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(mainElement, MatchKind.VARIABLE_WRITE, 'v = 1;'),
+        _expectId(mainElement, MatchKind.VARIABLE_READ_WRITE, 'v += 2;'),
+        _expectId(mainElement, MatchKind.VARIABLE_READ, 'v);'),
+        _expectId(mainElement, MatchKind.FUNCTION_EXECUTION, 'v();')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_MethodElement() {
+    _indexTestUnit('''
+class A {
+  m() {}
+  main() {
+    m(); // 1
+    this.m(); // 2
+    print(m); // 3
+    print(this.m); // 4
+  }
+}
+''');
+    MethodElement method = findElement('m');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(mainElement, MatchKind.METHOD_INVOCATION, 'm(); // 1'),
+        _expectIdQ(mainElement, MatchKind.METHOD_INVOCATION, 'm(); // 2'),
+        _expectId(mainElement, MatchKind.METHOD_REFERENCE, 'm); // 3'),
+        _expectIdQ(mainElement, MatchKind.METHOD_REFERENCE, 'm); // 4')];
+    return _verifyReferences(method, expected);
+  }
+
+  Future test_searchReferences_MethodMember() {
+    _indexTestUnit('''
+class A<T> {
+  T m() => null;
+}
+main(A<int> a) {
+  a.m(); // ref
+}
+''');
+    MethodMember method = findNodeElementAtString('m(); // ref');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectIdQ(mainElement, MatchKind.METHOD_INVOCATION, 'm(); // ref')];
+    return _verifyReferences(method, expected);
+  }
+
+  Future test_searchReferences_ParameterElement() {
+    _indexTestUnit('''
+foo({p}) {
+  p = 1;
+  p += 2;
+  print(p);
+  p();
+}
+main() {
+  foo(p: 42);
+}
+''');
+    ParameterElement element = findElement('p');
+    Element fooElement = findElement('foo');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(fooElement, MatchKind.VARIABLE_WRITE, 'p = 1;'),
+        _expectId(fooElement, MatchKind.VARIABLE_READ_WRITE, 'p += 2;'),
+        _expectId(fooElement, MatchKind.VARIABLE_READ, 'p);'),
+        _expectId(fooElement, MatchKind.FUNCTION_EXECUTION, 'p();'),
+        _expectId(mainElement, MatchKind.NAMED_PARAMETER_REFERENCE, 'p: 42')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_PropertyAccessorElement_getter() {
+    _indexTestUnit('''
+class A {
+  get g => null;
+  main() {
+    g; // 1
+    this.g; // 2
+  }
+}
+''');
+    PropertyAccessorElement element = findElement('g', ElementKind.GETTER);
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(mainElement, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 'g; // 1'),
+        _expectIdQ(mainElement, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 'g; // 2')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_PropertyAccessorElement_setter() {
+    _indexTestUnit('''
+class A {
+  set s(x) {}
+  main() {
+    s = 1;
+    this.s = 2;
+  }
+}
+''');
+    PropertyAccessorElement element = findElement('s=');
+    Element mainElement = findElement('main');
+    var expected = [
+        _expectId(mainElement, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 's = 1'),
+        _expectIdQ(mainElement, MatchKind.PROPERTY_ACCESSOR_REFERENCE, 's = 2')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchReferences_TopLevelVariableElement() {
+    addSource('/lib.dart', '''
+library lib;
+var V;
+''');
+    _indexTestUnit('''
+import 'lib.dart' show V; // imp
+import 'lib.dart' as pref;
+main() {
+  V = 1;
+  print(V);
+  V();
+}
+mainQ() {
+  pref.V = 1; // Q
+  print(pref.V); // Q
+  pref.V(); // Q
+}
+''');
+    ImportElement importElement = testLibraryElement.imports[0];
+    CompilationUnitElement impUnit =
+        importElement.importedLibrary.definingCompilationUnit;
+    TopLevelVariableElement variable = impUnit.topLevelVariables[0];
+    Element main = findElement('main');
+    Element mainQ = findElement('mainQ');
+    var expected = [
+        _expectIdQ(testUnitElement, MatchKind.FIELD_REFERENCE, 'V; // imp'),
+        _expectId(main, MatchKind.FIELD_WRITE, 'V = 1;'),
+        _expectId(main, MatchKind.FIELD_READ, 'V);'),
+        _expectId(main, MatchKind.FIELD_INVOCATION, 'V();'),
+        _expectIdQ(mainQ, MatchKind.FIELD_WRITE, 'V = 1; // Q'),
+        _expectIdQ(mainQ, MatchKind.FIELD_READ, 'V); // Q'),
+        _expectIdQ(mainQ, MatchKind.FIELD_INVOCATION, 'V(); // Q')];
+    return _verifyReferences(variable, expected);
+  }
+
+  Future test_searchReferences_TypeParameterElement() {
+    _indexTestUnit('''
+class A<T> {
+  main(T a, T b) {}
+}
+''');
+    TypeParameterElement element = findElement('T');
+    Element aElement = findElement('a');
+    Element bElement = findElement('b');
+    var expected = [
+        _expectId(aElement, MatchKind.TYPE_PARAMETER_REFERENCE, 'T a'),
+        _expectId(bElement, MatchKind.TYPE_PARAMETER_REFERENCE, 'T b')];
+    return _verifyReferences(element, expected);
+  }
+
+  Future test_searchSubtypes() {
+    _indexTestUnit('''
+class T {}
+class A extends T {} // A
+class B = Object with T; // B
+class C implements T {} // C
+''');
+    ClassElement element = findElement('T');
+    ClassElement elementA = findElement('A');
+    ClassElement elementB = findElement('B');
+    ClassElement elementC = findElement('C');
+    var expected = [
+        _expectId(elementA, MatchKind.EXTENDS_REFERENCE, 'T {} // A'),
+        _expectId(elementB, MatchKind.WITH_REFERENCE, 'T; // B'),
+        _expectId(elementC, MatchKind.IMPLEMENTS_REFERENCE, 'T {} // C')];
+    return searchEngine.searchSubtypes(element).then((matches) {
+      _assertMatches(matches, expected);
+    });
+  }
+
+  Future test_searchMemberReferences() {
+    _indexTestUnit('''
+class A {
+  var test; // A
+  mainA() {
+    test(); // a-inv-r-nq
+    test = 1; // a-write-r-nq
+    test += 2; // a-read-write-r-nq
+    print(test); // a-read-r-nq
+  }
+}
+main(A a, p) {
+  a.test(); // a-inv-r-q
+  a.test = 1; // a-write-r-q
+  a.test += 2; // a-read-write-r-q
+  print(a.test); // a-read-r-q
+  p.test(); // p-inv-ur-q
+  p.test = 1; // p-write-ur-q
+  p.test += 2; // p-read-write-ur-q
+  print(p.test); // p-read-ur-q
+}
+''');
+    ClassElement elementA = findElement('A');
+    ClassElement elementB = findElement('B');
+    Element mainA = findElement('mainA');
+    Element main = findElement('main');
+    var expected = [
+        _expectId(mainA, MatchKind.NAME_INVOCATION_RESOLVED, 'test(); // a-inv-r-nq'),
+        _expectId(mainA, MatchKind.NAME_WRITE_RESOLVED, 'test = 1; // a-write-r-nq'),
+        _expectId(mainA, MatchKind.NAME_READ_WRITE_RESOLVED, 'test += 2; // a-read-write-r-nq'),
+        _expectId(mainA, MatchKind.NAME_READ_RESOLVED, 'test); // a-read-r-nq'),
+        _expectId(main, MatchKind.NAME_INVOCATION_RESOLVED, 'test(); // a-inv-r-q'),
+        _expectId(main, MatchKind.NAME_WRITE_RESOLVED, 'test = 1; // a-write-r-q'),
+        _expectId(main, MatchKind.NAME_READ_WRITE_RESOLVED, 'test += 2; // a-read-write-r-q'),
+        _expectId(main, MatchKind.NAME_READ_RESOLVED, 'test); // a-read-r-q'),
+        _expectIdU(main, MatchKind.NAME_INVOCATION_UNRESOLVED, 'test(); // p-inv-ur-q'),
+        _expectIdU(main, MatchKind.NAME_WRITE_UNRESOLVED, 'test = 1; // p-write-ur-q'),
+        _expectIdU(main, MatchKind.NAME_READ_WRITE_UNRESOLVED, 'test += 2; // p-read-write-ur-q'),
+        _expectIdU(main, MatchKind.NAME_READ_UNRESOLVED, 'test); // p-read-ur-q'),
+        ];
+    return searchEngine.searchMemberReferences('test').then((matches) {
+      _assertMatches(matches, expected);
+    });
+  }
+
+  Future test_searchTopLevelDeclarations() {
+    _indexTestUnit('''
+class A {} // A
+class B = Object with A;
+typedef C();
+D() {}
+var E = null;
+class NoMatchABCDE {}
+''');
+    NameElement element = new NameElement('test');
+    Element topA = findElement('A');
+    Element topB = findElement('B');
+    Element topC = findElement('C');
+    Element topD = findElement('D');
+    Element topE = findElement('E');
+    Element topNoMatch = new MockElement('NoMatchABCDE');
+    var expected = [
+        _expectId(topA, MatchKind.CLASS_DECLARATION, 'A {} // A'),
+        _expectId(topB, MatchKind.CLASS_ALIAS_DECLARATION, 'B ='),
+        _expectId(topC, MatchKind.FUNCTION_TYPE_DECLARATION, 'C()'),
+        _expectId(topD, MatchKind.FUNCTION_DECLARATION, 'D() {}'),
+        _expectId(topE, MatchKind.VARIABLE_DECLARATION, 'E = null')];
+    return _verifyTopLevelDeclarations('^[A-E]\$', expected);
+  }
+
+  ExpectedMatch _expectId(Element element, MatchKind kind, String search,
+      {int length, bool isResolved: true, bool isQualified: false}) {
+    int offset = findOffset(search);
+    if (length == null) {
+      length = getLeadingIdentifierLength(search);
+    }
+    return new ExpectedMatch(
+        element,
+        kind,
+        offset,
+        length,
+        isResolved: isResolved,
+        isQualified: isQualified);
+  }
+
+  ExpectedMatch _expectIdQ(Element element, MatchKind kind, String search) {
+    return _expectId(element, kind, search, isQualified: true);
+  }
+
+  ExpectedMatch _expectIdU(Element element, MatchKind kind, String search) {
+    return _expectId(element, kind, search, isResolved: false);
+  }
+
+  void _indexTestUnit(String code) {
+    resolveTestUnit(code);
+    index.indexUnit(context, testUnit);
+  }
+
+  Future _verifyReferences(Element element,
+      List<ExpectedMatch> expectedMatches) {
+    return searchEngine.searchReferences(
+        element).then((List<SearchMatch> matches) {
+      _assertMatches(matches, expectedMatches);
+    });
+  }
+
+  Future _verifyTopLevelDeclarations(String pattern,
+      List<ExpectedMatch> expectedMatches) {
+    return searchEngine.searchTopLevelDeclarations(
+        pattern).then((List<SearchMatch> matches) {
+      _assertMatches(matches, expectedMatches);
+    });
+  }
+
+  static void _assertMatches(List<SearchMatch> matches,
+      List<ExpectedMatch> expectedMatches) {
+    expect(matches, unorderedEquals(expectedMatches));
+  }
+}
diff --git a/pkg/analysis_services/test/search/test_all.dart b/pkg/analysis_services/test/search/test_all.dart
new file mode 100644
index 0000000..fad272d
--- /dev/null
+++ b/pkg/analysis_services/test/search/test_all.dart
@@ -0,0 +1,20 @@
+// 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.services.src.scheglov.all;
+
+import 'package:unittest/unittest.dart';
+
+import 'search_engine_test.dart' as search_engine_test;
+
+
+/**
+ * Utility for manually running all tests.
+ */
+main() {
+  groupSep = ' | ';
+  group('search', () {
+    search_engine_test.main();
+  });
+}
\ No newline at end of file
diff --git a/pkg/analysis_services/test/test_all.dart b/pkg/analysis_services/test/test_all.dart
index ee8b415..6f0df28 100644
--- a/pkg/analysis_services/test/test_all.dart
+++ b/pkg/analysis_services/test/test_all.dart
@@ -5,9 +5,11 @@
 import 'package:unittest/unittest.dart';
 
 import 'index/test_all.dart' as index_all;
+import 'search/test_all.dart' as search_all;
 
 /// Utility for manually running all tests.
 main() {
   groupSep = ' | ';
   index_all.main();
+  search_all.main();
 }
\ No newline at end of file
diff --git a/pkg/analysis_testing/lib/mock_sdk.dart b/pkg/analysis_testing/lib/mock_sdk.dart
index 05251ab..89de9b6 100644
--- a/pkg/analysis_testing/lib/mock_sdk.dart
+++ b/pkg/analysis_testing/lib/mock_sdk.dart
@@ -64,6 +64,8 @@
 
       "/lib/math/math.dart": '''
           library dart.math;
+          const double E = 2.718281828459045;
+          const double PI = 3.1415926535897932;
           '''
     };
 
diff --git a/pkg/analysis_testing/lib/mocks.dart b/pkg/analysis_testing/lib/mocks.dart
index 80aed86..aa1edef 100644
--- a/pkg/analysis_testing/lib/mocks.dart
+++ b/pkg/analysis_testing/lib/mocks.dart
@@ -16,24 +16,78 @@
 }
 
 
+class MockClassElement extends TypedMock implements ClassElement {
+  final ElementKind kind = ElementKind.CLASS;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
 class MockCompilationUnitElement extends TypedMock implements
     CompilationUnitElement {
+  final ElementKind kind = ElementKind.COMPILATION_UNIT;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockConstructorElement extends TypedMock implements ConstructorElement {
+  final kind = ElementKind.CONSTRUCTOR;
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 
 class MockElement extends StringTypedMock implements Element {
   MockElement([String name = '<element>']) : super(name);
+
+  @override
+  String get displayName => _toString;
+
+  @override
+  String get name => _toString;
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockFieldElement extends TypedMock implements FieldElement {
+  final ElementKind kind = ElementKind.FIELD;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockFunctionElement extends TypedMock implements FunctionElement {
+  final ElementKind kind = ElementKind.FUNCTION;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockFunctionTypeAliasElement extends TypedMock implements
+    FunctionTypeAliasElement {
+  final ElementKind kind = ElementKind.FUNCTION_TYPE_ALIAS;
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 
 class MockHtmlElement extends TypedMock implements HtmlElement {
+  final ElementKind kind = ElementKind.HTML;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockImportElement extends TypedMock implements ImportElement {
+  final ElementKind kind = ElementKind.IMPORT;
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 
 class MockLibraryElement extends TypedMock implements LibraryElement {
+  final ElementKind kind = ElementKind.LIBRARY;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockLocalVariableElement extends TypedMock implements LocalVariableElement
+    {
+  final ElementKind kind = ElementKind.LOCAL_VARIABLE;
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
@@ -43,12 +97,47 @@
 }
 
 
+class MockMethodElement extends StringTypedMock implements MethodElement {
+  final kind = ElementKind.METHOD;
+  MockMethodElement([String name = 'method']) : super(name);
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockParameterElement extends TypedMock implements ParameterElement {
+  final ElementKind kind = ElementKind.PARAMETER;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockPropertyAccessorElement extends TypedMock implements
+    PropertyAccessorElement {
+  final ElementKind kind;
+  MockPropertyAccessorElement(this.kind);
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
 class MockSource extends StringTypedMock implements Source {
   MockSource([String name = 'mocked.dart']) : super(name);
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 
+class MockTopLevelVariableElement extends TypedMock implements
+    TopLevelVariableElement {
+  final ElementKind kind = ElementKind.TOP_LEVEL_VARIABLE;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
+class MockTypeParameterElement extends TypedMock implements TypeParameterElement
+    {
+  final ElementKind kind = ElementKind.TYPE_PARAMETER;
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+
 class StringTypedMock extends TypedMock {
   String _toString;
 
diff --git a/pkg/analysis_testing/pubspec.yaml b/pkg/analysis_testing/pubspec.yaml
index f064788..84c6630 100644
--- a/pkg/analysis_testing/pubspec.yaml
+++ b/pkg/analysis_testing/pubspec.yaml
@@ -1,11 +1,11 @@
 name: analysis_testing
-version: 0.2.0
+version: 0.3.0
 author: Dart Team <misc@dartlang.org>
 description: A set of libraries for testing Analysis services and server
 homepage: http://www.dartlang.org
 environment:
   sdk: '>=1.0.0 <2.0.0'
 dependencies:
-  analyzer: '>=0.21.0 <1.0.0'
+  analyzer: '>=0.21.1 <1.0.0'
   typed_mock: '>=0.0.4 <1.0.0'
   unittest: '>=0.10.0 <0.12.0'
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index db282d9..495f618 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -17,6 +17,7 @@
 import 'utilities_collection.dart' show TokenMap;
 import 'element.dart';
 import 'constant.dart';
+import 'parser.dart';
 
 /**
  * Instances of the class `AdjacentStrings` represents two or more string literals that are
@@ -991,13 +992,16 @@
   AssignmentExpression visitAssignmentExpression(AssignmentExpression node) => new AssignmentExpression(cloneNode(node.leftHandSide), node.operator, cloneNode(node.rightHandSide));
 
   @override
+  AwaitExpression visitAwaitExpression(AwaitExpression node) => new AwaitExpression(node.awaitKeyword, node.expression, node.semicolon);
+
+  @override
   BinaryExpression visitBinaryExpression(BinaryExpression node) => new BinaryExpression(cloneNode(node.leftOperand), node.operator, cloneNode(node.rightOperand));
 
   @override
   Block visitBlock(Block node) => new Block(node.leftBracket, cloneNodeList(node.statements), node.rightBracket);
 
   @override
-  BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) => new BlockFunctionBody(cloneNode(node.block));
+  BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) => new BlockFunctionBody(node.keyword, node.star, cloneNode(node.block));
 
   @override
   BooleanLiteral visitBooleanLiteral(BooleanLiteral node) => new BooleanLiteral(node.literal, node.value);
@@ -1083,7 +1087,7 @@
   }
 
   @override
-  ExpressionFunctionBody visitExpressionFunctionBody(ExpressionFunctionBody node) => new ExpressionFunctionBody(node.functionDefinition, cloneNode(node.expression), node.semicolon);
+  ExpressionFunctionBody visitExpressionFunctionBody(ExpressionFunctionBody node) => new ExpressionFunctionBody(node.keyword, node.functionDefinition, cloneNode(node.expression), node.semicolon);
 
   @override
   ExpressionStatement visitExpressionStatement(ExpressionStatement node) => new ExpressionStatement(cloneNode(node.expression), node.semicolon);
@@ -1101,9 +1105,9 @@
   ForEachStatement visitForEachStatement(ForEachStatement node) {
     DeclaredIdentifier loopVariable = node.loopVariable;
     if (loopVariable == null) {
-      return new ForEachStatement.con2(node.forKeyword, node.leftParenthesis, cloneNode(node.identifier), node.inKeyword, cloneNode(node.iterator), node.rightParenthesis, cloneNode(node.body));
+      return new ForEachStatement.con2(node.awaitKeyword, node.forKeyword, node.leftParenthesis, cloneNode(node.identifier), node.inKeyword, cloneNode(node.iterator), node.rightParenthesis, cloneNode(node.body));
     }
-    return new ForEachStatement.con1(node.forKeyword, node.leftParenthesis, cloneNode(loopVariable), node.inKeyword, cloneNode(node.iterator), node.rightParenthesis, cloneNode(node.body));
+    return new ForEachStatement.con1(node.awaitKeyword, node.forKeyword, node.leftParenthesis, cloneNode(loopVariable), node.inKeyword, cloneNode(node.iterator), node.rightParenthesis, cloneNode(node.body));
   }
 
   @override
@@ -1321,6 +1325,9 @@
   @override
   WithClause visitWithClause(WithClause node) => new WithClause(node.withKeyword, cloneNodeList(node.mixinTypes));
 
+  @override
+  YieldStatement visitYieldStatement(YieldStatement node) => new YieldStatement(node.yieldKeyword, node.star, node.expression, node.semicolon);
+
   AstNode cloneNode(AstNode node) {
     if (node == null) {
       return null;
@@ -1389,6 +1396,12 @@
   }
 
   @override
+  bool visitAwaitExpression(AwaitExpression node) {
+    AwaitExpression other = this._other as AwaitExpression;
+    return _isEqualTokens(node.awaitKeyword, other.awaitKeyword) && _isEqualNodes(node.expression, other.expression) && _isEqualTokens(node.semicolon, other.semicolon);
+  }
+
+  @override
   bool visitBinaryExpression(BinaryExpression node) {
     BinaryExpression other = this._other as BinaryExpression;
     return _isEqualNodes(node.leftOperand, other.leftOperand) && _isEqualTokens(node.operator, other.operator) && _isEqualNodes(node.rightOperand, other.rightOperand);
@@ -1964,6 +1977,12 @@
     return _isEqualTokens(node.withKeyword, other.withKeyword) && _isEqualNodeLists(node.mixinTypes, other.mixinTypes);
   }
 
+  @override
+  bool visitYieldStatement(YieldStatement node) {
+    YieldStatement other = this._other as YieldStatement;
+    return _isEqualTokens(node.yieldKeyword, other.yieldKeyword) && _isEqualNodes(node.expression, other.expression) && _isEqualTokens(node.semicolon, other.semicolon);
+  }
+
   /**
    * Return `true` if the given lists of AST nodes have the same size and corresponding
    * elements are equal.
@@ -2303,6 +2322,8 @@
 
   R visitAssignmentExpression(AssignmentExpression node);
 
+  R visitAwaitExpression(AwaitExpression node);
+
   R visitBinaryExpression(BinaryExpression node);
 
   R visitBlock(Block node);
@@ -2494,6 +2515,82 @@
   R visitWhileStatement(WhileStatement node);
 
   R visitWithClause(WithClause node);
+
+  R visitYieldStatement(YieldStatement node);
+}
+
+/**
+ * Instances of the class `AwaitExpression` implement an await expression.
+ */
+class AwaitExpression extends Expression {
+  /**
+   * The 'await' keyword.
+   */
+  Token awaitKeyword;
+
+  /**
+   * The expression whose value is being waited on.
+   */
+  Expression _expression;
+
+  /**
+   * The semicolon following the expression.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created await expression.
+   *
+   * @param awaitKeyword the 'await' keyword
+   * @param expression the expression whose value is being waited on
+   * @param semicolon the semicolon following the expression
+   */
+  AwaitExpression(this.awaitKeyword, Expression expression, this.semicolon) {
+    this._expression = becomeParentOf(expression);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitAwaitExpression(this);
+
+  @override
+  Token get beginToken {
+    if (awaitKeyword != null) {
+      return awaitKeyword;
+    }
+    return _expression.beginToken;
+  }
+
+  @override
+  Token get endToken {
+    if (semicolon != null) {
+      return semicolon;
+    }
+    return _expression.endToken;
+  }
+
+  /**
+   * Return the expression whose value is being waited on.
+   *
+   * @return the expression whose value is being waited on
+   */
+  Expression get expression => _expression;
+
+  @override
+  int get precedence => 0;
+
+  /**
+   * Set the expression whose value is being waited on to the given expression.
+   *
+   * @param expression the expression whose value is being waited on
+   */
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    safelyVisitChild(_expression, visitor);
+  }
 }
 
 /**
@@ -2759,11 +2856,22 @@
  *
  * <pre>
  * blockFunctionBody ::=
- *     [Block]
+ *     ('async' | 'async' '*' | 'sync' '*')? [Block]
  * </pre>
  */
 class BlockFunctionBody extends FunctionBody {
   /**
+   * The token representing the 'async' or 'sync' keyword, or `null` if there is no such
+   * keyword.
+   */
+  Token keyword;
+
+  /**
+   * The star optionally following the 'async' or following the 'sync' keyword.
+   */
+  Token star;
+
+  /**
    * The block representing the body of the function.
    */
   Block _block;
@@ -2771,9 +2879,11 @@
   /**
    * Initialize a newly created function body consisting of a block of statements.
    *
+   * @param keyword the token representing the 'async' or 'sync' keyword
+   * @param star the star following the 'async' or 'sync' keyword
    * @param block the block representing the body of the function
    */
-  BlockFunctionBody(Block block) {
+  BlockFunctionBody(this.keyword, this.star, Block block) {
     this._block = becomeParentOf(block);
   }
 
@@ -2793,6 +2903,21 @@
   @override
   Token get endToken => _block.endToken;
 
+  @override
+  bool get isAsynchronous {
+    if (keyword == null) {
+      return false;
+    }
+    String keywordValue = keyword.lexeme;
+    return keywordValue == Parser.ASYNC;
+  }
+
+  @override
+  bool get isGenerator => star != null;
+
+  @override
+  bool get isSynchronous => keyword == null || keyword.lexeme != Parser.ASYNC;
+
   /**
    * Set the block representing the body of the function to the given block.
    *
@@ -6221,11 +6346,16 @@
  *
  * <pre>
  * expressionFunctionBody ::=
- *     '=>' [Expression] ';'
+ *     'async'? '=>' [Expression] ';'
  * </pre>
  */
 class ExpressionFunctionBody extends FunctionBody {
   /**
+   * The token representing the 'async' keyword, or `null` if there is no such keyword.
+   */
+  Token keyword;
+
+  /**
    * The token introducing the expression that represents the body of the function.
    */
   Token functionDefinition;
@@ -6243,12 +6373,13 @@
   /**
    * Initialize a newly created function body consisting of a block of statements.
    *
+   * @param keyword the token representing the 'async' keyword
    * @param functionDefinition the token introducing the expression that represents the body of the
    *          function
    * @param expression the expression representing the body of the function
    * @param semicolon the semicolon terminating the statement
    */
-  ExpressionFunctionBody(this.functionDefinition, Expression expression, this.semicolon) {
+  ExpressionFunctionBody(this.keyword, this.functionDefinition, Expression expression, this.semicolon) {
     this._expression = becomeParentOf(expression);
   }
 
@@ -6273,6 +6404,12 @@
    */
   Expression get expression => _expression;
 
+  @override
+  bool get isAsynchronous => keyword != null;
+
+  @override
+  bool get isSynchronous => keyword == null;
+
   /**
    * Set the expression representing the body of the function to the given expression.
    *
@@ -6629,12 +6766,17 @@
  *
  * <pre>
  * forEachStatement ::=
- *     'for' '(' [DeclaredIdentifier] 'in' [Expression] ')' [Block]
- *   | 'for' '(' [SimpleIdentifier] 'in' [Expression] ')' [Block]
+ *     'await'? 'for' '(' [DeclaredIdentifier] 'in' [Expression] ')' [Block]
+ *   | 'await'? 'for' '(' [SimpleIdentifier] 'in' [Expression] ')' [Block]
  * </pre>
  */
 class ForEachStatement extends Statement {
   /**
+   * The token representing the 'await' keyword, or `null` if there is no 'await' keyword.
+   */
+  Token awaitKeyword;
+
+  /**
    * The token representing the 'for' keyword.
    */
   Token forKeyword;
@@ -6678,6 +6820,7 @@
   /**
    * Initialize a newly created for-each statement.
    *
+   * @param awaitKeyword the token representing the 'await' keyword
    * @param forKeyword the token representing the 'for' keyword
    * @param leftParenthesis the left parenthesis
    * @param loopVariable the declaration of the loop variable
@@ -6685,7 +6828,7 @@
    * @param rightParenthesis the right parenthesis
    * @param body the body of the loop
    */
-  ForEachStatement.con1(this.forKeyword, this.leftParenthesis, DeclaredIdentifier loopVariable, this.inKeyword, Expression iterator, this.rightParenthesis, Statement body) {
+  ForEachStatement.con1(this.awaitKeyword, this.forKeyword, this.leftParenthesis, DeclaredIdentifier loopVariable, this.inKeyword, Expression iterator, this.rightParenthesis, Statement body) {
     this._loopVariable = becomeParentOf(loopVariable);
     this._iterator = becomeParentOf(iterator);
     this._body = becomeParentOf(body);
@@ -6694,6 +6837,7 @@
   /**
    * Initialize a newly created for-each statement.
    *
+   * @param awaitKeyword the token representing the 'await' keyword
    * @param forKeyword the token representing the 'for' keyword
    * @param leftParenthesis the left parenthesis
    * @param identifier the loop variable
@@ -6701,7 +6845,7 @@
    * @param rightParenthesis the right parenthesis
    * @param body the body of the loop
    */
-  ForEachStatement.con2(this.forKeyword, this.leftParenthesis, SimpleIdentifier identifier, this.inKeyword, Expression iterator, this.rightParenthesis, Statement body) {
+  ForEachStatement.con2(this.awaitKeyword, this.forKeyword, this.leftParenthesis, SimpleIdentifier identifier, this.inKeyword, Expression iterator, this.rightParenthesis, Statement body) {
     this._identifier = becomeParentOf(identifier);
     this._iterator = becomeParentOf(iterator);
     this._body = becomeParentOf(body);
@@ -7226,6 +7370,26 @@
  * </pre>
  */
 abstract class FunctionBody extends AstNode {
+  /**
+   * Return `true` if this function body is asynchronous.
+   *
+   * @return `true` if this function body is asynchronous
+   */
+  bool get isAsynchronous => false;
+
+  /**
+   * Return `true` if this function body is a generator.
+   *
+   * @return `true` if this function body is a generator
+   */
+  bool get isGenerator => false;
+
+  /**
+   * Return `true` if this function body is synchronous.
+   *
+   * @return `true` if this function body is synchronous
+   */
+  bool get isSynchronous => true;
 }
 
 /**
@@ -7938,6 +8102,9 @@
   R visitAssignmentExpression(AssignmentExpression node) => visitExpression(node);
 
   @override
+  R visitAwaitExpression(AwaitExpression node) => visitExpression(node);
+
+  @override
   R visitBinaryExpression(BinaryExpression node) => visitExpression(node);
 
   @override
@@ -8269,6 +8436,9 @@
 
   @override
   R visitWithClause(WithClause node) => visitNode(node);
+
+  @override
+  R visitYieldStatement(YieldStatement node) => visitStatement(node);
 }
 
 class GeneralizingAstVisitor_BreadthFirstVisitor extends GeneralizingAstVisitor<Object> {
@@ -8819,6 +8989,9 @@
   }
 
   @override
+  AwaitExpression visitAwaitExpression(AwaitExpression node) => new AwaitExpression(_mapToken(node.awaitKeyword), _cloneNode(node.expression), _mapToken(node.semicolon));
+
+  @override
   BinaryExpression visitBinaryExpression(BinaryExpression node) {
     BinaryExpression copy = new BinaryExpression(_cloneNode(node.leftOperand), _mapToken(node.operator), _cloneNode(node.rightOperand));
     copy.propagatedElement = node.propagatedElement;
@@ -8832,7 +9005,7 @@
   Block visitBlock(Block node) => new Block(_mapToken(node.leftBracket), _cloneNodeList(node.statements), _mapToken(node.rightBracket));
 
   @override
-  BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) => new BlockFunctionBody(_cloneNode(node.block));
+  BlockFunctionBody visitBlockFunctionBody(BlockFunctionBody node) => new BlockFunctionBody(_mapToken(node.keyword), _mapToken(node.star), _cloneNode(node.block));
 
   @override
   BooleanLiteral visitBooleanLiteral(BooleanLiteral node) {
@@ -8946,7 +9119,7 @@
   }
 
   @override
-  ExpressionFunctionBody visitExpressionFunctionBody(ExpressionFunctionBody node) => new ExpressionFunctionBody(_mapToken(node.functionDefinition), _cloneNode(node.expression), _mapToken(node.semicolon));
+  ExpressionFunctionBody visitExpressionFunctionBody(ExpressionFunctionBody node) => new ExpressionFunctionBody(_mapToken(node.keyword), _mapToken(node.functionDefinition), _cloneNode(node.expression), _mapToken(node.semicolon));
 
   @override
   ExpressionStatement visitExpressionStatement(ExpressionStatement node) => new ExpressionStatement(_cloneNode(node.expression), _mapToken(node.semicolon));
@@ -8964,9 +9137,9 @@
   ForEachStatement visitForEachStatement(ForEachStatement node) {
     DeclaredIdentifier loopVariable = node.loopVariable;
     if (loopVariable == null) {
-      return new ForEachStatement.con2(_mapToken(node.forKeyword), _mapToken(node.leftParenthesis), _cloneNode(node.identifier), _mapToken(node.inKeyword), _cloneNode(node.iterator), _mapToken(node.rightParenthesis), _cloneNode(node.body));
+      return new ForEachStatement.con2(_mapToken(node.awaitKeyword), _mapToken(node.forKeyword), _mapToken(node.leftParenthesis), _cloneNode(node.identifier), _mapToken(node.inKeyword), _cloneNode(node.iterator), _mapToken(node.rightParenthesis), _cloneNode(node.body));
     }
-    return new ForEachStatement.con1(_mapToken(node.forKeyword), _mapToken(node.leftParenthesis), _cloneNode(loopVariable), _mapToken(node.inKeyword), _cloneNode(node.iterator), _mapToken(node.rightParenthesis), _cloneNode(node.body));
+    return new ForEachStatement.con1(_mapToken(node.awaitKeyword), _mapToken(node.forKeyword), _mapToken(node.leftParenthesis), _cloneNode(loopVariable), _mapToken(node.inKeyword), _cloneNode(node.iterator), _mapToken(node.rightParenthesis), _cloneNode(node.body));
   }
 
   @override
@@ -9340,6 +9513,9 @@
   @override
   WithClause visitWithClause(WithClause node) => new WithClause(_mapToken(node.withKeyword), _cloneNodeList(node.mixinTypes));
 
+  @override
+  YieldStatement visitYieldStatement(YieldStatement node) => new YieldStatement(_mapToken(node.yieldKeyword), _mapToken(node.star), _cloneNode(node.expression), _mapToken(node.semicolon));
+
   AstNode _cloneNode(AstNode node) {
     if (node == null) {
       return null;
@@ -11640,6 +11816,14 @@
   }
 
   @override
+  bool visitAwaitExpression(AwaitExpression node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitBinaryExpression(BinaryExpression node) {
     if (identical(node.leftOperand, _oldNode)) {
       node.leftOperand = _newNode as Expression;
@@ -12634,6 +12818,14 @@
     return visitNode(node);
   }
 
+  @override
+  bool visitYieldStatement(YieldStatement node) {
+    if (identical(node.expression, _oldNode)) {
+      node.expression = _newNode as Expression;
+    }
+    return visitNode(node);
+  }
+
   bool _replaceInList(NodeList list) {
     int count = list.length;
     for (int i = 0; i < count; i++) {
@@ -13722,6 +13914,12 @@
   }
 
   @override
+  R visitAwaitExpression(AwaitExpression node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitBinaryExpression(BinaryExpression node) {
     node.visitChildren(this);
     return null;
@@ -14296,6 +14494,12 @@
     node.visitChildren(this);
     return null;
   }
+
+  @override
+  R visitYieldStatement(YieldStatement node) {
+    node.visitChildren(this);
+    return null;
+  }
 }
 
 /**
@@ -14793,6 +14997,9 @@
   R visitAssignmentExpression(AssignmentExpression node) => null;
 
   @override
+  R visitAwaitExpression(AwaitExpression node) => null;
+
+  @override
   R visitBinaryExpression(BinaryExpression node) => null;
 
   @override
@@ -15079,6 +15286,9 @@
 
   @override
   R visitWithClause(WithClause node) => null;
+
+  @override
+  R visitYieldStatement(YieldStatement node) => null;
 }
 
 /**
@@ -16330,6 +16540,14 @@
   }
 
   @override
+  Object visitAwaitExpression(AwaitExpression node) {
+    _writer.print("await ");
+    _visitNode(node.expression);
+    _writer.print(";");
+    return null;
+  }
+
+  @override
   Object visitBinaryExpression(BinaryExpression node) {
     _visitNode(node.leftOperand);
     _writer.print(' ');
@@ -16349,6 +16567,14 @@
 
   @override
   Object visitBlockFunctionBody(BlockFunctionBody node) {
+    Token keyword = node.keyword;
+    if (keyword != null) {
+      _writer.print(keyword.lexeme);
+      if (node.star != null) {
+        _writer.print('*');
+      }
+      _writer.print(' ');
+    }
     _visitNode(node.block);
     return null;
   }
@@ -16552,6 +16778,11 @@
 
   @override
   Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    Token keyword = node.keyword;
+    if (keyword != null) {
+      _writer.print(keyword.lexeme);
+      _writer.print(' ');
+    }
     _writer.print("=> ");
     _visitNode(node.expression);
     if (node.semicolon != null) {
@@ -16596,6 +16827,9 @@
   @override
   Object visitForEachStatement(ForEachStatement node) {
     DeclaredIdentifier loopVariable = node.loopVariable;
+    if (node.awaitKeyword != null) {
+      _writer.print("await ");
+    }
     _writer.print("for (");
     if (loopVariable == null) {
       _visitNode(node.identifier);
@@ -17203,6 +17437,18 @@
     return null;
   }
 
+  @override
+  Object visitYieldStatement(YieldStatement node) {
+    if (node.star != null) {
+      _writer.print("yield* ");
+    } else {
+      _writer.print("yield ");
+    }
+    _visitNode(node.expression);
+    _writer.print(";");
+    return null;
+  }
+
   /**
    * Visit the given function body, printing the prefix before if given body is not empty.
    *
@@ -17978,6 +18224,9 @@
   R visitAssignmentExpression(AssignmentExpression node) => visitNode(node);
 
   @override
+  R visitAwaitExpression(AwaitExpression node) => visitNode(node);
+
+  @override
   R visitBinaryExpression(BinaryExpression node) => visitNode(node);
 
   @override
@@ -18269,6 +18518,9 @@
 
   @override
   R visitWithClause(WithClause node) => visitNode(node);
+
+  @override
+  R visitYieldStatement(YieldStatement node) => visitNode(node);
 }
 
 /**
@@ -18865,6 +19117,83 @@
     _mixinTypes.accept(visitor);
   }
 }
+
+/**
+ * Instances of the class `YieldStatement` implement a yield statement.
+ */
+class YieldStatement extends Statement {
+  /**
+   * The 'yield' keyword.
+   */
+  Token yieldKeyword;
+
+  /**
+   * The star optionally following the 'yield' keyword.
+   */
+  Token star;
+
+  /**
+   * The expression whose value will be yielded.
+   */
+  Expression _expression;
+
+  /**
+   * The semicolon following the expression.
+   */
+  Token semicolon;
+
+  /**
+   * Initialize a newly created yield expression.
+   *
+   * @param yieldKeyword the 'yield' keyword
+   * @param star the star following the 'yield' keyword
+   * @param expression the expression whose value will be yielded
+   * @param semicolon the semicolon following the expression
+   */
+  YieldStatement(this.yieldKeyword, this.star, Expression expression, this.semicolon) {
+    this._expression = becomeParentOf(expression);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitYieldStatement(this);
+
+  @override
+  Token get beginToken {
+    if (yieldKeyword != null) {
+      return yieldKeyword;
+    }
+    return _expression.beginToken;
+  }
+
+  @override
+  Token get endToken {
+    if (semicolon != null) {
+      return semicolon;
+    }
+    return _expression.endToken;
+  }
+
+  /**
+   * Return the expression whose value will be yielded.
+   *
+   * @return the expression whose value will be yielded
+   */
+  Expression get expression => _expression;
+
+  /**
+   * Set the expression whose value will be yielded to the given expression.
+   *
+   * @param expression the expression whose value will be yielded
+   */
+  void set expression(Expression expression) {
+    this._expression = becomeParentOf(expression);
+  }
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    safelyVisitChild(_expression, visitor);
+  }
+}
 /**
  * Instances of the class {@code NodeList} represent a list of AST nodes that have a common parent.
  */
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index c911a76..9258a57 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -287,6 +287,11 @@
  */
 class ConstantValueComputer {
   /**
+   * Parameter to "fromEnvironment" methods that denotes the default value.
+   */
+  static String _DEFAULT_VALUE_PARAM = "defaultValue";
+
+  /**
    * The type provider used to access the known types.
    */
   TypeProvider typeProvider;
@@ -319,11 +324,17 @@
   List<InstanceCreationExpression> _constructorInvocations;
 
   /**
+   * The set of variables declared on the command line using '-D'.
+   */
+  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'
    */
-  ConstantValueComputer(TypeProvider typeProvider) {
+  ConstantValueComputer(TypeProvider typeProvider, this._declaredVariables) {
     this.typeProvider = typeProvider;
   }
 
@@ -445,6 +456,42 @@
   ConstructorDeclaration findConstructorDeclaration(ConstructorElement constructor) => 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.
+   */
+  bool _checkFromEnvironmentArguments(NodeList<Expression> arguments, List<DartObjectImpl> argumentValues, HashMap<String, DartObjectImpl> namedArgumentValues, InterfaceType expectedDefaultValueType) {
+    int argumentCount = arguments.length;
+    if (argumentCount < 1 || argumentCount > 2) {
+      return false;
+    }
+    if (arguments[0] is NamedExpression) {
+      return false;
+    }
+    if (!identical(argumentValues[0].type, typeProvider.stringType)) {
+      return false;
+    }
+    if (argumentCount == 2) {
+      if (arguments[1] is! NamedExpression) {
+        return false;
+      }
+      if (!((arguments[1] as NamedExpression).name.label.name == _DEFAULT_VALUE_PARAM)) {
+        return false;
+      }
+      InterfaceType defaultValueType = namedArgumentValues[_DEFAULT_VALUE_PARAM].type;
+      if (!(identical(defaultValueType, expectedDefaultValueType) || identical(defaultValueType, typeProvider.nullType))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
    * Compute a value for the given constant.
    *
    * @param constNode the constant for which a value is to be computed
@@ -465,7 +512,7 @@
         return;
       }
       ConstantVisitor constantVisitor = createConstantVisitor();
-      ValidResult result = _evaluateConstructorCall(expression.argumentList.arguments, constructor, constantVisitor);
+      EvaluationResultImpl result = _evaluateConstructorCall(constNode, expression.argumentList.arguments, constructor, constantVisitor);
       expression.evaluationResult = result;
     } else if (constNode is ConstructorDeclaration) {
       ConstructorDeclaration declaration = constNode;
@@ -489,7 +536,34 @@
     }
   }
 
-  ValidResult _evaluateConstructorCall(NodeList<Expression> arguments, ConstructorElement constructor, ConstantVisitor constantVisitor) {
+  /**
+   * 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 [ValidResult] object corresponding to the evaluated result
+   */
+  ValidResult _computeValueFromEnvironment(DartObject environmentValue, DartObjectImpl builtInDefaultValue, HashMap<String, DartObjectImpl> namedArgumentValues) {
+    DartObjectImpl value = environmentValue as DartObjectImpl;
+    if (value.isUnknown || value.isNull) {
+      // The name either doesn't exist in the environment or we couldn't parse the corresponding
+      // value.  If the code supplied an explicit default, use it.
+      if (namedArgumentValues.containsKey(_DEFAULT_VALUE_PARAM)) {
+        value = namedArgumentValues[_DEFAULT_VALUE_PARAM];
+      } else if (value.isNull) {
+        // The code didn't supply an explicit default.  The name exists in the environment but
+        // we couldn't parse the corresponding value.  So use the built-in default value, because
+        // this is what the VM does.
+        value = builtInDefaultValue;
+      } else {
+      }
+    }
+    return new ValidResult(value);
+  }
+
+  EvaluationResultImpl _evaluateConstructorCall(AstNode node, NodeList<Expression> arguments, ConstructorElement constructor, ConstantVisitor constantVisitor) {
     int argumentCount = arguments.length;
     List<DartObjectImpl> argumentValues = new List<DartObjectImpl>(argumentCount);
     HashMap<String, DartObjectImpl> namedArgumentValues = new HashMap<String, DartObjectImpl>();
@@ -509,10 +583,25 @@
     if (constructor.isFactory) {
       // We couldn't find a non-factory constructor.  See if it's because we reached an external
       // const factory constructor that we can emulate.
-      // TODO(paulberry): if the constructor is one of {bool,int,String}.fromEnvironment(),
-      // we may be able to infer the value based on -D flags provided to the analyzer (see
-      // dartbug.com/17234).
-      if (identical(definingClass, typeProvider.symbolType) && argumentCount == 1) {
+      if (constructor.name == "fromEnvironment") {
+        if (!_checkFromEnvironmentArguments(arguments, argumentValues, namedArgumentValues, definingClass)) {
+          return new ErrorResult.con1(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
+        }
+        String variableName = argumentCount < 1 ? null : argumentValues[0].stringValue;
+        if (identical(definingClass, typeProvider.boolType)) {
+          DartObject valueFromEnvironment;
+          valueFromEnvironment = _declaredVariables.getBool(typeProvider, variableName);
+          return _computeValueFromEnvironment(valueFromEnvironment, new DartObjectImpl(typeProvider.boolType, BoolState.FALSE_STATE), namedArgumentValues);
+        } else if (identical(definingClass, typeProvider.intType)) {
+          DartObject valueFromEnvironment;
+          valueFromEnvironment = _declaredVariables.getInt(typeProvider, variableName);
+          return _computeValueFromEnvironment(valueFromEnvironment, new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE), namedArgumentValues);
+        } else if (identical(definingClass, typeProvider.stringType)) {
+          DartObject valueFromEnvironment;
+          valueFromEnvironment = _declaredVariables.getString(typeProvider, variableName);
+          return _computeValueFromEnvironment(valueFromEnvironment, new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE), namedArgumentValues);
+        }
+      } else if (constructor.name == "" && identical(definingClass, typeProvider.symbolType) && argumentCount == 1) {
         String argumentValue = argumentValues[0].stringValue;
         if (argumentValue != null) {
           return constantVisitor._valid(definingClass, new SymbolState(argumentValue));
@@ -605,16 +694,19 @@
         if (superArguments == null) {
           superArguments = new NodeList<Expression>(null);
         }
-        _evaluateSuperConstructorCall(fieldMap, superConstructor, superArguments, initializerVisitor);
+        _evaluateSuperConstructorCall(node, fieldMap, superConstructor, superArguments, initializerVisitor);
       }
     }
     return constantVisitor._valid(definingClass, new GenericState(fieldMap));
   }
 
-  void _evaluateSuperConstructorCall(HashMap<String, DartObjectImpl> fieldMap, ConstructorElement superConstructor, NodeList<Expression> superArguments, ConstantVisitor initializerVisitor) {
+  void _evaluateSuperConstructorCall(AstNode node, HashMap<String, DartObjectImpl> fieldMap, ConstructorElement superConstructor, NodeList<Expression> superArguments, ConstantVisitor initializerVisitor) {
     if (superConstructor != null && superConstructor.isConst) {
-      ValidResult evaluationResult = _evaluateConstructorCall(superArguments, superConstructor, initializerVisitor);
-      fieldMap[GenericState.SUPERCLASS_FIELD] = evaluationResult.value;
+      EvaluationResultImpl evaluationResult = _evaluateConstructorCall(node, superArguments, superConstructor, initializerVisitor);
+      if (evaluationResult is ValidResult) {
+        ValidResult validResult = evaluationResult;
+        fieldMap[GenericState.SUPERCLASS_FIELD] = validResult.value;
+      }
     }
   }
 
@@ -1743,8 +1835,10 @@
   }
 
   /**
-   * Return the value of the variable with the given name interpreted as a boolean value, or
-   * `null` if the variable is not defined.
+   * 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
@@ -1752,35 +1846,44 @@
   DartObject getBool(TypeProvider typeProvider, String variableName) {
     String value = _declaredVariables[variableName];
     if (value == null) {
-      return null;
+      return new DartObjectImpl(typeProvider.boolType, BoolState.UNKNOWN_VALUE);
     }
     if (value == "true") {
-      return new DartObjectImpl(typeProvider.boolType, BoolState.from(true));
+      return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE);
     } else if (value == "false") {
-      return new DartObjectImpl(typeProvider.boolType, BoolState.from(false));
+      return new DartObjectImpl(typeProvider.boolType, BoolState.FALSE_STATE);
     }
-    return null;
+    return new DartObjectImpl(typeProvider.nullType, NullState.NULL_STATE);
   }
 
   /**
-   * Return the value of the variable with the given name interpreted as an integer value, or
-   * `null` if the variable is not defined.
+   * 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
-   * @throws NumberFormatException if the value of the variable is not a valid integer value
    */
   DartObject getInt(TypeProvider typeProvider, String variableName) {
     String value = _declaredVariables[variableName];
     if (value == null) {
-      return null;
+      return new DartObjectImpl(typeProvider.intType, IntState.UNKNOWN_VALUE);
     }
-    return new DartObjectImpl(typeProvider.intType, new IntState(int.parse(value)));
+    int bigInteger;
+    try {
+      bigInteger = int.parse(value);
+    } on FormatException catch (exception) {
+      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.
+   * `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
@@ -1788,7 +1891,7 @@
   DartObject getString(TypeProvider typeProvider, String variableName) {
     String value = _declaredVariables[variableName];
     if (value == null) {
-      return null;
+      return new DartObjectImpl(typeProvider.intType, IntState.UNKNOWN_VALUE);
     }
     return new DartObjectImpl(typeProvider.stringType, new StringState(value));
   }
@@ -1986,6 +2089,9 @@
   bool get isBoolNumStringOrNull => true;
 
   @override
+  bool get isUnknown => value == null;
+
+  @override
   BoolState lessThan(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
     if (value == null) {
@@ -3565,6 +3671,9 @@
   bool get isBoolNumStringOrNull => true;
 
   @override
+  bool get isUnknown => value == null;
+
+  @override
   BoolState lessThan(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
     if (value == null) {
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index a5fe2d0..fc098f7 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -18,6 +18,7 @@
 import 'html.dart' show XmlAttributeNode, XmlTagNode;
 import 'engine.dart' show AnalysisContext, AnalysisEngine, AnalysisException;
 import 'constant.dart' show EvaluationResultImpl;
+import 'resolver.dart';
 import 'utilities_dart.dart';
 
 /**
@@ -5486,6 +5487,16 @@
     return sRetType.isVoid || (tRetType as TypeImpl).isMoreSpecificThan2(sRetType, withDynamic, visitedTypePairs);
   }
 
+  /**
+   * 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
+   */
   @override
   bool isAssignableTo(DartType type) => isSubtypeOf2(type, new HashSet<TypeImpl_TypePair>());
 
@@ -7166,10 +7177,57 @@
     } else if (type is TypeParameterType) {
       return false;
     } else if (type is FunctionType) {
+      // This implementation assumes transitivity
+      // for function type subtyping on the RHS, but a literal reading
+      // of the spec does not specify this. More precisely: if T <: F1 and F1 <: F2 and
+      // F1 and F2 are function types, then we assume T <: F2.
+      //
+      // From the Function Types section of the spec:
+      //
+      //   If a type I includes an instance method named call(), and the type of call()
+      //   is the function type F, then I is considered to be a subtype of F.
+      //
+      // However, the section on Interface Types says
+      //
+      //   T is a subtype of S, written T <: S, iff [bottom/dynamic]T << S.
+      //
+      // after giving rules for << (pronounced "more specific than"). However, the "only if"
+      // direction of the "iff"
+      // in the definition of <: seems to be contradicted by the special case <: rule
+      // quoted from the Function Types section: I see no rule for << which tells us that
+      // I << F if I has call() at type F.
+      //
+      // After defining <: , the spec then
+      // emphasizes that unlike the relation <<, the relation <: is not transitive in general:
+      //
+      //   Note that <: is not a partial order on types, it is only binary relation on types.
+      //   This is because <: is not transitive. If it was, the subtype rule would have a cycle.
+      //   For example: List <: List<String> and List<int> <: List, but List<int> is not a subtype
+      //   of List<String>. Although <: is not a partial order on types, it does contain a partial
+      //   order, namely <<. This means that, barring raw types, intuition about classical subtype
+      //   rules does apply.
+      //
+      // There is no other occurrence of the word "raw" in relation to types in the spec that I can
+      // find, but presumably it's a reference to
+      //
+      //   http://docs.oracle.com/javase/tutorial/java/generics/rawTypes.html
+      //
+      // so e.g. non-generic types are never raw. As pointed out by paulberry, it's not clear
+      // whether a type like T<int, dynamic> should be considered raw or not. On the one hand, it
+      // doesn't correspond to a "raw"-in-the-Java-sense occurrence of T, which would instead
+      // be T<dynamic, dynamic>; on the other hand, it's treated differently by <: and << when
+      // occurring on the left hand side.
       ClassElement element = this.element;
-      MethodElement callMethod = element.lookUpMethod("call", element.library);
-      if (callMethod != null) {
-        return callMethod.type.isSubtypeOf(type);
+      InheritanceManager manager = new InheritanceManager(element.library);
+      FunctionType callType = manager.lookupMemberType(this, "call");
+      if (callType != null) {
+        // A more literal reading of the spec would give something like
+        //
+        //  return callType.equals(type)
+        //
+        // here, but that causes 101 errors in the external tests
+        // (tools/test.py --mode release --compiler dartanalyzer --runtime none).
+        return callType.isSubtypeOf(type);
       }
       return false;
     } else if (type is! InterfaceType) {
@@ -9751,6 +9809,13 @@
     builder.append(variable.displayName);
     super.appendTo(builder);
   }
+
+  @override
+  String get identifier {
+    String name = displayName;
+    String suffix = isGetter ? "?" : "=";
+    return "${name}${suffix}";
+  }
 }
 
 /**
@@ -10483,14 +10548,14 @@
   /**
    * 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>.
+   * 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 visitedPairs the set of pairs of types used to prevent infinite loops
+   * @param visitedTypePairs the set of pairs of types used to prevent infinite loops
    * @return `true` if this type is assignable to the given type
    */
   bool isAssignableTo2(DartType type, Set<TypeImpl_TypePair> visitedTypePairs) => isSubtypeOf2(type, visitedTypePairs) || (type as TypeImpl).isSubtypeOf2(this, visitedTypePairs);
@@ -10516,7 +10581,7 @@
    *
    * @param type the type being compared with this type
    * @param withDynamic `true` if "dynamic" should be considered as a subtype of any type
-   * @param visitedPairs the set of pairs of types used to prevent infinite loops
+   * @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
    */
   bool isMoreSpecificThan2(DartType type, bool withDynamic, Set<TypeImpl_TypePair> visitedTypePairs) {
@@ -10544,7 +10609,7 @@
    * used to prevent infinite loops.
    *
    * @param type the type being compared with this type
-   * @param visitedPairs the set of pairs of types used to prevent infinite loops
+   * @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
    */
   bool isSubtypeOf2(DartType type, Set<TypeImpl_TypePair> visitedTypePairs) {
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index c7442b8..9fcadc7 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -5601,8 +5601,26 @@
   }
 
   /**
+   * 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.
+   */
+  void _ensureElementModel(ResolvableLibrary library) {
+    Source librarySource = library.librarySource;
+    DartEntry libraryEntry = AnalysisContextImpl_this._getReadableDartEntry(librarySource);
+    if (libraryEntry != null && libraryEntry.getState(DartEntry.PARSED_UNIT) != CacheState.ERROR) {
+      AnalysisContextImpl_this._workManager.addFirst(librarySource, SourcePriority.LIBRARY);
+      if (_taskData == null) {
+        _taskData = AnalysisContextImpl_this._createResolveDartLibraryTask(librarySource, libraryEntry);
+      }
+    }
+  }
+
+  /**
    * 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.
+   * 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
    */
@@ -5613,17 +5631,12 @@
       ResolvableLibrary dependency = dependencies[i];
       if (!_librariesInCycle.contains(dependency) && visitedLibraries.add(dependency.librarySource)) {
         if (dependency.libraryElement == null) {
-          Source dependencySource = dependency.librarySource;
-          AnalysisContextImpl_this._workManager.addFirst(dependencySource, SourcePriority.LIBRARY);
-          if (_taskData == null) {
-            _taskData = AnalysisContextImpl_this._createResolveDartLibraryTask(dependencySource, AnalysisContextImpl_this._getReadableDartEntry(dependencySource));
-            return;
-          }
+          _ensureElementModel(dependency);
         } else {
           _ensureExports(dependency, visitedLibraries);
-          if (_taskData != null) {
-            return;
-          }
+        }
+        if (_taskData != null) {
+          return;
         }
       }
     }
@@ -5631,11 +5644,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.
+   * 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
-   * @throws MissingDataException if there is at least one library being depended on that does not
-   *           have an element model built for it
    */
   void _ensureImports(ResolvableLibrary library) {
     List<ResolvableLibrary> dependencies = library.imports;
@@ -5643,10 +5655,8 @@
     for (int i = 0; i < dependencyCount; i++) {
       ResolvableLibrary dependency = dependencies[i];
       if (!_librariesInCycle.contains(dependency) && dependency.libraryElement == null) {
-        Source dependencySource = dependency.librarySource;
-        AnalysisContextImpl_this._workManager.addFirst(dependencySource, SourcePriority.LIBRARY);
-        if (_taskData == null) {
-          _taskData = AnalysisContextImpl_this._createResolveDartLibraryTask(dependencySource, AnalysisContextImpl_this._getReadableDartEntry(dependencySource));
+        _ensureElementModel(dependency);
+        if (_taskData != null) {
           return;
         }
       }
@@ -6361,6 +6371,11 @@
   static bool DEFAULT_ENABLE_DEFERRED_LOADING = true;
 
   /**
+   * The default value for enabling async support.
+   */
+  static bool DEFAULT_ENABLE_ASYNC = false;
+
+  /**
    * A flag indicating whether analysis is to analyze Angular.
    */
   bool analyzeAngular = true;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 8ffc875..ffdfe0e 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -157,6 +157,15 @@
   }
 
   @override
+  AstNode visitAwaitExpression(AwaitExpression node) {
+    if (identical(_oldNode, node.expression)) {
+      // TODO(brianwilkerson) Depending on precedence, this might not be sufficient.
+      return _parser.parseExpression2();
+    }
+    return _notAChild(node);
+  }
+
+  @override
   AstNode visitBinaryExpression(BinaryExpression node) {
     if (identical(_oldNode, node.leftOperand)) {
       throw new InsufficientContextException();
@@ -1092,6 +1101,14 @@
     return _notAChild(node);
   }
 
+  @override
+  AstNode visitYieldStatement(YieldStatement node) {
+    if (identical(_oldNode, node.expression)) {
+      return _parser.parseExpression2();
+    }
+    return _notAChild(node);
+  }
+
   /**
    * Return `true` if the given assignment expression can have a cascade expression on the
    * right-hand side.
@@ -1437,11 +1454,16 @@
   bool _parseFunctionBodies = true;
 
   /**
-   * A flag indicating whether parser is to parse deferred libraries.
+   * A flag indicating whether the parser is to parse deferred libraries.
    */
   bool _parseDeferredLibraries = AnalysisOptionsImpl.DEFAULT_ENABLE_DEFERRED_LOADING;
 
   /**
+   * A flag indicating whether the parser is to parse the async support.
+   */
+  bool _parseAsync = AnalysisOptionsImpl.DEFAULT_ENABLE_ASYNC;
+
+  /**
    * The next token to be parsed.
    */
   Token _currentToken;
@@ -1462,6 +1484,10 @@
    */
   bool _inInitializer = false;
 
+  static String ASYNC = "async";
+
+  static String _AWAIT = "await";
+
   static String _HIDE = "hide";
 
   static String _OF = "of";
@@ -1472,6 +1498,10 @@
 
   static String _SHOW = "show";
 
+  static String SYNC = "sync";
+
+  static String _YIELD = "yield";
+
   /**
    * Initialize a newly created parser.
    *
@@ -1567,6 +1597,15 @@
   }
 
   /**
+   * Set whether the parser is to parse the async support.
+   *
+   * @param parseAsync `true` if the parser is to parse the async support
+   */
+  void set parseAsync(bool parseAsync) {
+    this._parseAsync = parseAsync;
+  }
+
+  /**
    * Set whether parser is to parse deferred libraries.
    *
    * @param parseDeferredLibraries `true` if parser is to parse deferred libraries
@@ -2065,7 +2104,10 @@
     if (_matchesKeyword(Keyword.THROW)) {
       return _parseThrowExpression();
     } else if (_matchesKeyword(Keyword.RETHROW)) {
+      // TODO(brianwilkerson) Rethrow is a statement again.
       return _parseRethrowExpression();
+    } else if (_parseAsync && _matchesString(_AWAIT)) {
+      return _parseAwaitExpression();
     }
     //
     // assignableExpression is a subset of conditionalExpression, so we can parse a conditional
@@ -3558,6 +3600,23 @@
   }
 
   /**
+   * Parse a await expression.
+   *
+   * <pre>
+   * awaitExpression ::=
+   *     'await' expression ';'
+   * </pre>
+   *
+   * @return the await expression that was parsed
+   */
+  AwaitExpression _parseAwaitExpression() {
+    Token awaitToken = andAdvance;
+    Expression expression = parseExpression2();
+    Token semicolon = _expect(TokenType.SEMICOLON);
+    return new AwaitExpression(awaitToken, expression, semicolon);
+  }
+
+  /**
    * Parse a bitwise and expression.
    *
    * <pre>
@@ -4637,6 +4696,10 @@
     bool wasInLoop = _inLoop;
     _inLoop = true;
     try {
+      Token awaitKeyword = null;
+      if (_matchesString(_AWAIT)) {
+        awaitKeyword = andAdvance;
+      }
       Token forKeyword = _expectKeyword(Keyword.FOR);
       Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
       VariableDeclarationList variableList = null;
@@ -4683,11 +4746,14 @@
           Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
           Statement body = parseStatement2();
           if (loopVariable == null) {
-            return new ForEachStatement.con2(forKeyword, leftParenthesis, identifier, inKeyword, iterator, rightParenthesis, body);
+            return new ForEachStatement.con2(awaitKeyword, forKeyword, leftParenthesis, identifier, inKeyword, iterator, rightParenthesis, body);
           }
-          return new ForEachStatement.con1(forKeyword, leftParenthesis, loopVariable, inKeyword, iterator, rightParenthesis, body);
+          return new ForEachStatement.con1(awaitKeyword, forKeyword, leftParenthesis, loopVariable, inKeyword, iterator, rightParenthesis, body);
         }
       }
+      if (awaitKeyword != null) {
+        _reportErrorForToken(ParserErrorCode.INVALID_AWAIT_IN_FOR, awaitKeyword, []);
+      }
       Token leftSeparator = _expect(TokenType.SEMICOLON);
       Expression condition = null;
       if (!_matches(TokenType.SEMICOLON)) {
@@ -4736,7 +4802,38 @@
           _reportErrorForCurrentToken(emptyErrorCode, []);
         }
         return new EmptyFunctionBody(andAdvance);
-      } else if (_matches(TokenType.FUNCTION)) {
+      } else if (_matchesString(_NATIVE)) {
+        Token nativeToken = andAdvance;
+        StringLiteral stringLiteral = null;
+        if (_matches(TokenType.STRING)) {
+          stringLiteral = parseStringLiteral();
+        }
+        return new NativeFunctionBody(nativeToken, stringLiteral, _expect(TokenType.SEMICOLON));
+      }
+      Token keyword = null;
+      Token star = null;
+      if (_parseAsync) {
+        if (_matchesString(ASYNC)) {
+          keyword = andAdvance;
+          if (_matches(TokenType.STAR)) {
+            star = andAdvance;
+          }
+        } else if (_matchesString(SYNC)) {
+          keyword = andAdvance;
+          if (_matches(TokenType.STAR)) {
+            star = andAdvance;
+          }
+        }
+      }
+      if (_matches(TokenType.FUNCTION)) {
+        if (keyword != null) {
+          if (!_tokenMatchesString(keyword, ASYNC)) {
+            _reportErrorForToken(ParserErrorCode.INVALID_SYNC, keyword, []);
+            keyword = null;
+          } else if (star != null) {
+            _reportErrorForToken(ParserErrorCode.INVALID_STAR_AFTER_ASYNC, star, []);
+          }
+        }
         Token functionDefinition = andAdvance;
         Expression expression = parseExpression2();
         Token semicolon = null;
@@ -4746,20 +4843,18 @@
         if (!_parseFunctionBodies) {
           return new EmptyFunctionBody(_createSyntheticToken(TokenType.SEMICOLON));
         }
-        return new ExpressionFunctionBody(functionDefinition, expression, semicolon);
+        return new ExpressionFunctionBody(keyword, functionDefinition, expression, semicolon);
       } else if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
+        if (keyword != null) {
+          if (_tokenMatchesString(keyword, SYNC) && star == null) {
+            _reportErrorForToken(ParserErrorCode.MISSING_STAR_AFTER_SYNC, keyword, []);
+          }
+        }
         if (!_parseFunctionBodies) {
           _skipBlock();
           return new EmptyFunctionBody(_createSyntheticToken(TokenType.SEMICOLON));
         }
-        return new BlockFunctionBody(parseBlock());
-      } else if (_matchesString(_NATIVE)) {
-        Token nativeToken = andAdvance;
-        StringLiteral stringLiteral = null;
-        if (_matches(TokenType.STRING)) {
-          stringLiteral = parseStringLiteral();
-        }
-        return new NativeFunctionBody(nativeToken, stringLiteral, _expect(TokenType.SEMICOLON));
+        return new BlockFunctionBody(keyword, star, parseBlock());
       } else {
         // Invalid function body
         _reportErrorForCurrentToken(emptyErrorCode, []);
@@ -5549,6 +5644,10 @@
         _reportErrorForCurrentToken(ParserErrorCode.MISSING_STATEMENT, []);
         return new EmptyStatement(_createSyntheticToken(TokenType.SEMICOLON));
       }
+    } else if (_parseAsync && _matchesString(_YIELD)) {
+      return _parseYieldStatement();
+    } else if (_parseAsync && _matchesString(_AWAIT) && _tokenMatchesKeyword(_peek(), Keyword.FOR)) {
+      return _parseForStatement();
     } else if (_matches(TokenType.SEMICOLON)) {
       return _parseEmptyStatement();
     } else if (_isInitializedVariableDeclaration()) {
@@ -6501,6 +6600,27 @@
   }
 
   /**
+   * Parse a yield statement.
+   *
+   * <pre>
+   * yieldStatement ::=
+   *     'yield' '*'? expression ';'
+   * </pre>
+   *
+   * @return the yield statement that was parsed
+   */
+  YieldStatement _parseYieldStatement() {
+    Token yieldToken = andAdvance;
+    Token star = null;
+    if (_matches(TokenType.STAR)) {
+      star = andAdvance;
+    }
+    Expression expression = parseExpression2();
+    Token semicolon = _expect(TokenType.SEMICOLON);
+    return new YieldStatement(yieldToken, star, expression, semicolon);
+  }
+
+  /**
    * Return the token that is immediately after the current token. This is equivalent to
    * [peekAt].
    *
@@ -6564,6 +6684,9 @@
    * @param arguments the arguments to the error, used to compose the error message
    */
   void _reportErrorForToken(ParserErrorCode errorCode, Token token, List<Object> arguments) {
+    if (token.type == TokenType.EOF) {
+      token = token.previous;
+    }
     _reportError(new AnalysisError.con2(_source, token.offset, Math.max(token.length, 1), errorCode, arguments));
   }
 
@@ -7036,6 +7159,15 @@
   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
+   */
+  bool _tokenMatchesString(Token token, String identifier) => token.type == TokenType.IDENTIFIER && token.lexeme == identifier;
+
+  /**
    * Translate the characters at the given index in the given string, appending the translated
    * character to the given builder. The index is assumed to be valid.
    *
@@ -7571,151 +7703,159 @@
 
   static const ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH = const ParserErrorCode.con3('INITIALIZED_VARIABLE_IN_FOR_EACH', 60, "The loop variable in a for-each loop cannot be initialized");
 
-  static const ParserErrorCode INVALID_CODE_POINT = const ParserErrorCode.con3('INVALID_CODE_POINT', 61, "The escape sequence '%s' is not a valid code point");
+  static const ParserErrorCode INVALID_AWAIT_IN_FOR = const ParserErrorCode.con4('INVALID_AWAIT_IN_FOR', 61, "The modifier 'await' is not allowed for a normal 'for' statement", "Remove the keyword or use a for-each statement.");
 
-  static const ParserErrorCode INVALID_COMMENT_REFERENCE = const ParserErrorCode.con3('INVALID_COMMENT_REFERENCE', 62, "Comment references should contain a possibly prefixed identifier and can start with 'new', but should not contain anything else");
+  static const ParserErrorCode INVALID_CODE_POINT = const ParserErrorCode.con3('INVALID_CODE_POINT', 62, "The escape sequence '%s' is not a valid code point");
 
-  static const ParserErrorCode INVALID_HEX_ESCAPE = const ParserErrorCode.con3('INVALID_HEX_ESCAPE', 63, "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
+  static const ParserErrorCode INVALID_COMMENT_REFERENCE = const ParserErrorCode.con3('INVALID_COMMENT_REFERENCE', 63, "Comment references should contain a possibly prefixed identifier and can start with 'new', but should not contain anything else");
 
-  static const ParserErrorCode INVALID_OPERATOR = const ParserErrorCode.con3('INVALID_OPERATOR', 64, "The string '%s' is not a valid operator");
+  static const ParserErrorCode INVALID_HEX_ESCAPE = const ParserErrorCode.con3('INVALID_HEX_ESCAPE', 64, "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
 
-  static const ParserErrorCode INVALID_OPERATOR_FOR_SUPER = const ParserErrorCode.con3('INVALID_OPERATOR_FOR_SUPER', 65, "The operator '%s' cannot be used with 'super'");
+  static const ParserErrorCode INVALID_OPERATOR = const ParserErrorCode.con3('INVALID_OPERATOR', 65, "The string '%s' is not a valid operator");
 
-  static const ParserErrorCode INVALID_UNICODE_ESCAPE = const ParserErrorCode.con3('INVALID_UNICODE_ESCAPE', 66, "An escape sequence starting with '\\u' must be followed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'");
+  static const ParserErrorCode INVALID_OPERATOR_FOR_SUPER = const ParserErrorCode.con3('INVALID_OPERATOR_FOR_SUPER', 66, "The operator '%s' cannot be used with 'super'");
 
-  static const ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST = const ParserErrorCode.con3('LIBRARY_DIRECTIVE_NOT_FIRST', 67, "The library directive must appear before all other directives");
+  static const ParserErrorCode INVALID_STAR_AFTER_ASYNC = const ParserErrorCode.con4('INVALID_STAR_AFTER_ASYNC', 67, "The modifier 'async*' is not allowed for an expression function body", "Convert the body to a block.");
 
-  static const ParserErrorCode LOCAL_FUNCTION_DECLARATION_MODIFIER = const ParserErrorCode.con3('LOCAL_FUNCTION_DECLARATION_MODIFIER', 68, "Local function declarations cannot specify any modifier");
+  static const ParserErrorCode INVALID_SYNC = const ParserErrorCode.con4('INVALID_SYNC', 68, "The modifier 'sync' is not allowed for an exrpression function body", "Convert the body to a block.");
 
-  static const ParserErrorCode MISSING_ASSIGNABLE_SELECTOR = const ParserErrorCode.con3('MISSING_ASSIGNABLE_SELECTOR', 69, "Missing selector such as \".<identifier>\" or \"[0]\"");
+  static const ParserErrorCode INVALID_UNICODE_ESCAPE = const ParserErrorCode.con3('INVALID_UNICODE_ESCAPE', 69, "An escape sequence starting with '\\u' must be followed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'");
 
-  static const ParserErrorCode MISSING_CATCH_OR_FINALLY = const ParserErrorCode.con3('MISSING_CATCH_OR_FINALLY', 70, "A try statement must have either a catch or finally clause");
+  static const ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST = const ParserErrorCode.con3('LIBRARY_DIRECTIVE_NOT_FIRST', 70, "The library directive must appear before all other directives");
 
-  static const ParserErrorCode MISSING_CLASS_BODY = const ParserErrorCode.con3('MISSING_CLASS_BODY', 71, "A class definition must have a body, even if it is empty");
+  static const ParserErrorCode LOCAL_FUNCTION_DECLARATION_MODIFIER = const ParserErrorCode.con3('LOCAL_FUNCTION_DECLARATION_MODIFIER', 71, "Local function declarations cannot specify any modifier");
 
-  static const ParserErrorCode MISSING_CLOSING_PARENTHESIS = const ParserErrorCode.con3('MISSING_CLOSING_PARENTHESIS', 72, "The closing parenthesis is missing");
+  static const ParserErrorCode MISSING_ASSIGNABLE_SELECTOR = const ParserErrorCode.con3('MISSING_ASSIGNABLE_SELECTOR', 72, "Missing selector such as \".<identifier>\" or \"[0]\"");
 
-  static const ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE = const ParserErrorCode.con3('MISSING_CONST_FINAL_VAR_OR_TYPE', 73, "Variables must be declared using the keywords 'const', 'final', 'var' or a type name");
+  static const ParserErrorCode MISSING_CATCH_OR_FINALLY = const ParserErrorCode.con3('MISSING_CATCH_OR_FINALLY', 73, "A try statement must have either a catch or finally clause");
 
-  static const ParserErrorCode MISSING_EXPRESSION_IN_THROW = const ParserErrorCode.con3('MISSING_EXPRESSION_IN_THROW', 74, "Throw expressions must compute the object to be thrown");
+  static const ParserErrorCode MISSING_CLASS_BODY = const ParserErrorCode.con3('MISSING_CLASS_BODY', 74, "A class definition must have a body, even if it is empty");
 
-  static const ParserErrorCode MISSING_FUNCTION_BODY = const ParserErrorCode.con3('MISSING_FUNCTION_BODY', 75, "A function body must be provided");
+  static const ParserErrorCode MISSING_CLOSING_PARENTHESIS = const ParserErrorCode.con3('MISSING_CLOSING_PARENTHESIS', 75, "The closing parenthesis is missing");
 
-  static const ParserErrorCode MISSING_FUNCTION_PARAMETERS = const ParserErrorCode.con3('MISSING_FUNCTION_PARAMETERS', 76, "Functions must have an explicit list of parameters");
+  static const ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE = const ParserErrorCode.con3('MISSING_CONST_FINAL_VAR_OR_TYPE', 76, "Variables must be declared using the keywords 'const', 'final', 'var' or a type name");
 
-  static const ParserErrorCode MISSING_GET = const ParserErrorCode.con3('MISSING_GET', 77, "Getters must have the keyword 'get' before the getter name");
+  static const ParserErrorCode MISSING_EXPRESSION_IN_THROW = const ParserErrorCode.con3('MISSING_EXPRESSION_IN_THROW', 77, "Throw expressions must compute the object to be thrown");
 
-  static const ParserErrorCode MISSING_IDENTIFIER = const ParserErrorCode.con3('MISSING_IDENTIFIER', 78, "Expected an identifier");
+  static const ParserErrorCode MISSING_FUNCTION_BODY = const ParserErrorCode.con3('MISSING_FUNCTION_BODY', 78, "A function body must be provided");
 
-  static const ParserErrorCode MISSING_KEYWORD_OPERATOR = const ParserErrorCode.con3('MISSING_KEYWORD_OPERATOR', 79, "Operator declarations must be preceeded by the keyword 'operator'");
+  static const ParserErrorCode MISSING_FUNCTION_PARAMETERS = const ParserErrorCode.con3('MISSING_FUNCTION_PARAMETERS', 79, "Functions must have an explicit list of parameters");
 
-  static const ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE = const ParserErrorCode.con3('MISSING_NAME_IN_LIBRARY_DIRECTIVE', 80, "Library directives must include a library name");
+  static const ParserErrorCode MISSING_GET = const ParserErrorCode.con3('MISSING_GET', 80, "Getters must have the keyword 'get' before the getter name");
 
-  static const ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE = const ParserErrorCode.con3('MISSING_NAME_IN_PART_OF_DIRECTIVE', 81, "Library directives must include a library name");
+  static const ParserErrorCode MISSING_IDENTIFIER = const ParserErrorCode.con3('MISSING_IDENTIFIER', 81, "Expected an identifier");
 
-  static const ParserErrorCode MISSING_PREFIX_IN_DEFERRED_IMPORT = const ParserErrorCode.con3('MISSING_PREFIX_IN_DEFERRED_IMPORT', 82, "Deferred imports must have a prefix");
+  static const ParserErrorCode MISSING_KEYWORD_OPERATOR = const ParserErrorCode.con3('MISSING_KEYWORD_OPERATOR', 82, "Operator declarations must be preceeded by the keyword 'operator'");
 
-  static const ParserErrorCode MISSING_STATEMENT = const ParserErrorCode.con3('MISSING_STATEMENT', 83, "Expected a statement");
+  static const ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE = const ParserErrorCode.con3('MISSING_NAME_IN_LIBRARY_DIRECTIVE', 83, "Library directives must include a library name");
 
-  static const ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('MISSING_TERMINATOR_FOR_PARAMETER_GROUP', 84, "There is no '%s' to close the parameter group");
+  static const ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE = const ParserErrorCode.con3('MISSING_NAME_IN_PART_OF_DIRECTIVE', 84, "Library directives must include a library name");
 
-  static const ParserErrorCode MISSING_TYPEDEF_PARAMETERS = const ParserErrorCode.con3('MISSING_TYPEDEF_PARAMETERS', 85, "Type aliases for functions must have an explicit list of parameters");
+  static const ParserErrorCode MISSING_PREFIX_IN_DEFERRED_IMPORT = const ParserErrorCode.con3('MISSING_PREFIX_IN_DEFERRED_IMPORT', 85, "Deferred imports must have a prefix");
 
-  static const ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = const ParserErrorCode.con3('MISSING_VARIABLE_IN_FOR_EACH', 86, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
+  static const ParserErrorCode MISSING_STAR_AFTER_SYNC = const ParserErrorCode.con4('MISSING_STAR_AFTER_SYNC', 86, "The modifier 'sync' must be followed by a star ('*')", "Remove the modifier or add a star.");
 
-  static const ParserErrorCode MIXED_PARAMETER_GROUPS = const ParserErrorCode.con3('MIXED_PARAMETER_GROUPS', 87, "Cannot have both positional and named parameters in a single parameter list");
+  static const ParserErrorCode MISSING_STATEMENT = const ParserErrorCode.con3('MISSING_STATEMENT', 87, "Expected a statement");
 
-  static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_EXTENDS_CLAUSES', 88, "Each class definition can have at most one extends clause");
+  static const ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('MISSING_TERMINATOR_FOR_PARAMETER_GROUP', 88, "There is no '%s' to close the parameter group");
 
-  static const ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_IMPLEMENTS_CLAUSES', 89, "Each class definition can have at most one implements clause");
+  static const ParserErrorCode MISSING_TYPEDEF_PARAMETERS = const ParserErrorCode.con3('MISSING_TYPEDEF_PARAMETERS', 89, "Type aliases for functions must have an explicit list of parameters");
 
-  static const ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_LIBRARY_DIRECTIVES', 90, "Only one library directive may be declared in a file");
+  static const ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = const ParserErrorCode.con3('MISSING_VARIABLE_IN_FOR_EACH', 90, "A loop variable must be declared in a for-each loop before the 'in', but none were found");
 
-  static const ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_NAMED_PARAMETER_GROUPS', 91, "Cannot have multiple groups of named parameters in a single parameter list");
+  static const ParserErrorCode MIXED_PARAMETER_GROUPS = const ParserErrorCode.con3('MIXED_PARAMETER_GROUPS', 91, "Cannot have both positional and named parameters in a single parameter list");
 
-  static const ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_PART_OF_DIRECTIVES', 92, "Only one part-of directive may be declared in a file");
+  static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_EXTENDS_CLAUSES', 92, "Each class definition can have at most one extends clause");
 
-  static const ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 93, "Cannot have multiple groups of positional parameters in a single parameter list");
+  static const ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = const ParserErrorCode.con3('MULTIPLE_IMPLEMENTS_CLAUSES', 93, "Each class definition can have at most one implements clause");
 
-  static const ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = const ParserErrorCode.con3('MULTIPLE_VARIABLES_IN_FOR_EACH', 94, "A single loop variable must be declared in a for-each loop before the 'in', but %s were found");
+  static const ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_LIBRARY_DIRECTIVES', 94, "Only one library directive may be declared in a file");
 
-  static const ParserErrorCode MULTIPLE_WITH_CLAUSES = const ParserErrorCode.con3('MULTIPLE_WITH_CLAUSES', 95, "Each class definition can have at most one with clause");
+  static const ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_NAMED_PARAMETER_GROUPS', 95, "Cannot have multiple groups of named parameters in a single parameter list");
+
+  static const ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES = const ParserErrorCode.con3('MULTIPLE_PART_OF_DIRECTIVES', 96, "Only one part-of directive may be declared in a file");
+
+  static const ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS = const ParserErrorCode.con3('MULTIPLE_POSITIONAL_PARAMETER_GROUPS', 97, "Cannot have multiple groups of positional parameters in a single parameter list");
+
+  static const ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH = const ParserErrorCode.con3('MULTIPLE_VARIABLES_IN_FOR_EACH', 98, "A single loop variable must be declared in a for-each loop before the 'in', but %s were found");
+
+  static const ParserErrorCode MULTIPLE_WITH_CLAUSES = const ParserErrorCode.con3('MULTIPLE_WITH_CLAUSES', 99, "Each class definition can have at most one with clause");
 
-  static const ParserErrorCode NAMED_FUNCTION_EXPRESSION = const ParserErrorCode.con3('NAMED_FUNCTION_EXPRESSION', 96, "Function expressions cannot be named");
+  static const ParserErrorCode NAMED_FUNCTION_EXPRESSION = const ParserErrorCode.con3('NAMED_FUNCTION_EXPRESSION', 100, "Function expressions cannot be named");
 
-  static const ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('NAMED_PARAMETER_OUTSIDE_GROUP', 97, "Named parameters must be enclosed in curly braces ('{' and '}')");
+  static const ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('NAMED_PARAMETER_OUTSIDE_GROUP', 101, "Named parameters must be enclosed in curly braces ('{' and '}')");
 
-  static const ParserErrorCode NATIVE_CLAUSE_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_CLAUSE_IN_NON_SDK_CODE', 98, "Native clause can only be used in the SDK and code that is loaded through native extensions");
+  static const ParserErrorCode NATIVE_CLAUSE_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_CLAUSE_IN_NON_SDK_CODE', 102, "Native clause can only be used in the SDK and code that is loaded through native extensions");
 
-  static const ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE', 99, "Native functions can only be declared in the SDK and code that is loaded through native extensions");
+  static const ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE = const ParserErrorCode.con3('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE', 103, "Native functions can only be declared in the SDK and code that is loaded through native extensions");
 
-  static const ParserErrorCode NON_CONSTRUCTOR_FACTORY = const ParserErrorCode.con3('NON_CONSTRUCTOR_FACTORY', 100, "Only constructors can be declared to be a 'factory'");
+  static const ParserErrorCode NON_CONSTRUCTOR_FACTORY = const ParserErrorCode.con3('NON_CONSTRUCTOR_FACTORY', 104, "Only constructors can be declared to be a 'factory'");
 
-  static const ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = const ParserErrorCode.con3('NON_IDENTIFIER_LIBRARY_NAME', 101, "The name of a library must be an identifier");
+  static const ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME = const ParserErrorCode.con3('NON_IDENTIFIER_LIBRARY_NAME', 105, "The name of a library must be an identifier");
 
-  static const ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = const ParserErrorCode.con3('NON_PART_OF_DIRECTIVE_IN_PART', 102, "The part-of directive must be the only directive in a part");
+  static const ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART = const ParserErrorCode.con3('NON_PART_OF_DIRECTIVE_IN_PART', 106, "The part-of directive must be the only directive in a part");
 
-  static const ParserErrorCode NON_USER_DEFINABLE_OPERATOR = const ParserErrorCode.con3('NON_USER_DEFINABLE_OPERATOR', 103, "The operator '%s' is not user definable");
+  static const ParserErrorCode NON_USER_DEFINABLE_OPERATOR = const ParserErrorCode.con3('NON_USER_DEFINABLE_OPERATOR', 107, "The operator '%s' is not user definable");
 
-  static const ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS = const ParserErrorCode.con3('NORMAL_BEFORE_OPTIONAL_PARAMETERS', 104, "Normal parameters must occur before optional parameters");
+  static const ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS = const ParserErrorCode.con3('NORMAL_BEFORE_OPTIONAL_PARAMETERS', 108, "Normal parameters must occur before optional parameters");
 
-  static const ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = const ParserErrorCode.con3('POSITIONAL_AFTER_NAMED_ARGUMENT', 105, "Positional arguments must occur before named arguments");
+  static const ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT = const ParserErrorCode.con3('POSITIONAL_AFTER_NAMED_ARGUMENT', 109, "Positional arguments must occur before named arguments");
 
-  static const ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 106, "Positional parameters must be enclosed in square brackets ('[' and ']')");
+  static const ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP = const ParserErrorCode.con3('POSITIONAL_PARAMETER_OUTSIDE_GROUP', 110, "Positional parameters must be enclosed in square brackets ('[' and ']')");
 
-  static const ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR = const ParserErrorCode.con3('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR', 107, "Only factory constructor can specify '=' redirection.");
+  static const ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR = const ParserErrorCode.con3('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR', 111, "Only factory constructor can specify '=' redirection.");
 
-  static const ParserErrorCode SETTER_IN_FUNCTION = const ParserErrorCode.con3('SETTER_IN_FUNCTION', 108, "Setters cannot be defined within methods or functions");
+  static const ParserErrorCode SETTER_IN_FUNCTION = const ParserErrorCode.con3('SETTER_IN_FUNCTION', 112, "Setters cannot be defined within methods or functions");
 
-  static const ParserErrorCode STATIC_AFTER_CONST = const ParserErrorCode.con3('STATIC_AFTER_CONST', 109, "The modifier 'static' should be before the modifier 'const'");
+  static const ParserErrorCode STATIC_AFTER_CONST = const ParserErrorCode.con3('STATIC_AFTER_CONST', 113, "The modifier 'static' should be before the modifier 'const'");
 
-  static const ParserErrorCode STATIC_AFTER_FINAL = const ParserErrorCode.con3('STATIC_AFTER_FINAL', 110, "The modifier 'static' should be before the modifier 'final'");
+  static const ParserErrorCode STATIC_AFTER_FINAL = const ParserErrorCode.con3('STATIC_AFTER_FINAL', 114, "The modifier 'static' should be before the modifier 'final'");
 
-  static const ParserErrorCode STATIC_AFTER_VAR = const ParserErrorCode.con3('STATIC_AFTER_VAR', 111, "The modifier 'static' should be before the modifier 'var'");
+  static const ParserErrorCode STATIC_AFTER_VAR = const ParserErrorCode.con3('STATIC_AFTER_VAR', 115, "The modifier 'static' should be before the modifier 'var'");
 
-  static const ParserErrorCode STATIC_CONSTRUCTOR = const ParserErrorCode.con3('STATIC_CONSTRUCTOR', 112, "Constructors cannot be static");
+  static const ParserErrorCode STATIC_CONSTRUCTOR = const ParserErrorCode.con3('STATIC_CONSTRUCTOR', 116, "Constructors cannot be static");
 
-  static const ParserErrorCode STATIC_GETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_GETTER_WITHOUT_BODY', 113, "A 'static' getter must have a body");
+  static const ParserErrorCode STATIC_GETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_GETTER_WITHOUT_BODY', 117, "A 'static' getter must have a body");
 
-  static const ParserErrorCode STATIC_OPERATOR = const ParserErrorCode.con3('STATIC_OPERATOR', 114, "Operators cannot be static");
+  static const ParserErrorCode STATIC_OPERATOR = const ParserErrorCode.con3('STATIC_OPERATOR', 118, "Operators cannot be static");
 
-  static const ParserErrorCode STATIC_SETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_SETTER_WITHOUT_BODY', 115, "A 'static' setter must have a body");
+  static const ParserErrorCode STATIC_SETTER_WITHOUT_BODY = const ParserErrorCode.con3('STATIC_SETTER_WITHOUT_BODY', 119, "A 'static' setter must have a body");
 
-  static const ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = const ParserErrorCode.con3('STATIC_TOP_LEVEL_DECLARATION', 116, "Top-level declarations cannot be declared to be 'static'");
+  static const ParserErrorCode STATIC_TOP_LEVEL_DECLARATION = const ParserErrorCode.con3('STATIC_TOP_LEVEL_DECLARATION', 120, "Top-level declarations cannot be declared to be 'static'");
 
-  static const ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE = const ParserErrorCode.con3('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE', 117, "The 'default' case should be the last case in a switch statement");
+  static const ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE = const ParserErrorCode.con3('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE', 121, "The 'default' case should be the last case in a switch statement");
 
-  static const ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES = const ParserErrorCode.con3('SWITCH_HAS_MULTIPLE_DEFAULT_CASES', 118, "The 'default' case can only be declared once");
+  static const ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES = const ParserErrorCode.con3('SWITCH_HAS_MULTIPLE_DEFAULT_CASES', 122, "The 'default' case can only be declared once");
 
-  static const ParserErrorCode TOP_LEVEL_OPERATOR = const ParserErrorCode.con3('TOP_LEVEL_OPERATOR', 119, "Operators must be declared within a class");
+  static const ParserErrorCode TOP_LEVEL_OPERATOR = const ParserErrorCode.con3('TOP_LEVEL_OPERATOR', 123, "Operators must be declared within a class");
 
-  static const ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP', 120, "There is no '%s' to open a parameter group");
+  static const ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP', 124, "There is no '%s' to open a parameter group");
 
-  static const ParserErrorCode UNEXPECTED_TOKEN = const ParserErrorCode.con3('UNEXPECTED_TOKEN', 121, "Unexpected token '%s'");
+  static const ParserErrorCode UNEXPECTED_TOKEN = const ParserErrorCode.con3('UNEXPECTED_TOKEN', 125, "Unexpected token '%s'");
 
-  static const ParserErrorCode WITH_BEFORE_EXTENDS = const ParserErrorCode.con3('WITH_BEFORE_EXTENDS', 122, "The extends clause must be before the with clause");
+  static const ParserErrorCode WITH_BEFORE_EXTENDS = const ParserErrorCode.con3('WITH_BEFORE_EXTENDS', 126, "The extends clause must be before the with clause");
 
-  static const ParserErrorCode WITH_WITHOUT_EXTENDS = const ParserErrorCode.con3('WITH_WITHOUT_EXTENDS', 123, "The with clause cannot be used without an extends clause");
+  static const ParserErrorCode WITH_WITHOUT_EXTENDS = const ParserErrorCode.con3('WITH_WITHOUT_EXTENDS', 127, "The with clause cannot be used without an extends clause");
 
-  static const ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 124, "The default value of a named parameter should be preceeded by ':'");
+  static const ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_NAMED_PARAMETER', 128, "The default value of a named parameter should be preceeded by ':'");
 
-  static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 125, "The default value of a positional parameter should be preceeded by '='");
+  static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER = const ParserErrorCode.con3('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER', 129, "The default value of a positional parameter should be preceeded by '='");
 
-  static const ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('WRONG_TERMINATOR_FOR_PARAMETER_GROUP', 126, "Expected '%s' to close parameter group");
+  static const ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP = const ParserErrorCode.con3('WRONG_TERMINATOR_FOR_PARAMETER_GROUP', 130, "Expected '%s' to close parameter group");
 
-  static const ParserErrorCode VAR_AND_TYPE = const ParserErrorCode.con3('VAR_AND_TYPE', 127, "Variables cannot be declared using both 'var' and a type name; remove the 'var'");
+  static const ParserErrorCode VAR_AND_TYPE = const ParserErrorCode.con3('VAR_AND_TYPE', 131, "Variables cannot be declared using both 'var' and a type name; remove the 'var'");
 
-  static const ParserErrorCode VAR_AS_TYPE_NAME = const ParserErrorCode.con3('VAR_AS_TYPE_NAME', 128, "The keyword 'var' cannot be used as a type name");
+  static const ParserErrorCode VAR_AS_TYPE_NAME = const ParserErrorCode.con3('VAR_AS_TYPE_NAME', 132, "The keyword 'var' cannot be used as a type name");
 
-  static const ParserErrorCode VAR_CLASS = const ParserErrorCode.con3('VAR_CLASS', 129, "Classes cannot be declared to be 'var'");
+  static const ParserErrorCode VAR_CLASS = const ParserErrorCode.con3('VAR_CLASS', 133, "Classes cannot be declared to be 'var'");
 
-  static const ParserErrorCode VAR_RETURN_TYPE = const ParserErrorCode.con3('VAR_RETURN_TYPE', 130, "The return type cannot be 'var'");
+  static const ParserErrorCode VAR_RETURN_TYPE = const ParserErrorCode.con3('VAR_RETURN_TYPE', 134, "The return type cannot be 'var'");
 
-  static const ParserErrorCode VAR_TYPEDEF = const ParserErrorCode.con3('VAR_TYPEDEF', 131, "Type aliases cannot be declared to be 'var'");
+  static const ParserErrorCode VAR_TYPEDEF = const ParserErrorCode.con3('VAR_TYPEDEF', 135, "Type aliases cannot be declared to be 'var'");
 
-  static const ParserErrorCode VOID_PARAMETER = const ParserErrorCode.con3('VOID_PARAMETER', 132, "Parameters cannot have a type of 'void'");
+  static const ParserErrorCode VOID_PARAMETER = const ParserErrorCode.con3('VOID_PARAMETER', 136, "Parameters cannot have a type of 'void'");
 
-  static const ParserErrorCode VOID_VARIABLE = const ParserErrorCode.con3('VOID_VARIABLE', 133, "Variables cannot have a type of 'void'");
+  static const ParserErrorCode VOID_VARIABLE = const ParserErrorCode.con3('VOID_VARIABLE', 137, "Variables cannot have a type of 'void'");
 
   static const List<ParserErrorCode> values = const [
       ABSTRACT_CLASS_MEMBER,
@@ -7779,11 +7919,14 @@
       IMPLEMENTS_BEFORE_WITH,
       IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE,
       INITIALIZED_VARIABLE_IN_FOR_EACH,
+      INVALID_AWAIT_IN_FOR,
       INVALID_CODE_POINT,
       INVALID_COMMENT_REFERENCE,
       INVALID_HEX_ESCAPE,
       INVALID_OPERATOR,
       INVALID_OPERATOR_FOR_SUPER,
+      INVALID_STAR_AFTER_ASYNC,
+      INVALID_SYNC,
       INVALID_UNICODE_ESCAPE,
       LIBRARY_DIRECTIVE_NOT_FIRST,
       LOCAL_FUNCTION_DECLARATION_MODIFIER,
@@ -7801,6 +7944,7 @@
       MISSING_NAME_IN_LIBRARY_DIRECTIVE,
       MISSING_NAME_IN_PART_OF_DIRECTIVE,
       MISSING_PREFIX_IN_DEFERRED_IMPORT,
+      MISSING_STAR_AFTER_SYNC,
       MISSING_STATEMENT,
       MISSING_TERMINATOR_FOR_PARAMETER_GROUP,
       MISSING_TYPEDEF_PARAMETERS,
@@ -7893,6 +8037,14 @@
    */
   const ParserErrorCode.con3(String name, int ordinal, String message) : this.con2(name, ordinal, ErrorSeverity.ERROR, message, null);
 
+  /**
+   * Initialize a newly created error code to have the given message and a severity of ERROR.
+   *
+   * @param message the message template used to create the message to be displayed for the error
+   * @param correction the template used to create the correction to be displayed for the error
+   */
+  const ParserErrorCode.con4(String name, int ordinal, String message, String correction) : this.con2(name, ordinal, ErrorSeverity.ERROR, message, correction);
+
   @override
   ErrorType get type => ErrorType.SYNTACTIC_ERROR;
 
@@ -7995,6 +8147,12 @@
   }
 
   @override
+  bool visitAwaitExpression(AwaitExpression node) {
+    AwaitExpression toNode = this._toNode as AwaitExpression;
+    return javaBooleanAnd(javaBooleanAnd(_isEqualTokens(node.awaitKeyword, toNode.awaitKeyword), _isEqualNodes(node.expression, toNode.expression)), _isEqualTokens(node.semicolon, toNode.semicolon));
+  }
+
+  @override
   bool visitBinaryExpression(BinaryExpression node) {
     BinaryExpression toNode = this._toNode as BinaryExpression;
     if (javaBooleanAnd(javaBooleanAnd(_isEqualNodes(node.leftOperand, toNode.leftOperand), _isEqualTokens(node.operator, toNode.operator)), _isEqualNodes(node.rightOperand, toNode.rightOperand))) {
@@ -8776,6 +8934,12 @@
     return javaBooleanAnd(_isEqualTokens(node.withKeyword, toNode.withKeyword), _isEqualNodeLists(node.mixinTypes, toNode.mixinTypes));
   }
 
+  @override
+  bool visitYieldStatement(YieldStatement node) {
+    YieldStatement toNode = this._toNode as YieldStatement;
+    return javaBooleanAnd(javaBooleanAnd(_isEqualTokens(node.yieldKeyword, toNode.yieldKeyword), _isEqualNodes(node.expression, toNode.expression)), _isEqualTokens(node.semicolon, toNode.semicolon));
+  }
+
   /**
    * Return `true` if the given lists of AST nodes have the same size and corresponding
    * elements are equal.
@@ -8953,6 +9117,7 @@
   'parseAssertStatement_0': new MethodTrampoline(0, (Parser target) => target._parseAssertStatement()),
   'parseAssignableExpression_1': new MethodTrampoline(1, (Parser target, arg0) => target._parseAssignableExpression(arg0)),
   'parseAssignableSelector_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target._parseAssignableSelector(arg0, arg1)),
+  'parseAwaitExpression_0': new MethodTrampoline(0, (Parser target) => target._parseAwaitExpression()),
   'parseBitwiseAndExpression_0': new MethodTrampoline(0, (Parser target) => target._parseBitwiseAndExpression()),
   'parseBitwiseXorExpression_0': new MethodTrampoline(0, (Parser target) => target._parseBitwiseXorExpression()),
   'parseBreakStatement_0': new MethodTrampoline(0, (Parser target) => target._parseBreakStatement()),
@@ -9031,6 +9196,7 @@
   'parseVariableDeclarationStatementAfterMetadata_1': new MethodTrampoline(1, (Parser target, arg0) => target._parseVariableDeclarationStatementAfterMetadata(arg0)),
   'parseVariableDeclarationStatementAfterType_3': new MethodTrampoline(3, (Parser target, arg0, arg1, arg2) => target._parseVariableDeclarationStatementAfterType(arg0, arg1, arg2)),
   'parseWhileStatement_0': new MethodTrampoline(0, (Parser target) => target._parseWhileStatement()),
+  'parseYieldStatement_0': new MethodTrampoline(0, (Parser target) => target._parseYieldStatement()),
   'peek_0': new MethodTrampoline(0, (Parser target) => target._peek()),
   'peekAt_1': new MethodTrampoline(1, (Parser target, arg0) => target._peekAt(arg0)),
   'reportError_1': new MethodTrampoline(1, (Parser target, arg0) => target._reportError(arg0)),
@@ -9052,6 +9218,7 @@
   'tokenMatches_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target._tokenMatches(arg0, arg1)),
   'tokenMatchesIdentifier_1': new MethodTrampoline(1, (Parser target, arg0) => target._tokenMatchesIdentifier(arg0)),
   'tokenMatchesKeyword_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target._tokenMatchesKeyword(arg0, arg1)),
+  'tokenMatchesString_2': new MethodTrampoline(2, (Parser target, arg0, arg1) => target._tokenMatchesString(arg0, arg1)),
   'translateCharacter_3': new MethodTrampoline(3, (Parser target, arg0, arg1, arg2) => target._translateCharacter(arg0, arg1, arg2)),
   'unlockErrorListener_0': new MethodTrampoline(0, (Parser target) => target._unlockErrorListener()),
   'validateFormalParameterList_1': new MethodTrampoline(1, (Parser target, arg0) => target._validateFormalParameterList(arg0)),
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 503dbcd..fa12291 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1400,6 +1400,9 @@
 
   @override
   Object visitInstanceCreationExpression(InstanceCreationExpression node) {
+    if (node.isConst) {
+      _validate(node, null);
+    }
     _validateInstanceCreationArguments(node);
     return super.visitInstanceCreationExpression(node);
   }
@@ -1609,7 +1612,7 @@
         ErrorCode dataErrorCode = data.errorCode;
         if (identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_INT) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM)) {
           _errorReporter.reportErrorForNode(dataErrorCode, data.node, []);
-        } else {
+        } else if (errorCode != null) {
           _errorReporter.reportErrorForNode(errorCode, data.node, []);
         }
       }
@@ -15898,7 +15901,7 @@
   void _performConstantEvaluation() {
     TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
     try {
-      ConstantValueComputer computer = new ConstantValueComputer(_typeProvider);
+      ConstantValueComputer computer = new ConstantValueComputer(_typeProvider, analysisContext.declaredVariables);
       for (Library library in _librariesInCycles) {
         for (Source source in library.compilationUnitSources) {
           try {
@@ -16350,7 +16353,7 @@
   void _performConstantEvaluation() {
     TimeCounter_TimeCounterHandle timeCounter = PerformanceStatistics.resolve.start();
     try {
-      ConstantValueComputer computer = new ConstantValueComputer(_typeProvider);
+      ConstantValueComputer computer = new ConstantValueComputer(_typeProvider, analysisContext.declaredVariables);
       for (ResolvableLibrary library in _librariesInCycle) {
         for (ResolvableCompilationUnit unit in library.resolvableCompilationUnits) {
           CompilationUnit ast = unit.compilationUnit;
@@ -19668,7 +19671,7 @@
     } finally {
       _nameScope = outerScope;
     }
-    if (functionElement.enclosingElement is! CompilationUnitElement) {
+    if (functionElement != null && functionElement.enclosingElement is! CompilationUnitElement) {
       _nameScope.define(functionElement);
     }
     return null;
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
index e01193b..9751221 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
@@ -40,13 +40,21 @@
 
   static AssignmentExpression assignmentExpression(Expression leftHandSide, TokenType operator, Expression rightHandSide) => new AssignmentExpression(leftHandSide, TokenFactory.tokenFromType(operator), rightHandSide);
 
+  static BlockFunctionBody asyncBlockFunctionBody(List<Statement> statements) => new BlockFunctionBody(TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "async"), null, block(statements));
+
+  static ExpressionFunctionBody asyncExpressionFunctionBody(Expression expression) => new ExpressionFunctionBody(TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "async"), TokenFactory.tokenFromType(TokenType.FUNCTION), expression, TokenFactory.tokenFromType(TokenType.SEMICOLON));
+
+  static BlockFunctionBody asyncGeneratorBlockFunctionBody(List<Statement> statements) => new BlockFunctionBody(TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "async"), TokenFactory.tokenFromType(TokenType.STAR), block(statements));
+
+  static AwaitExpression awaitExpression(Expression expression) => new AwaitExpression(TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "await"), expression, TokenFactory.tokenFromType(TokenType.SEMICOLON));
+
   static BinaryExpression binaryExpression(Expression leftOperand, TokenType operator, Expression rightOperand) => new BinaryExpression(leftOperand, TokenFactory.tokenFromType(operator), rightOperand);
 
   static Block block(List<Statement> statements) => new Block(TokenFactory.tokenFromType(TokenType.OPEN_CURLY_BRACKET), list(statements), TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
 
-  static BlockFunctionBody blockFunctionBody(Block block) => new BlockFunctionBody(block);
+  static BlockFunctionBody blockFunctionBody(Block block) => new BlockFunctionBody(null, null, block);
 
-  static BlockFunctionBody blockFunctionBody2(List<Statement> statements) => new BlockFunctionBody(block(statements));
+  static BlockFunctionBody blockFunctionBody2(List<Statement> statements) => new BlockFunctionBody(null, null, block(statements));
 
   static BooleanLiteral booleanLiteral(bool value) => new BooleanLiteral(value ? TokenFactory.tokenFromKeyword(Keyword.TRUE) : TokenFactory.tokenFromKeyword(Keyword.FALSE), value);
 
@@ -127,7 +135,7 @@
 
   static ExportDirective exportDirective2(String uri, List<Combinator> combinators) => exportDirective(new List<Annotation>(), uri, combinators);
 
-  static ExpressionFunctionBody expressionFunctionBody(Expression expression) => new ExpressionFunctionBody(TokenFactory.tokenFromType(TokenType.FUNCTION), expression, TokenFactory.tokenFromType(TokenType.SEMICOLON));
+  static ExpressionFunctionBody expressionFunctionBody(Expression expression) => new ExpressionFunctionBody(null, TokenFactory.tokenFromType(TokenType.FUNCTION), expression, TokenFactory.tokenFromType(TokenType.SEMICOLON));
 
   static ExpressionStatement expressionStatement(Expression expression) => new ExpressionStatement(expression, TokenFactory.tokenFromType(TokenType.SEMICOLON));
 
@@ -141,9 +149,9 @@
 
   static FieldFormalParameter fieldFormalParameter2(String identifier) => fieldFormalParameter(null, null, identifier);
 
-  static ForEachStatement forEachStatement(DeclaredIdentifier loopVariable, Expression iterator, Statement body) => new ForEachStatement.con1(TokenFactory.tokenFromKeyword(Keyword.FOR), TokenFactory.tokenFromType(TokenType.OPEN_PAREN), loopVariable, TokenFactory.tokenFromKeyword(Keyword.IN), iterator, TokenFactory.tokenFromType(TokenType.CLOSE_PAREN), body);
+  static ForEachStatement forEachStatement(DeclaredIdentifier loopVariable, Expression iterator, Statement body) => new ForEachStatement.con1(null, TokenFactory.tokenFromKeyword(Keyword.FOR), TokenFactory.tokenFromType(TokenType.OPEN_PAREN), loopVariable, TokenFactory.tokenFromKeyword(Keyword.IN), iterator, TokenFactory.tokenFromType(TokenType.CLOSE_PAREN), body);
 
-  static ForEachStatement forEachStatement2(SimpleIdentifier identifier, Expression iterator, Statement body) => new ForEachStatement.con2(TokenFactory.tokenFromKeyword(Keyword.FOR), TokenFactory.tokenFromType(TokenType.OPEN_PAREN), identifier, TokenFactory.tokenFromKeyword(Keyword.IN), iterator, TokenFactory.tokenFromType(TokenType.CLOSE_PAREN), body);
+  static ForEachStatement forEachStatement2(SimpleIdentifier identifier, Expression iterator, Statement body) => new ForEachStatement.con2(null, TokenFactory.tokenFromKeyword(Keyword.FOR), TokenFactory.tokenFromType(TokenType.OPEN_PAREN), identifier, TokenFactory.tokenFromKeyword(Keyword.IN), iterator, TokenFactory.tokenFromType(TokenType.CLOSE_PAREN), body);
 
   static FormalParameterList formalParameterList(List<FormalParameter> parameters) => new FormalParameterList(TokenFactory.tokenFromType(TokenType.OPEN_PAREN), list(parameters), null, null, TokenFactory.tokenFromType(TokenType.CLOSE_PAREN));
 
@@ -347,6 +355,10 @@
     return new SymbolLiteral(TokenFactory.tokenFromType(TokenType.HASH), new List.from(identifierList));
   }
 
+  static BlockFunctionBody syncBlockFunctionBody(List<Statement> statements) => new BlockFunctionBody(TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "sync"), null, block(statements));
+
+  static BlockFunctionBody syncGeneratorBlockFunctionBody(List<Statement> statements) => new BlockFunctionBody(TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "sync"), TokenFactory.tokenFromType(TokenType.STAR), block(statements));
+
   static ThisExpression thisExpression() => new ThisExpression(TokenFactory.tokenFromKeyword(Keyword.THIS));
 
   static ThrowExpression throwExpression() => throwExpression2(null);
@@ -425,4 +437,8 @@
   static WhileStatement whileStatement(Expression condition, Statement body) => new WhileStatement(TokenFactory.tokenFromKeyword(Keyword.WHILE), TokenFactory.tokenFromType(TokenType.OPEN_PAREN), condition, TokenFactory.tokenFromType(TokenType.CLOSE_PAREN), body);
 
   static WithClause withClause(List<TypeName> types) => new WithClause(TokenFactory.tokenFromKeyword(Keyword.WITH), list(types));
+
+  static YieldStatement yieldEachStatement(Expression expression) => new YieldStatement(TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "yield"), TokenFactory.tokenFromType(TokenType.STAR), expression, TokenFactory.tokenFromType(TokenType.SEMICOLON));
+
+  static YieldStatement yieldStatement(Expression expression) => new YieldStatement(TokenFactory.tokenFromTypeAndString(TokenType.IDENTIFIER, "yield"), null, expression, TokenFactory.tokenFromType(TokenType.SEMICOLON));
 }
\ No newline at end of file
diff --git a/pkg/analyzer/lib/src/services/formatter_impl.dart b/pkg/analyzer/lib/src/services/formatter_impl.dart
index 588464d..4b0c7e9 100644
--- a/pkg/analyzer/lib/src/services/formatter_impl.dart
+++ b/pkg/analyzer/lib/src/services/formatter_impl.dart
@@ -385,6 +385,9 @@
   /// 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;
 
@@ -423,8 +426,13 @@
 
   visitArgumentList(ArgumentList node) {
     token(node.leftParenthesis);
-    breakableNonSpace();
-    visitCommaSeparatedNodes(node.arguments);
+    if (node.arguments.isNotEmpty) {
+      int weight = lastSpaceWeight++;
+      levelSpace(weight, 0);
+      visitCommaSeparatedNodes(
+          node.arguments,
+          followedBy: () => levelSpace(weight));
+    }
     token(node.rightParenthesis);
   }
 
@@ -454,12 +462,39 @@
     });
   }
 
+  @override
+  visitAwaitExpression(AwaitExpression node) {
+    token(node.awaitKeyword);
+    space();
+    visit(node.expression);
+    // TODO(scheglov) a bug in the spec, there sould not be a ';'
+    token(node.semicolon);
+  }
+
   visitBinaryExpression(BinaryExpression node) {
-    visit(node.leftOperand);
-    space();
-    token(node.operator);
-    space();
-    visit(node.rightOperand);
+    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) {
@@ -595,15 +630,16 @@
   }
 
   visitConditionalExpression(ConditionalExpression node) {
+    int weight = lastSpaceWeight++;
     visit(node.condition);
     space();
     token(node.question);
     allowContinuedLines((){
-      space();
+      levelSpace(weight);
       visit(node.thenExpression);
       space();
       token(node.colon);
-      space();
+      levelSpace(weight);
       visit(node.elseExpression);
     });
   }
@@ -748,8 +784,9 @@
   }
 
   visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    int weight = lastSpaceWeight++;
     token(node.functionDefinition);
-    space();
+    levelSpace(weight);
     visit(node.expression);
     token(node.semicolon);
   }
@@ -1019,11 +1056,15 @@
   }
 
   visitListLiteral(ListLiteral node) {
+    int weight = lastSpaceWeight++;
     modifier(node.constKeyword);
     visit(node.typeArguments);
     token(node.leftBracket);
     indent();
-    visitCommaSeparatedNodes(node.elements /*, followedBy: breakableSpace*/);
+    levelSpace(weight, 0);
+    visitCommaSeparatedNodes(
+        node.elements,
+        followedBy: () => levelSpace(weight));
     optionalTrailingComma(node.rightBracket);
     token(node.rightBracket, precededBy: unindent);
   }
@@ -1319,14 +1360,24 @@
       space();
       token(node.equals);
       var initializer = node.initializer;
-      if (initializer is! ListLiteral && initializer is! MapLiteral) {
-        allowContinuedLines((){
+      if (initializer is ListLiteral || initializer is MapLiteral) {
+        space();
+        visit(initializer);
+      } else if (initializer is BinaryExpression) {
+        allowContinuedLines(() {
+          levelSpace(lastSpaceWeight);
+          visit(initializer);
+        });
+      } else if (initializer is ConditionalExpression) {
+        allowContinuedLines(() {
           space();
           visit(initializer);
         });
       } else {
-        space();
-        visit(initializer);
+        allowContinuedLines(() {
+          levelSpace(lastSpaceWeight++);
+          visit(initializer);
+        });
       }
     }
   }
@@ -1388,6 +1439,15 @@
     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) {
@@ -1573,6 +1633,12 @@
     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);
@@ -1583,7 +1649,7 @@
   /// 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;
+    leadingSpaces += n;
     allowLineLeadingSpaces = allowLineLeading;
     currentBreakWeight = breakWeight;
   }
@@ -1782,5 +1848,4 @@
   }
 
   String toString() => writer.toString();
-
-}
\ No newline at end of file
+}
diff --git a/pkg/analyzer/lib/src/services/writer.dart b/pkg/analyzer/lib/src/services/writer.dart
index cf0dd74..f4443cd 100644
--- a/pkg/analyzer/lib/src/services/writer.dart
+++ b/pkg/analyzer/lib/src/services/writer.dart
@@ -4,7 +4,7 @@
 
 library source_writer;
 
-
+import 'dart:math' as math;
 
 class Line {
 
@@ -84,63 +84,82 @@
     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(chunks[i], line.indentLevel));
+        buf.write(indent(chunk, chunk.indent));
       } else {
-        buf.write(chunks[i]);
+        buf.write(chunk);
       }
     }
     return buf.toString();
   }
 
-  String indent(Chunk chunk, int level) =>
-      '\n' + indenter(level + 2) + chunk.toString();
+  String indent(Chunk chunk, int level) {
+    return '\n' + indenter(level) + chunk.toString();
+  }
 
   List<Chunk> breakLine(Line line) {
-
-    var tokens = preprocess(line.tokens);
-
-    var chunks = <Chunk>[];
-
-    // The current unbroken line
-    var current = new Chunk(maxLength: maxLength);
-
-    // A tentative working chunk that will either start a new line or get
-    // absorbed into 'current'
-    var work = new Chunk(maxLength: maxLength);
-
-    tokens.forEach((tok) {
-
-      if (goodStart(tok, work)) {
-        if (current.fits(work)) {
-          current.add(work);
-        } else {
-          if (current.length > 0) {
-            chunks.add(current);
+    List<LineToken> tokens = preprocess(line.tokens);
+    List<Chunk> chunks = <Chunk>[new Chunk(line.indentLevel, maxLength, tokens)];
+    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 {
+              List<LineToken> part = [];
+              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);
           }
-          current = work;
+        } else {
+          newChunks.add(chunk);
         }
-        work = new Chunk(start: tok, maxLength: maxLength - current.length);
-      } else {
-        if (work.fits(tok)) {
-          work.add(tok);
-        } else {
-          if (!isAllWhitespace(work) || isLineStart(current)) {
-            current.add(work);
-          } else if (current.length > 0) {
-            chunks.add(current);
-            current = new Chunk(maxLength: maxLength);
-          }
-          work = new Chunk(maxLength: maxLength);
-          work.add(tok);
+        if (newChunks.length > chunks.length) {
+          hasChanges = true;
         }
       }
-
-    });
-
-    current.add(work);
-    if (current.length > 0) {
-      chunks.add(current);
+      if (!hasChanges) {
+        break;
+      }
+      chunks = newChunks;
     }
     return chunks;
   }
@@ -150,7 +169,7 @@
     var tokens = <LineToken>[];
     var curr;
 
-    tok.forEach((token){
+    tok.forEach((token) {
       if (token is! SpaceToken) {
         if (curr == null) {
           curr = token;
@@ -182,15 +201,6 @@
 
   static LineToken merge(LineToken first, LineToken second) =>
       new LineToken(first.value + second.value);
-
-  bool isAllWhitespace(Chunk chunk) => isWhitespace(chunk.buffer.toString());
-
-  bool isLineStart(chunk) => chunk.length == 0 && chunk.start == LINE_START;
-
-  /// Test whether this token is a good start for a new working chunk
-  bool goodStart(LineToken tok, Chunk workingChunk) =>
-      tok is SpaceToken && tok.breakWeight >= workingChunk.start.breakWeight;
-
 }
 
 /// Test if this [string] contains only whitespace characters
@@ -200,8 +210,8 @@
 /// Special token indicating a line start
 final LINE_START = new SpaceToken(0);
 
-const DEFAULT_SPACE_WEIGHT = 0;
-const UNBREAKABLE_SPACE_WEIGHT = -1;
+const DEFAULT_SPACE_WEIGHT = UNBREAKABLE_SPACE_WEIGHT - 1;
+const UNBREAKABLE_SPACE_WEIGHT = 100000000;
 
 /// Simple non-breaking printer
 class SimpleLinePrinter extends LinePrinter {
@@ -220,38 +230,49 @@
 /// Describes a piece of text in a [Line].
 abstract class LineText {
   int get length;
-  void addTo(Chunk chunk);
 }
 
 
 /// A working piece of text used in calculating line breaks
-class Chunk implements LineText {
+class Chunk {
+  final int indent;
+  final int maxLength;
+  final List<LineToken> tokens = <LineToken>[];
 
-  final StringBuffer buffer = new StringBuffer();
+  Chunk(this.indent, this.maxLength, [List<LineToken> tokens]) {
+    this.tokens.addAll(tokens);
+  }
 
-  int maxLength;
-  SpaceToken start;
+  int get length => tokens.fold(0, (len, token) => len + token.length);
 
-  Chunk({this.start, this.maxLength}) {
-    if (start == null) {
-      start = LINE_START;
+  bool fits(LineToken a, LineToken b) {
+    return length + a.length + a.length <= maxLength;
+  }
+
+  void add(LineToken token) {
+    tokens.add(token);
+  }
+
+  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;
   }
 
-  bool fits(LineText text) => length + text.length <= maxLength;
-
-  int get length => start.value.length + buffer.length;
-
-  void add(LineText text) {
-    text.addTo(this);
+  Chunk subChunk(int indentLevel, int start, [int end]) {
+    List<LineToken> subTokens = tokens.sublist(start, end);
+    return new Chunk(indentLevel, maxLength, subTokens);
   }
 
-  String toString() => buffer.toString();
-
-  void addTo(Chunk chunk) {
-    chunk.buffer.write(start.value);
-    chunk.buffer.write(buffer.toString());
-  }
+  String toString() => tokens.join();
 }
 
 
@@ -265,10 +286,6 @@
 
   int get length => lengthLessNewlines(value);
 
-  void addTo(Chunk chunk) {
-    chunk.buffer.write(value);
-  }
-
   int lengthLessNewlines(String str) =>
       str.endsWith('\n') ? str.length - 1 : str.length;
 
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index eabd388..386d415 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.21.0
+version: 0.21.1
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart
index fc4531b6..68fe1cb 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -1648,6 +1648,10 @@
     _assertSource("a = b", AstFactory.assignmentExpression(AstFactory.identifier3("a"), TokenType.EQ, AstFactory.identifier3("b")));
   }
 
+  void test_visitAwaitExpression() {
+    _assertSource("await e;", AstFactory.awaitExpression(AstFactory.identifier3("e")));
+  }
+
   void test_visitBinaryExpression() {
     _assertSource("a + b", AstFactory.binaryExpression(AstFactory.identifier3("a"), TokenType.PLUS, AstFactory.identifier3("b")));
   }
@@ -1660,10 +1664,26 @@
     _assertSource("{break; break;}", AstFactory.block([AstFactory.breakStatement(), AstFactory.breakStatement()]));
   }
 
-  void test_visitBlockFunctionBody() {
+  void test_visitBlockFunctionBody_async() {
+    _assertSource("async {}", AstFactory.asyncBlockFunctionBody([]));
+  }
+
+  void test_visitBlockFunctionBody_async_star() {
+    _assertSource("async* {}", AstFactory.asyncGeneratorBlockFunctionBody([]));
+  }
+
+  void test_visitBlockFunctionBody_simple() {
     _assertSource("{}", AstFactory.blockFunctionBody2([]));
   }
 
+  void test_visitBlockFunctionBody_sync() {
+    _assertSource("sync {}", AstFactory.syncBlockFunctionBody([]));
+  }
+
+  void test_visitBlockFunctionBody_sync_star() {
+    _assertSource("sync* {}", AstFactory.syncGeneratorBlockFunctionBody([]));
+  }
+
   void test_visitBooleanLiteral_false() {
     _assertSource("false", AstFactory.booleanLiteral(false));
   }
@@ -1982,7 +2002,11 @@
     _assertSource("@deprecated export 'a.dart';", directive);
   }
 
-  void test_visitExpressionFunctionBody() {
+  void test_visitExpressionFunctionBody_async() {
+    _assertSource("async => a;", AstFactory.asyncExpressionFunctionBody(AstFactory.identifier3("a")));
+  }
+
+  void test_visitExpressionFunctionBody_simple() {
     _assertSource("=> a;", AstFactory.expressionFunctionBody(AstFactory.identifier3("a")));
   }
 
@@ -2029,7 +2053,11 @@
   }
 
   void test_visitForEachStatement_variable() {
-    _assertSource("for (a in b) {}", new ForEachStatement.con2(TokenFactory.tokenFromKeyword(Keyword.FOR), TokenFactory.tokenFromType(TokenType.OPEN_PAREN), AstFactory.identifier3("a"), TokenFactory.tokenFromKeyword(Keyword.IN), AstFactory.identifier3("b"), TokenFactory.tokenFromType(TokenType.CLOSE_PAREN), AstFactory.block([])));
+    _assertSource("for (a in b) {}", new ForEachStatement.con2(null, TokenFactory.tokenFromKeyword(Keyword.FOR), TokenFactory.tokenFromType(TokenType.OPEN_PAREN), AstFactory.identifier3("a"), TokenFactory.tokenFromKeyword(Keyword.IN), AstFactory.identifier3("b"), TokenFactory.tokenFromType(TokenType.CLOSE_PAREN), AstFactory.block([])));
+  }
+
+  void test_visitForEachStatement_variable_await() {
+    _assertSource("await for (a in b) {}", new ForEachStatement.con2(TokenFactory.tokenFromString("await"), TokenFactory.tokenFromKeyword(Keyword.FOR), TokenFactory.tokenFromType(TokenType.OPEN_PAREN), AstFactory.identifier3("a"), TokenFactory.tokenFromKeyword(Keyword.IN), AstFactory.identifier3("b"), TokenFactory.tokenFromType(TokenType.CLOSE_PAREN), AstFactory.block([])));
   }
 
   void test_visitFormalParameterList_empty() {
@@ -2790,6 +2818,14 @@
     _assertSource("with A", AstFactory.withClause([AstFactory.typeName4("A", [])]));
   }
 
+  void test_visitYieldStatement() {
+    _assertSource("yield e;", AstFactory.yieldStatement(AstFactory.identifier3("e")));
+  }
+
+  void test_visitYieldStatement_each() {
+    _assertSource("yield* e;", AstFactory.yieldEachStatement(AstFactory.identifier3("e")));
+  }
+
   /**
    * Assert that a `ToSourceVisitor` will produce the expected source when visiting the given
    * node.
@@ -2834,13 +2870,33 @@
         final __test = new ToSourceVisitorTest();
         runJUnitTest(__test, __test.test_visitAssignmentExpression);
       });
+      _ut.test('test_visitAwaitExpression', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitAwaitExpression);
+      });
       _ut.test('test_visitBinaryExpression', () {
         final __test = new ToSourceVisitorTest();
         runJUnitTest(__test, __test.test_visitBinaryExpression);
       });
-      _ut.test('test_visitBlockFunctionBody', () {
+      _ut.test('test_visitBlockFunctionBody_async', () {
         final __test = new ToSourceVisitorTest();
-        runJUnitTest(__test, __test.test_visitBlockFunctionBody);
+        runJUnitTest(__test, __test.test_visitBlockFunctionBody_async);
+      });
+      _ut.test('test_visitBlockFunctionBody_async_star', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBlockFunctionBody_async_star);
+      });
+      _ut.test('test_visitBlockFunctionBody_simple', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBlockFunctionBody_simple);
+      });
+      _ut.test('test_visitBlockFunctionBody_sync', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBlockFunctionBody_sync);
+      });
+      _ut.test('test_visitBlockFunctionBody_sync_star', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitBlockFunctionBody_sync_star);
       });
       _ut.test('test_visitBlock_empty', () {
         final __test = new ToSourceVisitorTest();
@@ -3146,9 +3202,13 @@
         final __test = new ToSourceVisitorTest();
         runJUnitTest(__test, __test.test_visitExportDirective_withMetadata);
       });
-      _ut.test('test_visitExpressionFunctionBody', () {
+      _ut.test('test_visitExpressionFunctionBody_async', () {
         final __test = new ToSourceVisitorTest();
-        runJUnitTest(__test, __test.test_visitExpressionFunctionBody);
+        runJUnitTest(__test, __test.test_visitExpressionFunctionBody_async);
+      });
+      _ut.test('test_visitExpressionFunctionBody_simple', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitExpressionFunctionBody_simple);
       });
       _ut.test('test_visitExpressionStatement', () {
         final __test = new ToSourceVisitorTest();
@@ -3194,6 +3254,10 @@
         final __test = new ToSourceVisitorTest();
         runJUnitTest(__test, __test.test_visitForEachStatement_variable);
       });
+      _ut.test('test_visitForEachStatement_variable_await', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitForEachStatement_variable_await);
+      });
       _ut.test('test_visitForStatement_c', () {
         final __test = new ToSourceVisitorTest();
         runJUnitTest(__test, __test.test_visitForStatement_c);
@@ -3858,6 +3922,14 @@
         final __test = new ToSourceVisitorTest();
         runJUnitTest(__test, __test.test_visitWithClause_single);
       });
+      _ut.test('test_visitYieldStatement', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitYieldStatement);
+      });
+      _ut.test('test_visitYieldStatement_each', () {
+        final __test = new ToSourceVisitorTest();
+        runJUnitTest(__test, __test.test_visitYieldStatement_each);
+      });
     });
   }
 }
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 3a9c2c3..83e7eaf 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -913,6 +913,10 @@
     ParserTestCase.parse3("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "4 score", [ParserErrorCode.EXPECTED_EXECUTABLE]);
   }
 
+  void test_expectedExecutable_topLevel_eof() {
+    ParserTestCase.parse2("parseCompilationUnitMember", <Object> [emptyCommentAndMetadata()], "x", [new AnalysisError.con2(null, 0, 1, ParserErrorCode.EXPECTED_EXECUTABLE, [])]);
+  }
+
   void test_expectedInterpolationIdentifier() {
     ParserTestCase.parse4("parseStringLiteral", "'\$x\$'", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
@@ -1141,6 +1145,10 @@
     ParserTestCase.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]);
+  }
+
   void test_invalidCodePoint() {
     ParserTestCase.parse4("parseStringLiteral", "'\\uD900'", [ParserErrorCode.INVALID_CODE_POINT]);
   }
@@ -1165,6 +1173,14 @@
     ParserTestCase.parse4("parseUnaryExpression", "++super", [ParserErrorCode.INVALID_OPERATOR_FOR_SUPER]);
   }
 
+  void test_invalidStarAfterAsync() {
+    ParserTestCase.parse3("parseFunctionBody", <Object> [false, null, false], "async* => 0;", [ParserErrorCode.INVALID_STAR_AFTER_ASYNC]);
+  }
+
+  void test_invalidSync() {
+    ParserTestCase.parse3("parseFunctionBody", <Object> [false, null, false], "sync* => 0;", [ParserErrorCode.INVALID_SYNC]);
+  }
+
   void test_invalidUnicodeEscape_incomplete_noDigits() {
     ParserTestCase.parse4("parseStringLiteral", "'\\u{'", [ParserErrorCode.INVALID_UNICODE_ESCAPE]);
   }
@@ -1355,6 +1371,10 @@
     ParserTestCase.parseCompilationUnit("import 'foo.dart' deferred;", [ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT]);
   }
 
+  void test_missingStartAfterSync() {
+    ParserTestCase.parse3("parseFunctionBody", <Object> [false, null, false], "sync {}", [ParserErrorCode.MISSING_STAR_AFTER_SYNC]);
+  }
+
   void test_missingStatement() {
     ParserTestCase.parseStatement("is", [ParserErrorCode.MISSING_STATEMENT]);
   }
@@ -1940,6 +1960,10 @@
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_expectedExecutable_topLevel_beforeType);
       });
+      _ut.test('test_expectedExecutable_topLevel_eof', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_expectedExecutable_topLevel_eof);
+      });
       _ut.test('test_expectedInterpolationIdentifier', () {
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_expectedInterpolationIdentifier);
@@ -2148,6 +2172,10 @@
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_initializedVariableInForEach);
       });
+      _ut.test('test_invalidAwaitInFor', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidAwaitInFor);
+      });
       _ut.test('test_invalidCodePoint', () {
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_invalidCodePoint);
@@ -2172,6 +2200,14 @@
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_invalidOperatorForSuper);
       });
+      _ut.test('test_invalidStarAfterAsync', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidStarAfterAsync);
+      });
+      _ut.test('test_invalidSync', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_invalidSync);
+      });
       _ut.test('test_invalidUnicodeEscape_incomplete_noDigits', () {
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_invalidUnicodeEscape_incomplete_noDigits);
@@ -2352,6 +2388,10 @@
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_missingPrefixInDeferredImport);
       });
+      _ut.test('test_missingStartAfterSync', () {
+        final __test = new ErrorParserTest();
+        runJUnitTest(__test, __test.test_missingStartAfterSync);
+      });
       _ut.test('test_missingStatement', () {
         final __test = new ErrorParserTest();
         runJUnitTest(__test, __test.test_missingStatement);
@@ -3296,6 +3336,7 @@
     Parser parser = new Parser(null, listener);
     parser.parseFunctionBodies = parseFunctionBodies;
     parser.parseDeferredLibraries = true;
+    parser.parseAsync = true;
     Object result = invokeParserMethodImpl(parser, methodName, objects, tokenStream);
     //
     // Partially test the results.
@@ -5555,6 +5596,13 @@
     JUnitTestCase.assertNotNull(selector);
   }
 
+  void test_parseAwaitExpression() {
+    AwaitExpression expression = ParserTestCase.parse4("parseAwaitExpression", "await x;", []);
+    JUnitTestCase.assertNotNull(expression.awaitKeyword);
+    JUnitTestCase.assertNotNull(expression.expression);
+    JUnitTestCase.assertNotNull(expression.semicolon);
+  }
+
   void test_parseBitwiseAndExpression_normal() {
     BinaryExpression expression = ParserTestCase.parse4("parseBitwiseAndExpression", "x & y", []);
     JUnitTestCase.assertNotNull(expression.leftOperand);
@@ -7428,8 +7476,22 @@
     JUnitTestCase.assertNotNull(parameterList.rightParenthesis);
   }
 
+  void test_parseForStatement_each_await() {
+    ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "await for (element in list) {}", []);
+    JUnitTestCase.assertNotNull(statement.awaitKeyword);
+    JUnitTestCase.assertNotNull(statement.forKeyword);
+    JUnitTestCase.assertNotNull(statement.leftParenthesis);
+    JUnitTestCase.assertNull(statement.loopVariable);
+    JUnitTestCase.assertNotNull(statement.identifier);
+    JUnitTestCase.assertNotNull(statement.inKeyword);
+    JUnitTestCase.assertNotNull(statement.iterator);
+    JUnitTestCase.assertNotNull(statement.rightParenthesis);
+    JUnitTestCase.assertNotNull(statement.body);
+  }
+
   void test_parseForStatement_each_identifier() {
     ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (element in list) {}", []);
+    JUnitTestCase.assertNull(statement.awaitKeyword);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNull(statement.loopVariable);
@@ -7442,6 +7504,7 @@
 
   void test_parseForStatement_each_noType_metadata() {
     ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (@A var element in list) {}", []);
+    JUnitTestCase.assertNull(statement.awaitKeyword);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.loopVariable);
@@ -7455,6 +7518,7 @@
 
   void test_parseForStatement_each_type() {
     ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (A element in list) {}", []);
+    JUnitTestCase.assertNull(statement.awaitKeyword);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.loopVariable);
@@ -7467,6 +7531,7 @@
 
   void test_parseForStatement_each_var() {
     ForEachStatement statement = ParserTestCase.parse4("parseForStatement", "for (var element in list) {}", []);
+    JUnitTestCase.assertNull(statement.awaitKeyword);
     JUnitTestCase.assertNotNull(statement.forKeyword);
     JUnitTestCase.assertNotNull(statement.leftParenthesis);
     JUnitTestCase.assertNotNull(statement.loopVariable);
@@ -7633,7 +7698,45 @@
 
   void test_parseFunctionBody_block() {
     BlockFunctionBody functionBody = ParserTestCase.parse("parseFunctionBody", <Object> [false, null, false], "{}");
+    JUnitTestCase.assertNull(functionBody.keyword);
+    JUnitTestCase.assertNull(functionBody.star);
     JUnitTestCase.assertNotNull(functionBody.block);
+    JUnitTestCase.assertFalse(functionBody.isAsynchronous);
+    JUnitTestCase.assertFalse(functionBody.isGenerator);
+    JUnitTestCase.assertTrue(functionBody.isSynchronous);
+  }
+
+  void test_parseFunctionBody_block_async() {
+    BlockFunctionBody functionBody = ParserTestCase.parse("parseFunctionBody", <Object> [false, null, false], "async {}");
+    JUnitTestCase.assertNotNull(functionBody.keyword);
+    JUnitTestCase.assertEquals(Parser.ASYNC, functionBody.keyword.lexeme);
+    JUnitTestCase.assertNull(functionBody.star);
+    JUnitTestCase.assertNotNull(functionBody.block);
+    JUnitTestCase.assertTrue(functionBody.isAsynchronous);
+    JUnitTestCase.assertFalse(functionBody.isGenerator);
+    JUnitTestCase.assertFalse(functionBody.isSynchronous);
+  }
+
+  void test_parseFunctionBody_block_asyncGenerator() {
+    BlockFunctionBody functionBody = ParserTestCase.parse("parseFunctionBody", <Object> [false, null, false], "async* {}");
+    JUnitTestCase.assertNotNull(functionBody.keyword);
+    JUnitTestCase.assertEquals(Parser.ASYNC, functionBody.keyword.lexeme);
+    JUnitTestCase.assertNotNull(functionBody.star);
+    JUnitTestCase.assertNotNull(functionBody.block);
+    JUnitTestCase.assertTrue(functionBody.isAsynchronous);
+    JUnitTestCase.assertTrue(functionBody.isGenerator);
+    JUnitTestCase.assertFalse(functionBody.isSynchronous);
+  }
+
+  void test_parseFunctionBody_block_syncGenerator() {
+    BlockFunctionBody functionBody = ParserTestCase.parse("parseFunctionBody", <Object> [false, null, false], "sync* {}");
+    JUnitTestCase.assertNotNull(functionBody.keyword);
+    JUnitTestCase.assertEquals(Parser.SYNC, functionBody.keyword.lexeme);
+    JUnitTestCase.assertNotNull(functionBody.star);
+    JUnitTestCase.assertNotNull(functionBody.block);
+    JUnitTestCase.assertFalse(functionBody.isAsynchronous);
+    JUnitTestCase.assertTrue(functionBody.isGenerator);
+    JUnitTestCase.assertTrue(functionBody.isSynchronous);
   }
 
   void test_parseFunctionBody_empty() {
@@ -7643,9 +7746,25 @@
 
   void test_parseFunctionBody_expression() {
     ExpressionFunctionBody functionBody = ParserTestCase.parse("parseFunctionBody", <Object> [false, null, false], "=> y;");
+    JUnitTestCase.assertNull(functionBody.keyword);
     JUnitTestCase.assertNotNull(functionBody.functionDefinition);
     JUnitTestCase.assertNotNull(functionBody.expression);
     JUnitTestCase.assertNotNull(functionBody.semicolon);
+    JUnitTestCase.assertFalse(functionBody.isAsynchronous);
+    JUnitTestCase.assertFalse(functionBody.isGenerator);
+    JUnitTestCase.assertTrue(functionBody.isSynchronous);
+  }
+
+  void test_parseFunctionBody_expression_async() {
+    ExpressionFunctionBody functionBody = ParserTestCase.parse("parseFunctionBody", <Object> [false, null, false], "async => y;");
+    JUnitTestCase.assertNotNull(functionBody.keyword);
+    JUnitTestCase.assertEquals(Parser.ASYNC, functionBody.keyword.lexeme);
+    JUnitTestCase.assertNotNull(functionBody.functionDefinition);
+    JUnitTestCase.assertNotNull(functionBody.expression);
+    JUnitTestCase.assertNotNull(functionBody.semicolon);
+    JUnitTestCase.assertTrue(functionBody.isAsynchronous);
+    JUnitTestCase.assertFalse(functionBody.isGenerator);
+    JUnitTestCase.assertFalse(functionBody.isSynchronous);
   }
 
   void test_parseFunctionBody_nativeFunctionBody() {
@@ -9463,6 +9582,22 @@
     EngineTestCase.assertSizeOfList(1, clause.mixinTypes);
   }
 
+  void test_parseYieldStatement_each() {
+    YieldStatement statement = ParserTestCase.parse4("parseYieldStatement", "yield* x;", []);
+    JUnitTestCase.assertNotNull(statement.yieldKeyword);
+    JUnitTestCase.assertNotNull(statement.star);
+    JUnitTestCase.assertNotNull(statement.expression);
+    JUnitTestCase.assertNotNull(statement.semicolon);
+  }
+
+  void test_parseYieldStatement_normal() {
+    YieldStatement statement = ParserTestCase.parse4("parseYieldStatement", "yield x;", []);
+    JUnitTestCase.assertNotNull(statement.yieldKeyword);
+    JUnitTestCase.assertNull(statement.star);
+    JUnitTestCase.assertNotNull(statement.expression);
+    JUnitTestCase.assertNotNull(statement.semicolon);
+  }
+
   void test_skipPrefixedIdentifier_invalid() {
     Token following = _skip("skipPrefixedIdentifier", "+");
     JUnitTestCase.assertNull(following);
@@ -10109,6 +10244,10 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseAssignableSelector_none);
       });
+      _ut.test('test_parseAwaitExpression', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseAwaitExpression);
+      });
       _ut.test('test_parseBitwiseAndExpression_normal', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseBitwiseAndExpression_normal);
@@ -10853,6 +10992,10 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseFinalConstVarOrType_var);
       });
+      _ut.test('test_parseForStatement_each_await', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseForStatement_each_await);
+      });
       _ut.test('test_parseForStatement_each_identifier', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseForStatement_each_identifier);
@@ -10985,6 +11128,18 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseFunctionBody_block);
       });
+      _ut.test('test_parseFunctionBody_block_async', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionBody_block_async);
+      });
+      _ut.test('test_parseFunctionBody_block_asyncGenerator', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionBody_block_asyncGenerator);
+      });
+      _ut.test('test_parseFunctionBody_block_syncGenerator', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionBody_block_syncGenerator);
+      });
       _ut.test('test_parseFunctionBody_empty', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseFunctionBody_empty);
@@ -10993,6 +11148,10 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseFunctionBody_expression);
       });
+      _ut.test('test_parseFunctionBody_expression_async', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseFunctionBody_expression_async);
+      });
       _ut.test('test_parseFunctionBody_nativeFunctionBody', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseFunctionBody_nativeFunctionBody);
@@ -11889,6 +12048,14 @@
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_parseWithClause_single);
       });
+      _ut.test('test_parseYieldStatement_each', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseYieldStatement_each);
+      });
+      _ut.test('test_parseYieldStatement_normal', () {
+        final __test = new SimpleParserTest();
+        runJUnitTest(__test, __test.test_parseYieldStatement_normal);
+      });
       _ut.test('test_skipPrefixedIdentifier_invalid', () {
         final __test = new SimpleParserTest();
         runJUnitTest(__test, __test.test_skipPrefixedIdentifier_invalid);
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 3879cf3..a097820 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -1636,6 +1636,31 @@
     verify([source]);
   }
 
+  void test_fromEnvironment_bool_badArgs() {
+    Source source = addSource(EngineTestCase.createSource([
+        "var b1 = const bool.fromEnvironment(1);",
+        "var b2 = const bool.fromEnvironment('x', defaultValue: 1);"]));
+    resolve(source);
+    assertErrors(source, [
+        CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+        StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+        CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+        StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+
+  void test_fromEnvironment_bool_badDefault_whenDefined() {
+    // The type of the defaultValue needs to be correct even when the default value
+    // isn't used (because the variable is defined in the environment).
+    analysisContext2.declaredVariables.define("x", "true");
+    Source source = addSource(EngineTestCase.createSource(["var b = const bool.fromEnvironment('x', defaultValue: 1);"]));
+    resolve(source);
+    assertErrors(source, [
+        CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+        StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+    verify([source]);
+  }
+
   void test_getterAndMethodWithSameName() {
     Source source = addSource(EngineTestCase.createSource(["class A {", "  x(y) {}", "  get x => 0;", "}"]));
     resolve(source);
@@ -4573,6 +4598,14 @@
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_finalNotInitialized_local_const);
       });
+      _ut.test('test_fromEnvironment_bool_badArgs', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_fromEnvironment_bool_badArgs);
+      });
+      _ut.test('test_fromEnvironment_bool_badDefault_whenDefined', () {
+        final __test = new CompileTimeErrorCodeTest();
+        runJUnitTest(__test, __test.test_fromEnvironment_bool_badDefault_whenDefined);
+      });
       _ut.test('test_getterAndMethodWithSameName', () {
         final __test = new CompileTimeErrorCodeTest();
         runJUnitTest(__test, __test.test_getterAndMethodWithSameName);
@@ -10184,27 +10217,6 @@
 }
 
 class NonErrorResolverTest extends ResolverTestCase {
-  void fail_invalidAssignment_implicitlyImplementFunctionViaCall_2() {
-    // 18341
-    //
-    // Here 'C' checks as a subtype of 'I', but 'C' does not
-    // check as a subtype of 'IntToInt'. Together with
-    // 'test_invalidAssignment_implicitlyImplementFunctionViaCall_1()' we see
-    // that subtyping is not transitive here.
-    Source source = addSource(EngineTestCase.createSource([
-        "class I {",
-        "  int call(int x) => 0;",
-        "}",
-        "class C implements I {",
-        "  noSuchMethod(_) => null;",
-        "}",
-        "typedef int IntToInt(int x);",
-        "IntToInt f = new C();"]));
-    resolve(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
   void test_ambiguousExport() {
     Source source = addSource(EngineTestCase.createSource([
         "library L;",
@@ -11805,7 +11817,7 @@
   void test_invalidAssignment_implicitlyImplementFunctionViaCall_1() {
     // 18341
     //
-    // This test and 'fail/test_invalidAssignment_implicitlyImplementFunctionViaCall_2()'
+    // This test and 'test_invalidAssignment_implicitlyImplementFunctionViaCall_2()'
     // are closely related: here we see that 'I' checks as a subtype of 'IntToInt'.
     Source source = addSource(EngineTestCase.createSource([
         "class I {",
@@ -11821,10 +11833,31 @@
     verify([source]);
   }
 
+  void test_invalidAssignment_implicitlyImplementFunctionViaCall_2() {
+    // 18341
+    //
+    // Here 'C' checks as a subtype of 'I', but 'C' does not
+    // check as a subtype of 'IntToInt'. Together with
+    // 'test_invalidAssignment_implicitlyImplementFunctionViaCall_1()' we see
+    // that subtyping is not transitive here.
+    Source source = addSource(EngineTestCase.createSource([
+        "class I {",
+        "  int call(int x) => 0;",
+        "}",
+        "class C implements I {",
+        "  noSuchMethod(_) => null;",
+        "}",
+        "typedef int IntToInt(int x);",
+        "IntToInt f = new C();"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_invalidAssignment_implicitlyImplementFunctionViaCall_3() {
     // 18341
     //
-    // Like 'fail/test_invalidAssignment_implicitlyImplementFunctionViaCall_2()',
+    // Like 'test_invalidAssignment_implicitlyImplementFunctionViaCall_2()',
     // but uses type 'Function' instead of more precise type 'IntToInt' for 'f'.
     Source source = addSource(EngineTestCase.createSource([
         "class I {",
@@ -11840,6 +11873,30 @@
     verify([source]);
   }
 
+  void test_invalidAssignment_implicitlyImplementFunctionViaCall_4() {
+    // 18341
+    //
+    // Like 'test_invalidAssignment_implicitlyImplementFunctionViaCall_2()',
+    // but uses type 'VoidToInt' instead of more precise type 'IntToInt' for 'f'.
+    //
+    // Here 'C <: IntToInt <: VoidToInt', but the spec gives no transitivity rule
+    // for '<:'. However, many of the :/tools/test.py tests assume this transitivity
+    // for 'JsBuilder' objects, assigning them to '(String) -> dynamic'. The declared type of
+    // 'JsBuilder.call' is '(String, [dynamic]) -> Expression'.
+    Source source = addSource(EngineTestCase.createSource([
+        "class I {",
+        "  int call([int x]) => 0;",
+        "}",
+        "class C implements I {",
+        "  noSuchMethod(_) => null;",
+        "}",
+        "typedef int VoidToInt();",
+        "VoidToInt f = new C();"]));
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_invalidAssignment_toDynamic() {
     Source source = addSource(EngineTestCase.createSource(["f() {", "  var g;", "  g = () => 0;", "}"]));
     resolve(source);
@@ -14754,10 +14811,18 @@
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_invalidAssignment_implicitlyImplementFunctionViaCall_1);
       });
+      _ut.test('test_invalidAssignment_implicitlyImplementFunctionViaCall_2', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_invalidAssignment_implicitlyImplementFunctionViaCall_2);
+      });
       _ut.test('test_invalidAssignment_implicitlyImplementFunctionViaCall_3', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_invalidAssignment_implicitlyImplementFunctionViaCall_3);
       });
+      _ut.test('test_invalidAssignment_implicitlyImplementFunctionViaCall_4', () {
+        final __test = new NonErrorResolverTest();
+        runJUnitTest(__test, __test.test_invalidAssignment_implicitlyImplementFunctionViaCall_4);
+      });
       _ut.test('test_invalidAssignment_toDynamic', () {
         final __test = new NonErrorResolverTest();
         runJUnitTest(__test, __test.test_invalidAssignment_toDynamic);
@@ -25946,7 +26011,14 @@
   @override
   InterfaceType get boolType {
     if (_boolType == null) {
-      _boolType = ElementFactory.classElement2("bool", []).type;
+      ClassElementImpl boolElement = ElementFactory.classElement2("bool", []);
+      _boolType = boolElement.type;
+      ConstructorElementImpl fromEnvironment = ElementFactory.constructorElement(boolElement, "fromEnvironment", true, []);
+      fromEnvironment.parameters = <ParameterElement> [
+          ElementFactory.requiredParameter2("name", stringType),
+          ElementFactory.namedParameter2("defaultValue", _boolType)];
+      fromEnvironment.factory = true;
+      boolElement.constructors = <ConstructorElement> [fromEnvironment];
     }
     return _boolType;
   }
@@ -26114,6 +26186,12 @@
           ElementFactory.methodElement("+", _stringType, [_stringType]),
           ElementFactory.methodElement("toLowerCase", _stringType, []),
           ElementFactory.methodElement("toUpperCase", _stringType, [])];
+      ConstructorElementImpl fromEnvironment = ElementFactory.constructorElement(stringElement, "fromEnvironment", true, []);
+      fromEnvironment.parameters = <ParameterElement> [
+          ElementFactory.requiredParameter2("name", stringType),
+          ElementFactory.namedParameter2("defaultValue", _stringType)];
+      fromEnvironment.factory = true;
+      stringElement.constructors = <ConstructorElement> [fromEnvironment];
     }
     return _stringType;
   }
@@ -26203,6 +26281,12 @@
         ElementFactory.methodElement("ceil", _intType, []),
         ElementFactory.methodElement("truncate", _intType, []),
         ElementFactory.methodElement("toString", _stringType, [])];
+    ConstructorElementImpl fromEnvironment = ElementFactory.constructorElement(intElement, "fromEnvironment", true, []);
+    fromEnvironment.parameters = <ParameterElement> [
+        ElementFactory.requiredParameter2("name", stringType),
+        ElementFactory.namedParameter2("defaultValue", _intType)];
+    fromEnvironment.factory = true;
+    intElement.constructors = <ConstructorElement> [fromEnvironment];
     List<FieldElement> fields = <FieldElement> [
         ElementFactory.fieldElement("NAN", true, false, true, _doubleType),
         ElementFactory.fieldElement("INFINITY", true, false, true, _doubleType),
diff --git a/pkg/analyzer/test/services/data/stmt_tests.data b/pkg/analyzer/test/services/data/stmt_tests.data
index 3143fe1..d1cf4cc 100644
--- a/pkg/analyzer/test/services/data/stmt_tests.data
+++ b/pkg/analyzer/test/services/data/stmt_tests.data
@@ -34,10 +34,12 @@
   print(x);
 }
 >>>
-var primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71];
+List<int> numbers = <int>[a012345678901234567890123456789, b012345678901234567890123456789, c012345678901234567890123456789];
 <<<
-var primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
-    61, 67, 71];
+List<int> numbers = <int>[
+    a012345678901234567890123456789,
+    b012345678901234567890123456789,
+    c012345678901234567890123456789];
 >>>
 blah() {
   print('blah blah blah blah blah blah blah blah blah blah blah blah blah blah $foo');
@@ -193,12 +195,13 @@
 }
 >>>
 main() {
-  f(a, b) {}
-  f(0000000000000000000000000000000000000000000000000000000000000000000000, 111);
+  printNumbers(a, b) {}
+  printNumbers(00000000000000000000000000000000000000000000000000000000000, 111);
 }
 <<<
 main() {
-  f(a, b) {}
-  f(0000000000000000000000000000000000000000000000000000000000000000000000,
+  printNumbers(a, b) {}
+  printNumbers(
+      00000000000000000000000000000000000000000000000000000000000,
       111);
 }
diff --git a/pkg/analyzer/test/services/data/wrap_tests.data b/pkg/analyzer/test/services/data/wrap_tests.data
new file mode 100644
index 0000000..9d21517
--- /dev/null
+++ b/pkg/analyzer/test/services/data/wrap_tests.data
@@ -0,0 +1,95 @@
+>>> list literal
+main() {
+  List<String> values = <String>[a0123456789012345, b0123456789012345, c0123456789012345, d0123456789012345];
+}
+<<<
+main() {
+  List<String> values = <String>[
+      a0123456789012345,
+      b0123456789012345,
+      c0123456789012345,
+      d0123456789012345];
+}
+>>> operators
+main() {
+  int result = a0123456789012345 * b0123456789012345 + c0123456789012345 * d0123456789012345;
+}
+<<<
+main() {
+  int result =
+      a0123456789012345 * b0123456789012345 +
+      c0123456789012345 * d0123456789012345;
+}
+>>> 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
index 5298d73..c4907ac 100644
--- a/pkg/analyzer/test/services/formatter_test.dart
+++ b/pkg/analyzer/test/services/formatter_test.dart
@@ -42,6 +42,13 @@
     });
   });
 
+  /// Data-driven wrapping tests
+  group('wrap_tests.data', () {
+    runTests('wrap_tests.data', (input, expectedOutput) {
+      expectCUFormatsTo(input, expectedOutput);
+    });
+  });
+
   /// Formatter tests
   group('formatter', () {
 
@@ -1331,7 +1338,10 @@
         new SimpleLineBreaker(maxLength).breakLine(line);
 
     String printLine(Line line, int maxLength) =>
-        new SimpleLineBreaker(maxLength).printLine(line);
+        new SimpleLineBreaker(
+            maxLength,
+            (n) => new List.filled(n, '  ').join()
+        ).printLine(line);
 
     Line line(List tokens) {
       var line = new Line();
@@ -1349,7 +1359,9 @@
     }
 
 
-    final SP_1 = new SpaceToken(1, breakWeight: 1);
+    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);
 
     // 'foo|1|bar|1|baz|1|foo|1|bar|1|baz'
     final LINE_1 = line(['foo', SP_1, 'bar', SP_1, 'baz', SP_1,
@@ -1389,24 +1401,40 @@
       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\nbar\nbaz\nfoo\nbar\nbaz');
+      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\nbar\nbaz\nfoo\nbar\nbaz');
+      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\nbaz foo\nbar baz');
+      expect(line, 'foo bar\n    baz foo\n    bar baz');
     });
 
     test('printLine - 4', () {
       var line = printLine(LINE_1, 12);
-      expect(line, 'foo bar baz\nfoo bar baz');
+      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('isWhitespace', () {
diff --git a/pkg/compiler_unsupported/pubspec.yaml b/pkg/compiler_unsupported/pubspec.yaml
index a228bcd..988747b 100644
--- a/pkg/compiler_unsupported/pubspec.yaml
+++ b/pkg/compiler_unsupported/pubspec.yaml
@@ -1,9 +1,10 @@
 name: compiler_unsupported
-version: 0.7.1
+version: 0.7.2
 author: Dart2js Team <compiler-dev@dartlang.org>
 homepage: http://www.dartlang.org
 description: >
   This is an unsupported copy of the dart2js source. The API of this package
-  can and will change in unpredictable and incompatible ways.
+  can and will change in unpredictable and incompatible ways. This release
+  tracks the 1.6.0-dev.1.2 dart2js version.
 environment:
   sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/intl/CHANGELOG.md b/pkg/intl/CHANGELOG.md
index 67cad08..1085a24 100644
--- a/pkg/intl/CHANGELOG.md
+++ b/pkg/intl/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 0.11.2
+
+ * Missed canonicalization of locales in one place in message library generation.
+
+ * Added a simple debug script for message_extraction_test.
+
 ## 0.11.1
 
  * Negative numbers were being parsed as positive.
diff --git a/pkg/intl/lib/generate_localized.dart b/pkg/intl/lib/generate_localized.dart
index 9b8051d..0003331 100644
--- a/pkg/intl/lib/generate_localized.dart
+++ b/pkg/intl/lib/generate_localized.dart
@@ -183,7 +183,8 @@
   }
   output.write("\n");
   output.write("\nMap<String, Function> _deferredLibraries = {\n");
-  for (var locale in allLocales) {
+  for (var rawLocale in allLocales) {
+    var locale = Intl.canonicalizedLocale(rawLocale);
     output.write("  '$locale' : () => ${_libraryName(locale)}.loadLibrary(),\n");
   }
   output.write("};\n");
diff --git a/pkg/intl/pubspec.yaml b/pkg/intl/pubspec.yaml
index 6c1f0be..fdd984f 100644
--- a/pkg/intl/pubspec.yaml
+++ b/pkg/intl/pubspec.yaml
@@ -1,5 +1,5 @@
 name: intl
-version: 0.11.1
+version: 0.11.2
 author: Dart Team <misc@dartlang.org>
 description: Contains code to deal with internationalized/localized messages, date and number formatting and parsing, bi-directional text, and other internationalization issues.
 homepage: http://www.dartlang.org
diff --git a/pkg/intl/test/message_extraction/debug.sh b/pkg/intl/test/message_extraction/debug.sh
new file mode 100755
index 0000000..82c8b87
--- /dev/null
+++ b/pkg/intl/test/message_extraction/debug.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+# The message_extraction_test.dart test uses a temporary directory and spawns 
+# separate processes for each step. This can make it very painful to debug the
+# steps. 
+# This script runs the steps individually, putting the files in the current
+# directory. You can run the script to run the test locally, or use this to
+# run individual steps or create them as launches in the editor.
+dart ../../bin/extract_to_arb.dart sample_with_messages.dart \
+part_of_sample_with_messages.dart
+dart make_hardcoded_translation.dart intl_messages.arb
+dart ../../bin/generate_from_arb.dart --generated-file-prefix=foo_ \
+sample_with_messages.dart part_of_sample_with_messages.dart \
+translation_fr.arb translation_de_DE.arb
diff --git a/pkg/observe/CHANGELOG.md b/pkg/observe/CHANGELOG.md
index b32303a..53a425f 100644
--- a/pkg/observe/CHANGELOG.md
+++ b/pkg/observe/CHANGELOG.md
@@ -3,6 +3,11 @@
 This file contains highlights of what changes on each version of the observe
 package.
 
+#### Pub version 0.11.0-dev
+  * PathObserver.value= no longer discards changes (this is in combination with
+    a change in template_binding and polymer to improve interop with JS custom
+    elements).
+
 #### Pub version 0.10.0+3
   * minor changes to documentation, deprecated `discardListChages` in favor of
     `discardListChanges` (the former had a typo).
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 1d7c97c..798f43d 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -48,6 +48,7 @@
 polymer/test/register_test: Pass, RuntimeError # Issue 18931
 polymer/test/take_attributes_test: Pass, RuntimeError # Issue 18931
 polymer/test/template_distribute_dynamic_test: Pass, RuntimeError # Issue 18931
+polymer/test/two_way_bind_test: Pass, RuntimeError # Issue 18931
 web_components/test/interop_test: Pass, RuntimeError # Issue 18931
 
 [ $compiler == none && ($runtime == dartium) && $mode == debug ]
@@ -171,6 +172,7 @@
 polymer/test/register_test: Skip #uses dart:html
 polymer/test/take_attributes_test: Skip #uses dart:html
 polymer/test/template_distribute_dynamic_test: Skip #uses dart:html
+polymer/test/two_way_bind_test: Skip #uses dart:html
 polymer/test/unbind_test: Skip # uses dart:html
 third_party/angular_tests/browser_test: Skip # uses dart:html
 web_components/test/*: Skip # uses dart:html
diff --git a/pkg/pkgbuild.status b/pkg/pkgbuild.status
index e3628f1..83daf7f 100644
--- a/pkg/pkgbuild.status
+++ b/pkg/pkgbuild.status
@@ -17,9 +17,6 @@
 
 [ $use_public_packages ]
 samples/third_party/angular_todo: Pass, Slow
-pkg/template_binding: PubGetError
-pkg/polymer_expressions: PubGetError
-pkg/polymer: PubGetError
 
 [ $use_public_packages && $builder_tag == russian ]
 samples/third_party/todomvc: Fail # Issue 18104
diff --git a/pkg/polymer/CHANGELOG.md b/pkg/polymer/CHANGELOG.md
index a250752..97cb4d3 100644
--- a/pkg/polymer/CHANGELOG.md
+++ b/pkg/polymer/CHANGELOG.md
@@ -4,6 +4,11 @@
 package. We will also note important changes to the polyfill packages (observe,
 web_components, and template_binding) if they impact polymer.
 
+#### Pub version 0.11.1-dev
+ * Use the latest template_binding with better NodeBind interop support (for
+   two-way bindings with JS polymer elements).
+ * Fix for [19770](https://code.google.com/p/dart/issues/detail?id=19770)
+
 #### Pub version 0.11.0+5
   * fixes web_components version in dependencies
 
diff --git a/pkg/polymer/lib/src/build/import_inliner.dart b/pkg/polymer/lib/src/build/import_inliner.dart
index 71ab67c..3167f26 100644
--- a/pkg/polymer/lib/src/build/import_inliner.dart
+++ b/pkg/polymer/lib/src/build/import_inliner.dart
@@ -289,13 +289,18 @@
   _UrlNormalizer(this.transform, this.sourceId);
 
   visitElement(Element node) {
-    node.attributes.forEach((name, value) {
-      if (_urlAttributes.contains(name)) {
-        if (value != '' && !value.trim().startsWith('{{')) {
-          node.attributes[name] = _newUrl(value, node.sourceSpan);
+    // TODO(jakemac): Support custom elements that extend html elements which
+    // have url-like attributes. This probably means keeping a list of which
+    // html elements support each url-like attribute.
+    if (!isCustomTagName(node.localName)) {
+      node.attributes.forEach((name, value) {
+        if (_urlAttributes.contains(name)) {
+          if (value != '' && !value.trim().startsWith('{{')) {
+            node.attributes[name] = _newUrl(value, node.sourceSpan);
+          }
         }
-      }
-    });
+      });
+    }
     if (node.localName == 'style') {
       node.text = visitCss(node.text);
     } else if (node.localName == 'script' &&
diff --git a/pkg/polymer/test/build/import_inliner_test.dart b/pkg/polymer/test/build/import_inliner_test.dart
index 663e353..2e5437e 100644
--- a/pkg/polymer/test/build/import_inliner_test.dart
+++ b/pkg/polymer/test/build/import_inliner_test.dart
@@ -20,6 +20,7 @@
   group('rel=import', importTests);
   group('rel=stylesheet', stylesheetTests);
   group('script type=dart', codeExtractorTests);
+  group('url attributes', urlAttributeTests);
 }
 
 void importTests() {
@@ -740,3 +741,28 @@
           'h1 { font-size: 70px; }',
     });
 }
+
+void urlAttributeTests() {
+
+  testPhases('url attributes are normalized', phases, {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head>'
+          '<link rel="import" href="foo/test_1.html">'
+          '<link rel="import" href="foo/test_2.html">'
+          '</head></html>',
+      'a|web/foo/test_1.html':
+          '<script src="baz.jpg"></script>',
+      'a|web/foo/test_2.html':
+          '<foo-element src="baz.jpg"></foo-element>'
+    }, {
+      'a|web/test.html':
+          '<!DOCTYPE html><html><head></head><body>'
+          '<script src="foo/baz.jpg"></script>'        // normalized
+          '<foo-element src="baz.jpg"></foo-element>'  // left alone (custom)
+          '</body></html>',
+      'a|web/foo/test_1.html':
+          '<script src="baz.jpg"></script>',
+      'a|web/foo/test_2.html':
+          '<foo-element src="baz.jpg"></foo-element>',
+    }); 
+}
\ No newline at end of file
diff --git a/pkg/polymer/test/two_way_bind_test.dart b/pkg/polymer/test/two_way_bind_test.dart
new file mode 100644
index 0000000..66347e7
--- /dev/null
+++ b/pkg/polymer/test/two_way_bind_test.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('inner-element')
+class InnerElement extends PolymerElement {
+  @published int number;
+  @published bool boolean;
+  @published String string;
+
+  InnerElement.created() : super.created();
+}
+
+@CustomTag('outer-element')
+class OuterElement extends PolymerElement {
+  @observable int number = 1;
+  @observable bool boolean = false;
+  @observable String string = 'a';
+
+  OuterElement.created() : super.created();
+}
+
+main() => initPolymer().run(() {
+  useHtmlConfiguration();
+
+  setUp(() => Polymer.onReady);
+  
+  test('inner element gets initial values', () {
+    var outer = querySelector('outer-element');
+    var inner = outer.shadowRoot.querySelector('inner-element');
+    
+    expect(inner.number, 1);
+    expect(inner.boolean, false);
+    expect(inner.string, 'a');
+  });
+
+  test('inner element updates the outer element', () {
+    var outer = querySelector('outer-element');
+    var inner = outer.shadowRoot.querySelector('inner-element');
+    
+    // Toggle the value in the child and make sure that propagates around.
+    inner.number = 2;
+    inner.boolean = true;
+    inner.string = 'b';
+    return new Future(() {}).then((_) {
+      expect(outer.number, 2);
+      expect(outer.boolean, true);
+      expect(outer.string, 'b');
+      
+      inner.number = 1;
+      inner.boolean = false;
+      inner.string = 'a';
+    }).then((_) => new Future(() {})).then((_) {
+      expect(outer.number, 1);
+      expect(outer.boolean, false);
+      expect(outer.string, 'a');
+    });
+  });
+  
+  test('outer element updates the inner element', () {
+    var outer = querySelector('outer-element');
+    var inner = outer.shadowRoot.querySelector('inner-element');
+    
+    // Toggle the value in the parent and make sure that propagates around.
+    outer.number = 2;
+    outer.boolean = true;
+    outer.string = 'b';
+    return new Future(() {}).then((_) {
+      expect(inner.number, 2);
+      expect(inner.boolean, true);
+      expect(inner.string, 'b');
+      
+      outer.number = 1;
+      outer.boolean = false;
+      outer.string = 'a';
+    }).then((_) => new Future(() {})).then((_) {
+      expect(inner.number, 1);
+      expect(inner.boolean, false);
+      expect(inner.string, 'a');
+    });
+  });
+});
diff --git a/pkg/polymer/test/two_way_bind_test.html b/pkg/polymer/test/two_way_bind_test.html
new file mode 100644
index 0000000..94b4b21
--- /dev/null
+++ b/pkg/polymer/test/two_way_bind_test.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+  <!--polymer-test: this comment is needed for test_suite.dart-->
+  <head>
+    <title>two way bindings</title>
+    <script src="packages/web_components/platform.js"></script>
+    <script src="packages/web_components/dart_support.js"></script>
+    <link rel="import" href="packages/polymer/polymer.html">
+    <script src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  </head>
+
+  <body>
+    <polymer-element name="inner-element">
+      <template>
+        <h1>Hello from the child</h1>
+        <p>The number is {{number}}</p>
+        <p>The boolean is {{boolean}}</p>
+        <p>The string is {{string}}</p>
+      </template>
+    </polymer-element>
+
+    <polymer-element name="outer-element">
+      <template>
+        <h1>Hello from the custom element</h1>
+        <p>The number is {{number}}</p>
+        <p>The boolean is {{boolean}}</p>
+        <p>The string is {{string}}</p>
+        <p>
+          <inner-element id="child" number="{{number}}"
+              boolean="{{boolean}}" string="{{string}}"></inner-element>
+        </p>
+      </template>
+    </polymer-element>
+
+    <outer-element></outer-element>
+
+    <script type="application/dart" src="two_way_bind_test.dart"></script>
+  </body>
+</html>
diff --git a/pkg/polymer_expressions/CHANGELOG.md b/pkg/polymer_expressions/CHANGELOG.md
index 909fcc1..8683f55 100644
--- a/pkg/polymer_expressions/CHANGELOG.md
+++ b/pkg/polymer_expressions/CHANGELOG.md
@@ -3,6 +3,10 @@
 This file contains highlights of what changes on each version of the
 polymer_expressions package.
 
+#### Pub version 0.12.0-dev
+  * Updated to depend on latest template_binding and observe. Setting a value on
+    a polymer expression binding now produces a change notification.
+
 #### Pub version 0.11.0
   * Remove faulty assert that threw when an iterable field was updated.
   
diff --git a/runtime/bin/dbg_message.cc b/runtime/bin/dbg_message.cc
index 28fe8ad..1135c52 100644
--- a/runtime/bin/dbg_message.cc
+++ b/runtime/bin/dbg_message.cc
@@ -447,6 +447,9 @@
   intptr_t trace_len = 0;
   Dart_Handle res = Dart_StackTraceLength(trace, &trace_len);
   ASSERT_NOT_ERROR(res);
+  if (trace_len == 0) {
+    return;
+  }
   Dart_ActivationFrame frame;
   res = Dart_GetActivationFrame(trace, 0, &frame);
   ASSERT_NOT_ERROR(res);
diff --git a/runtime/bin/vmservice/client/deployed/web/index.html b/runtime/bin/vmservice/client/deployed/web/index.html
index fd11844..a344255 100644
--- a/runtime/bin/vmservice/client/deployed/web/index.html
+++ b/runtime/bin/vmservice/client/deployed/web/index.html
@@ -3131,14 +3131,14 @@
   word-wrap: break-word;
 }
 </style><!-- These comments are here to allow newlines.
-     --><template if="{{ isDart }}"><!--
-       --><template if="{{ qualified &amp;&amp; !hasParent &amp;&amp; hasClass }}"><!--
-       --><class-ref ref="{{ ref['owner'] }}"></class-ref>.</template><!--
-     --><template if="{{ qualified &amp;&amp; hasParent }}"><!--
-       --><function-ref ref="{{ ref['parent'] }}" qualified="{{ true }}">
+     --><template if="{{ ref.isDart }}"><!--
+       --><template if="{{ qualified &amp;&amp; ref.parent == null &amp;&amp; ref.owningClass != null }}"><!--
+       --><class-ref ref="{{ ref.owningClass] }}"></class-ref>.</template><!--
+     --><template if="{{ qualified &amp;&amp; ref.parent != null }}"><!--
+       --><function-ref ref="{{ ref.parent }}" qualified="{{ true }}">
           </function-ref>.<!--
      --></template><a on-click="{{ goto }}" href="{{ url }}">{{ name }}</a><!--
-  --></template><template if="{{ !isDart }}"><span> {{ name }}</span></template></template>
+  --></template><template if="{{ !ref.isDart }}"><span> {{ name }}</span></template></template>
 </polymer-element>
 
 
@@ -3412,26 +3412,65 @@
         padding-left: 15%;
         padding-right: 15%;
       }
-      .grayBox {
+      .sourceBox {
         width: 100%;
         background-color: #f5f5f5;
         border: 1px solid #ccc;
         padding: 10px;
-     }
+        overflow-y: auto;
+      }
+      .sourceTable {
+        display: table;
+      }
+      .sourceRow {
+        display: table-row;
+      }
+      .sourceItem, .sourceItemCurrent {
+        display: table-cell;
+        vertical-align: top;
+        font: 400 14px consolas, courier, monospace;
+        line-height: 125%;
+        white-space: pre;
+      }
+      .sourceItemCurrent {
+        background-color: #6cf;
+      }
+      .hitsNone, .hitsNotExecuted, .hitsExecuted {
+        min-width: 32px;
+        text-align: right;
+      }
+      .hitsNotExecuted {
+        background-color: #e66;
+      }
+      .hitsExecuted {
+        background-color: #6d6;
+      }
     </style>
     <div class="sourceInset">
       <content></content>
-      <div class="grayBox">
-        <table>
-          <tbody>
-            <tr template="" repeat="{{ lineNumber in lineNumbers }}">
-              <td style="{{ styleForHits(script.lines[lineNumber].hits) }}"><span>  </span></td>
-              <td style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: nowrap;">{{script.lines[lineNumber].line}}</td>
-              <td>&nbsp;</td>
-              <td width="99%" style="font-family: consolas, courier, monospace;font-size: 1em;line-height: 1.2em;white-space: pre;">{{script.lines[lineNumber].text}}</td>
-            </tr>
-          </tbody>
-        </table>
+      <div class="sourceBox" style="height:{{height}}">
+        <div class="sourceTable">
+          <template repeat="{{ line in lines }}">
+            <div class="sourceRow" id="{{ makeLineId(line.line) }}">
+              <template if="{{ line.hits == null }}">
+                <div class="hitsNone">{{ line.line }}</div>
+              </template>
+              <template if="{{ line.hits == 0 }}">
+                <div class="hitsNotExecuted">{{ line.line }}</div>
+              </template>
+              <template if="{{ line.hits > 0 }}">
+                <div class="hitsExecuted">{{ line.line }}</div>
+              </template>
+              <div class="sourceItem">&nbsp;</div>
+              <template if="{{ line.line == currentLine }}">
+                <div id="currentLine" class="sourceItemCurrent">{{line.text}}</div>
+              </template>
+              <template if="{{ line.line != currentLine }}">
+                <div class="sourceItem">{{line.text}}</div>
+              </template>
+            </div>
+          </template>
+        </div>
       </div>
     </div>
   </template>
@@ -4117,7 +4156,7 @@
     </div>
 
     <hr>
-    <script-inset script="{{ cls.script }}" pos="{{ cls.tokenPos }}" endpos="{{ cls.endTokenPos }}">
+    <script-inset script="{{ cls.script }}" startpos="{{ cls.tokenPos }}" endpos="{{ cls.endTokenPos }}">
     </script-inset>
 
     <br><br><br><br>
@@ -4128,6 +4167,7 @@
 
 
 
+
 <polymer-element name="code-ref" extends="service-ref">
   <template>
     <style>
@@ -4698,7 +4738,7 @@
     <nav-bar>
       <top-nav-menu></top-nav-menu>
       <isolate-nav-menu isolate="{{ code.isolate }}"></isolate-nav-menu>
-      <nav-menu link="." anchor="{{ code.name }}" last="{{ true }}"></nav-menu>
+      <nav-menu link="{{ code.link }}" anchor="{{ code.name }}" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
       <nav-control></nav-control>
     </nav-bar>
@@ -6516,12 +6556,12 @@
     <nav-bar>
       <top-nav-menu></top-nav-menu>
       <isolate-nav-menu isolate="{{ function.isolate }}"></isolate-nav-menu>
-      <template if="{{ function['owner'].serviceType == 'Class' }}">
+      <template if="{{ function.owningClass != null }}">
         <!-- TODO(turnidge): Add library nav menu here. -->
-        <class-nav-menu cls="{{ function['owner'] }}"></class-nav-menu>
+        <class-nav-menu cls="{{ function.owningClass }}"></class-nav-menu>
       </template>
-      <template if="{{ function['owner'].serviceType == 'Library' }}">
-        <library-nav-menu library="{{ function['owner'] }}"></library-nav-menu>
+      <template if="{{ function.owningLibrary != null }}">
+        <library-nav-menu library="{{ function.owningLibrary }}"></library-nav-menu>
       </template>
       <nav-menu link="{{ function.link }}" anchor="{{ function.name }}" last="{{ true }}"></nav-menu>
       <nav-refresh callback="{{ refresh }}"></nav-refresh>
@@ -6529,78 +6569,78 @@
     </nav-bar>
 
     <div class="content">
-      <h1>function {{ qualifiedName }}</h1>
+      <h1>function {{ function.qualifiedName }}</h1>
 
       <div class="memberList">
         <div class="memberItem">
           <div class="memberName">kind</div>
           <div class="memberValue">
-            <template if="{{ function['is_static'] }}">static</template>
-            <template if="{{ function['is_const'] }}">const</template>
-            {{ kind }}
+            <template if="{{ function.isStatic }}">static</template>
+            <template if="{{ function.isConst }}">const</template>
+            {{ function.kind.toString() }}
           </div>
         </div>
-        <template if="{{ function['parent'] != null }}">
+        <template if="{{ function.parent != null }}">
           <div class="memberItem">
             <div class="memberName">parent function</div>
             <div class="memberValue">
-              <function-ref ref="{{ function['parent'] }}"></function-ref>
+              <function-ref ref="{{ function.parent }}"></function-ref>
             </div>
           </div>
         </template>
         <div class="memberItem">
           <div class="memberName">owner</div>
           <div class="memberValue">
-            <template if="{{ function['owner'].serviceType == 'Class' }}">
-              <class-ref ref="{{ function['owner'] }}"></class-ref>
+            <template if="{{ function.owningClass != null }}">
+              <class-ref ref="{{ function.owningClass }}"></class-ref>
             </template>
-            <template if="{{ function['owner'].serviceType != 'Class' }}">
-              <library-ref ref="{{ function['owner'] }}"></library-ref>
+            <template if="{{ function.owningLibrary != null }}">
+              <library-ref ref="{{ function.owningLibrary }}"></library-ref>
             </template>
           </div>
         </div>
         <div class="memberItem">
           <div class="memberName">script</div>
           <div class="memberValue">
-            <script-ref ref="{{ function['script'] }}" pos="{{ function['tokenPos'] }}">
+            <script-ref ref="{{ function.script }}" pos="{{ function.tokenPos }}">
             </script-ref>
           </div>
         </div>
 
         <div class="memberItem">&nbsp;</div>
 
-        <template if="{{ function['code'] != null }}">
+        <template if="{{ function.code != null }}">
           <div class="memberItem">
             <div class="memberName">optimized code</div>
             <div class="memberValue">
-              <code-ref ref="{{ function['code'] }}"></code-ref>
+              <code-ref ref="{{ function.code }}"></code-ref>
             </div>
           </div>
         </template>
-        <template if="{{ function['unoptimized_code'] != null }}">
+        <template if="{{ function.unoptimizedCode != null }}">
           <div class="memberItem">
             <div class="memberName">unoptimized code</div>
             <div class="memberValue">
-              <code-ref ref="{{ function['unoptimized_code'] }}"></code-ref>
+              <code-ref ref="{{ function.unoptimizedCode }}"></code-ref>
             </div>
               <div class="memberValue">
                 <span title="This count is used to determine when a function will be optimized.  It is a combination of call counts and other factors.">
-                  (usage count: {{ function['usage_counter'] }})
+                  (usage count: {{ function.usageCounter }})
                 </span>
              </div>
            </div>
          </template>
          <div class="memberItem">
            <div class="memberName">deoptimizations</div>
-           <div class="memberValue">{{ function['deoptimizations'] }}</div>
+           <div class="memberValue">{{ function.deoptimizations }}</div>
          </div>
          <div class="memberItem">
            <div class="memberName">optimizable</div>
-           <div class="memberValue">{{ function['is_optimizable'] }}</div>
+           <div class="memberValue">{{ function.isOptimizable }}</div>
          </div>
          <div class="memberItem">
            <div class="memberName">inlinable</div>
-           <div class="memberValue">{{ function['is_inlinable'] }}</div>
+           <div class="memberValue">{{ function.isInlinable }}</div>
          </div>
          <template if="{{ function.name != function.vmName }}">
            <div class="memberItem">
@@ -6612,7 +6652,7 @@
     </div>
 
     <hr>
-    <script-inset script="{{ function['script'] }}" pos="{{ function['tokenPos'] }}" endpos="{{ function['endTokenPos'] }}">
+    <script-inset script="{{ function.script }}" startpos="{{ function.tokenPos }}" endpos="{{ function.endTokenPos }}">
     </script-inset>
 
     <br>
@@ -13438,7 +13478,7 @@
 
     <template if="{{ isolate.topFrame != null }}">
       <br>
-      <script-inset script="{{ isolate.topFrame['script'] }}" pos="{{ isolate.topFrame['tokenPos'] }}">
+      <script-inset script="{{ isolate.topFrame['script'] }}" currentpos="{{ isolate.topFrame['tokenPos'] }}" height="200px">
       </script-inset>
     </template>
 
@@ -15599,9 +15639,18 @@
     <nav-control></nav-control>
   </nav-bar>
 
-  <script-inset id="scriptInset" script="{{ script }}" pos="{{ script.firstTokenPos }}" endpos="{{ script.lastTokenPos }}">
-  <h1>script {{ script.name }}</h1>
-  </script-inset>
+  <template if="{{ args['pos'] == null }}">
+    <script-inset id="scriptInset" script="{{ script }}">
+      <h1>script {{ script.name }}</h1>
+    </script-inset>
+  </template>
+
+  <template if="{{ args['pos'] != null }}">
+    <script-inset id="scriptInset" script="{{ script }}" currentpos="{{ args['pos'] | parseInt }}">
+      <h1>script {{ script.name }}</h1>
+    </script-inset>
+  </template>
+
 </template>
 </polymer-element>
 
@@ -15610,6 +15659,7 @@
 
 
 
+
 <polymer-element name="stack-trace" extends="observatory-element">
   <template>
     <style>
diff --git a/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js b/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js
index ab4e425..754a75f 100644
--- a/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js
+++ b/runtime/bin/vmservice/client/deployed/web/index.html_bootstrap.dart.js
@@ -193,23 +193,23 @@
 "^":"a;",
 n:function(a,b){return a===b},
 giO:function(a){return H.eQ(a)},
-bu:function(a){return H.a5(a)},
-T:[function(a,b){throw H.b(P.lr(a,b.gWa(),b.gnd(),b.gVm(),null))},"$1","gxK",2,0,null,69],
-gbx:function(a){return new H.cu(H.b7(a),null)},
+bu:[function(a){return H.a5(a)},"$0","gAY",0,0,69],
+T:[function(a,b){throw H.b(P.lr(a,b.gWa(),b.gnd(),b.gVm(),null))},"$1","gxK",2,0,null,70],
+gbx:function(a){return new H.cu(H.wO(a),null)},
 "%":"DOMImplementation|Navigator|SVGAnimatedEnumeration|SVGAnimatedLength|SVGAnimatedLengthList|SVGAnimatedNumber|SVGAnimatedNumberList|SVGAnimatedString"},
 yEe:{
 "^":"Gv;",
-bu:function(a){return String(a)},
+bu:[function(a){return String(a)},"$0","gAY",0,0,69],
 giO:function(a){return a?519018:218159},
 gbx:function(a){return C.HL},
 $isa2:true},
 CDU:{
 "^":"Gv;",
 n:function(a,b){return null==b},
-bu:function(a){return"null"},
+bu:[function(a){return"null"},"$0","gAY",0,0,69],
 giO:function(a){return 0},
 gbx:function(a){return C.GX},
-T:[function(a,b){return J.Gv.prototype.T.call(this,a,b)},"$1","gxK",2,0,null,69]},
+T:[function(a,b){return J.Gv.prototype.T.call(this,a,b)},"$1","gxK",2,0,null,70]},
 Ue1:{
 "^":"Gv;",
 giO:function(a){return 0},
@@ -243,7 +243,7 @@
 for(z=J.mY(b);z.G();)this.h(a,z.gl())},
 V1:function(a){this.sB(a,0)},
 aN:function(a,b){return H.bQ(a,b)},
-ez:[function(a,b){return H.VM(new H.A8(a,b),[null,null])},"$1","gIr",2,0,function(){return H.XW(function(a){return{func:"fQ",ret:P.QV,args:[{func:"ub",args:[a]}]}},this.$receiver,"Q")},31],
+ez:[function(a,b){return H.VM(new H.A8(a,b),[null,null])},"$1","gIr",2,0,function(){return H.XW(function(a){return{func:"fQ",ret:P.QV,args:[{func:"Jm",args:[a]}]}},this.$receiver,"Q")},31],
 zV:function(a,b){var z,y,x,w
 z=a.length
 y=Array(z)
@@ -256,11 +256,11 @@
 return a[b]},
 aM:function(a,b,c){if(b<0||b>a.length)throw H.b(P.TE(b,0,a.length))
 if(c<b||c>a.length)throw H.b(P.TE(c,b,a.length))
-if(b===c)return H.VM([],[H.Kp(a,0)])
-return H.VM(a.slice(b,c),[H.Kp(a,0)])},
+if(b===c)return H.VM([],[H.Oq(a,0)])
+return H.VM(a.slice(b,c),[H.Oq(a,0)])},
 Mu:function(a,b,c){H.xF(a,b,c)
 return H.c1(a,b,c,null)},
-gtH:function(a){if(a.length>0)return a[0]
+gTw:function(a){if(a.length>0)return a[0]
 throw H.b(P.w("No elements"))},
 grZ:function(a){var z=a.length
 if(z>0)return a[z-1]
@@ -285,17 +285,17 @@
 return!1},
 gl0:function(a){return a.length===0},
 gor:function(a){return a.length!==0},
-bu:function(a){return P.WE(a,"[","]")},
+bu:[function(a){return P.WE(a,"[","]")},"$0","gAY",0,0,69],
 tt:function(a,b){var z
-if(b)return H.VM(a.slice(),[H.Kp(a,0)])
-else{z=H.VM(a.slice(),[H.Kp(a,0)])
+if(b)return H.VM(a.slice(),[H.Oq(a,0)])
+else{z=H.VM(a.slice(),[H.Oq(a,0)])
 z.fixed$length=init
 return z}},
 br:function(a){return this.tt(a,!0)},
-zH:function(a){var z=P.Ls(null,null,null,H.Kp(a,0))
+zH:function(a){var z=P.Ls(null,null,null,H.Oq(a,0))
 z.FV(0,a)
 return z},
-gA:function(a){return H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)])},
+gA:function(a){return H.VM(new H.a7(a,a.length,0,null),[H.Oq(a,0)])},
 giO:function(a){return H.eQ(a)},
 gB:function(a){return a.length},
 sB:function(a,b){if(typeof b!=="number"||Math.floor(b)!==b)throw H.b(P.u(b))
@@ -349,11 +349,11 @@
 if(z.C(b,0)||z.D(b,20))throw H.b(P.KP(b))
 y=a.toFixed(b)
 if(a===0&&this.gzP(a))return"-"+y
-return y},"$1","gKy",2,0,15,70],
+return y},"$1","gKy",2,0,15,71],
 WZ:function(a,b){if(b<2||b>36)throw H.b(P.KP(b))
 return a.toString(b)},
-bu:function(a){if(a===0&&1/a<0)return"-0.0"
-else return""+a},
+bu:[function(a){if(a===0&&1/a<0)return"-0.0"
+else return""+a},"$0","gAY",0,0,69],
 giO:function(a){return a&0x1FFFFFFF},
 J:function(a){return-a},
 g:function(a,b){if(typeof b!=="number")throw H.b(P.u(b))
@@ -478,6 +478,7 @@
 b=b>>>1
 if(b===0)break
 z+=z}return y},
+gYC:function(a){return new J.mN(a)},
 XU:function(a,b,c){var z,y,x,w
 if(b==null)H.vh(P.u(null))
 if(c<0||c>a.length)throw H.b(P.TE(c,0,a.length))
@@ -505,7 +506,7 @@
 if(a===b)z=0
 else z=a<b?-1:1
 return z},
-bu:function(a){return a},
+bu:[function(a){return a},"$0","gAY",0,0,69],
 giO:function(a){var z,y,x
 for(z=a.length,y=0,x=0;x<z;++x){y=536870911&y+a.charCodeAt(x)
 y=536870911&y+((524287&y)<<10>>>0)
@@ -527,7 +528,22 @@
 for(z=a.length;b>0;b=y){y=b-1
 if(y>=z)H.vh(P.N(y))
 x=a.charCodeAt(y)
-if(x!==32&&x!==13&&!J.Ga(x))break}return b}}}}],["_isolate_helper","dart:_isolate_helper",,H,{
+if(x!==32&&x!==13&&!J.Ga(x))break}return b}}},
+mN:{
+"^":"w2Y;iN",
+gB:function(a){return this.iN.length},
+t:function(a,b){var z,y
+z=this.iN
+if(typeof b!=="number"||Math.floor(b)!==b)H.vh(P.u(b))
+y=J.Wx(b)
+if(y.C(b,0))H.vh(P.N(b))
+if(y.F(b,z.length))H.vh(P.N(b))
+return z.charCodeAt(b)},
+$asw2Y:function(){return[P.KN]},
+$asark:function(){return[P.KN]},
+$asIr:function(){return[P.KN]},
+$asWO:function(){return[P.KN]},
+$asQV:function(){return[P.KN]}}}],["_isolate_helper","dart:_isolate_helper",,H,{
 "^":"",
 dB:function(a,b){var z=a.vV(0,b)
 init.globalState.Xz.bL()
@@ -542,7 +558,7 @@
 z.a=b
 y=b}else y=b
 if(!J.x(y).$isWO)throw H.b(P.u("Arguments to main must be a List: "+H.d(y)))
-y=new H.FU(0,0,1,null,null,null,null,null,null,null,null,null,a)
+y=new H.pq(0,0,1,null,null,null,null,null,null,null,null,null,a)
 y.qi(a)
 init.globalState=y
 if(init.globalState.EF===!0)return
@@ -576,16 +592,16 @@
 if(y!=null)return y[1]
 throw H.b(P.f("Cannot extract URI from \""+H.d(z)+"\""))},
 uK:[function(a,b){var z,y,x,w,v,u,t,s,r,q,p,o,n,m
-z=H.Hh(b.data)
+z=H.b0(b.data)
 y=J.U6(z)
-switch(y.t(z,"command")){case"start":init.globalState.oL=y.t(z,"id")
+switch(y.t(z,"command")){case"start":init.globalState.NO=y.t(z,"id")
 x=y.t(z,"functionName")
 w=x==null?init.globalState.w2:init.globalFunctions[x]()
 v=y.t(z,"args")
-u=H.Hh(y.t(z,"msg"))
+u=H.b0(y.t(z,"msg"))
 t=y.t(z,"isSpawnUri")
 s=y.t(z,"startPaused")
-r=H.Hh(y.t(z,"replyTo"))
+r=H.b0(y.t(z,"replyTo"))
 y=init.globalState.Hg++
 q=P.L5(null,null,null,P.KN,H.yo)
 p=P.Ls(null,null,null,P.KN)
@@ -598,7 +614,7 @@
 init.globalState.Xz.bL()
 break
 case"spawn-worker":m=y.t(z,"replyPort")
-H.EN(y.t(z,"functionName"),y.t(z,"uri"),y.t(z,"args"),y.t(z,"msg"),!1,y.t(z,"isSpawnUri"),y.t(z,"startPaused")).Rx(new H.mN(m),new H.xn(m))
+H.EN(y.t(z,"functionName"),y.t(z,"uri"),y.t(z,"args"),y.t(z,"msg"),!1,y.t(z,"isSpawnUri"),y.t(z,"startPaused")).Rx(new H.xn(m),new H.jl3(m))
 break
 case"message":if(y.t(z,"port")!=null)J.H4(y.t(z,"port"),y.t(z,"msg"))
 init.globalState.Xz.bL()
@@ -624,16 +640,16 @@
 throw H.b(P.FM(z))}},
 EN:function(a,b,c,d,e,f,g){var z,y,x,w,v,u
 if(b!=null&&J.Vr(b,".dart"))b=J.ew(b,".js")
-z=P.hM()
+z=P.at()
 y=H.VM(new P.Zf(P.Dt(null)),[null])
-z.gtH(z).ml(new H.WK(y))
+z.gTw(z).ml(new H.yk(y))
 x=new H.VU(z.vl,init.globalState.N0.jO)
 if(init.globalState.ji===!0&&!e)if(init.globalState.EF===!0){w=init.globalState.rj
 v=H.t0(P.EF(["command","spawn-worker","functionName",a,"args",c,"msg",d,"uri",b,"isSpawnUri",f,"startPaused",g,"replyPort",x],null,null))
 w.toString
 self.postMessage(v)}else{if(b==null)b=$.Zt()
 u=new Worker(b)
-u.onerror=function(h,i,j){return function(k){return h(k,i,j)}}(H.GA,b,new H.tZ(y))
+u.onerror=function(h,i,j){return function(k){return h(k,i,j)}}(H.GA,b,new H.WK(y))
 u.onmessage=function(h,i){return function(j){j.onerror=null
 return h(i,j)}}(H.uK,u)
 w=init.globalState.Y7++
@@ -680,23 +696,23 @@
 return z.Zo(a)}else{z=new H.fL(new H.cx())
 z.mR=new H.m3(null)
 return z.Zo(a)}},
-Hh:function(a){if(init.globalState.ji===!0)return new H.BV(null).ug(a)
+b0:function(a){if(init.globalState.ji===!0)return new H.BV(null).ug(a)
 else return a},
 vM:function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},
 ZR:function(a){return a==null||typeof a==="string"||typeof a==="number"||typeof a==="boolean"},
 PK:{
-"^":"Tp:71;a,b",
+"^":"TpZ:72;a,b",
 $0:function(){this.b.$1(this.a.a)},
 $isEH:true},
 JO:{
-"^":"Tp:71;a,c",
+"^":"TpZ:72;a,c",
 $0:function(){this.c.$2(this.a.a,null)},
 $isEH:true},
-FU:{
-"^":"a;Hg,oL,Y7,N0,Nr,Xz,da,EF,ji,iR<,rj,XC,w2<",
+pq:{
+"^":"a;Hg,NO,Y7,N0,Nr,Xz,da,EF,ji,iR<,rj,XC,w2<",
 qi:function(a){var z,y,x,w
 z=$.My()==null
-y=$.rm()
+y=$.Fv()
 x=z&&$.wB()===!0
 this.EF=x
 if(!x)y=y!=null&&$.Zt()!=null
@@ -715,13 +731,13 @@
 $.jk().onmessage=w
 $.jk().dartPrint=function(b){}}}},
 aX:{
-"^":"a;jO>,Gx,fW,En<,EE<,um,PX,xF?,UF<,C9<,lw,CN,M2,mf,pa,ir",
+"^":"a;jO>,Gx,fW,En<,EE<,um,PX,xF?,UF<,C9<,lJ,CN,M2,Ji,pa,ir",
 oz:function(a,b){if(!this.um.n(0,a))return
-if(this.lw.h(0,b)&&!this.UF)this.UF=!0
+if(this.lJ.h(0,b)&&!this.UF)this.UF=!0
 this.PC()},
 NR:function(a){var z,y,x,w,v,u
 if(!this.UF)return
-z=this.lw
+z=this.lJ
 z.Rz(0,a)
 if(z.X5===0){for(z=this.C9;y=z.length,y!==0;){if(0>=y)return H.e(z,0)
 x=z.pop()
@@ -745,7 +761,7 @@
 this.pa=b},
 ZC:function(a,b){var z,y
 z=J.x(b)
-if(!z.n(b,0))y=z.n(b,1)&&!this.mf
+if(!z.n(b,0))y=z.n(b,1)&&!this.Ji
 else y=!0
 if(y){J.H4(a,null)
 return}y=new H.NY(a)
@@ -757,7 +773,7 @@
 bc:function(a,b){var z,y
 if(!this.PX.n(0,a))return
 z=J.x(b)
-if(!z.n(b,0))y=z.n(b,1)&&!this.mf
+if(!z.n(b,0))y=z.n(b,1)&&!this.Ji
 else y=!0
 if(y){this.Dm()
 return}if(z.n(b,2)){z=init.globalState.Xz
@@ -783,16 +799,16 @@
 init.globalState.N0=this
 $=this.En
 y=null
-this.mf=!0
+this.Ji=!0
 try{y=b.$0()}catch(v){u=H.Ru(v)
 x=u
 w=new H.XO(v,null)
 this.hk(x,w)
 if(this.pa===!0){this.Dm()
-if(this===init.globalState.Nr)throw v}}finally{this.mf=!1
+if(this===init.globalState.Nr)throw v}}finally{this.Ji=!1
 init.globalState.N0=z
 if(z!=null)$=z.gEn()
-if(this.M2!=null)for(;u=this.M2,!u.gl0(u);)this.M2.AR().$0()}return y},"$1","gZm",2,0,72,73],
+if(this.M2!=null)for(;u=this.M2,!u.gl0(u);)this.M2.AR().$0()}return y},"$1","gZm",2,0,73,74],
 Ds:function(a){var z=J.U6(a)
 switch(z.t(a,0)){case"pause":this.oz(z.t(a,1),z.t(a,2))
 break
@@ -821,17 +837,17 @@
 Dm:[function(){var z,y
 z=this.M2
 if(z!=null)z.V1(0)
-for(z=this.Gx,y=z.gUQ(z),y=H.VM(new H.MH(null,J.mY(y.l6),y.T6),[H.Kp(y,0),H.Kp(y,1)]);y.G();)y.lo.pr()
+for(z=this.Gx,y=z.gUQ(z),y=H.VM(new H.MH(null,J.mY(y.l6),y.T6),[H.Oq(y,0),H.Oq(y,1)]);y.G();)y.lo.pr()
 z.V1(0)
 this.fW.V1(0)
 init.globalState.iR.Rz(0,this.jO)
 this.ir.V1(0)
 z=this.CN
-if(z!=null){for(z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();)J.H4(z.lo,null)
+if(z!=null){for(z=H.VM(new H.a7(z,z.length,0,null),[H.Oq(z,0)]);z.G();)J.H4(z.lo,null)
 this.CN=null}},"$0","gIm",0,0,18],
 $isaX:true},
 NY:{
-"^":"Tp:18;a",
+"^":"TpZ:18;a",
 $0:[function(){J.H4(this.a,null)},"$0",null,0,0,null,"call"],
 $isEH:true},
 cC:{
@@ -860,7 +876,7 @@
 w.toString
 self.postMessage(v)}}},
 Rm:{
-"^":"Tp:18;a",
+"^":"TpZ:18;a",
 $0:[function(){if(!this.a.xB())return
 P.rT(C.ny,this)},"$0",null,0,0,null,"call"],
 $isEH:true},
@@ -872,37 +888,37 @@
 In:{
 "^":"a;"},
 kb:{
-"^":"Tp:71;a,b,c,d,e,f",
+"^":"TpZ:72;a,b,c,d,e,f",
 $0:[function(){H.Di(this.a,this.b,this.c,this.d,this.e,this.f)},"$0",null,0,0,null,"call"],
 $isEH:true},
-mN:{
-"^":"Tp:13;UI",
-$1:[function(a){J.H4(this.UI,a)},"$1",null,2,0,null,74,"call"],
-$isEH:true},
 xn:{
-"^":"Tp:5;bK",
-$1:[function(a){J.H4(this.bK,["spawn failed",a])},"$1",null,2,0,null,75,"call"],
+"^":"TpZ:13;UI",
+$1:[function(a){J.H4(this.UI,a)},"$1",null,2,0,null,75,"call"],
 $isEH:true},
-WK:{
-"^":"Tp:13;a",
+jl3:{
+"^":"TpZ:5;bK",
+$1:[function(a){J.H4(this.bK,["spawn failed",a])},"$1",null,2,0,null,76,"call"],
+$isEH:true},
+yk:{
+"^":"TpZ:13;a",
 $1:[function(a){var z,y
 z=J.U6(a)
 y=this.a
 if(J.xC(z.t(a,0),"spawned")){z=y.MM
 if(z.Gv!==0)H.vh(P.w("Future already completed"))
-z.OH(a)}else y.pm(z.t(a,1))},"$1",null,2,0,null,74,"call"],
+z.OH(a)}else y.pm(z.t(a,1))},"$1",null,2,0,null,75,"call"],
 $isEH:true},
-tZ:{
-"^":"Tp:5;b",
-$1:[function(a){return this.b.pm(a)},"$1",null,2,0,null,76,"call"],
+WK:{
+"^":"TpZ:5;b",
+$1:[function(a){return this.b.pm(a)},"$1",null,2,0,null,77,"call"],
 $isEH:true},
 hI:{
-"^":"Tp:71;a,b,c,d,e",
+"^":"TpZ:72;a,b,c,d,e",
 $0:[function(){var z=this.a
 H.Di(init.globalFunctions[this.b](),z.a,z.b,this.c,this.d,this.e)},"$0",null,0,0,null,"call"],
 $isEH:true},
 vK:{
-"^":"Tp:18;a,b,c,d,e",
+"^":"TpZ:18;a,b,c,d,e",
 $0:[function(){var z,y,x
 this.e.sxF(!0)
 if(this.d!==!0)this.a.$1(this.c)
@@ -917,7 +933,7 @@
 Iy4:{
 "^":"a;",
 $ispW:true,
-$isXY:true},
+$ishq:true},
 VU:{
 "^":"Iy4;JE,tv",
 wR:function(a,b){var z,y,x,w,v
@@ -939,13 +955,13 @@
 giO:function(a){return J.ki(this.JE)},
 $isVU:true,
 $ispW:true,
-$isXY:true},
+$ishq:true},
 Ua:{
-"^":"Tp:71;a,b,c",
+"^":"TpZ:72;a,b,c",
 $0:[function(){var z,y
 z=this.b.JE
 if(!z.gKS()){if(this.c){y=this.a
-y.a=H.Hh(y.a)}J.n0(z,this.a.a)}},"$0",null,0,0,null,"call"],
+y.a=H.b0(y.a)}J.n0(z,this.a.a)}},"$0",null,0,0,null,"call"],
 $isEH:true},
 bM:{
 "^":"Iy4;ZU,bv,tv",
@@ -964,7 +980,7 @@
 return(z^y^x)>>>0},
 $isbM:true,
 $ispW:true,
-$isXY:true},
+$ishq:true},
 yo:{
 "^":"a;qK>,D1,KS<",
 wy:function(a){return this.D1.$1(a)},
@@ -992,14 +1008,14 @@
 yI:function(a){return this.KR(a,null,null,null)},
 xO:[function(a){this.vl.xO(0)
 this.tU.xO(0)},"$0","gQF",0,0,18],
-TL:function(a){var z=P.x2(this.gQF(this),null,null,null,!0,null)
+TL:function(a){var z=P.HT(this.gQF(this),null,null,null,!0,null)
 this.tU=z
 this.vl.D1=z.ght(z)},
 $aswS:function(){return[null]},
 $iswS:true},
 RS:{
-"^":"jP1;Ao,mR",
-DE:function(a){if(!!a.$isVU)return["sendport",init.globalState.oL,a.tv,J.ki(a.JE)]
+"^":"hz;Ao,mR",
+DE:function(a){if(!!a.$isVU)return["sendport",init.globalState.NO,a.tv,J.ki(a.JE)]
 if(!!a.$isbM)return["sendport",a.ZU,a.tv,a.bv]
 throw H.b("Illegal underlying port "+a.bu(0))},
 yf:function(a){if(!!a.$isiV)return["capability",a.qK]
@@ -1018,22 +1034,22 @@
 y=z.t(a,1)
 x=z.t(a,2)
 w=z.t(a,3)
-if(J.xC(y,init.globalState.oL)){v=init.globalState.iR.t(0,x)
+if(J.xC(y,init.globalState.NO)){v=init.globalState.iR.t(0,x)
 if(v==null)return
 u=v.hV(w)
 if(u==null)return
 return new H.VU(u,x)}else return new H.bM(y,w,x)},
 Op:function(a){return new H.iV(J.UQ(a,1))}},
 m3:{
-"^":"a;MD",
+"^":"a;u5",
 t:function(a,b){return b.__MessageTraverser__attached_info__},
-u:function(a,b,c){this.MD.push(b)
+u:function(a,b,c){this.u5.push(b)
 b.__MessageTraverser__attached_info__=c},
-CH:function(a){this.MD=[]},
+CH:function(a){this.u5=[]},
 no:function(){var z,y,x
-for(z=this.MD.length,y=0;y<z;++y){x=this.MD
+for(z=this.u5.length,y=0;y<z;++y){x=this.u5
 if(y>=x.length)return H.e(x,y)
-x[y].__MessageTraverser__attached_info__=null}this.MD=null}},
+x[y].__MessageTraverser__attached_info__=null}this.u5=null}},
 cx:{
 "^":"a;",
 t:function(a,b){return},
@@ -1053,7 +1069,7 @@
 if(!!z.$isWO)return this.wb(a)
 if(!!z.$isZ0)return this.TI(a)
 if(!!z.$ispW)return this.DE(a)
-if(!!z.$isXY)return this.yf(a)
+if(!!z.$ishq)return this.yf(a)
 return this.N1(a)},
 N1:function(a){throw H.b("Message serialization: Illegal value "+H.d(a)+" passed")}},
 ooy:{
@@ -1082,11 +1098,11 @@
 DE:function(a){return H.vh(P.SY(null))},
 yf:function(a){return H.vh(P.SY(null))}},
 RK:{
-"^":"Tp:79;a,b",
+"^":"TpZ:80;a,b",
 $2:[function(a,b){var z=this.b
-J.kW(this.a.a,z.Q9(a),z.Q9(b))},"$2",null,4,0,null,77,78,"call"],
+J.kW(this.a.a,z.Q9(a),z.Q9(b))},"$2",null,4,0,null,78,79,"call"],
 $isEH:true},
-jP1:{
+hz:{
 "^":"BB;",
 Pq:function(a){return a},
 wb:function(a){var z,y
@@ -1175,12 +1191,12 @@
 z.Qa(a,b)
 return z}}},
 Av:{
-"^":"Tp:18;a,b",
+"^":"TpZ:18;a,b",
 $0:[function(){this.a.p9=null
 this.b.$0()},"$0",null,0,0,null,"call"],
 $isEH:true},
 vt:{
-"^":"Tp:18;c,d",
+"^":"TpZ:18;c,d",
 $0:[function(){this.c.p9=null
 H.cv()
 this.d.$0()},"$0",null,0,0,null,"call"],
@@ -1205,7 +1221,7 @@
 y=b.qK
 return z==null?y==null:z===y}return!1},
 $isiV:true,
-$isXY:true}}],["_js_helper","dart:_js_helper",,H,{
+$ishq:true}}],["_js_helper","dart:_js_helper",,H,{
 "^":"",
 Gp:function(a,b){var z
 if(b!=null){z=b.x
@@ -1262,30 +1278,30 @@
 if(typeof y==="string")z=/^\w+$/.test(y)?y:z}if(z.length>1&&C.xB.j(z,0)===36)z=C.xB.yn(z,1)
 return(z+H.ia(H.oX(a),0,null)).replace(/[^<,> ]+/g,function(b){return init.mangledGlobalNames[b]||b})},
 a5:function(a){return"Instance of '"+H.lh(a)+"'"},
-Ms:function(){if(typeof window!="undefined"&&window!==null){var z=window.performance
+Ao:function(){if(typeof window!="undefined"&&window!==null){var z=window.performance
 if(z!=null&&typeof z.webkitNow=="function")return C.CD.yu(Math.floor(1000*z.webkitNow()))}return 1000*Date.now()},
-Cb:function(a){var z,y,x,w,v,u
+RF:function(a){var z,y,x,w,v,u
 z=a.length
 for(y=z<=500,x="",w=0;w<z;w+=500){if(y)v=a
 else{u=w+500
 u=u<z?u:z
 v=a.slice(w,u)}x+=String.fromCharCode.apply(null,v)}return x},
-YF:function(a){var z,y,x
+XZ:function(a){var z,y,x
 z=[]
 z.$builtinTypeInfo=[P.KN]
 y=new H.a7(a,a.length,0,null)
-y.$builtinTypeInfo=[H.Kp(a,0)]
+y.$builtinTypeInfo=[H.Oq(a,0)]
 for(;y.G();){x=y.lo
 if(typeof x!=="number"||Math.floor(x)!==x)throw H.b(P.u(x))
 if(x<=65535)z.push(x)
 else if(x<=1114111){z.push(55296+(C.jn.GG(x-65536,10)&1023))
-z.push(56320+(x&1023))}else throw H.b(P.u(x))}return H.Cb(z)},
+z.push(56320+(x&1023))}else throw H.b(P.u(x))}return H.RF(z)},
 LY:function(a){var z,y
-for(z=H.VM(new H.a7(a,a.length,0,null),[H.Kp(a,0)]);z.G();){y=z.lo
+for(z=H.VM(new H.a7(a,a.length,0,null),[H.Oq(a,0)]);z.G();){y=z.lo
 if(typeof y!=="number"||Math.floor(y)!==y)throw H.b(P.u(y))
 if(y<0)throw H.b(P.u(y))
-if(y>65535)return H.YF(a)}return H.Cb(a)},
-JM:function(a){var z
+if(y>65535)return H.XZ(a)}return H.RF(a)},
+mx:function(a){var z
 if(typeof a!=="number")return H.s(a)
 if(0<=a){if(a<=65535)return String.fromCharCode(a)
 if(a<=1114111){z=a-65536
@@ -1297,7 +1313,7 @@
 if(typeof d!=="number"||Math.floor(d)!==d)H.vh(P.u(d))
 if(typeof e!=="number"||Math.floor(e)!==e)H.vh(P.u(e))
 if(typeof f!=="number"||Math.floor(f)!==f)H.vh(P.u(f))
-z=J.bI(b,1)
+z=J.Hn(b,1)
 y=h?Date.UTC(a,z,c,d,e,f,g):new Date(a,z,c,d,e,f,g).valueOf()
 if(isNaN(y)||y<-8640000000000000||y>8640000000000000)throw H.b(P.u(null))
 x=J.Wx(a)
@@ -1374,7 +1390,7 @@
 p=$.W6()
 $.Bi()
 o=$.eA()
-n=$.ko()
+n=$.qK()
 m=v.qS(y)
 if(m!=null)return z.$1(H.T3(y,m))
 else{m=u.qS(y)
@@ -1391,7 +1407,7 @@
 if(v){v=m==null?null:m.method
 return z.$1(new H.Zo(y,v))}}}v=typeof y==="string"?y:""
 return z.$1(new H.vV(v))}if(a instanceof RangeError){if(typeof y==="string"&&y.indexOf("call stack")!==-1)return new P.KY()
-return z.$1(new P.AT(null))}if(typeof InternalError=="function"&&a instanceof InternalError)if(typeof y==="string"&&y==="too much recursion")return new P.KY()
+return z.$1(new P.OY(null))}if(typeof InternalError=="function"&&a instanceof InternalError)if(typeof y==="string"&&y==="too much recursion")return new P.KY()
 return a},
 CU:function(a){if(a==null||typeof a!='object')return J.v1(a)
 else return H.eQ(a)},
@@ -1431,7 +1447,7 @@
 v.prototype=w
 u=!d
 if(u){t=e.length==1&&!0
-s=H.SD(a,z,t)
+s=H.bx(a,z,t)
 s.$reflectionInfo=c}else{w.$name=f
 s=z
 t=!1}if(typeof x=="number")r=function(g){return function(){return init.metadata[g]}}(x)
@@ -1441,7 +1457,7 @@
 w[y]=s
 for(u=b.length,p=1;p<u;++p){o=b[p]
 n=o.$callName
-if(n!=null){m=d?o:H.SD(a,o,t)
+if(n!=null){m=d?o:H.bx(a,o,t)
 w[n]=m}}w["call*"]=s
 return v},
 vq:function(a,b,c,d){var z=H.uj
@@ -1452,7 +1468,7 @@
 case 4:return function(e,f){return function(g,h,i,j){return f(this)[e](g,h,i,j)}}(c,z)
 case 5:return function(e,f){return function(g,h,i,j,k){return f(this)[e](g,h,i,j,k)}}(c,z)
 default:return function(e,f){return function(){return e.apply(f(this),arguments)}}(d,z)}},
-SD:function(a,b,c){var z,y,x,w,v,u
+bx:function(a,b,c){var z,y,x,w,v,u
 if(c)return H.Hf(a,b)
 z=b.$stubName
 y=b.length
@@ -1460,19 +1476,19 @@
 w=b==null?x==null:b===x
 if(typeof dart_precompiled=="function"||!w||y>=27)return H.vq(y,!w,z,b)
 if(y===0){w=$.bf
-if(w==null){w=H.B3("self")
+if(w==null){w=H.bd("self")
 $.bf=w}w="return function(){return this."+H.d(w)+"."+H.d(z)+"();"
 v=$.OK
 $.OK=J.ew(v,1)
 return new Function(w+H.d(v)+"}")()}u="abcdefghijklmnopqrstuvwxyz".split("").splice(0,y).join(",")
 w="return function("+u+"){return this."
 v=$.bf
-if(v==null){v=H.B3("self")
+if(v==null){v=H.bd("self")
 $.bf=v}v=w+H.d(v)+"."+H.d(z)+"("+u+");"
 w=$.OK
 $.OK=J.ew(w,1)
 return new Function(v+H.d(w)+"}")()},
-Zq:function(a,b,c,d){var z,y
+rm:function(a,b,c,d){var z,y
 z=H.uj
 y=H.HY
 switch(b?-1:a){case 0:throw H.b(H.Yi("Intercepted function with no arguments."))
@@ -1488,13 +1504,13 @@
 Hf:function(a,b){var z,y,x,w,v,u,t,s
 z=H.bO()
 y=$.U9
-if(y==null){y=H.B3("receiver")
+if(y==null){y=H.bd("receiver")
 $.U9=y}x=b.$stubName
 w=b.length
 v=typeof dart_precompiled=="function"
 u=a[x]
 t=b==null?u==null:b===u
-if(v||!t||w>=28)return H.Zq(w,!t,x,b)
+if(v||!t||w>=28)return H.rm(w,!t,x,b)
 if(w===1){y="return function(){return this."+H.d(z)+"."+H.d(x)+"(this."+H.d(y)+");"
 t=$.OK
 $.OK=J.ew(t,1)
@@ -1516,8 +1532,8 @@
 ag:function(a){throw H.b(P.mE("Cyclic initialization for static "+H.d(a)))},
 KT:function(a,b,c){return new H.GN(a,b,c,null)},
 Og:function(a,b){var z=a.name
-if(b==null||b.length===0)return new H.Fp(z)
-return new H.KEA(z,b,null)},
+if(b==null||b.length===0)return new H.tu(z)
+return new H.fw(z,b,null)},
 G3:function(){return C.KZ},
 IL:function(a){return new H.cu(a,null)},
 VM:function(a,b){if(a!=null)a.$builtinTypeInfo=b
@@ -1527,7 +1543,7 @@
 IM:function(a,b){return H.Y9(a["$as"+H.d(b)],H.oX(a))},
 ip:function(a,b,c){var z=H.IM(a,b)
 return z==null?null:z[c]},
-Kp:function(a,b){var z=H.oX(a)
+Oq:function(a,b){var z=H.oX(a)
 return z==null?null:z[b]},
 Ko:function(a,b){if(a==null)return"dynamic"
 else if(typeof a==="object"&&a!==null&&a.constructor===Array)return a[0].builtin$cls+H.ia(a,1,b)
@@ -1543,7 +1559,7 @@
 if(v!=null)w=!1
 u=H.Ko(v,c)
 z.vM+=typeof u==="string"?u:H.d(u)}return w?"":"<"+H.d(z)+">"},
-b7:function(a){var z=J.x(a).constructor.builtin$cls
+wO:function(a){var z=J.x(a).constructor.builtin$cls
 if(a==null)return z
 return z+H.ia(a.$builtinTypeInfo,0,null)},
 Y9:function(a,b){if(typeof a==="object"&&a!==null&&a.constructor===Array)b=a
@@ -1721,7 +1737,7 @@
 else{z=J.x(b)
 if(!!z.$isVR){z=C.xB.yn(a,c)
 y=b.Ej
-return y.test(z)}else return J.yx(z.dd(b,C.xB.yn(a,c)))}},
+return y.test(z)}else return J.pO(z.dd(b,C.xB.yn(a,c)))}},
 ys:function(a,b,c){var z,y,x,w
 if(b==="")if(a==="")return c
 else{z=P.p9("")
@@ -1734,7 +1750,7 @@
 "^":"a;",
 gl0:function(a){return J.xC(this.gB(this),0)},
 gor:function(a){return!J.xC(this.gB(this),0)},
-bu:function(a){return P.vW(this)},
+bu:[function(a){return P.vW(this)},"$0","gAY",0,0,69],
 EP:function(){throw H.b(P.f("Cannot modify unmodifiable Map"))},
 u:function(a,b,c){return this.EP()},
 Rz:function(a,b){return this.EP()},
@@ -1754,12 +1770,12 @@
 z=this.tc
 for(y=0;y<z.length;++y){x=z[y]
 b.$2(x,this.TZ(x))}},
-gvc:function(a){return H.VM(new H.XR(this),[H.Kp(this,0)])},
-gUQ:function(a){return H.K1(this.tc,new H.hY(this),H.Kp(this,0),H.Kp(this,1))},
+gvc:function(a){return H.VM(new H.XR(this),[H.Oq(this,0)])},
+gUQ:function(a){return H.K1(this.tc,new H.hY(this),H.Oq(this,0),H.Oq(this,1))},
 $isyN:true},
 hY:{
-"^":"Tp:13;a",
-$1:[function(a){return this.a.TZ(a)},"$1",null,2,0,null,77,"call"],
+"^":"TpZ:13;a",
+$1:[function(a){return this.a.TZ(a)},"$1",null,2,0,null,78,"call"],
 $isEH:true},
 XR:{
 "^":"mW;Y3",
@@ -1779,18 +1795,18 @@
 x.fixed$length=!0
 return x},
 gVm:function(){var z,y,x,w,v,u,t,s
-if(this.xI!==0)return P.Fl(P.GD,null)
+if(this.xI!==0)return P.Fl(P.IN,null)
 z=this.FX
 y=z.length
 x=this.rq
 w=x.length-y
-if(y===0)return P.Fl(P.GD,null)
-v=P.L5(null,null,null,P.GD,null)
+if(y===0)return P.Fl(P.IN,null)
+v=P.L5(null,null,null,P.IN,null)
 for(u=0;u<y;++u){if(u>=z.length)return H.e(z,u)
 t=z[u]
 s=w+u
 if(s<0||s>=x.length)return H.e(x,s)
-v.u(0,new H.IN(t),x[s])}return v},
+v.u(0,new H.tx(t),x[s])}return v},
 static:{"^":"hAw,eHF,Y8"}},
 FD:{
 "^":"a;mr,Rn>,XZ,Rv,hG,Mo,AM,NE",
@@ -1830,7 +1846,7 @@
 x=z[1]
 return new H.FD(a,z,(y&1)===1,y>>1,x>>1,(x&1)===1,z[2],null)}}},
 uV:{
-"^":"Tp:5;a,b,c",
+"^":"TpZ:5;a,b,c",
 $1:function(a){var z,y,x
 z=this.b.NE
 y=this.a.a++
@@ -1839,14 +1855,14 @@
 z[y]=x},
 $isEH:true},
 Cj:{
-"^":"Tp:80;a,b,c",
+"^":"TpZ:81;a,b,c",
 $2:function(a,b){var z=this.a
 z.b=z.b+"$"+H.d(a)
 this.c.push(a)
 this.b.push(b);++z.a},
 $isEH:true},
 u8:{
-"^":"Tp:80;a,b",
+"^":"TpZ:81;a,b",
 $2:function(a,b){var z=this.b
 if(z.x4(0,a))z.u(0,a,b)
 else this.a.a=!0},
@@ -1868,7 +1884,7 @@
 x=this.cR
 if(x!==-1)y.receiver=z[x+1]
 return y},
-static:{"^":"lm,k1,Re,fN,qi,cz,BX,tt,dt,A7",cM:function(a){var z,y,x,w,v,u
+static:{"^":"lm,k1,Re,fN,qi,cz,BX,tt,dt,Ai",cM:function(a){var z,y,x,w,v,u
 a=a.replace(String({}),'$receiver$').replace(new RegExp("[[\\]{}()*+?.\\\\^$|]",'g'),'\\$&')
 z=a.match(/\\\$[a-zA-Z]+\\\$/g)
 if(z==null)z=[]
@@ -1881,19 +1897,19 @@
 try{$expr$.$method$($argumentsExpr$)}catch(z){return z.message}}(a)},Mj:function(a){return function($expr$){try{$expr$.$method$}catch(z){return z.message}}(a)}}},
 Zo:{
 "^":"XS;K9,Ga",
-bu:function(a){var z=this.Ga
+bu:[function(a){var z=this.Ga
 if(z==null)return"NullError: "+H.d(this.K9)
-return"NullError: Cannot call \""+H.d(z)+"\" on null"},
+return"NullError: Cannot call \""+H.d(z)+"\" on null"},"$0","gAY",0,0,69],
 $isJS:true,
 $isXS:true},
 u0:{
 "^":"XS;K9,Ga,cR",
-bu:function(a){var z,y
+bu:[function(a){var z,y
 z=this.Ga
 if(z==null)return"NoSuchMethodError: "+H.d(this.K9)
 y=this.cR
 if(y==null)return"NoSuchMethodError: Cannot call \""+H.d(z)+"\" ("+H.d(this.K9)+")"
-return"NoSuchMethodError: Cannot call \""+H.d(z)+"\" on \""+H.d(y)+"\" ("+H.d(this.K9)+")"},
+return"NoSuchMethodError: Cannot call \""+H.d(z)+"\" on \""+H.d(y)+"\" ("+H.d(this.K9)+")"},"$0","gAY",0,0,69],
 $isJS:true,
 $isXS:true,
 static:{T3:function(a,b){var z,y
@@ -1903,50 +1919,50 @@
 return new H.u0(a,y,z)}}},
 vV:{
 "^":"XS;K9",
-bu:function(a){var z=this.K9
-return C.xB.gl0(z)?"Error":"Error: "+z}},
+bu:[function(a){var z=this.K9
+return C.xB.gl0(z)?"Error":"Error: "+z},"$0","gAY",0,0,69]},
 Am:{
-"^":"Tp:13;a",
+"^":"TpZ:13;a",
 $1:function(a){if(!!J.x(a).$isXS)if(a.$thrownJsError==null)a.$thrownJsError=this.a
 return a},
 $isEH:true},
 XO:{
 "^":"a;lA,ui",
-bu:function(a){var z,y
+bu:[function(a){var z,y
 z=this.ui
 if(z!=null)return z
 z=this.lA
 y=typeof z==="object"?z.stack:null
 z=y==null?"":y
 this.ui=z
-return z}},
+return z},"$0","gAY",0,0,69]},
 dr:{
-"^":"Tp:71;a",
+"^":"TpZ:72;a",
 $0:function(){return this.a.$0()},
 $isEH:true},
 TL:{
-"^":"Tp:71;b,c",
+"^":"TpZ:72;b,c",
 $0:function(){return this.b.$1(this.c)},
 $isEH:true},
 uZ:{
-"^":"Tp:71;d,e,f",
+"^":"TpZ:72;d,e,f",
 $0:function(){return this.d.$2(this.e,this.f)},
 $isEH:true},
 OQ:{
-"^":"Tp:71;UI,bK,Gq,Rm",
+"^":"TpZ:72;UI,bK,Gq,Rm",
 $0:function(){return this.UI.$3(this.bK,this.Gq,this.Rm)},
 $isEH:true},
 Qx:{
-"^":"Tp:71;w3,HZ,mG,xC,cj",
+"^":"TpZ:72;w3,HZ,mG,xC,cj",
 $0:function(){return this.w3.$4(this.HZ,this.mG,this.xC,this.cj)},
 $isEH:true},
-Tp:{
+TpZ:{
 "^":"a;",
-bu:function(a){return"Closure"},
+bu:[function(a){return"Closure"},"$0","gAY",0,0,69],
 $isEH:true,
 gKu:function(){return this}},
 Bp:{
-"^":"Tp;"},
+"^":"TpZ;"},
 v:{
 "^":"Bp;nw,jm,cR,RA",
 n:function(a,b){if(b==null)return!1
@@ -1960,8 +1976,8 @@
 return J.UN(y,H.eQ(this.jm))},
 $isv:true,
 static:{"^":"bf,U9",uj:function(a){return a.nw},HY:function(a){return a.cR},bO:function(){var z=$.bf
-if(z==null){z=H.B3("self")
-$.bf=z}return z},B3:function(a){var z,y,x,w,v
+if(z==null){z=H.bd("self")
+$.bf=z}return z},bd:function(a){var z,y,x,w,v
 z=new H.v("self","target","receiver","name")
 y=Object.getOwnPropertyNames(z)
 y.fixed$length=init
@@ -1970,12 +1986,12 @@
 if(z[v]===a)return v}}}},
 Pe:{
 "^":"XS;G1>",
-bu:function(a){return this.G1},
+bu:[function(a){return this.G1},"$0","gAY",0,0,69],
 $isXS:true,
 static:{aq:function(a,b){return new H.Pe("CastError: Casting value of type "+H.d(a)+" to incompatible type "+H.d(b))}}},
 bb:{
 "^":"XS;G1>",
-bu:function(a){return"RuntimeError: "+H.d(this.G1)},
+bu:[function(a){return"RuntimeError: "+H.d(this.G1)},"$0","gAY",0,0,69],
 static:{Yi:function(a){return new H.bb(a)}}},
 lbp:{
 "^":"a;"},
@@ -2000,7 +2016,7 @@
 v=H.kU(y)
 for(x=v.length,u=0;u<x;++u){t=v[u]
 w[t]=y[t].za()}z.named=w}return z},
-bu:function(a){var z,y,x,w,v,u,t,s
+bu:[function(a){var z,y,x,w,v,u,t,s
 z=this.Iq
 if(z!=null)for(y=z.length,x="(",w=!1,v=0;v<y;++v,w=!0){u=z[v]
 if(w)x+=", "
@@ -2014,7 +2030,7 @@
 t=H.kU(z)
 for(y=t.length,w=!1,v=0;v<y;++v,w=!0){s=t[v]
 if(w)x+=", "
-x+=H.d(z[s].za())+" "+s}x+="}"}}return x+(") -> "+H.d(this.dw))},
+x+=H.d(z[s].za())+" "+s}x+="}"}}return x+(") -> "+H.d(this.dw))},"$0","gAY",0,0,69],
 static:{"^":"lcs",Dz:function(a){var z,y,x
 a=a
 z=[]
@@ -2022,18 +2038,18 @@
 return z}}},
 hJ:{
 "^":"lbp;",
-bu:function(a){return"dynamic"},
+bu:[function(a){return"dynamic"},"$0","gAY",0,0,69],
 za:function(){return},
 $ishJ:true},
-Fp:{
+tu:{
 "^":"lbp;oc>",
 za:function(){var z,y
 z=this.oc
 y=init.allClasses[z]
 if(y==null)throw H.b("no type for '"+H.d(z)+"'")
 return y},
-bu:function(a){return this.oc}},
-KEA:{
+bu:[function(a){return this.oc},"$0","gAY",0,0,69]},
+fw:{
 "^":"lbp;oc>,re,Et",
 za:function(){var z,y
 z=this.Et
@@ -2042,33 +2058,33 @@
 y=[init.allClasses[z]]
 if(0>=y.length)return H.e(y,0)
 if(y[0]==null)throw H.b("no type for '"+H.d(z)+"<...>'")
-for(z=this.re,z=H.VM(new H.a7(z,z.length,0,null),[H.Kp(z,0)]);z.G();)y.push(z.lo.za())
+for(z=this.re,z=H.VM(new H.a7(z,z.length,0,null),[H.Oq(z,0)]);z.G();)y.push(z.lo.za())
 this.Et=y
 return y},
-bu:function(a){return H.d(this.oc)+"<"+J.Ia(this.re,", ")+">"}},
+bu:[function(a){return H.d(this.oc)+"<"+J.uG(this.re,", ")+">"},"$0","gAY",0,0,69]},
 cu:{
 "^":"a;LU,ke",
-bu:function(a){var z,y
+bu:[function(a){var z,y
 z=this.ke
 if(z!=null)return z
 y=this.LU.replace(/[^<,> ]+/g,function(b){return init.mangledGlobalNames[b]||b})
 this.ke=y
-return y},
+return y},"$0","gAY",0,0,69],
 giO:function(a){return J.v1(this.LU)},
 n:function(a,b){if(b==null)return!1
 return!!J.x(b).$iscu&&J.xC(this.LU,b.LU)},
 $iscu:true,
 $isuq:true},
 dC:{
-"^":"Tp:13;a",
+"^":"TpZ:13;a",
 $1:function(a){return this.a(a)},
 $isEH:true},
 VX:{
-"^":"Tp:81;b",
+"^":"TpZ:82;b",
 $2:function(a,b){return this.b(a,b)},
 $isEH:true},
 rh:{
-"^":"Tp:5;c",
+"^":"TpZ:5;c",
 $1:function(a){return this.c(a)},
 $isEH:true},
 VR:{
@@ -2166,7 +2182,7 @@
 $isns:true}}],["action_link_element","package:observatory/src/elements/action_link.dart",,X,{
 "^":"",
 hV:{
-"^":"LPc;fi,dB,KW,AP,fn,AP,fn,IX,q9,Sa,Uk,oq,Wz,q1,SD,XN,Xy,ZQ",
+"^":"LPc;fi,dB,KW,AP,fn,AP,fn,IX,q9,Cc,Uk,oq,Wz,q1,SD,oG,ZM,ZQ",
 gv8:function(a){return a.fi},
 sv8:function(a,b){a.fi=this.ct(a,C.S4,a.fi,b)},
 gFR:function(a){return a.dB},
@@ -2178,7 +2194,7 @@
 F6:[function(a,b,c,d){var z=a.fi
 if(z===!0)return
 if(a.dB!=null){a.fi=this.ct(a,C.S4,z,!0)
-this.LY(a,null).YM(new X.jE(a))}},"$3","gNa",6,0,82,46,47,83],
+this.LY(a,null).YM(new X.jE(a))}},"$3","gNa",6,0,83,46,47,84],
 static:{zy:function(a){var z,y
 z=P.L5(null,null,null,P.qU,W.I0)
 y=P.qU
@@ -2186,10 +2202,10 @@
 a.fi=!1
 a.dB=null
 a.KW="action"
-a.Sa=[]
+a.Cc=[]
 a.q1=!1
-a.XN=!1
-a.Xy=z
+a.oG=!1
+a.ZM=z
 a.ZQ=y
 C.Df.ZL(a)
 C.Df.XI(a)
@@ -2198,7 +2214,7 @@
 "^":"xc+Pi;",
 $isd3:true},
 jE:{
-"^":"Tp:71;a",
+"^":"TpZ:72;a",
 $0:[function(){var z=this.a
 z.fi=J.Q5(z,C.S4,z.fi,!1)},"$0",null,0,0,null,"call"],
 $isEH:true}}],["app","package:observatory/app.dart",,G,{
@@ -2208,11 +2224,11 @@
 z=J.UQ(J.UQ($.Si(),"google"),"visualization")
 $.BY=z
 return z},"$1","vN",2,0,13,14],
-oh:function(a){var z=$.Vy().getItem(a)
+Xk:function(a){var z=$.Vy().getItem(a)
 if(z==null)return
 return C.xr.kV(z)},
 FI:function(a){if(a==null)return P.Vu(null,null,null)
-return W.Kn("/crdptargets/"+P.jW(C.yD,a,C.xM,!1),null,null).ml(new G.tx()).OA(new G.KF())},
+return W.Kn("/crdptargets/"+P.jW(C.yD,a,C.xM,!1),null,null).ml(new G.KF()).OA(new G.XN())},
 dj:function(a,b){return C.CD.Sy(100*J.X9(a,b),2)+"%"},
 o1:function(a,b){var z
 for(z="";b>1;){--b
@@ -2224,7 +2240,7 @@
 a=z.Z(a,1000)
 x=G.o1(y,3)
 for(;z=J.Wx(a),z.D(a,1000);){x=G.o1(z.Y(a,1000),3)+","+x
-a=z.Z(a,1000)}return!z.n(a,0)?H.d(a)+","+x:x},"$1","kh",2,0,15],
+a=z.Z(a,1000)}return!z.n(a,0)?H.d(a)+","+x:x},"$1","xK",2,0,15],
 P0:function(a){var z,y,x,w
 z=C.CD.yu(C.CD.UD(a*1000))
 y=C.jn.cU(z,3600000)
@@ -2253,7 +2269,7 @@
 if(x!==0)return""+x+"m "+w+"s"
 return""+w+"s"},
 mL:{
-"^":"Pi;cE,GZ,Z6,Eh,m2<,Eb,bn,Pv,cC,AP,fn",
+"^":"Pi;OJ,Ef,Z6,Eh,m2<,Eb,bn,Pv,cC,AP,fn",
 gwv:function(a){return this.Eh},
 swv:function(a,b){var z
 if(J.xC(this.Eh,b))return
@@ -2263,74 +2279,78 @@
 b.gEH().ml(this.gwn())
 J.d7(b).ml(this.gkq())
 z=b.gG2()
-H.VM(new P.Ik(z),[H.Kp(z,0)]).yI(this.gbf())
+H.VM(new P.Ik(z),[H.Oq(z,0)]).yI(this.gbf())
 z=b.gLi()
-H.VM(new P.Ik(z),[H.Kp(z,0)]).yI(this.gXa())}this.Eh=b},
+H.VM(new P.Ik(z),[H.Oq(z,0)]).yI(this.gXa())}this.Eh=b},
 god:function(a){return this.Eb},
 sod:function(a,b){this.Eb=F.Wi(this,C.rB,this.Eb,b)},
 gvK:function(){return this.cC},
 svK:function(a){this.cC=F.Wi(this,C.c6,this.cC,a)},
 AQ:function(a){var z,y
-$.mf=this
-z=this.cE
-z.push(new G.BA(this,null,null,null))
-z.push(new G.HS(this,null,null,null))
-z.push(new G.f2(this,null,null,null))
-z.push(new G.cZ(this,null,null,null))
+$.Kh=this
+z=this.OJ
+z.push(new G.t9(this,null,null,null,null))
+z.push(new G.v5(this,null,null,null,null))
+z.push(new G.Sy(this,null,null,null,null))
+z.push(new G.by(this,null,null,null,null))
 z=this.Z6
 z.ec=this
 y=H.VM(new W.RO(window,C.yf.Ph,!1),[null])
-H.VM(new W.Ov(0,y.DK,y.Ph,W.aF(z.gbQ()),y.Sg),[H.Kp(y,0)]).Zz()
+H.VM(new W.Ov(0,y.DK,y.Ph,W.aF(z.gbQ()),y.Sg),[H.Oq(y,0)]).Zz()
 z.Cy()},
-x3:function(a){J.uY(this.cC,new G.dw(a,new G.cE()))},
-kj:[function(a){this.Pv=a
-this.og("error/",null)},"$1","gbf",2,0,84,24],
+x3:function(a){J.rA(this.cC,new G.xE(a,new G.cE()))},
+yS:[function(a){this.Pv=a
+this.og("error/",null)},"$1","gbf",2,0,85,24],
 kI:[function(a){this.Pv=a
 if(J.xC(J.Iz(a),"NetworkException"))this.Z6.bo(0,"#/vm-connect/")
-else this.og("error/",null)},"$1","gXa",2,0,85,86],
-og:function(a,b){var z,y,x
-for(z=this.cE,y=0;y<z.length;++y){x=z[y]
-if(x.VU(a)){this.lJ(x)
-x.DV(a)
+else this.og("error/",null)},"$1","gXa",2,0,86,87],
+og:function(a,b){var z,y,x,w,v
+z=b==null?P.Fl(null,null):P.Ms(b,C.xM)
+for(y=this.OJ,x=0;x<y.length;++x){w=y[x]
+if(w.VU(a)){this.GP(w)
+y=R.tB(z)
+v=w.fz
+if(w.gnz(w)&&!J.xC(v,y)){v=new T.qI(w,C.Zg,v,y)
+v.$builtinTypeInfo=[null]
+w.nq(w,v)}w.fz=y
+w.qY(a)
 return}}throw H.b(P.a9())},
-lJ:function(a){var z,y,x,w
-y=this.GZ
+GP:function(a){var z,y,x,w
+if(J.xC(this.Ef,a))return
+if(this.Ef!=null){N.QM("").To("Uninstalling page: "+H.d(this.Ef))
+this.Ef.oV()
+J.r4(this.bn)}N.QM("").To("Installing page: "+H.d(a))
+try{a.ci()}catch(y){x=H.Ru(y)
+z=x
+N.QM("").YX("Failed to install page: "+H.d(z))}this.bn.appendChild(a.gyF())
 x=a
-if(y==null?x==null:y===x)return
-if(y!=null){N.QM("").To("Uninstalling pane: "+J.AG(this.GZ))
-y=this.GZ
-x=y.yF
-if(y.gnz(y)&&x!=null){x=new T.qI(y,C.GP,x,null)
-x.$builtinTypeInfo=[null]
-y.nq(y,x)}y.yF=null
-J.r4(this.bn)}N.QM("").To("Installing pane: "+H.d(a))
-try{a.ci()}catch(w){y=H.Ru(w)
-z=y
-N.QM("").YX("Failed to install pane: "+H.d(z))}this.bn.appendChild(a.gyF())
-this.GZ=a},
-mn:[function(a){if(!!J.x(a).$isKM)this.m2.h(0,a.N)},"$1","gwn",2,0,87,88],
+w=this.Ef
+if(this.gnz(this)&&!J.xC(w,x)){w=new T.qI(this,C.RG,w,x)
+w.$builtinTypeInfo=[null]
+this.nq(this,w)}this.Ef=x},
+ab:[function(a){if(!!J.x(a).$isKM)this.m2.h(0,a.N)},"$1","gwn",2,0,88,89],
 aO:[function(a){if(!J.xC(this.Eh,a))return
 this.swv(0,null)
-this.Z6.bo(0,"#/vm-connect/")},"$1","gkq",2,0,87,88],
+this.Z6.bo(0,"#/vm-connect/")},"$1","gkq",2,0,88,89],
 Ty:function(a){var z=this.m2.TY
 z=new U.KM(H.VM(new P.Zf(P.Dt(null)),[null]),H.VM(new P.Zf(P.Dt(null)),[null]),z,P.L5(null,null,null,P.qU,U.U2),P.L5(null,null,null,P.qU,U.U2),0,null,"unknown","unknown",0,!1,!1,"",null,P.bK(null,null,!1,null),P.bK(null,null,!1,null),P.bK(null,null,!1,null),P.L5(null,null,null,P.qU,D.af),P.L5(null,null,null,P.qU,D.bv),null,null,null,null,null,!1,null,null,null,null,null)
 z.Lw()
 this.swv(0,z)
 this.AQ(!1)},
-E0:function(a){var z=new U.ZW(H.VM(new P.Zf(P.Dt(null)),[null]),H.VM(new P.Zf(P.Dt(null)),[null]),P.L5(null,null,null,P.qU,P.AE),0,"unknown","unknown",0,!1,!1,"",null,P.bK(null,null,!1,null),P.bK(null,null,!1,null),P.bK(null,null,!1,null),P.L5(null,null,null,P.qU,D.af),P.L5(null,null,null,P.qU,D.bv),null,null,null,null,null,!1,null,null,null,null,null)
+E0:function(a){var z=new U.dS(H.VM(new P.Zf(P.Dt(null)),[null]),H.VM(new P.Zf(P.Dt(null)),[null]),P.L5(null,null,null,P.qU,P.A5),0,"unknown","unknown",0,!1,!1,"",null,P.bK(null,null,!1,null),P.bK(null,null,!1,null),P.bK(null,null,!1,null),P.L5(null,null,null,P.qU,D.af),P.L5(null,null,null,P.qU,D.bv),null,null,null,null,null,!1,null,null,null,null,null)
 z.Lw()
 z.ZH()
 this.swv(0,z)
 this.AQ(!0)},
-static:{"^":"mf<"}},
+static:{"^":"Kh<"}},
 cE:{
-"^":"Tp:89;",
+"^":"TpZ:90;",
 $1:function(a){var z=J.RE(a)
 return J.xC(z.gfG(a),"IsolateInterrupted")||J.xC(z.gfG(a),"BreakpointReached")||J.xC(z.gfG(a),"ExceptionThrown")},
 $isEH:true},
-dw:{
-"^":"Tp:13;a,b",
-$1:[function(a){return J.xC(J.aT(a),this.a)&&this.b.$1(a)===!0},"$1",null,2,0,null,90,"call"],
+xE:{
+"^":"TpZ:13;a,b",
+$1:[function(a){return J.xC(J.aT(a),this.a)&&this.b.$1(a)===!0},"$1",null,2,0,null,91,"call"],
 $isEH:true},
 Kf:{
 "^":"a;KJ",
@@ -2340,7 +2360,7 @@
 z.V7("removeRows",[0,z.nQ("getNumberOfRows")])},
 Id:function(a,b){var z=[]
 C.Nm.FV(z,J.kl(b,P.En()))
-this.KJ.V7("addRow",[H.VM(new P.Tz(z),[null])])}},
+this.KJ.V7("addRow",[H.VM(new P.GD(z),[null])])}},
 qu:{
 "^":"a;vR,bG",
 W2:function(a){var z=P.jT(this.bG)
@@ -2363,7 +2383,7 @@
 if(y>1&&!J.xC(z[1],"")){if(1>=z.length)return H.e(z,1)
 x=z[1]}else x=null}else x=null
 this.ec.og(a,x)},
-Cz:function(a,b,c){var z,y,x
+WV:function(a,b,c){var z,y,x
 z=J.Vs(c).MW.getAttribute("href")
 y=J.RE(a)
 x=y.gpL(a)
@@ -2377,64 +2397,67 @@
 if(window.location.hash===""||window.location.hash==="#")z="#"+this.MP
 window.history.pushState(z,document.title,z)
 this.lU(window.location.hash)},
-y0:[function(a){this.lU(window.location.hash)},"$1","gbQ",2,0,91,14],
+y0:[function(a){this.lU(window.location.hash)},"$1","gbQ",2,0,92,14],
 wa:function(a){return"#"+H.d(a)}},
-uG:{
+OS:{
 "^":"Pi;i6>,yF<",
 gFL:function(a){return this.yF},
-$isuG:true},
-cZ:{
-"^":"uG;i6,yF,AP,fn",
+gKw:function(a){return this.fz},
+sKw:function(a,b){this.fz=F.Wi(this,C.Zg,this.fz,b)},
+oV:function(){this.yF=F.Wi(this,C.GP,this.yF,null)},
+$isOS:true},
+by:{
+"^":"OS;i6,yF,fz,AP,fn",
 ci:function(){if(this.yF==null){var z=W.r3("service-view",null)
 this.yF=F.Wi(this,C.GP,this.yF,z)}},
-DV:function(a){if(J.xC(a,""))return
-this.i6.Eh.cv(a).ml(new G.zv(this)).OA(new G.OX())},
+qY:function(a){if(J.xC(a,""))return
+this.i6.Eh.cv(a).ml(new G.mo(this)).OA(new G.Go5())},
 VU:function(a){return!0}},
-zv:{
-"^":"Tp:13;a",
-$1:[function(a){J.h9(this.a.yF,a)},"$1",null,2,0,null,92,"call"],
+mo:{
+"^":"TpZ:13;a",
+$1:[function(a){J.h9(this.a.yF,a)},"$1",null,2,0,null,93,"call"],
 $isEH:true},
-OX:{
-"^":"Tp:13;",
-$1:[function(a){N.QM("").YX("ServiceObjectPane visit error: "+H.d(a))},"$1",null,2,0,null,1,"call"],
+Go5:{
+"^":"TpZ:13;",
+$1:[function(a){N.QM("").YX("ServiceObjectPage visit error: "+H.d(a))},"$1",null,2,0,null,1,"call"],
 $isEH:true},
-BA:{
-"^":"uG;i6,yF,AP,fn",
+t9:{
+"^":"OS;i6,yF,fz,AP,fn",
 ci:function(){if(this.yF==null){var z=W.r3("class-tree",null)
 this.yF=F.Wi(this,C.GP,this.yF,z)}},
-DV:function(a){a=J.ZZ(a,11)
-this.i6.Eh.cv(a).ml(new G.yk(this)).OA(new G.qH())},
+qY:function(a){a=J.ZZ(a,11)
+this.i6.Eh.cv(a).ml(new G.Za(this)).OA(new G.ha())},
 VU:function(a){return J.co(a,"class-tree/")},
-static:{"^":"o9x"}},
-yk:{
-"^":"Tp:13;a",
+static:{"^":"rjk"}},
+Za:{
+"^":"TpZ:13;a",
 $1:[function(a){var z=this.a.yF
-if(z!=null)J.uM(z,a)},"$1",null,2,0,null,93,"call"],
+if(z!=null)J.uM(z,a)},"$1",null,2,0,null,94,"call"],
 $isEH:true},
-qH:{
-"^":"Tp:13;",
-$1:[function(a){N.QM("").YX("ClassTreePane visit error: "+H.d(a))},"$1",null,2,0,null,1,"call"],
+ha:{
+"^":"TpZ:13;",
+$1:[function(a){N.QM("").YX("ClassTreePage visit error: "+H.d(a))},"$1",null,2,0,null,1,"call"],
 $isEH:true},
-f2:{
-"^":"uG;i6,yF,AP,fn",
+Sy:{
+"^":"OS;i6,yF,fz,AP,fn",
 ci:function(){if(this.yF==null){var z=W.r3("service-view",null)
 this.yF=F.Wi(this,C.GP,this.yF,z)}},
-DV:function(a){var z,y
+qY:function(a){var z,y
 z=H.Go(this.yF,"$isTi")
 y=this.i6.Pv
 z.Ll=J.Q5(z,C.td,z.Ll,y)},
 VU:function(a){return J.co(a,"error/")}},
-HS:{
-"^":"uG;i6,yF,AP,fn",
+v5:{
+"^":"OS;i6,yF,fz,AP,fn",
 ci:function(){if(this.yF==null){var z=W.r3("vm-connect",null)
 this.yF=F.Wi(this,C.GP,this.yF,z)}},
-DV:function(a){},
+qY:function(a){},
 VU:function(a){return J.co(a,"vm-connect/")}},
 ut:{
 "^":"a;IU",
-cv:function(a){return G.oh(this.IU+"."+H.d(a))}},
-tx:{
-"^":"Tp:5;",
+cv:function(a){return G.Xk(this.IU+"."+H.d(a))}},
+KF:{
+"^":"TpZ:5;",
 $1:[function(a){var z,y,x,w
 z=C.xr.kV(a)
 if(z==null)return z
@@ -2443,15 +2466,15 @@
 while(!0){w=y.gB(z)
 if(typeof w!=="number")return H.s(w)
 if(!(x<w))break
-y.u(z,x,U.K9(y.t(z,x)));++x}return z},"$1",null,2,0,null,94,"call"],
+y.u(z,x,U.K9(y.t(z,x)));++x}return z},"$1",null,2,0,null,95,"call"],
 $isEH:true},
-KF:{
-"^":"Tp:13;",
+XN:{
+"^":"TpZ:13;",
 $1:[function(a){},"$1",null,2,0,null,1,"call"],
 $isEH:true},
 nD:{
 "^":"d3;wu,jY>,TY,ro,dUC,pt",
-NY:function(){return"ws://"+H.d(window.location.host)+"/ws"},
+BZ:function(){return"ws://"+H.d(window.location.host)+"/ws"},
 TP:function(a){var z=this.MG(a)
 if(z!=null)return z
 z=new U.Z5(0,!1,null,a)
@@ -2461,7 +2484,7 @@
 z={}
 z.a=null
 y=this.jY
-y.aN(y,new G.La(z,a))
+y.aN(y,new G.Un(z,a))
 return z.a},
 h:function(a,b){var z,y
 if(b.gA9()===!0)return
@@ -2484,7 +2507,7 @@
 UJ:function(){var z,y,x,w,v
 z=this.jY
 z.V1(z)
-y=G.oh(this.wu.IU+".history")
+y=G.Xk(this.wu.IU+".history")
 if(y==null)return
 x=J.U6(y)
 w=0
@@ -2494,16 +2517,16 @@
 x.u(y,w,U.K9(x.t(y,w)));++w}z.FV(0,y)
 this.XT()},
 Ff:function(){this.UJ()
-var z=this.TP(this.NY())
+var z=this.TP(this.BZ())
 this.TY=z
 this.h(0,z)},
-static:{"^":"AN"}},
-La:{
-"^":"Tp:13;a,b",
+static:{"^":"dI"}},
+Un:{
+"^":"TpZ:13;a,b",
 $1:function(a){if(J.xC(a.gw8(),this.b)&&J.xC(a.gA9(),!1))this.a.a=a},
 $isEH:true},
 jQ:{
-"^":"Tp:95;",
+"^":"TpZ:96;",
 $2:function(a,b){return J.FW(b.geX(),a.geX())},
 $isEH:true},
 Y2:{
@@ -2521,7 +2544,7 @@
 return this.yq},
 k7:function(a){if(!this.Nh())this.aZ=F.Wi(this,C.Pn,this.aZ,"visibility:hidden;")},
 $isY2:true},
-XN:{
+iY:{
 "^":"Pi;vp>,AP,fn",
 mA:function(a){var z,y
 z=this.vp
@@ -2561,10 +2584,10 @@
 F.Wi(this,C.JB,0,1)},
 eE:function(a,b){var z=this.vp
 if(a>>>0!==a||a>=z.length)return H.e(z,a)
-return J.UQ(J.TP(z[a]),b)},
+return J.UQ(J.U8o(z[a]),b)},
 PV:[function(a,b){var z=this.eE(a,this.pT)
-return J.FW(this.eE(b,this.pT),z)},"$2","gpPX",4,0,96],
-zF:[function(a,b){return J.FW(this.eE(a,this.pT),this.eE(b,this.pT))},"$2","gPd",4,0,96],
+return J.FW(this.eE(b,this.pT),z)},"$2","gpPX",4,0,97],
+zF:[function(a,b){return J.FW(this.eE(a,this.pT),this.eE(b,this.pT))},"$2","gPd",4,0,97],
 Jd:function(a){var z,y
 new P.VV(1000000,null,null).wE(0)
 z=this.zz
@@ -2579,7 +2602,7 @@
 Gu:function(a,b){var z,y
 z=this.vp
 if(a>=z.length)return H.e(z,a)
-y=J.UQ(J.TP(z[a]),b)
+y=J.UQ(J.U8o(z[a]),b)
 z=this.oH
 if(b>=z.length)return H.e(z,b)
 return z[b].gOV().$1(y)},
@@ -2589,1846 +2612,1902 @@
 return J.ew(J.Yq(z[a]),"\u2003")}z=this.oH
 if(a>>>0!==a||a>=z.length)return H.e(z,a)
 z=J.Yq(z[a])
-return J.ew(z,this.jV?"\u25bc":"\u25b2")},"$1","gCO",2,0,15,97]}}],["app_bootstrap","index.html_bootstrap.dart",,E,{
+return J.ew(z,this.jV?"\u25bc":"\u25b2")},"$1","gCO",2,0,15,98]}}],["app_bootstrap","index.html_bootstrap.dart",,E,{
 "^":"",
 Jz:[function(){var z,y,x,w,v
-z=P.EF([C.aP,new E.em(),C.IH,new E.Lb(),C.cg,new E.QA(),C.j2,new E.Cv(),C.ET,new E.ed(),C.BE,new E.wa(),C.WC,new E.Or(),C.hR,new E.YL(),C.S4,new E.wf(),C.Ro,new E.Oa(),C.hN,new E.emv(),C.AV,new E.Lbd(),C.bV,new E.QAa(),C.C0,new E.CvS(),C.eZ,new E.edy(),C.bk,new E.waE(),C.lH,new E.Ore(),C.am,new E.YLa(),C.oE,new E.wfa(),C.kG,new E.Oaa(),C.OI,new E.e0(),C.I9,new E.e1(),C.To,new E.e2(),C.XA,new E.e3(),C.i4,new E.e4(),C.qt,new E.e5(),C.p1,new E.e6(),C.yJ,new E.e7(),C.la,new E.e8(),C.yL,new E.e9(),C.bJ,new E.e10(),C.ox,new E.e11(),C.Je,new E.e12(),C.Lw,new E.e13(),C.iE,new E.e14(),C.f4,new E.e15(),C.VK,new E.e16(),C.aH,new E.e17(),C.aK,new E.e18(),C.GP,new E.e19(),C.vs,new E.e20(),C.Gr,new E.e21(),C.TU,new E.e22(),C.Fe,new E.e23(),C.tP,new E.e24(),C.yh,new E.e25(),C.Zb,new E.e26(),C.u7,new E.e27(),C.p8,new E.e28(),C.qR,new E.e29(),C.ld,new E.e30(),C.ne,new E.e31(),C.B0,new E.e32(),C.r1,new E.e33(),C.mr,new E.e34(),C.Ek,new E.e35(),C.Pn,new E.e36(),C.YT,new E.e37(),C.h7,new E.e38(),C.R3,new E.e39(),C.WQ,new E.e40(),C.fV,new E.e41(),C.jU,new E.e42(),C.Gd,new E.e43(),C.OO,new E.e44(),C.Mc,new E.e45(),C.FP,new E.e46(),C.kF,new E.e47(),C.UD,new E.e48(),C.Aq,new E.e49(),C.DS,new E.e50(),C.C9,new E.e51(),C.VF,new E.e52(),C.uU,new E.e53(),C.YJ,new E.e54(),C.eF,new E.e55(),C.oI,new E.e56(),C.ST,new E.e57(),C.QH,new E.e58(),C.qX,new E.e59(),C.rE,new E.e60(),C.nf,new E.e61(),C.pO,new E.e62(),C.EI,new E.e63(),C.JB,new E.e64(),C.RY,new E.e65(),C.d4,new E.e66(),C.cF,new E.e67(),C.Ql,new E.e68(),C.SI,new E.e69(),C.zS,new E.e70(),C.YA,new E.e71(),C.ak,new E.e72(),C.Ge,new E.e73(),C.He,new E.e74(),C.im,new E.e75(),C.Ss,new E.e76(),C.k6,new E.e77(),C.oj,new E.e78(),C.PJ,new E.e79(),C.q2,new E.e80(),C.d2,new E.e81(),C.kN,new E.e82(),C.fn,new E.e83(),C.yB,new E.e84(),C.eJ,new E.e85(),C.iG,new E.e86(),C.Py,new E.e87(),C.pC,new E.e88(),C.uu,new E.e89(),C.qs,new E.e90(),C.XH,new E.e91(),C.tJ,new E.e92(),C.F8,new E.e93(),C.C1,new E.e94(),C.nL,new E.e95(),C.a0,new E.e96(),C.Yg,new E.e97(),C.bR,new E.e98(),C.ai,new E.e99(),C.ob,new E.e100(),C.Iv,new E.e101(),C.Wg,new E.e102(),C.tD,new E.e103(),C.nZ,new E.e104(),C.Of,new E.e105(),C.pY,new E.e106(),C.XL,new E.e107(),C.LA,new E.e108(),C.Lk,new E.e109(),C.dK,new E.e110(),C.xf,new E.e111(),C.rB,new E.e112(),C.bz,new E.e113(),C.Jx,new E.e114(),C.b5,new E.e115(),C.Lc,new E.e116(),C.hf,new E.e117(),C.uk,new E.e118(),C.Zi,new E.e119(),C.TN,new E.e120(),C.kA,new E.e121(),C.GI,new E.e122(),C.Wn,new E.e123(),C.ur,new E.e124(),C.VN,new E.e125(),C.EV,new E.e126(),C.VI,new E.e127(),C.eh,new E.e128(),C.r6,new E.e129(),C.MW,new E.e130(),C.SA,new E.e131(),C.kV,new E.e132(),C.vp,new E.e133(),C.cc,new E.e134(),C.DY,new E.e135(),C.Lx,new E.e136(),C.M3,new E.e137(),C.wT,new E.e138(),C.SR,new E.e139(),C.t6,new E.e140(),C.rP,new E.e141(),C.pX,new E.e142(),C.VD,new E.e143(),C.NN,new E.e144(),C.UX,new E.e145(),C.YS,new E.e146(),C.pu,new E.e147(),C.BJ,new E.e148(),C.c6,new E.e149(),C.td,new E.e150(),C.Gn,new E.e151(),C.zO,new E.e152(),C.vg,new E.e153(),C.Ys,new E.e154(),C.zm,new E.e155(),C.XM,new E.e156(),C.Ic,new E.e157(),C.yG,new E.e158(),C.uI,new E.e159(),C.O9,new E.e160(),C.ba,new E.e161(),C.tW,new E.e162(),C.CG,new E.e163(),C.Wj,new E.e164(),C.vb,new E.e165(),C.UL,new E.e166(),C.AY,new E.e167(),C.QK,new E.e168(),C.AO,new E.e169(),C.Xd,new E.e170(),C.I7,new E.e171(),C.xP,new E.e172(),C.Wm,new E.e173(),C.GR,new E.e174(),C.KX,new E.e175(),C.ja,new E.e176(),C.Dj,new E.e177(),C.ir,new E.e178(),C.dx,new E.e179(),C.ni,new E.e180(),C.X2,new E.e181(),C.F3,new E.e182(),C.UY,new E.e183(),C.Aa,new E.e184(),C.nY,new E.e185(),C.tg,new E.e186(),C.HD,new E.e187(),C.iU,new E.e188(),C.eN,new E.e189(),C.ue,new E.e190(),C.nh,new E.e191(),C.L2,new E.e192(),C.Gs,new E.e193(),C.bE,new E.e194(),C.YD,new E.e195(),C.PX,new E.e196(),C.N8,new E.e197(),C.EA,new E.e198(),C.oW,new E.e199(),C.hd,new E.e200(),C.pH,new E.e201(),C.Ve,new E.e202(),C.jM,new E.e203(),C.W5,new E.e204(),C.uX,new E.e205(),C.nt,new E.e206(),C.PM,new E.e207(),C.xA,new E.e208(),C.k5,new E.e209(),C.Nv,new E.e210(),C.Cw,new E.e211(),C.TW,new E.e212(),C.xS,new E.e213(),C.ft,new E.e214(),C.QF,new E.e215(),C.mi,new E.e216(),C.zz,new E.e217(),C.hO,new E.e218(),C.ei,new E.e219(),C.HK,new E.e220(),C.je,new E.e221(),C.Ef,new E.e222(),C.RH,new E.e223(),C.Q1,new E.e224(),C.ID,new E.e225(),C.z6,new E.e226(),C.bc,new E.e227(),C.kw,new E.e228(),C.ep,new E.e229(),C.J2,new E.e230(),C.zU,new E.e231(),C.bn,new E.e232(),C.mh,new E.e233(),C.Fh,new E.e234(),C.LP,new E.e235(),C.jh,new E.e236(),C.fj,new E.e237(),C.xw,new E.e238(),C.zn,new E.e239(),C.RJ,new E.e240(),C.Tc,new E.e241(),C.YE,new E.e242(),C.Uy,new E.e243()],null,null)
-y=P.EF([C.aP,new E.e244(),C.cg,new E.e245(),C.S4,new E.e246(),C.AV,new E.e247(),C.bk,new E.e248(),C.lH,new E.e249(),C.am,new E.e250(),C.oE,new E.e251(),C.kG,new E.e252(),C.XA,new E.e253(),C.i4,new E.e254(),C.yL,new E.e255(),C.bJ,new E.e256(),C.VK,new E.e257(),C.aH,new E.e258(),C.vs,new E.e259(),C.Gr,new E.e260(),C.Fe,new E.e261(),C.tP,new E.e262(),C.yh,new E.e263(),C.Zb,new E.e264(),C.p8,new E.e265(),C.ld,new E.e266(),C.ne,new E.e267(),C.B0,new E.e268(),C.mr,new E.e269(),C.YT,new E.e270(),C.WQ,new E.e271(),C.jU,new E.e272(),C.Gd,new E.e273(),C.OO,new E.e274(),C.Mc,new E.e275(),C.QH,new E.e276(),C.rE,new E.e277(),C.nf,new E.e278(),C.Ql,new E.e279(),C.ak,new E.e280(),C.Ge,new E.e281(),C.He,new E.e282(),C.oj,new E.e283(),C.d2,new E.e284(),C.fn,new E.e285(),C.yB,new E.e286(),C.Py,new E.e287(),C.uu,new E.e288(),C.qs,new E.e289(),C.a0,new E.e290(),C.rB,new E.e291(),C.Lc,new E.e292(),C.hf,new E.e293(),C.uk,new E.e294(),C.Zi,new E.e295(),C.TN,new E.e296(),C.kA,new E.e297(),C.ur,new E.e298(),C.EV,new E.e299(),C.eh,new E.e300(),C.SA,new E.e301(),C.kV,new E.e302(),C.vp,new E.e303(),C.SR,new E.e304(),C.t6,new E.e305(),C.UX,new E.e306(),C.YS,new E.e307(),C.c6,new E.e308(),C.td,new E.e309(),C.zO,new E.e310(),C.Ys,new E.e311(),C.XM,new E.e312(),C.Ic,new E.e313(),C.O9,new E.e314(),C.tW,new E.e315(),C.Wj,new E.e316(),C.vb,new E.e317(),C.QK,new E.e318(),C.AO,new E.e319(),C.Xd,new E.e320(),C.xP,new E.e321(),C.GR,new E.e322(),C.KX,new E.e323(),C.ja,new E.e324(),C.Dj,new E.e325(),C.X2,new E.e326(),C.UY,new E.e327(),C.Aa,new E.e328(),C.nY,new E.e329(),C.tg,new E.e330(),C.HD,new E.e331(),C.iU,new E.e332(),C.eN,new E.e333(),C.Gs,new E.e334(),C.bE,new E.e335(),C.YD,new E.e336(),C.PX,new E.e337(),C.pH,new E.e338(),C.Ve,new E.e339(),C.jM,new E.e340(),C.uX,new E.e341(),C.nt,new E.e342(),C.PM,new E.e343(),C.Nv,new E.e344(),C.Cw,new E.e345(),C.TW,new E.e346(),C.ft,new E.e347(),C.mi,new E.e348(),C.zz,new E.e349(),C.z6,new E.e350(),C.kw,new E.e351(),C.zU,new E.e352(),C.RJ,new E.e353(),C.YE,new E.e354()],null,null)
-x=P.EF([C.K4,C.qJ,C.yS,C.Mt,C.OG,C.il,C.nw,C.Mt,C.xE,C.Mt,C.oT,C.il,C.jR,C.Mt,C.Lg,C.qJ,C.KO,C.Mt,C.wk,C.Mt,C.jA,C.qJ,C.Jo,C.il,C.Az,C.Mt,C.Vx,C.Mt,C.BL,C.Mt,C.lE,C.al,C.te,C.Mt,C.iD,C.Mt,C.Ju,C.Mt,C.Wz,C.il,C.MI,C.Mt,C.pF,C.il,C.Wh,C.Mt,C.qF,C.Mt,C.nX,C.il,C.Zj,C.Mt,C.Ep,C.Mt,C.dD,C.al,C.hP,C.Mt,C.tc,C.Mt,C.rR,C.il,C.oG,C.Mt,C.Jf,C.il,C.EZ,C.Mt,C.FG,C.il,C.pJ,C.Mt,C.tU,C.Mt,C.DD,C.Mt,C.Yy,C.il,C.Xv,C.Mt,C.ce,C.Mt,C.UJ,C.il,C.ca,C.Mt,C.Io,C.Mt,C.j4,C.Mt,C.EG,C.Mt,C.CT,C.Mt,C.mq,C.Mt,C.Tq,C.Mt,C.lp,C.il,C.PT,C.Mt,C.Ey,C.Mt,C.km,C.Mt,C.vw,C.Mt,C.LT,C.Mt,C.NW,C.l4,C.ms,C.Mt,C.FA,C.Mt,C.Qt,C.Mt,C.a8,C.Mt,C.JW,C.Mt,C.Mf,C.Mt,C.Dl,C.Mt,C.l4,C.qJ,C.ON,C.Mt,C.Sb,C.al,C.Th,C.Mt,C.wH,C.Mt,C.pK,C.Mt,C.il,C.Mt,C.X8,C.Mt,C.Y3,C.qJ,C.NR,C.Mt,C.vu,C.Mt,C.bC,C.Mt,C.ws,C.Mt,C.cK,C.il,C.jK,C.Mt,C.qJ,C.jw,C.Mt,C.l4,C.al,C.il],null,null)
-w=P.EF([C.K4,P.EF([C.S4,C.FB,C.AV,C.Qp,C.hf,C.V0],null,null),C.yS,P.EF([C.UX,C.Pt],null,null),C.OG,C.CM,C.nw,P.EF([C.rB,C.xY,C.bz,C.Bk],null,null),C.xE,P.EF([C.XA,C.dq,C.yB,C.vZ,C.tg,C.DC],null,null),C.oT,P.EF([C.i4,C.Qs,C.Wm,C.QW],null,null),C.jR,P.EF([C.i4,C.aJ],null,null),C.Lg,P.EF([C.S4,C.FB,C.AV,C.Qp,C.B0,C.b6,C.r1,C.nP,C.mr,C.HE],null,null),C.KO,P.EF([C.yh,C.zd],null,null),C.wk,P.EF([C.AV,C.fr,C.eh,C.rH,C.Aa,C.Uz,C.mi,C.yV],null,null),C.jA,P.EF([C.S4,C.FB,C.AV,C.Qp,C.YT,C.LC,C.hf,C.V0,C.UY,C.n6],null,null),C.Jo,C.CM,C.Az,P.EF([C.WQ,C.ah],null,null),C.Vx,P.EF([C.OO,C.Cf],null,null),C.BL,P.EF([C.Mc,C.f0],null,null),C.lE,P.EF([C.Ql,C.TJ,C.ak,C.yI,C.a0,C.P9,C.QK,C.Yo,C.Wm,C.QW],null,null),C.te,P.EF([C.nf,C.V3,C.pO,C.au,C.Lc,C.Pc,C.AO,C.fi],null,null),C.iD,P.EF([C.QH,C.C4,C.qX,C.dO,C.PM,C.jv],null,null),C.Ju,P.EF([C.kG,C.Pr,C.rB,C.xY,C.Zi,C.xx,C.TN,C.Gj,C.vb,C.Mq,C.UL,C.mM],null,null),C.Wz,C.CM,C.MI,P.EF([C.fn,C.fz,C.XM,C.Tt,C.tg,C.DC],null,null),C.pF,C.CM,C.Wh,P.EF([C.yL,C.j5],null,null),C.qF,P.EF([C.vp,C.o0],null,null),C.nX,C.CM,C.Zj,P.EF([C.oj,C.GT],null,null),C.Ep,P.EF([C.vp,C.o0],null,null),C.dD,P.EF([C.pH,C.Fk],null,null),C.hP,P.EF([C.Wj,C.Ah],null,null),C.tc,P.EF([C.vp,C.o0],null,null),C.rR,C.CM,C.oG,P.EF([C.jU,C.bw],null,null),C.Jf,C.CM,C.EZ,P.EF([C.vp,C.o0],null,null),C.FG,C.CM,C.pJ,P.EF([C.Ve,C.X4],null,null),C.tU,P.EF([C.qs,C.MN],null,null),C.DD,P.EF([C.vp,C.o0],null,null),C.Yy,C.CM,C.Xv,P.EF([C.YE,C.Wl],null,null),C.ce,P.EF([C.aH,C.w3,C.He,C.oV,C.vb,C.Mq,C.UL,C.mM,C.Dj,C.Ay,C.Gs,C.iO,C.bE,C.h3,C.YD,C.fP,C.TW,C.H0,C.xS,C.bB,C.zz,C.lS],null,null),C.UJ,C.CM,C.ca,P.EF([C.bJ,C.UI,C.ox,C.Rh],null,null),C.Io,P.EF([C.rB,C.RU],null,null),C.j4,P.EF([C.rB,C.RU],null,null),C.EG,P.EF([C.rB,C.RU],null,null),C.CT,P.EF([C.rB,C.RU],null,null),C.mq,P.EF([C.rB,C.RU],null,null),C.Tq,P.EF([C.SR,C.S9,C.t6,C.hr,C.rP,C.Nt],null,null),C.lp,C.CM,C.PT,P.EF([C.EV,C.ZQ],null,null),C.Ey,P.EF([C.XA,C.dq,C.uk,C.p4],null,null),C.km,P.EF([C.rB,C.RU,C.bz,C.Bk,C.uk,C.p4],null,null),C.vw,P.EF([C.uk,C.p4,C.EV,C.ZQ],null,null),C.LT,P.EF([C.Ys,C.Ce],null,null),C.NW,C.CM,C.ms,P.EF([C.cg,C.ll,C.uk,C.p4,C.kV,C.vz],null,null),C.FA,P.EF([C.cg,C.ll,C.kV,C.vz],null,null),C.Qt,P.EF([C.ld,C.Gw],null,null),C.a8,P.EF([C.p8,C.uc,C.ld,C.Gw],null,null),C.JW,P.EF([C.aP,C.xD,C.AV,C.Qp,C.hf,C.V0],null,null),C.Mf,P.EF([C.uk,C.p4],null,null),C.Dl,P.EF([C.VK,C.Od],null,null),C.l4,P.EF([C.O9,C.q9,C.ba,C.kQ],null,null),C.ON,P.EF([C.vs,C.MP,C.Gr,C.VJ,C.TU,C.Cp,C.SA,C.KI,C.tW,C.kH,C.CG,C.Ml,C.PX,C.jz,C.N8,C.qE,C.nt,C.VS],null,null),C.Sb,P.EF([C.tW,C.kH,C.CG,C.Ml],null,null),C.Th,P.EF([C.PX,C.jz],null,null),C.wH,P.EF([C.yh,C.lJ],null,null),C.pK,P.EF([C.ne,C.rZ],null,null),C.il,P.EF([C.uu,C.yY,C.xP,C.TO,C.Wm,C.QW],null,null),C.X8,P.EF([C.td,C.Zk,C.Gn,C.az],null,null),C.Y3,P.EF([C.bk,C.Ud,C.lH,C.dG,C.zU,C.uT],null,null),C.NR,P.EF([C.rE,C.KS],null,null),C.vu,P.EF([C.kw,C.oC],null,null),C.bC,P.EF([C.am,C.JD,C.oE,C.r2,C.uX,C.Eb],null,null),C.ws,P.EF([C.ft,C.u3],null,null),C.cK,C.CM,C.jK,P.EF([C.yh,C.Ul,C.RJ,C.BP],null,null)],null,null)
-v=O.ty(new O.Oj(z,y,x,w,C.CM,P.EF([C.aP,"active",C.IH,"address",C.cg,"anchor",C.j2,"app",C.ET,"assertsEnabled",C.BE,"averageCollectionPeriodInMillis",C.WC,"bpt",C.hR,"breakpoint",C.S4,"busy",C.Ro,"buttonClick",C.hN,"bytes",C.AV,"callback",C.bV,"capacity",C.C0,"change",C.eZ,"changeSort",C.bk,"checked",C.lH,"checkedText",C.am,"chromeTargets",C.oE,"chromiumAddress",C.kG,"classTable",C.OI,"classes",C.I9,"closeItem",C.To,"closing",C.XA,"cls",C.i4,"code",C.qt,"coloring",C.p1,"columns",C.yJ,"connectStandalone",C.la,"connectToVm",C.yL,"connection",C.bJ,"counters",C.ox,"countersChanged",C.Je,"current",C.Lw,"deleteVm",C.iE,"descriptor",C.f4,"descriptors",C.VK,"devtools",C.aH,"displayCutoff",C.aK,"doAction",C.GP,"element",C.vs,"endLine",C.Gr,"endPos",C.TU,"endPosChanged",C.Fe,"endTokenPos",C.tP,"entry",C.yh,"error",C.Zb,"eval",C.u7,"evalNow",C.p8,"event",C.qR,"eventType",C.ld,"events",C.ne,"exception",C.B0,"expand",C.r1,"expandChanged",C.mr,"expanded",C.Ek,"expander",C.Pn,"expanderStyle",C.YT,"expr",C.h7,"external",C.R3,"fd",C.WQ,"field",C.fV,"fields",C.jU,"file",C.Gd,"firstTokenPos",C.OO,"flag",C.Mc,"flagList",C.FP,"formatSize",C.kF,"formatTime",C.UD,"formattedAddress",C.Aq,"formattedAverage",C.DS,"formattedCollections",C.C9,"formattedDeoptId",C.VF,"formattedExclusive",C.uU,"formattedExclusiveTicks",C.YJ,"formattedInclusive",C.eF,"formattedInclusiveTicks",C.oI,"formattedLine",C.ST,"formattedTotalCollectionTime",C.QH,"fragmentation",C.qX,"fragmentationChanged",C.rE,"frame",C.nf,"function",C.pO,"functionChanged",C.EI,"functions",C.JB,"getColumnLabel",C.RY,"getTabs",C.d4,"goto",C.cF,"gotoLink",C.Ql,"hasClass",C.SI,"hasDescriptors",C.zS,"hasDisassembly",C.YA,"hasNoAllocations",C.ak,"hasParent",C.Ge,"hashLinkWorkaround",C.He,"hideTagsChecked",C.im,"history",C.Ss,"hits",C.k6,"hoverText",C.oj,"httpServer",C.PJ,"human",C.q2,"idle",C.d2,"imp",C.kN,"imports",C.fn,"instance",C.yB,"instances",C.eJ,"instruction",C.iG,"instructions",C.Py,"interface",C.pC,"interfaces",C.uu,"internal",C.qs,"io",C.XH,"isAbstract",C.tJ,"isBool",C.F8,"isChromeTarget",C.C1,"isComment",C.nL,"isCurrentTarget",C.a0,"isDart",C.Yg,"isDartCode",C.bR,"isDouble",C.ai,"isEmpty",C.ob,"isError",C.Iv,"isInstance",C.Wg,"isInt",C.tD,"isList",C.nZ,"isNotEmpty",C.Of,"isNull",C.pY,"isOptimized",C.XL,"isPatch",C.LA,"isPipe",C.Lk,"isString",C.dK,"isType",C.xf,"isUnexpected",C.rB,"isolate",C.bz,"isolateChanged",C.Jx,"isolates",C.b5,"jumpTarget",C.Lc,"kind",C.hf,"label",C.uk,"last",C.Zi,"lastAccumulatorReset",C.TN,"lastServiceGC",C.kA,"lastTokenPos",C.GI,"lastUpdate",C.Wn,"length",C.ur,"lib",C.VN,"libraries",C.EV,"library",C.VI,"line",C.eh,"lineMode",C.r6,"lineNumber",C.MW,"lineNumbers",C.SA,"lines",C.kV,"link",C.vp,"list",C.cc,"listening",C.DY,"loading",C.Lx,"localAddress",C.M3,"localPort",C.wT,"mainPort",C.SR,"map",C.t6,"mapAsString",C.rP,"mapChanged",C.pX,"message",C.VD,"mouseOut",C.NN,"mouseOver",C.UX,"msg",C.YS,"name",C.pu,"nameIsEmpty",C.BJ,"newSpace",C.c6,"notifications",C.td,"object",C.Gn,"objectChanged",C.zO,"objectPool",C.vg,"oldSpace",C.Ys,"pad",C.zm,"padding",C.XM,"path",C.Ic,"pause",C.yG,"pauseEvent",C.uI,"pid",C.O9,"pollPeriod",C.ba,"pollPeriodChanged",C.tW,"pos",C.CG,"posChanged",C.Wj,"process",C.vb,"profile",C.UL,"profileChanged",C.AY,"protocol",C.QK,"qualified",C.AO,"qualifiedName",C.Xd,"reachable",C.I7,"readClosed",C.xP,"ref",C.Wm,"refChanged",C.GR,"refresh",C.KX,"refreshCoverage",C.ja,"refreshGC",C.Dj,"refreshTime",C.ir,"relativeLink",C.dx,"remoteAddress",C.ni,"remotePort",C.X2,"resetAccumulator",C.F3,"response",C.UY,"result",C.Aa,"results",C.nY,"resume",C.tg,"retainedBytes",C.HD,"retainedSize",C.iU,"retainingPath",C.eN,"rootLib",C.ue,"row",C.nh,"rows",C.L2,"running",C.Gs,"sampleCount",C.bE,"sampleDepth",C.YD,"sampleRate",C.PX,"script",C.N8,"scriptChanged",C.EA,"scripts",C.oW,"selectExpr",C.hd,"serviceType",C.pH,"small",C.Ve,"socket",C.jM,"socketOwner",C.W5,"standalone",C.uX,"standaloneVmAddress",C.nt,"startLine",C.PM,"status",C.xA,"styleForHits",C.k5,"subClasses",C.Nv,"subclass",C.Cw,"superClass",C.TW,"tagSelector",C.xS,"tagSelectorChanged",C.ft,"target",C.QF,"targets",C.mi,"text",C.zz,"timeSpan",C.hO,"tipExclusive",C.ei,"tipKind",C.HK,"tipParent",C.je,"tipTicks",C.Ef,"tipTime",C.RH,"toStringAsFixed",C.Q1,"toggleExpand",C.ID,"toggleExpanded",C.z6,"tokenPos",C.bc,"topFrame",C.kw,"trace",C.ep,"tree",C.J2,"typeChecksEnabled",C.zU,"uncheckedText",C.bn,"updateLineMode",C.mh,"uptime",C.Fh,"url",C.LP,"used",C.jh,"v",C.fj,"variable",C.xw,"variables",C.zn,"version",C.RJ,"vm",C.Tc,"vmName",C.YE,"webSocket",C.Uy,"writeClosed"],null,null),!1))
+z=P.EF([C.aP,new E.em(),C.IH,new E.Lb(),C.cg,new E.QA(),C.j2,new E.Cv(),C.Zg,new E.ed(),C.ET,new E.wa(),C.BE,new E.Or(),C.WC,new E.YL(),C.hR,new E.wf(),C.S4,new E.Oa(),C.Ro,new E.emv(),C.hN,new E.Lbd(),C.AV,new E.QAa(),C.bV,new E.CvS(),C.C0,new E.edy(),C.eZ,new E.waE(),C.bk,new E.Ore(),C.lH,new E.YLa(),C.am,new E.wfa(),C.oE,new E.Oaa(),C.kG,new E.e0(),C.OI,new E.e1(),C.I9,new E.e2(),C.To,new E.e3(),C.XA,new E.e4(),C.i4,new E.e5(),C.qt,new E.e6(),C.p1,new E.e7(),C.yJ,new E.e8(),C.la,new E.e9(),C.yL,new E.e10(),C.bJ,new E.e11(),C.ox,new E.e12(),C.Je,new E.e13(),C.kI,new E.e14(),C.vY,new E.e15(),C.Rs,new E.e16(),C.Lw,new E.e17(),C.eR,new E.e18(),C.iE,new E.e19(),C.f4,new E.e20(),C.VK,new E.e21(),C.aH,new E.e22(),C.aK,new E.e23(),C.GP,new E.e24(),C.vs,new E.e25(),C.Gr,new E.e26(),C.TU,new E.e27(),C.Fe,new E.e28(),C.tP,new E.e29(),C.yh,new E.e30(),C.Zb,new E.e31(),C.u7,new E.e32(),C.p8,new E.e33(),C.qR,new E.e34(),C.ld,new E.e35(),C.ne,new E.e36(),C.B0,new E.e37(),C.r1,new E.e38(),C.mr,new E.e39(),C.Ek,new E.e40(),C.Pn,new E.e41(),C.YT,new E.e42(),C.h7,new E.e43(),C.R3,new E.e44(),C.WQ,new E.e45(),C.fV,new E.e46(),C.jU,new E.e47(),C.OO,new E.e48(),C.Mc,new E.e49(),C.FP,new E.e50(),C.kF,new E.e51(),C.UD,new E.e52(),C.Aq,new E.e53(),C.DS,new E.e54(),C.C9,new E.e55(),C.VF,new E.e56(),C.uU,new E.e57(),C.YJ,new E.e58(),C.eF,new E.e59(),C.oI,new E.e60(),C.ST,new E.e61(),C.QH,new E.e62(),C.qX,new E.e63(),C.rE,new E.e64(),C.nf,new E.e65(),C.EI,new E.e66(),C.JB,new E.e67(),C.RY,new E.e68(),C.d4,new E.e69(),C.cF,new E.e70(),C.SI,new E.e71(),C.zS,new E.e72(),C.YA,new E.e73(),C.Ge,new E.e74(),C.A7,new E.e75(),C.He,new E.e76(),C.im,new E.e77(),C.Ss,new E.e78(),C.k6,new E.e79(),C.oj,new E.e80(),C.PJ,new E.e81(),C.q2,new E.e82(),C.d2,new E.e83(),C.kN,new E.e84(),C.fn,new E.e85(),C.yB,new E.e86(),C.eJ,new E.e87(),C.iG,new E.e88(),C.Py,new E.e89(),C.pC,new E.e90(),C.uu,new E.e91(),C.qs,new E.e92(),C.XH,new E.e93(),C.tJ,new E.e94(),C.F8,new E.e95(),C.C1,new E.e96(),C.Nr,new E.e97(),C.nL,new E.e98(),C.a0,new E.e99(),C.Yg,new E.e100(),C.bR,new E.e101(),C.ai,new E.e102(),C.ob,new E.e103(),C.MY,new E.e104(),C.Iv,new E.e105(),C.Wg,new E.e106(),C.tD,new E.e107(),C.nZ,new E.e108(),C.Of,new E.e109(),C.Vl,new E.e110(),C.pY,new E.e111(),C.XL,new E.e112(),C.LA,new E.e113(),C.AT,new E.e114(),C.Lk,new E.e115(),C.dK,new E.e116(),C.xf,new E.e117(),C.rB,new E.e118(),C.bz,new E.e119(),C.Jx,new E.e120(),C.b5,new E.e121(),C.Lc,new E.e122(),C.hf,new E.e123(),C.uk,new E.e124(),C.Zi,new E.e125(),C.TN,new E.e126(),C.GI,new E.e127(),C.Wn,new E.e128(),C.ur,new E.e129(),C.VN,new E.e130(),C.EV,new E.e131(),C.VI,new E.e132(),C.eh,new E.e133(),C.SA,new E.e134(),C.kV,new E.e135(),C.vp,new E.e136(),C.cc,new E.e137(),C.DY,new E.e138(),C.Lx,new E.e139(),C.M3,new E.e140(),C.wT,new E.e141(),C.JK,new E.e142(),C.SR,new E.e143(),C.t6,new E.e144(),C.rP,new E.e145(),C.pX,new E.e146(),C.VD,new E.e147(),C.NN,new E.e148(),C.UX,new E.e149(),C.YS,new E.e150(),C.pu,new E.e151(),C.BJ,new E.e152(),C.c6,new E.e153(),C.td,new E.e154(),C.Gn,new E.e155(),C.zO,new E.e156(),C.vg,new E.e157(),C.YV,new E.e158(),C.If,new E.e159(),C.Ys,new E.e160(),C.zm,new E.e161(),C.nX,new E.e162(),C.xP,new E.e163(),C.XM,new E.e164(),C.Ic,new E.e165(),C.yG,new E.e166(),C.uI,new E.e167(),C.O9,new E.e168(),C.ba,new E.e169(),C.tW,new E.e170(),C.CG,new E.e171(),C.Wj,new E.e172(),C.vb,new E.e173(),C.UL,new E.e174(),C.AY,new E.e175(),C.QK,new E.e176(),C.AO,new E.e177(),C.Xd,new E.e178(),C.I7,new E.e179(),C.kY,new E.e180(),C.Wm,new E.e181(),C.GR,new E.e182(),C.KX,new E.e183(),C.ja,new E.e184(),C.Dj,new E.e185(),C.ir,new E.e186(),C.dx,new E.e187(),C.ni,new E.e188(),C.X2,new E.e189(),C.F3,new E.e190(),C.UY,new E.e191(),C.Aa,new E.e192(),C.nY,new E.e193(),C.tg,new E.e194(),C.HD,new E.e195(),C.iU,new E.e196(),C.eN,new E.e197(),C.ue,new E.e198(),C.nh,new E.e199(),C.L2,new E.e200(),C.Gs,new E.e201(),C.bE,new E.e202(),C.YD,new E.e203(),C.PX,new E.e204(),C.N8,new E.e205(),C.EA,new E.e206(),C.oW,new E.e207(),C.hd,new E.e208(),C.pH,new E.e209(),C.Ve,new E.e210(),C.jM,new E.e211(),C.W5,new E.e212(),C.uX,new E.e213(),C.nt,new E.e214(),C.IT,new E.e215(),C.li,new E.e216(),C.PM,new E.e217(),C.k5,new E.e218(),C.Nv,new E.e219(),C.Cw,new E.e220(),C.TW,new E.e221(),C.xS,new E.e222(),C.ft,new E.e223(),C.QF,new E.e224(),C.mi,new E.e225(),C.zz,new E.e226(),C.hO,new E.e227(),C.ei,new E.e228(),C.HK,new E.e229(),C.je,new E.e230(),C.Ef,new E.e231(),C.QL,new E.e232(),C.RH,new E.e233(),C.Q1,new E.e234(),C.ID,new E.e235(),C.z6,new E.e236(),C.bc,new E.e237(),C.kw,new E.e238(),C.ep,new E.e239(),C.J2,new E.e240(),C.zU,new E.e241(),C.OU,new E.e242(),C.bn,new E.e243(),C.mh,new E.e244(),C.Fh,new E.e245(),C.yv,new E.e246(),C.LP,new E.e247(),C.jh,new E.e248(),C.fj,new E.e249(),C.xw,new E.e250(),C.zn,new E.e251(),C.RJ,new E.e252(),C.Tc,new E.e253(),C.YE,new E.e254(),C.Uy,new E.e255()],null,null)
+y=P.EF([C.aP,new E.e256(),C.cg,new E.e257(),C.Zg,new E.e258(),C.S4,new E.e259(),C.AV,new E.e260(),C.bk,new E.e261(),C.lH,new E.e262(),C.am,new E.e263(),C.oE,new E.e264(),C.kG,new E.e265(),C.XA,new E.e266(),C.i4,new E.e267(),C.yL,new E.e268(),C.bJ,new E.e269(),C.kI,new E.e270(),C.vY,new E.e271(),C.VK,new E.e272(),C.aH,new E.e273(),C.vs,new E.e274(),C.Gr,new E.e275(),C.Fe,new E.e276(),C.tP,new E.e277(),C.yh,new E.e278(),C.Zb,new E.e279(),C.p8,new E.e280(),C.ld,new E.e281(),C.ne,new E.e282(),C.B0,new E.e283(),C.mr,new E.e284(),C.YT,new E.e285(),C.WQ,new E.e286(),C.jU,new E.e287(),C.OO,new E.e288(),C.Mc,new E.e289(),C.QH,new E.e290(),C.rE,new E.e291(),C.nf,new E.e292(),C.Ge,new E.e293(),C.A7,new E.e294(),C.He,new E.e295(),C.oj,new E.e296(),C.d2,new E.e297(),C.fn,new E.e298(),C.yB,new E.e299(),C.Py,new E.e300(),C.uu,new E.e301(),C.qs,new E.e302(),C.rB,new E.e303(),C.hf,new E.e304(),C.uk,new E.e305(),C.Zi,new E.e306(),C.TN,new E.e307(),C.ur,new E.e308(),C.EV,new E.e309(),C.eh,new E.e310(),C.SA,new E.e311(),C.kV,new E.e312(),C.vp,new E.e313(),C.SR,new E.e314(),C.t6,new E.e315(),C.UX,new E.e316(),C.YS,new E.e317(),C.c6,new E.e318(),C.td,new E.e319(),C.zO,new E.e320(),C.YV,new E.e321(),C.If,new E.e322(),C.Ys,new E.e323(),C.nX,new E.e324(),C.XM,new E.e325(),C.Ic,new E.e326(),C.O9,new E.e327(),C.tW,new E.e328(),C.Wj,new E.e329(),C.vb,new E.e330(),C.QK,new E.e331(),C.Xd,new E.e332(),C.kY,new E.e333(),C.GR,new E.e334(),C.KX,new E.e335(),C.ja,new E.e336(),C.Dj,new E.e337(),C.X2,new E.e338(),C.UY,new E.e339(),C.Aa,new E.e340(),C.nY,new E.e341(),C.tg,new E.e342(),C.HD,new E.e343(),C.iU,new E.e344(),C.eN,new E.e345(),C.Gs,new E.e346(),C.bE,new E.e347(),C.YD,new E.e348(),C.PX,new E.e349(),C.pH,new E.e350(),C.Ve,new E.e351(),C.jM,new E.e352(),C.uX,new E.e353(),C.nt,new E.e354(),C.IT,new E.e355(),C.PM,new E.e356(),C.Nv,new E.e357(),C.Cw,new E.e358(),C.TW,new E.e359(),C.ft,new E.e360(),C.mi,new E.e361(),C.zz,new E.e362(),C.z6,new E.e363(),C.kw,new E.e364(),C.zU,new E.e365(),C.OU,new E.e366(),C.RJ,new E.e367(),C.YE,new E.e368()],null,null)
+x=P.EF([C.K4,C.qJ,C.yS,C.Mt,C.OG,C.il,C.nw,C.Mt,C.ou,C.Mt,C.oT,C.il,C.jR,C.Mt,C.Lg,C.qJ,C.KO,C.Mt,C.wk,C.Mt,C.jA,C.qJ,C.Jo,C.il,C.Az,C.Mt,C.Vx,C.Mt,C.Qb,C.Mt,C.lE,C.al,C.te,C.Mt,C.iD,C.Mt,C.Ju,C.Mt,C.Wz,C.il,C.MI,C.Mt,C.pF,C.il,C.Wh,C.Mt,C.qF,C.Mt,C.qZ,C.il,C.Zj,C.Mt,C.he,C.Mt,C.dD,C.al,C.hP,C.Mt,C.tc,C.Mt,C.rR,C.il,C.oG,C.Mt,C.Jf,C.il,C.EZ,C.Mt,C.FG,C.il,C.pJ,C.Mt,C.tU,C.Mt,C.DD,C.Mt,C.Yy,C.il,C.Xv,C.Mt,C.ce,C.Mt,C.UJ,C.il,C.ca,C.Mt,C.Io,C.Mt,C.j4,C.Mt,C.EG,C.Mt,C.CT,C.Mt,C.mq,C.Mt,C.Tq,C.Mt,C.lp,C.il,C.PT,C.Mt,C.Ey,C.Mt,C.km,C.Mt,C.vw,C.Mt,C.LT,C.Mt,C.NW,C.l4,C.ms,C.Mt,C.FA,C.Mt,C.Qt,C.Mt,C.a8,C.Mt,C.JW,C.Mt,C.Mf,C.Mt,C.Dl,C.Mt,C.l4,C.qJ,C.ON,C.Mt,C.Sb,C.al,C.Th,C.Mt,C.wH,C.Mt,C.pK,C.Mt,C.il,C.Mt,C.X8,C.Mt,C.Y3,C.qJ,C.NR,C.Mt,C.vu,C.Mt,C.bC,C.Mt,C.ws,C.Mt,C.cK,C.il,C.jK,C.Mt,C.qJ,C.jw,C.Mt,C.l4,C.al,C.il],null,null)
+w=P.EF([C.K4,P.EF([C.S4,C.FB,C.AV,C.Qp,C.hf,C.V0],null,null),C.yS,P.EF([C.UX,C.Pt],null,null),C.OG,C.CM,C.nw,P.EF([C.rB,C.xY,C.bz,C.Bk],null,null),C.ou,P.EF([C.XA,C.dq,C.yB,C.vZ,C.tg,C.DC],null,null),C.oT,P.EF([C.i4,C.Qs,C.Wm,C.QW],null,null),C.jR,P.EF([C.i4,C.aJ],null,null),C.Lg,P.EF([C.S4,C.FB,C.AV,C.Qp,C.B0,C.b6,C.r1,C.nP,C.mr,C.HE],null,null),C.KO,P.EF([C.yh,C.zd],null,null),C.wk,P.EF([C.AV,C.fr,C.eh,C.rH,C.Aa,C.Uz,C.mi,C.yV],null,null),C.jA,P.EF([C.S4,C.FB,C.AV,C.Qp,C.YT,C.LC,C.hf,C.V0,C.UY,C.n6],null,null),C.Jo,C.CM,C.Az,P.EF([C.WQ,C.ah],null,null),C.Vx,P.EF([C.OO,C.Cf],null,null),C.Qb,P.EF([C.Mc,C.f0],null,null),C.lE,P.EF([C.QK,C.Yo],null,null),C.te,P.EF([C.nf,C.wR],null,null),C.iD,P.EF([C.QH,C.C4,C.qX,C.dO,C.PM,C.jv],null,null),C.Ju,P.EF([C.kG,C.Pr,C.rB,C.xY,C.Zi,C.xx,C.TN,C.Gj,C.vb,C.Mq,C.UL,C.mM],null,null),C.Wz,C.CM,C.MI,P.EF([C.fn,C.fz,C.XM,C.Tt,C.tg,C.DC],null,null),C.pF,C.CM,C.Wh,P.EF([C.yL,C.j5],null,null),C.qF,P.EF([C.vp,C.o0],null,null),C.qZ,C.CM,C.Zj,P.EF([C.oj,C.GT],null,null),C.he,P.EF([C.vp,C.o0],null,null),C.dD,P.EF([C.pH,C.Fk],null,null),C.hP,P.EF([C.Wj,C.Ah],null,null),C.tc,P.EF([C.vp,C.o0],null,null),C.rR,C.CM,C.oG,P.EF([C.jU,C.bw],null,null),C.Jf,C.CM,C.EZ,P.EF([C.vp,C.o0],null,null),C.FG,C.CM,C.pJ,P.EF([C.Ve,C.X4],null,null),C.tU,P.EF([C.qs,C.MN],null,null),C.DD,P.EF([C.vp,C.o0],null,null),C.Yy,C.CM,C.Xv,P.EF([C.YE,C.Wl],null,null),C.ce,P.EF([C.aH,C.w3,C.He,C.oV,C.vb,C.Mq,C.UL,C.mM,C.Dj,C.Ay,C.Gs,C.iO,C.bE,C.h3,C.YD,C.fP,C.TW,C.H0,C.xS,C.bB,C.zz,C.lS],null,null),C.UJ,C.CM,C.ca,P.EF([C.bJ,C.UI,C.ox,C.Rh],null,null),C.Io,P.EF([C.rB,C.RU],null,null),C.j4,P.EF([C.rB,C.RU],null,null),C.EG,P.EF([C.rB,C.RU],null,null),C.CT,P.EF([C.rB,C.RU],null,null),C.mq,P.EF([C.rB,C.RU],null,null),C.Tq,P.EF([C.SR,C.S9,C.t6,C.hr,C.rP,C.Nt],null,null),C.lp,C.CM,C.PT,P.EF([C.EV,C.ZQ],null,null),C.Ey,P.EF([C.XA,C.dq,C.uk,C.p4],null,null),C.km,P.EF([C.rB,C.RU,C.bz,C.Bk,C.uk,C.p4],null,null),C.vw,P.EF([C.uk,C.p4,C.EV,C.ZQ],null,null),C.LT,P.EF([C.Ys,C.Ce],null,null),C.NW,C.CM,C.ms,P.EF([C.cg,C.ll,C.uk,C.p4,C.kV,C.vz],null,null),C.FA,P.EF([C.cg,C.ll,C.kV,C.vz],null,null),C.Qt,P.EF([C.ld,C.Gw],null,null),C.a8,P.EF([C.p8,C.uc,C.ld,C.Gw],null,null),C.JW,P.EF([C.aP,C.xD,C.AV,C.Qp,C.hf,C.V0],null,null),C.Mf,P.EF([C.uk,C.p4],null,null),C.Dl,P.EF([C.VK,C.Od],null,null),C.l4,P.EF([C.O9,C.q9,C.ba,C.kQ],null,null),C.ON,P.EF([C.kI,C.JM,C.vY,C.ZS,C.Rs,C.EW,C.vs,C.MP,C.Gr,C.VJ,C.TU,C.Cp,C.A7,C.SD,C.SA,C.KI,C.PX,C.jz,C.N8,C.qE,C.nt,C.VS,C.IT,C.NL,C.li,C.Tz],null,null),C.Sb,P.EF([C.tW,C.kH,C.CG,C.Ml],null,null),C.Th,P.EF([C.PX,C.jz],null,null),C.wH,P.EF([C.yh,C.lJ],null,null),C.pK,P.EF([C.ne,C.rZ],null,null),C.il,P.EF([C.uu,C.yY,C.kY,C.TO,C.Wm,C.QW],null,null),C.X8,P.EF([C.Zg,C.b7,C.td,C.Zk,C.Gn,C.az],null,null),C.Y3,P.EF([C.bk,C.Ud,C.lH,C.dG,C.zU,C.uT],null,null),C.NR,P.EF([C.rE,C.KS],null,null),C.vu,P.EF([C.kw,C.oC],null,null),C.bC,P.EF([C.am,C.JD,C.oE,C.r2,C.uX,C.Eb],null,null),C.ws,P.EF([C.ft,C.u3],null,null),C.cK,C.CM,C.jK,P.EF([C.yh,C.Ul,C.RJ,C.BP],null,null)],null,null)
+v=O.ty(new O.Oj(z,y,x,w,C.CM,P.EF([C.aP,"active",C.IH,"address",C.cg,"anchor",C.j2,"app",C.Zg,"args",C.ET,"assertsEnabled",C.BE,"averageCollectionPeriodInMillis",C.WC,"bpt",C.hR,"breakpoint",C.S4,"busy",C.Ro,"buttonClick",C.hN,"bytes",C.AV,"callback",C.bV,"capacity",C.C0,"change",C.eZ,"changeSort",C.bk,"checked",C.lH,"checkedText",C.am,"chromeTargets",C.oE,"chromiumAddress",C.kG,"classTable",C.OI,"classes",C.I9,"closeItem",C.To,"closing",C.XA,"cls",C.i4,"code",C.qt,"coloring",C.p1,"columns",C.yJ,"connectStandalone",C.la,"connectToVm",C.yL,"connection",C.bJ,"counters",C.ox,"countersChanged",C.Je,"current",C.kI,"currentLine",C.vY,"currentPos",C.Rs,"currentPosChanged",C.Lw,"deleteVm",C.eR,"deoptimizations",C.iE,"descriptor",C.f4,"descriptors",C.VK,"devtools",C.aH,"displayCutoff",C.aK,"doAction",C.GP,"element",C.vs,"endLine",C.Gr,"endPos",C.TU,"endPosChanged",C.Fe,"endTokenPos",C.tP,"entry",C.yh,"error",C.Zb,"eval",C.u7,"evalNow",C.p8,"event",C.qR,"eventType",C.ld,"events",C.ne,"exception",C.B0,"expand",C.r1,"expandChanged",C.mr,"expanded",C.Ek,"expander",C.Pn,"expanderStyle",C.YT,"expr",C.h7,"external",C.R3,"fd",C.WQ,"field",C.fV,"fields",C.jU,"file",C.OO,"flag",C.Mc,"flagList",C.FP,"formatSize",C.kF,"formatTime",C.UD,"formattedAddress",C.Aq,"formattedAverage",C.DS,"formattedCollections",C.C9,"formattedDeoptId",C.VF,"formattedExclusive",C.uU,"formattedExclusiveTicks",C.YJ,"formattedInclusive",C.eF,"formattedInclusiveTicks",C.oI,"formattedLine",C.ST,"formattedTotalCollectionTime",C.QH,"fragmentation",C.qX,"fragmentationChanged",C.rE,"frame",C.nf,"function",C.EI,"functions",C.JB,"getColumnLabel",C.RY,"getTabs",C.d4,"goto",C.cF,"gotoLink",C.SI,"hasDescriptors",C.zS,"hasDisassembly",C.YA,"hasNoAllocations",C.Ge,"hashLinkWorkaround",C.A7,"height",C.He,"hideTagsChecked",C.im,"history",C.Ss,"hits",C.k6,"hoverText",C.oj,"httpServer",C.PJ,"human",C.q2,"idle",C.d2,"imp",C.kN,"imports",C.fn,"instance",C.yB,"instances",C.eJ,"instruction",C.iG,"instructions",C.Py,"interface",C.pC,"interfaces",C.uu,"internal",C.qs,"io",C.XH,"isAbstract",C.tJ,"isBool",C.F8,"isChromeTarget",C.C1,"isComment",C.Nr,"isConst",C.nL,"isCurrentTarget",C.a0,"isDart",C.Yg,"isDartCode",C.bR,"isDouble",C.ai,"isEmpty",C.ob,"isError",C.MY,"isInlinable",C.Iv,"isInstance",C.Wg,"isInt",C.tD,"isList",C.nZ,"isNotEmpty",C.Of,"isNull",C.Vl,"isOptimizable",C.pY,"isOptimized",C.XL,"isPatch",C.LA,"isPipe",C.AT,"isStatic",C.Lk,"isString",C.dK,"isType",C.xf,"isUnexpected",C.rB,"isolate",C.bz,"isolateChanged",C.Jx,"isolates",C.b5,"jumpTarget",C.Lc,"kind",C.hf,"label",C.uk,"last",C.Zi,"lastAccumulatorReset",C.TN,"lastServiceGC",C.GI,"lastUpdate",C.Wn,"length",C.ur,"lib",C.VN,"libraries",C.EV,"library",C.VI,"line",C.eh,"lineMode",C.SA,"lines",C.kV,"link",C.vp,"list",C.cc,"listening",C.DY,"loading",C.Lx,"localAddress",C.M3,"localPort",C.wT,"mainPort",C.JK,"makeLineId",C.SR,"map",C.t6,"mapAsString",C.rP,"mapChanged",C.pX,"message",C.VD,"mouseOut",C.NN,"mouseOver",C.UX,"msg",C.YS,"name",C.pu,"nameIsEmpty",C.BJ,"newSpace",C.c6,"notifications",C.td,"object",C.Gn,"objectChanged",C.zO,"objectPool",C.vg,"oldSpace",C.YV,"owningClass",C.If,"owningLibrary",C.Ys,"pad",C.zm,"padding",C.nX,"parent",C.xP,"parseInt",C.XM,"path",C.Ic,"pause",C.yG,"pauseEvent",C.uI,"pid",C.O9,"pollPeriod",C.ba,"pollPeriodChanged",C.tW,"pos",C.CG,"posChanged",C.Wj,"process",C.vb,"profile",C.UL,"profileChanged",C.AY,"protocol",C.QK,"qualified",C.AO,"qualifiedName",C.Xd,"reachable",C.I7,"readClosed",C.kY,"ref",C.Wm,"refChanged",C.GR,"refresh",C.KX,"refreshCoverage",C.ja,"refreshGC",C.Dj,"refreshTime",C.ir,"relativeLink",C.dx,"remoteAddress",C.ni,"remotePort",C.X2,"resetAccumulator",C.F3,"response",C.UY,"result",C.Aa,"results",C.nY,"resume",C.tg,"retainedBytes",C.HD,"retainedSize",C.iU,"retainingPath",C.eN,"rootLib",C.ue,"row",C.nh,"rows",C.L2,"running",C.Gs,"sampleCount",C.bE,"sampleDepth",C.YD,"sampleRate",C.PX,"script",C.N8,"scriptChanged",C.EA,"scripts",C.oW,"selectExpr",C.hd,"serviceType",C.pH,"small",C.Ve,"socket",C.jM,"socketOwner",C.W5,"standalone",C.uX,"standaloneVmAddress",C.nt,"startLine",C.IT,"startPos",C.li,"startPosChanged",C.PM,"status",C.k5,"subClasses",C.Nv,"subclass",C.Cw,"superClass",C.TW,"tagSelector",C.xS,"tagSelectorChanged",C.ft,"target",C.QF,"targets",C.mi,"text",C.zz,"timeSpan",C.hO,"tipExclusive",C.ei,"tipKind",C.HK,"tipParent",C.je,"tipTicks",C.Ef,"tipTime",C.QL,"toString",C.RH,"toStringAsFixed",C.Q1,"toggleExpand",C.ID,"toggleExpanded",C.z6,"tokenPos",C.bc,"topFrame",C.kw,"trace",C.ep,"tree",C.J2,"typeChecksEnabled",C.zU,"uncheckedText",C.OU,"unoptimizedCode",C.bn,"updateLineMode",C.mh,"uptime",C.Fh,"url",C.yv,"usageCounter",C.LP,"used",C.jh,"v",C.fj,"variable",C.xw,"variables",C.zn,"version",C.RJ,"vm",C.Tc,"vmName",C.YE,"webSocket",C.Uy,"writeClosed"],null,null),!1))
 $.j8=new O.fH(z,y,C.CM)
 $.Yv=new O.bY(x,w,!1)
 $.qe=v
-$.M6=[new E.e355(),new E.e356(),new E.e357(),new E.e358(),new E.e359(),new E.e360(),new E.e361(),new E.e362(),new E.e363(),new E.e364(),new E.e365(),new E.e366(),new E.e367(),new E.e368(),new E.e369(),new E.e370(),new E.e371(),new E.e372(),new E.e373(),new E.e374(),new E.e375(),new E.e376(),new E.e377(),new E.e378(),new E.e379(),new E.e380(),new E.e381(),new E.e382(),new E.e383(),new E.e384(),new E.e385(),new E.e386(),new E.e387(),new E.e388(),new E.e389(),new E.e390(),new E.e391(),new E.e392(),new E.e393(),new E.e394(),new E.e395(),new E.e396(),new E.e397(),new E.e398(),new E.e399(),new E.e400(),new E.e401(),new E.e402(),new E.e403(),new E.e404(),new E.e405(),new E.e406(),new E.e407(),new E.e408(),new E.e409(),new E.e410(),new E.e411(),new E.e412(),new E.e413(),new E.e414(),new E.e415(),new E.e416(),new E.e417(),new E.e418(),new E.e419(),new E.e420(),new E.e421(),new E.e422(),new E.e423(),new E.e424(),new E.e425(),new E.e426(),new E.e427(),new E.e428(),new E.e429(),new E.e430(),new E.e431(),new E.e432()]
+$.M6=[new E.e369(),new E.e370(),new E.e371(),new E.e372(),new E.e373(),new E.e374(),new E.e375(),new E.e376(),new E.e377(),new E.e378(),new E.e379(),new E.e380(),new E.e381(),new E.e382(),new E.e383(),new E.e384(),new E.e385(),new E.e386(),new E.e387(),new E.e388(),new E.e389(),new E.e390(),new E.e391(),new E.e392(),new E.e393(),new E.e394(),new E.e395(),new E.e396(),new E.e397(),new E.e398(),new E.e399(),new E.e400(),new E.e401(),new E.e402(),new E.e403(),new E.e404(),new E.e405(),new E.e406(),new E.e407(),new E.e408(),new E.e409(),new E.e410(),new E.e411(),new E.e412(),new E.e413(),new E.e414(),new E.e415(),new E.e416(),new E.e417(),new E.e418(),new E.e419(),new E.e420(),new E.e421(),new E.e422(),new E.e423(),new E.e424(),new E.e425(),new E.e426(),new E.e427(),new E.e428(),new E.e429(),new E.e430(),new E.e431(),new E.e432(),new E.e433(),new E.e434(),new E.e435(),new E.e436(),new E.e437(),new E.e438(),new E.e439(),new E.e440(),new E.e441(),new E.e442(),new E.e443(),new E.e444(),new E.e445(),new E.e446()]
 $.UG=!0
-F.E2()},"$0","V7",0,0,18],
+F.E2()},"$0","V7A",0,0,18],
 em:{
-"^":"Tp:13;",
+"^":"TpZ:13;",
 $1:function(a){return J.Jp(a)},
 $isEH:true},
 Lb:{
-"^":"Tp:13;",
+"^":"TpZ:13;",
 $1:function(a){return a.gYu()},
 $isEH:true},
 QA:{
-"^":"Tp:13;",
+"^":"TpZ:13;",
 $1:function(a){return J.Ln(a)},
 $isEH:true},
 Cv:{
-"^":"Tp:13;",
+"^":"TpZ:13;",
 $1:function(a){return J.r0(a)},
 $isEH:true},
 ed:{
-"^":"Tp:13;",
-$1:function(a){return a.gA3()},
-$isEH:true},
-wa:{
-"^":"Tp:13;",
-$1:function(a){return a.gqZ()},
-$isEH:true},
-Or:{
-"^":"Tp:13;",
-$1:function(a){return a.gqr()},
-$isEH:true},
-YL:{
-"^":"Tp:13;",
-$1:function(a){return a.gQ1()},
-$isEH:true},
-wf:{
-"^":"Tp:13;",
-$1:function(a){return J.nG(a)},
-$isEH:true},
-Oa:{
-"^":"Tp:13;",
-$1:function(a){return J.aA(a)},
-$isEH:true},
-emv:{
-"^":"Tp:13;",
-$1:function(a){return a.gfj()},
-$isEH:true},
-Lbd:{
-"^":"Tp:13;",
-$1:function(a){return J.WT(a)},
-$isEH:true},
-QAa:{
-"^":"Tp:13;",
-$1:function(a){return a.gCs()},
-$isEH:true},
-CvS:{
-"^":"Tp:13;",
-$1:function(a){return J.Wp(a)},
-$isEH:true},
-edy:{
-"^":"Tp:13;",
-$1:function(a){return J.n9(a)},
-$isEH:true},
-waE:{
-"^":"Tp:13;",
-$1:function(a){return J.K0(a)},
-$isEH:true},
-Ore:{
-"^":"Tp:13;",
-$1:function(a){return J.hn(a)},
-$isEH:true},
-YLa:{
-"^":"Tp:13;",
-$1:function(a){return J.HP(a)},
-$isEH:true},
-wfa:{
-"^":"Tp:13;",
-$1:function(a){return J.zF(a)},
-$isEH:true},
-Oaa:{
-"^":"Tp:13;",
-$1:function(a){return J.yz(a)},
-$isEH:true},
-e0:{
-"^":"Tp:13;",
+"^":"TpZ:13;",
 $1:function(a){return J.pP(a)},
 $isEH:true},
+wa:{
+"^":"TpZ:13;",
+$1:function(a){return a.gA3()},
+$isEH:true},
+Or:{
+"^":"TpZ:13;",
+$1:function(a){return a.gqZ()},
+$isEH:true},
+YL:{
+"^":"TpZ:13;",
+$1:function(a){return a.gqr()},
+$isEH:true},
+wf:{
+"^":"TpZ:13;",
+$1:function(a){return a.gQ1()},
+$isEH:true},
+Oa:{
+"^":"TpZ:13;",
+$1:function(a){return J.nG(a)},
+$isEH:true},
+emv:{
+"^":"TpZ:13;",
+$1:function(a){return J.aA(a)},
+$isEH:true},
+Lbd:{
+"^":"TpZ:13;",
+$1:function(a){return a.gfj()},
+$isEH:true},
+QAa:{
+"^":"TpZ:13;",
+$1:function(a){return J.WT(a)},
+$isEH:true},
+CvS:{
+"^":"TpZ:13;",
+$1:function(a){return a.gCs()},
+$isEH:true},
+edy:{
+"^":"TpZ:13;",
+$1:function(a){return J.Wp(a)},
+$isEH:true},
+waE:{
+"^":"TpZ:13;",
+$1:function(a){return J.n9(a)},
+$isEH:true},
+Ore:{
+"^":"TpZ:13;",
+$1:function(a){return J.K0(a)},
+$isEH:true},
+YLa:{
+"^":"TpZ:13;",
+$1:function(a){return J.hn(a)},
+$isEH:true},
+wfa:{
+"^":"TpZ:13;",
+$1:function(a){return J.HP(a)},
+$isEH:true},
+Oaa:{
+"^":"TpZ:13;",