Version 1.12.0-dev.1.0

Merge commit '0368173f201055c792ea24bedd5a46fd4aa8801e' into dev.
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..f9b1135
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,31 @@
+# Explicitly declare text files we want to be normalized.
+*.c text
+*.cpp text
+*.h text
+*.gyp text
+*.gypi text
+*.dart text
+*.mk text
+*.Makefile text
+*.md text
+*.yaml text
+
+# Files that should not be converted.
+tests/compiler/dart2js_extra/string_interpolation_test.dart -text
+tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart -text
+tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart -text
+tests/language/raw_string_test.dart -text
+tests/language/multiline_strings_test.dart -text
+tests/lib/convert/json_pretty_test.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_test.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_cr.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart -text
+tests/lib/mirrors/method_mirror_source_line_ending_lf.dart -text
+tests/lib/mirrors/method_mirror_source_test.dart -text
+tests/lib/mirrors/method_mirror_source_other.dart -text
+pkg/js_ast/test/printer_callback_test.dart -text
+
+# Files to leave alone and not diff.
+*.png binary
+*.jpg binary
+*.xpi binary
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ddd1600..884a584 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,7 +8,30 @@
     `setInnerHtml` or other methods that create DOM from text. It is
     also more efficient, skipping the creation of a `DocumentFragment`.
 
-## 1.11.0
+### Tool changes
+
+* Pub
+
+  * Pub will now generate a ".packages" file in addition to the "packages"
+    directory when running `pub get` or similar operations, per the
+    [package spec proposal][]. Pub now has a `--no-package-symlinks` flag that
+    will stop "packages" directories from being generated at all.
+
+  * When `pub publish` finds a violation, it will emit a non-zero exit code.
+
+  * `pub run` starts up faster for executables that don't import transformed
+    code.
+
+[package spec proposal]: https://github.com/lrhn/dep-pkgspec
+
+## 1.11.1
+
+### Tool changes
+
+* Pub will always load Dart SDK assets from the SDK whose `pub` executable was
+  run, even if a `DART_SDK` environment variable is set.
+
+## 1.11.0 - 2015-06-25
 
 ### Core library changes
 
@@ -56,6 +79,7 @@
   * `Isolate` methods `ping` and `addOnExitListener` now have a named parameter
     `response`.
     [r45092](https://github.com/dart-lang/sdk/commit/1b208bd)
+  * `Isolate.spawnUri` added a named argument `checked`.
   * Remove the experimental state of the API.
 
 * `dart:profiler` - **DEPRECATED**
diff --git a/DEPS b/DEPS
index 5fbe981..321d387 100644
--- a/DEPS
+++ b/DEPS
@@ -83,7 +83,7 @@
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "plugin_tag": "@0.1.0",
   "pool_rev": "@22e12aeb16ad0b626900dbe79e4a25391ddfb28c",
-  "pub_rev": "@9d707158fedc86fc2b02f62cdfe804902b098d9d",
+  "pub_rev": "@0c02113cc761ec5f142a8c41ff277505fafa5e10",
   "pub_cache_tag": "@v0.0.1+2",
   "pub_semver_tag": "@1.2.1",
   "quiver_tag": "@0.21.4",
diff --git a/create_sdk.gyp b/create_sdk.gyp
index 0ca1c9a..232009c 100644
--- a/create_sdk.gyp
+++ b/create_sdk.gyp
@@ -28,7 +28,7 @@
                 '"^(?!.*pub/test).*dart$",'
                 '"sdk/lib"])',
             '<!@(["python", "tools/list_files.py", "", '
-                '"sdk/lib/_internal/compiler/js_lib/preambles"])',
+                '"sdk/lib/_internal/js_runtime/lib/preambles"])',
             '<!@(["python", "tools/list_files.py", "", "sdk/bin"])',
             'tools/create_sdk.py',
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 10d6f2c..efd9b0d 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -6,8 +6,9 @@
 \usepackage{hyperref}
 \usepackage{lmodern}
 \newcommand{\code}[1]{{\sf #1}}
-\title{Dart Programming Language  Specification\\
-{\large Version 1.10}}
+\title{Dart Programming Language  Specification  \\
+(4th edition draft)\\
+{\large Version 1.11}}
 
 % For information about Location Markers (and in particular the
 % commands \LMHash and \LMLabel), see the long comment at the
@@ -1851,7 +1852,7 @@
 The scope of the \IMPLEMENTS{} clause of a class $C$ is the type-parameter scope of $C$.
 
 \LMHash{}
-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 an enumerated type (\ref{enums}),  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 \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 an enumerated type (\ref{enums}),  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{
@@ -3794,6 +3795,8 @@
 \LMHash{}
 $((x) => x == \NULL ? \NULL : x.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k}))(o)$. 
 
+unless $o$ is  a type literal, in which case it is equivalent to $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$.
+
 \LMHash{}
 The static type of $e$ is the same as the static type of $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$. Exactly the same static warnings that would be caused by $o.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$ are also generated in the case of $o?.m(a_1, \ldots , a_n, x_{n+1}: a_{n+1}, \ldots , x_{n+k}: a_{n+k})$.
 
@@ -3870,7 +3873,7 @@
 \item
 $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}.  Or
 \item  $T$ is \code{Type}, $e$ is a constant type literal and the class corresponding to $e$ has a static getter named $m$.
-\item $T$ is \code{Function} and $m$ is \CALL. \rationale {The type \code{Function} is treated as if it has a \code{call} method for any possible signature of \CALL. The expectation is that any concrete subclass of \code{Function} will implement \CALL. Note that a warning will be issue if this is not the case. Furthermore, any use of \CALL on a subclass of \code{Function} that fails to implement \CALL{} will also provoke a a warning, as this exemption is limited to type \code{Function}, and does not apply to its subtypes. 
+\item $T$ is \code{Function} and $m$ is \CALL. \rationale {The type \code{Function} is treated as if it has a \code{call} method for any possible signature of \CALL. The expectation is that any concrete subclass of \code{Function} will implement \CALL. Note that a warning will be issue if this is not the case. Furthermore, any use of \CALL{} on a subclass of \code{Function} that fails to implement \CALL{} will also provoke a a warning, as this exemption is limited to type \code{Function}, and does not apply to its subtypes. 
 }
 \end{itemize}
 
@@ -3993,11 +3996,10 @@
 Tear-offs using the \cd{ x\#id}  syntax cannot be conditional at this time; this is inconsistent, and is likely to be addressed in the near future, perhaps via  notation such as  \cd{ x?\#id} . As indicated in section \ref{ecmaConformance}, experimentation in this area is allowed.
 }
 
-Evaluation of a {\em conditional property extraction expression} $e$ of the form $e_1?.id$  is equivalent to the evaluation of the expression  $((x) => x == \NULL ? \NULL : x.id)(e_1)$. The static type of $e$ is the same as the static type of $e_1.id$. Let $T$ be the static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static warnings that would be caused by $y.id$ are also generated in the case of $e_1?.id$.
+Evaluation of a {\em conditional property extraction expression} $e$ of the form $e_1?.id$  is equivalent to the evaluation of the expression  $((x) => x == \NULL ? \NULL : x.id)(e_1)$. 
+unless $e_1$ is  a type literal, in which case it is equivalent to $e_1.m$.
 
-\commentary{
-One might be tempted to conclude that for $e \ne \NULL{}$, $e?.v$ is always equivalent to $e.v$. However this is not the case. If $e$ is a type literal representing a type with static member $v$, then $e.v$ refers to that member, but $e?.v$ does not.
-}
+The static type of $e$ is the same as the static type of $e_1.id$. Let $T$ be the static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static warnings that would be caused by $y.id$ are also generated in the case of $e_1?.id$.
 
 \LMHash{}
 Unconditional property extraction takes several syntactic forms: $e.m$ (\ref{getterAccessAndMethodExtraction}), $\SUPER.m$ (\ref{superGetterAccessAndMethodClosurization}), $e\#m$ (\ref{generalClosurization}), $\NEW{}$ $T\#m$ (\ref{namedConstructorExtraction}), $\NEW{}$ $T\#$ (\ref{anonymousConstructorExtraction}) and $\SUPER\#m$ (\ref{generalSuperPropertyExtraction}), where $e$ is an expression, $m$ is an identifier optionally followed by an equal sign and $T$ is a type.
@@ -4434,7 +4436,9 @@
 It is a static type warning if the static type of $e$ may not be assigned to the static type of $v$. The static type of the expression $v$ \code{=} $e$ is the static type of $e$.
 
 \LMHash{}
-Evaluation of an assignment $a$ of the form $e_1?.v$ \code{=} $e_2$ is equivalent to the evaluation of the expression $((x) => x == \NULL? \NULL: x.v = e_2)(e_1)$. The static type of $a$ is the static type of $e_2$. Let $T$ be the static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static warnings that would be caused by $y.v = e_2$ are also generated in the case of $e_1?.v$ \code{=} $e_2$.
+Evaluation of an assignment $a$ of the form $e_1?.v$ \code{=} $e_2$ is equivalent to the evaluation of the expression $((x) => x == \NULL? \NULL: x.v = e_2)(e_1)$
+ unless $e_1$ is  a type literal, in which case it is equivalent to $e_1.v$ \code{=} $e_2$.
+. The static type of $a$ is the static type of $e_2$. Let $T$ be the static type of $e_1$ and let $y$ be a fresh variable of type $T$. Exactly the same static warnings that would be caused by $y.v = e_2$ are also generated in the case of $e_1?.v$ \code{=} $e_2$.
 
 \LMHash{}
 Evaluation of an assignment of the form $e_1.v$ \code{=} $e_2$ proceeds as follows:
@@ -4543,18 +4547,31 @@
 \LMLabel{compoundAssignment}
 
 \LMHash{}
-Evaluation of a compound assignment of the form $v$ {\em ??=} $e$ is equivalent to the evaluation of the expression  $((x) => x == \NULL{}$ ?  $v=e : x)(v)$ where $x$ is a fresh variable that is not used in $e$. Evaluation of a compound assignment of the form $C.v$ {\em ??=} $e$, where $C$ is a type literal, is equivalent to the evaluation of the expression  $((x) => x == \NULL{}$?  $C.v=e: x)(C.v)$ where $x$ is a fresh variable that is not used in $e$. 
+Evaluation of a compound assignment of the form $v$ {\em ??=} $e$ is equivalent to the evaluation of the expression  $((x) => x == \NULL{}$ ?  $v=e : x)(v)$ where $x$ is a fresh variable that is not used in $e$. 
+
+\LMHash{}
+Evaluation of a compound assignment of the form $C.v$ {\em ??=} $e$, where $C$ is a type literal, is equivalent to the evaluation of the expression  $((x) => x == \NULL{}$?  $C.v=e: x)(C.v)$ where $x$ is a fresh variable that is not used in $e$. 
 
 \commentary {
 The two rules above also apply when the variable v or the type C is prefixed.
 }
 
-Evaluation of a compound assignment of the form $e_1.v$ {\em ??=} $e_2$ is equivalent to the evaluation of the expression  $((x) =>((y) => y == \NULL{}$ ? $ x.v = e_2: y)(x.v))(e_1)$ where $x$ and $y$ are distinct fresh variables that are not used in $e_2$. Evaluation of a compound assignment of the form  $e_1[e_2]$  {\em ??=} $e_3$ is equivalent to the evaluation of the expression  
-$((a, i) => ((x) => x == \NULL{}$ ?  $a[i] = e_3: x)(a[i]))(e_1, e_2)$ where $x$, $a$ and $i$ are distinct fresh variables that are not used in $e_3$. Evaluation of a compound assignment of the form $\SUPER.v$  {\em ??=} $e$ is equivalent to the evaluation of the expression  $((x) => x == \NULL{}$ ? $\SUPER.v = e: x)(\SUPER.v)$ where $x$ is a fresh variable that is not used in $e$.
+\LMHash{}
+Evaluation of a compound assignment of the form $e_1.v$ {\em ??=} $e_2$ is equivalent to the evaluation of the expression  $((x) =>((y) => y == \NULL{}$ ? $ x.v = e_2: y)(x.v))(e_1)$ where $x$ and $y$ are distinct fresh variables that are not used in $e_2$. 
+
+\LMHash{}
+Evaluation of a compound assignment of the form  $e_1[e_2]$  {\em ??=} $e_3$ is equivalent to the evaluation of the expression  
+$((a, i) => ((x) => x == \NULL{}$ ?  $a[i] = e_3: x)(a[i]))(e_1, e_2)$ where $x$, $a$ and $i$ are distinct fresh variables that are not used in $e_3$. 
+
+\LMHash{}
+Evaluation of a compound assignment of the form $\SUPER.v$  {\em ??=} $e$ is equivalent to the evaluation of the expression  $((x) => x == \NULL{}$ ? $\SUPER.v = e: x)(\SUPER.v)$ where $x$ is a fresh variable that is not used in $e$.
 
 \LMHash{}
 Evaluation of a compound assignment of the form $e_1?.v$  {\em ??=} $e_2$ is equivalent to the evaluation of the expression \code{((x) $=>$ x == \NULL{} ?  \NULL: $x.v ??=  e_2$)($e_1$)} where $x$ is a variable that is not used in $e_2$. 
+% But what about C?.v ??= e
 
+\LMHash{}
+A compound assignment of the form $C?.v$  {\em ??=} $e_2$ is equivalent to the expression $C.v$ {\em ??=} $e$.
 
 \LMHash{}
 The static type of a compound assignment of the form $v$ {\em ??=} $e$ is the least upper bound of the static type of $v$ and the static type of $e$.  Exactly the same static warnings that would be caused by $v = e$ are also generated in the case of $v$ {\em ??=} $e$.
@@ -4579,7 +4596,9 @@
 \LMHash{}
 Evaluation of 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$. The static type of $e_1?.v$ $op = e_2$ is the static type of $e_1.v$ $op$ $e_2$. Exactly the same static warnings that would be caused by $e_1.v$ $op = e_2$ are also generated in the case of $e_1?.v$ $op = e_2$.
 
-% Buggy. Allows C?.v = e.
+\LMHash{}
+A compound assignment of the form $C?.v$ $op = e_2$ is equivalent to the expression 
+$C.v$ $op = e_2$. 
 
 \begin{grammar}
 {\bf compoundAssignmentOperator:}`*=';
@@ -5088,7 +5107,9 @@
 \LMHash{}
 Execution of a postfix expression of the form \code{$e_1?.v$++} is equivalent to executing 
 
-\code{((x) =$>$ x == \NULL? \NULL : x.v++)($e_1$)}.
+\code{((x) =$>$ x == \NULL? \NULL : x.v++)($e_1$)}
+unless $e_1$ is a type literal, in which case it is equivalent to \code{$e_1.v$++}
+.
 
 \LMHash{}
 The static type of such an expression is the static type of $e_1.v$.
@@ -5096,7 +5117,9 @@
 \LMHash{}
 Execution of a postfix expression of the form \code{$e_1?.v$-{}-} is equivalent to executing 
 
-\code{((x) =$>$ x == \NULL? \NULL : x.v-{}-)($e_1$)}.
+\code{((x) =$>$ x == \NULL? \NULL : x.v-{}-)($e_1$)}
+unless $e_1$ is a type literal, in which case it is equivalent to \code{$e_1.v$-{}-}
+.
 
 \LMHash{}
 The static type of such an expression is the static type of $e_1.v$.
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index d42eb49..db15b5f 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -6,6 +6,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:core' hide Resource;
 import 'dart:math' show max;
 
 import 'package:analysis_server/plugin/analyzed_files.dart';
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index c397a80..275df09 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -6,6 +6,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:core' hide Resource;
 
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/source/optimizing_pub_package_map_provider.dart';
@@ -477,9 +478,14 @@
     info.changeSubscription = folder.changes.listen((WatchEvent event) {
       _handleWatchEvent(folder, info, event);
     });
-    UriResolver packageUriResolver = _computePackageUriResolver(folder, info);
-    info.context = addContext(folder, packageUriResolver);
-    info.context.name = folder.path;
+    try {
+      UriResolver packageUriResolver = _computePackageUriResolver(folder, info);
+      info.context = addContext(folder, packageUriResolver);
+      info.context.name = folder.path;
+    } catch (_) {
+      info.changeSubscription.cancel();
+      rethrow;
+    }
     return info;
   }
 
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index 773af6e..fd32646 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -5,6 +5,7 @@
 library domain.analysis;
 
 import 'dart:async';
+import 'dart:core' hide Resource;
 
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/computer/computer_hover.dart';
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index 2b5e4f5..1d9c2dd 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -6,6 +6,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:core' hide Resource;
 
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/constants.dart';
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index e58a19f..3372933 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.dart
@@ -10,6 +10,8 @@
 import 'package:analysis_server/src/channel/web_socket_channel.dart';
 import 'package:analysis_server/src/get_handler.dart';
 import 'package:analysis_server/src/socket_server.dart';
+import 'package:analysis_server/src/status/get_handler.dart' as newHandler;
+import 'package:analyzer/src/generated/engine.dart';
 
 /**
  * Instances of the class [HttpServer] implement a simple HTTP server. The
@@ -34,6 +36,11 @@
   GetHandler getHandler;
 
   /**
+   * An object that can handle GET requests when the new task model is in use.
+   */
+  newHandler.GetHandler newGetHandler;
+
+  /**
    * Future that is completed with the HTTP server once it is running.
    */
   Future<HttpServer> _server;
@@ -77,10 +84,17 @@
    * Handle a GET request received by the HTTP server.
    */
   void _handleGetRequest(HttpRequest request) {
-    if (getHandler == null) {
-      getHandler = new GetHandler(socketServer, _printBuffer);
+    if (AnalysisEngine.instance.useTaskModel) {
+      if (newGetHandler == null) {
+        newGetHandler = new newHandler.GetHandler(socketServer, _printBuffer);
+      }
+      newGetHandler.handleGetRequest(request);
+    } else {
+      if (getHandler == null) {
+        getHandler = new GetHandler(socketServer, _printBuffer);
+      }
+      getHandler.handleGetRequest(request);
     }
-    getHandler.handleGetRequest(request);
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/services/completion/import_uri_contributor.dart b/pkg/analysis_server/lib/src/services/completion/import_uri_contributor.dart
index 0d56e98..574931b 100644
--- a/pkg/analysis_server/lib/src/services/completion/import_uri_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/import_uri_contributor.dart
@@ -6,6 +6,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:core' hide Resource;
 
 import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
 import 'package:analyzer/file_system/file_system.dart';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
index 654fc4f..849b9e1 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/move_file.dart
@@ -5,6 +5,7 @@
 library services.src.refactoring.move_file;
 
 import 'dart:async';
+import 'dart:core' hide Resource;
 
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/status.dart';
diff --git a/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart b/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart
index f6c9bb7..3d99622 100644
--- a/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart
+++ b/pkg/analysis_server/lib/src/source/caching_pub_package_map_provider.dart
@@ -5,6 +5,7 @@
 library source.caching_pub_package_map_provider;
 
 import 'dart:convert';
+import 'dart:core' hide Resource;
 import 'dart:io' as io;
 
 import 'package:analyzer/file_system/file_system.dart';
diff --git a/pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart b/pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart
index ccda5f9..deeee77 100644
--- a/pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart
+++ b/pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart
@@ -4,6 +4,8 @@
 
 library source.optimizing_pub_package_map_provider;
 
+import 'dart:core' hide Resource;
+
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
new file mode 100644
index 0000000..01a330a
--- /dev/null
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -0,0 +1,1678 @@
+// 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 analysis_server.src.status.get_handler;
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:io';
+import 'dart:math';
+
+import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domain_completion.dart';
+import 'package:analysis_server/src/domain_execution.dart';
+import 'package:analysis_server/src/operation/operation.dart';
+import 'package:analysis_server/src/operation/operation_analysis.dart';
+import 'package:analysis_server/src/operation/operation_queue.dart';
+import 'package:analysis_server/src/protocol.dart' hide Element;
+import 'package:analysis_server/src/services/index/index.dart';
+import 'package:analysis_server/src/services/index/local_index.dart';
+import 'package:analysis_server/src/services/index/store/split_store.dart';
+import 'package:analysis_server/src/socket_server.dart';
+import 'package:analysis_server/src/status/ast_writer.dart';
+import 'package:analysis_server/src/status/element_writer.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    hide AnalysisContextImpl, AnalysisTask;
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:plugin/plugin.dart';
+
+/**
+ * A function that can be used to generate HTML output into the given [buffer].
+ * The HTML that is generated must be valid (special characters must already be
+ * encoded).
+ */
+typedef void HtmlGenerator(StringBuffer buffer);
+
+/**
+ * Instances of the class [GetHandler] handle GET requests.
+ */
+class GetHandler {
+  /**
+   * The path used to request overall performance information.
+   */
+  static const String ANALYSIS_PERFORMANCE_PATH = '/perf/analysis';
+
+  /**
+   * The path used to request information about a element model.
+   */
+  static const String AST_PATH = '/ast';
+
+  /**
+   * The path used to request information about the cache entry corresponding
+   * to a single file.
+   */
+  static const String CACHE_ENTRY_PATH = '/cache_entry';
+
+  /**
+   * The path used to request the list of source files in a certain cache
+   * state.
+   */
+  static const String CACHE_STATE_PATH = '/cache_state';
+
+  /**
+   * The path used to request code completion information.
+   */
+  static const String COMPLETION_PATH = '/completion';
+
+  /**
+   * The path used to request communication performance information.
+   */
+  static const String COMMUNICATION_PERFORMANCE_PATH = '/perf/communication';
+
+  /**
+   * The path used to request information about a specific context.
+   */
+  static const String CONTEXT_PATH = '/context';
+
+  /**
+   * The path used to request information about a element model.
+   */
+  static const String ELEMENT_PATH = '/element';
+
+  /**
+   * The path used to request information about elements with the given name.
+   */
+  static const String INDEX_ELEMENT_BY_NAME = '/index/element-by-name';
+
+  /**
+   * The path used to request an overlay contents.
+   */
+  static const String OVERLAY_PATH = '/overlay';
+
+  /**
+   * The path used to request overlays information.
+   */
+  static const String OVERLAYS_PATH = '/overlays';
+
+  /**
+   * The path used to request the status of the analysis server as a whole.
+   */
+  static const String STATUS_PATH = '/status';
+
+  /**
+   * Query parameter used to represent the context to search for, when
+   * accessing [CACHE_ENTRY_PATH] or [CACHE_STATE_PATH].
+   */
+  static const String CONTEXT_QUERY_PARAM = 'context';
+
+  /**
+   * Query parameter used to represent the descriptor to search for, when
+   * accessing [CACHE_STATE_PATH].
+   */
+  static const String DESCRIPTOR_QUERY_PARAM = 'descriptor';
+
+  /**
+   * Query parameter used to represent the name of elements to search for, when
+   * accessing [INDEX_ELEMENT_BY_NAME].
+   */
+  static const String INDEX_ELEMENT_NAME = 'name';
+
+  /**
+   * Query parameter used to represent the path of an overlayed file.
+   */
+  static const String PATH_PARAM = 'path';
+
+  /**
+   * Query parameter used to represent the source to search for, when accessing
+   * [CACHE_ENTRY_PATH].
+   */
+  static const String SOURCE_QUERY_PARAM = 'entry';
+
+  /**
+   * Query parameter used to represent the cache state to search for, when
+   * accessing [CACHE_STATE_PATH].
+   */
+  static const String STATE_QUERY_PARAM = 'state';
+
+  static final ContentType _htmlContent =
+      new ContentType("text", "html", charset: "utf-8");
+
+  /**
+   * The socket server whose status is to be reported on.
+   */
+  SocketServer _server;
+
+  /**
+   * Buffer containing strings printed by the analysis server.
+   */
+  List<String> _printBuffer;
+
+  /**
+   * Contents of overlay files.
+   */
+  final Map<String, String> _overlayContents = <String, String>{};
+
+  /**
+   * Initialize a newly created handler for GET requests.
+   */
+  GetHandler(this._server, this._printBuffer);
+
+  /**
+   * Return the active [CompletionDomainHandler]
+   * or `null` if either analysis server is not running
+   * or there is no completion domain handler.
+   */
+  CompletionDomainHandler get _completionDomainHandler {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return null;
+    }
+    return analysisServer.handlers.firstWhere(
+        (h) => h is CompletionDomainHandler, orElse: () => null);
+  }
+
+  /**
+   * Handle a GET request received by the HTTP server.
+   */
+  void handleGetRequest(HttpRequest request) {
+    String path = request.uri.path;
+    if (path == STATUS_PATH) {
+      _returnServerStatus(request);
+    } else if (path == ANALYSIS_PERFORMANCE_PATH) {
+      _returnAnalysisPerformance(request);
+    } else if (path == AST_PATH) {
+      _returnAst(request);
+    } else if (path == CACHE_STATE_PATH) {
+      _returnCacheState(request);
+    } else if (path == CACHE_ENTRY_PATH) {
+      _returnCacheEntry(request);
+    } else if (path == COMPLETION_PATH) {
+      _returnCompletionInfo(request);
+    } else if (path == COMMUNICATION_PERFORMANCE_PATH) {
+      _returnCommunicationPerformance(request);
+    } else if (path == CONTEXT_PATH) {
+      _returnContextInfo(request);
+    } else if (path == ELEMENT_PATH) {
+      _returnElement(request);
+    } else if (path == INDEX_ELEMENT_BY_NAME) {
+      _returnIndexElementByName(request);
+    } else if (path == OVERLAY_PATH) {
+      _returnOverlayContents(request);
+    } else if (path == OVERLAYS_PATH) {
+      _returnOverlaysInfo(request);
+    } else {
+      _returnUnknownRequest(request);
+    }
+  }
+
+  /**
+   * Return the folder being managed by the given [analysisServer] that matches
+   * the given [contextFilter], or `null` if there is none.
+   */
+  Folder _findFolder(AnalysisServer analysisServer, String contextFilter) {
+    return analysisServer.folderMap.keys.firstWhere(
+        (Folder folder) => folder.path == contextFilter, orElse: () => null);
+  }
+
+  /**
+   * Return any AST structure stored in the given [entry].
+   */
+  CompilationUnit _getAnyAst(CacheEntry entry) {
+    CompilationUnit unit = entry.getValue(PARSED_UNIT);
+    if (unit != null) {
+      return unit;
+    }
+    unit = entry.getValue(RESOLVED_UNIT1);
+    if (unit != null) {
+      return unit;
+    }
+    unit = entry.getValue(RESOLVED_UNIT2);
+    if (unit != null) {
+      return unit;
+    }
+    unit = entry.getValue(RESOLVED_UNIT3);
+    if (unit != null) {
+      return unit;
+    }
+    unit = entry.getValue(RESOLVED_UNIT4);
+    if (unit != null) {
+      return unit;
+    }
+    unit = entry.getValue(RESOLVED_UNIT5);
+    if (unit != null) {
+      return unit;
+    }
+    return entry.getValue(RESOLVED_UNIT);
+  }
+
+  /**
+   * Return `true` if the given analysis [context] has at least one entry with
+   * an exception.
+   */
+  bool _hasException(InternalAnalysisContext context) {
+    MapIterator<AnalysisTarget, CacheEntry> iterator =
+        context.analysisCache.iterator();
+    while (iterator.moveNext()) {
+      if (iterator.value.exception != null) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Return the folder in the [folderMap] with which the given [context] is
+   * associated.
+   */
+  Folder _keyForValue(
+      Map<Folder, AnalysisContext> folderMap, AnalysisContext context) {
+    for (Folder folder in folderMap.keys) {
+      if (folderMap[folder] == context) {
+        return folder;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Return a response displaying overall performance information.
+   */
+  void _returnAnalysisPerformance(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server is not running');
+    }
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Analysis Performance', [],
+          (StringBuffer buffer) {
+        buffer.write('<h3>Analysis Performance</h3>');
+
+        //
+        // Write performance tags.
+        //
+        {
+          buffer.write('<p><b>Time spent in each phase of analysis</b></p>');
+          buffer.write(
+              '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
+          _writeRow(buffer, ['Time (in ms)', 'Percent', 'Analysis Phase'],
+              header: true);
+          // prepare sorted tags
+          List<PerformanceTag> tags = PerformanceTag.all.toList();
+          tags.remove(ServerPerformanceStatistics.idle);
+          tags.sort((a, b) => b.elapsedMs - a.elapsedMs);
+          // prepare total time
+          int totalTime = 0;
+          tags.forEach((PerformanceTag tag) {
+            totalTime += tag.elapsedMs;
+          });
+          // write rows
+          void writeRow(PerformanceTag tag) {
+            double percent = (tag.elapsedMs * 100) / totalTime;
+            String percentStr = '${percent.toStringAsFixed(2)}%';
+            _writeRow(buffer, [tag.elapsedMs, percentStr, tag.label],
+                classes: ["right", "right", null]);
+          }
+          tags.forEach(writeRow);
+          buffer.write('</table>');
+        }
+
+        //
+        // Write new task model timing information.
+        //
+        if (AnalysisEngine.instance.useTaskModel) {
+          buffer.write('<p><b>Task performace data</b></p>');
+          buffer.write(
+              '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
+          _writeRow(buffer, [
+            'Task Name',
+            'Count',
+            'Total Time (in ms)',
+            'Average Time (in ms)'
+          ], header: true);
+
+          Map<Type, int> countMap = AnalysisTask.countMap;
+          Map<Type, Stopwatch> stopwatchMap = AnalysisTask.stopwatchMap;
+          List<Type> taskClasses = stopwatchMap.keys.toList();
+          taskClasses.sort((Type first, Type second) =>
+              first.toString().compareTo(second.toString()));
+          int totalTime = 0;
+          taskClasses.forEach((Type taskClass) {
+            int count = countMap[taskClass];
+            if (count == null) {
+              count = 0;
+            }
+            int taskTime = stopwatchMap[taskClass].elapsedMilliseconds;
+            totalTime += taskTime;
+            _writeRow(buffer, [
+              taskClass.toString(),
+              count,
+              taskTime,
+              count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3)
+            ], classes: [null, "right", "right", "right"]);
+          });
+          _writeRow(buffer, ['Total', '-', totalTime, '-'],
+              classes: [null, "right", "right", "right"]);
+          buffer.write('</table>');
+        }
+
+        //
+        // Write old task model transition information.
+        //
+        {
+          Map<DataDescriptor, Map<CacheState, int>> transitionMap =
+              SourceEntry.transitionMap;
+          buffer.write(
+              '<p><b>Number of times a state transitioned to VALID (grouped by descriptor)</b></p>');
+          if (transitionMap.isEmpty) {
+            buffer.write('<p>none</p>');
+          } else {
+            List<DataDescriptor> descriptors = transitionMap.keys.toList();
+            descriptors.sort((DataDescriptor first, DataDescriptor second) =>
+                first.toString().compareTo(second.toString()));
+            for (DataDescriptor key in descriptors) {
+              Map<CacheState, int> countMap = transitionMap[key];
+              List<CacheState> oldStates = countMap.keys.toList();
+              oldStates.sort((CacheState first, CacheState second) =>
+                  first.toString().compareTo(second.toString()));
+              buffer.write('<p>${key.toString()}</p>');
+              buffer.write(
+                  '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
+              _writeRow(buffer, ['Count', 'Previous State'], header: true);
+              for (CacheState state in oldStates) {
+                _writeRow(buffer, [countMap[state], state.toString()],
+                    classes: ["right", null]);
+              }
+              buffer.write('</table>');
+            }
+          }
+        }
+      });
+    });
+  }
+
+  /**
+   * Return a response containing information about an AST structure.
+   */
+  void _returnAst(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server not running');
+    }
+    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+    if (contextFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+    }
+    Folder folder = _findFolder(analysisServer, contextFilter);
+    if (folder == null) {
+      return _returnFailure(request, 'Invalid context: $contextFilter');
+    }
+    String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
+    if (sourceUri == null) {
+      return _returnFailure(
+          request, 'Query parameter $SOURCE_QUERY_PARAM required');
+    }
+
+    InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - AST Structure', [
+        'Context: $contextFilter',
+        'File: $sourceUri'
+      ], (HttpResponse) {
+        Source source = context.sourceFactory.forUri(sourceUri);
+        if (source == null) {
+          buffer.write('<p>Not found.</p>');
+          return;
+        }
+        CacheEntry entry = context.analysisCache.get(source);
+        if (entry == null) {
+          buffer.write('<p>Not found.</p>');
+          return;
+        }
+        CompilationUnit ast = _getAnyAst(entry);
+        if (ast == null) {
+          buffer.write('<p>null</p>');
+          return;
+        }
+        AstWriter writer = new AstWriter(buffer);
+        ast.accept(writer);
+        if (writer.exceptions.isNotEmpty) {
+          buffer.write('<h3>Exceptions while creating page</h3>');
+          for (CaughtException exception in writer.exceptions) {
+            _writeException(buffer, exception);
+          }
+        }
+      });
+    });
+  }
+
+  /**
+   * Return a response containing information about a single source file in the
+   * cache.
+   */
+  void _returnCacheEntry(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server not running');
+    }
+    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+    if (contextFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+    }
+    Folder folder = _findFolder(analysisServer, contextFilter);
+    if (folder == null) {
+      return _returnFailure(request, 'Invalid context: $contextFilter');
+    }
+    String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
+    if (sourceUri == null) {
+      return _returnFailure(
+          request, 'Query parameter $SOURCE_QUERY_PARAM required');
+    }
+
+    List<Folder> allContexts = <Folder>[];
+    Map<Folder, List<CacheEntry>> entryMap =
+        new HashMap<Folder, List<CacheEntry>>();
+    analysisServer.folderMap
+        .forEach((Folder folder, InternalAnalysisContext context) {
+      Source source = context.sourceFactory.forUri(sourceUri);
+      if (source != null) {
+        MapIterator<AnalysisTarget, CacheEntry> iterator =
+            context.analysisCache.iterator();
+        while (iterator.moveNext()) {
+          if (source == iterator.key.source) {
+            if (!allContexts.contains(folder)) {
+              allContexts.add(folder);
+            }
+            List<CacheEntry> entries = entryMap[folder];
+            if (entries == null) {
+              entries = <CacheEntry>[];
+              entryMap[folder] = entries;
+            }
+            entries.add(iterator.value);
+          }
+        }
+      }
+    });
+    allContexts.sort((Folder firstFolder, Folder secondFolder) =>
+        firstFolder.path.compareTo(secondFolder.path));
+    InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Cache Entry', [
+        'Context: $contextFilter',
+        'File: $sourceUri'
+      ], (HttpResponse) {
+        buffer.write('<h3>Analyzing Contexts</h3><p>');
+        bool first = true;
+        allContexts.forEach((Folder folder) {
+          if (first) {
+            first = false;
+          } else {
+            buffer.write('<br>');
+          }
+          InternalAnalysisContext analyzingContext =
+              analysisServer.folderMap[folder];
+          if (analyzingContext == context) {
+            buffer.write(folder.path);
+          } else {
+            buffer.write(makeLink(CACHE_ENTRY_PATH, {
+              CONTEXT_QUERY_PARAM: folder.path,
+              SOURCE_QUERY_PARAM: sourceUri
+            }, HTML_ESCAPE.convert(folder.path)));
+          }
+          if (entryMap[folder][0].explicitlyAdded) {
+            buffer.write(' (explicit)');
+          } else {
+            buffer.write(' (implicit)');
+          }
+        });
+        buffer.write('</p>');
+
+        List<CacheEntry> entries = entryMap[folder];
+        if (entries == null) {
+          buffer.write('<p>Not being analyzed in this context.</p>');
+          return;
+        }
+        for (CacheEntry entry in entries) {
+          Map<String, String> linkParameters = <String, String>{
+            CONTEXT_QUERY_PARAM: folder.path,
+            SOURCE_QUERY_PARAM: sourceUri
+          };
+          List<ResultDescriptor> results = entry.nonInvalidResults;
+          results.sort((ResultDescriptor first, ResultDescriptor second) =>
+              first.toString().compareTo(second.toString()));
+
+          buffer.write('<h3>');
+          buffer.write(HTML_ESCAPE.convert(entry.target.toString()));
+          buffer.write('</h3>');
+          buffer.write('<dl>');
+          buffer.write('<dt>time</dt><dd>');
+          buffer.write(entry.modificationTime);
+          buffer.write('</dd></dl>');
+          for (ResultDescriptor result in results) {
+            ResultData data = entry.getResultData(result);
+            String descriptorName = HTML_ESCAPE.convert(result.toString());
+            String descriptorState = HTML_ESCAPE.convert(data.state.toString());
+            buffer.write('<dt>$descriptorName ($descriptorState)</dt><dd>');
+            try {
+              _writeValueAsHtml(buffer, data.value, linkParameters);
+            } catch (exception) {
+              buffer.write('(${HTML_ESCAPE.convert(exception.toString())})');
+            }
+            buffer.write('</dd>');
+          }
+          if (entry.exception != null) {
+            buffer.write('<dt>exception</dt><dd>');
+            _writeException(buffer, entry.exception);
+            buffer.write('</dd></dl>');
+          }
+          buffer.write('</dl>');
+        }
+      });
+    });
+  }
+
+  /**
+   * Return a response indicating the set of source files in a certain cache
+   * state.
+   */
+  void _returnCacheState(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server not running');
+    }
+    // Figure out which context is being searched within.
+    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+    if (contextFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+    }
+    // Figure out what CacheState is being searched for.
+    String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM];
+    if (stateQueryParam == null) {
+      return _returnFailure(
+          request, 'Query parameter $STATE_QUERY_PARAM required');
+    }
+    CacheState stateFilter = null;
+    for (CacheState value in CacheState.values) {
+      if (value.toString() == stateQueryParam) {
+        stateFilter = value;
+      }
+    }
+    if (stateFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $STATE_QUERY_PARAM is invalid');
+    }
+    // Figure out which descriptor is being searched for.
+    String descriptorFilter =
+        request.uri.queryParameters[DESCRIPTOR_QUERY_PARAM];
+    if (descriptorFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $DESCRIPTOR_QUERY_PARAM required');
+    }
+
+    // TODO(brianwilkerson) Figure out how to convert the 'descriptorFilter' to
+    // a ResultDescriptor so that we can query the state, then uncomment the
+    // code below that computes and prints the list of links.
+//    Folder folder = _findFolder(analysisServer, contextFilter);
+//    InternalAnalysisContext context = analysisServer.folderMap[folder];
+//    List<String> links = <String>[];
+//    MapIterator<AnalysisTarget, CacheEntry> iterator = context.analysisCache.iterator();
+//    while (iterator.moveNext()) {
+//      Source source = iterator.key.source;
+//      if (source != null) {
+//        CacheEntry entry = iterator.value;
+//        if (entry.getState(result) == stateFilter) {
+//          String link = makeLink(CACHE_ENTRY_PATH, {
+//            CONTEXT_QUERY_PARAM: folder.path,
+//            SOURCE_QUERY_PARAM: source.uri.toString()
+//          }, HTML_ESCAPE.convert(source.fullName));
+//          links.add(link);
+//        }
+//      }
+//    }
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Cache Search', [
+        'Context: $contextFilter',
+        'Descriptor: ${HTML_ESCAPE.convert(descriptorFilter)}',
+        'State: ${HTML_ESCAPE.convert(stateQueryParam)}'
+      ], (StringBuffer buffer) {
+        buffer.write('<p>Cache search is not yet implemented.</p>');
+//        buffer.write('<p>${links.length} files found</p>');
+//        buffer.write('<ul>');
+//        links.forEach((String link) {
+//          buffer.write('<li>$link</li>');
+//        });
+//        buffer.write('</ul>');
+      });
+    });
+  }
+
+  /**
+   * Return a response displaying overall performance information.
+   */
+  void _returnCommunicationPerformance(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server is not running');
+    }
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Communication Performance', [],
+          (StringBuffer buffer) {
+        buffer.write('<h3>Communication Performance</h3>');
+        _writeTwoColumns(buffer, (StringBuffer buffer) {
+          ServerPerformance perf = analysisServer.performanceDuringStartup;
+          int requestCount = perf.requestCount;
+          num averageLatency = requestCount > 0
+              ? (perf.requestLatency / requestCount).round()
+              : 0;
+          int maximumLatency = perf.maxLatency;
+          num slowRequestPercent = requestCount > 0
+              ? (perf.slowRequestCount * 100 / requestCount).round()
+              : 0;
+          buffer.write('<h4>Startup</h4>');
+          buffer.write('<table>');
+          _writeRow(buffer, [requestCount, 'requests'],
+              classes: ["right", null]);
+          _writeRow(buffer, [averageLatency, 'ms average latency'],
+              classes: ["right", null]);
+          _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
+              classes: ["right", null]);
+          _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
+              classes: ["right", null]);
+          if (analysisServer.performanceAfterStartup != null) {
+            int startupTime = analysisServer.performanceAfterStartup.startTime -
+                perf.startTime;
+            _writeRow(
+                buffer, [startupTime, 'ms for initial analysis to complete']);
+          }
+          buffer.write('</table>');
+        }, (StringBuffer buffer) {
+          ServerPerformance perf = analysisServer.performanceAfterStartup;
+          if (perf == null) {
+            return;
+          }
+          int requestCount = perf.requestCount;
+          num averageLatency = requestCount > 0
+              ? (perf.requestLatency * 10 / requestCount).round() / 10
+              : 0;
+          int maximumLatency = perf.maxLatency;
+          num slowRequestPercent = requestCount > 0
+              ? (perf.slowRequestCount * 100 / requestCount).round()
+              : 0;
+          buffer.write('<h4>Current</h4>');
+          buffer.write('<table>');
+          _writeRow(buffer, [requestCount, 'requests'],
+              classes: ["right", null]);
+          _writeRow(buffer, [averageLatency, 'ms average latency'],
+              classes: ["right", null]);
+          _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
+              classes: ["right", null]);
+          _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
+              classes: ["right", null]);
+          buffer.write('</table>');
+        });
+      });
+    });
+  }
+
+  /**
+   * Return a response displaying code completion information.
+   */
+  void _returnCompletionInfo(HttpRequest request) {
+    String value = request.requestedUri.queryParameters['index'];
+    int index = value != null ? int.parse(value, onError: (_) => 0) : 0;
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Completion Stats', [],
+          (StringBuffer buffer) {
+        _writeCompletionPerformanceDetail(buffer, index);
+        _writeCompletionPerformanceList(buffer);
+      });
+    });
+  }
+
+  /**
+   * Return a response containing information about a single source file in the
+   * cache.
+   */
+  void _returnContextInfo(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server not running');
+    }
+    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+    if (contextFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+    }
+    Folder folder = _findFolder(analysisServer, contextFilter);
+    if (folder == null) {
+      return _returnFailure(request, 'Invalid context: $contextFilter');
+    }
+
+    List<String> priorityNames;
+    List<String> explicitNames = <String>[];
+    List<String> implicitNames = <String>[];
+    Map<String, String> links = new HashMap<String, String>();
+    List<CaughtException> exceptions = <CaughtException>[];
+    InternalAnalysisContext context = analysisServer.folderMap[folder];
+    priorityNames = context.prioritySources
+        .map((Source source) => source.fullName)
+        .toList();
+    MapIterator<AnalysisTarget, CacheEntry> iterator =
+        context.analysisCache.iterator();
+    while (iterator.moveNext()) {
+      Source source = iterator.key.source;
+      if (source != null) {
+        CacheEntry entry = iterator.value;
+        String sourceName = source.fullName;
+        if (!links.containsKey(sourceName)) {
+          CaughtException exception = entry.exception;
+          if (exception != null) {
+            exceptions.add(exception);
+          }
+          String link = makeLink(CACHE_ENTRY_PATH, {
+            CONTEXT_QUERY_PARAM: folder.path,
+            SOURCE_QUERY_PARAM: source.uri.toString()
+          }, sourceName, exception != null);
+          if (entry.explicitlyAdded) {
+            explicitNames.add(sourceName);
+          } else {
+            implicitNames.add(sourceName);
+          }
+          links[sourceName] = link;
+        }
+      }
+    }
+    explicitNames.sort();
+    implicitNames.sort();
+
+    _overlayContents.clear();
+    context.visitContentCache((String fullName, int stamp, String contents) {
+      _overlayContents[fullName] = contents;
+    });
+
+    void _writeFiles(
+        StringBuffer buffer, String title, List<String> fileNames) {
+      buffer.write('<h3>$title</h3>');
+      if (fileNames == null || fileNames.isEmpty) {
+        buffer.write('<p>None</p>');
+      } else {
+        buffer.write('<table style="width: 100%">');
+        for (String fileName in fileNames) {
+          buffer.write('<tr><td>');
+          buffer.write(links[fileName]);
+          buffer.write('</td><td>');
+          if (_overlayContents.containsKey(fileName)) {
+            buffer.write(
+                makeLink(OVERLAY_PATH, {PATH_PARAM: fileName}, 'overlay'));
+          }
+          buffer.write('</td></tr>');
+        }
+        buffer.write('</table>');
+      }
+    }
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Context',
+          ['Context: $contextFilter'], (StringBuffer buffer) {
+        List headerRowText = ['Context'];
+        headerRowText.addAll(CacheState.values);
+        buffer.write('<h3>Summary</h3>');
+        buffer.write('<table>');
+        _writeRow(buffer, headerRowText, header: true);
+        AnalysisContextStatistics statistics = context.statistics;
+        statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
+          List rowText = [row.name];
+          for (CacheState state in CacheState.values) {
+            String text = row.getCount(state).toString();
+            Map<String, String> params = <String, String>{
+              STATE_QUERY_PARAM: state.toString(),
+              CONTEXT_QUERY_PARAM: folder.path,
+              DESCRIPTOR_QUERY_PARAM: row.name
+            };
+            rowText.add(makeLink(CACHE_STATE_PATH, params, text));
+          }
+          _writeRow(buffer, rowText, classes: [null, "right"]);
+        });
+        buffer.write('</table>');
+
+        _writeFiles(buffer, 'Priority Files', priorityNames);
+        _writeFiles(buffer, 'Explicitly Analyzed Files', explicitNames);
+        _writeFiles(buffer, 'Implicitly Analyzed Files', implicitNames);
+
+        buffer.write('<h3>Exceptions</h3>');
+        if (exceptions.isEmpty) {
+          buffer.write('<p>None</p>');
+        } else {
+          exceptions.forEach((CaughtException exception) {
+            _writeException(buffer, exception);
+          });
+        }
+      });
+    });
+  }
+
+  /**
+   * Return a response containing information about an element structure.
+   */
+  void _returnElement(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server not running');
+    }
+    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+    if (contextFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+    }
+    Folder folder = _findFolder(analysisServer, contextFilter);
+    if (folder == null) {
+      return _returnFailure(request, 'Invalid context: $contextFilter');
+    }
+    String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
+    if (sourceUri == null) {
+      return _returnFailure(
+          request, 'Query parameter $SOURCE_QUERY_PARAM required');
+    }
+
+    InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Element Model', [
+        'Context: $contextFilter',
+        'File: $sourceUri'
+      ], (StringBuffer buffer) {
+        Source source = context.sourceFactory.forUri(sourceUri);
+        if (source == null) {
+          buffer.write('<p>Not found.</p>');
+          return;
+        }
+        CacheEntry entry = context.analysisCache.get(source);
+        if (entry == null) {
+          buffer.write('<p>Not found.</p>');
+          return;
+        }
+        LibraryElement element = entry.getValue(LIBRARY_ELEMENT);
+        if (element == null) {
+          buffer.write('<p>null</p>');
+          return;
+        }
+        element.accept(new ElementWriter(buffer));
+      });
+    });
+  }
+
+  void _returnFailure(HttpRequest request, String message) {
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Failure', [],
+          (StringBuffer buffer) {
+        buffer.write(HTML_ESCAPE.convert(message));
+      });
+    });
+  }
+
+  /**
+   * Return a response containing information about elements with the given
+   * name.
+   */
+  Future _returnIndexElementByName(HttpRequest request) async {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server not running');
+    }
+    Index index = analysisServer.index;
+    if (index == null) {
+      return _returnFailure(request, 'Indexing is disabled');
+    }
+    String name = request.uri.queryParameters[INDEX_ELEMENT_NAME];
+    if (name == null) {
+      return _returnFailure(
+          request, 'Query parameter $INDEX_ELEMENT_NAME required');
+    }
+    if (index is LocalIndex) {
+      Map<List<String>, List<InspectLocation>> relations =
+          await index.findElementsByName(name);
+      _writeResponse(request, (StringBuffer buffer) {
+        _writePage(buffer, 'Analysis Server - Index Elements', ['Name: $name'],
+            (StringBuffer buffer) {
+          buffer.write('<table border="1">');
+          _writeRow(buffer, ['Element', 'Relationship', 'Location'],
+              header: true);
+          relations.forEach((List<String> elementPath,
+              List<InspectLocation> relations) {
+            String elementLocation = elementPath.join(' ');
+            relations.forEach((InspectLocation location) {
+              var relString = location.relationship.identifier;
+              var locString = '${location.path} offset=${location.offset} '
+                  'length=${location.length} flags=${location.flags}';
+              _writeRow(buffer, [elementLocation, relString, locString]);
+            });
+          });
+          buffer.write('</table>');
+        });
+      });
+    } else {
+      return _returnFailure(request, 'LocalIndex expected, but $index found.');
+    }
+  }
+
+  void _returnOverlayContents(HttpRequest request) {
+    String path = request.requestedUri.queryParameters[PATH_PARAM];
+    if (path == null) {
+      return _returnFailure(request, 'Query parameter $PATH_PARAM required');
+    }
+    String contents = _overlayContents[path];
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Overlay', [],
+          (StringBuffer buffer) {
+        buffer.write('<pre>${HTML_ESCAPE.convert(contents)}</pre>');
+      });
+    });
+  }
+
+  /**
+   * Return a response displaying overlays information.
+   */
+  void _returnOverlaysInfo(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server is not running');
+    }
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Overlays', [],
+          (StringBuffer buffer) {
+        buffer.write('<table border="1">');
+        _overlayContents.clear();
+        ContentCache overlayState = analysisServer.overlayState;
+        overlayState.accept((String fullName, int stamp, String contents) {
+          buffer.write('<tr>');
+          String link =
+              makeLink(OVERLAY_PATH, {PATH_PARAM: fullName}, fullName);
+          DateTime time = new DateTime.fromMillisecondsSinceEpoch(stamp);
+          _writeRow(buffer, [link, time]);
+          _overlayContents[fullName] = contents;
+        });
+        int count = _overlayContents.length;
+        buffer.write('<tr><td colspan="2">Total: $count entries.</td></tr>');
+        buffer.write('</table>');
+      });
+    });
+  }
+
+  /**
+   * Return a response indicating the status of the analysis server.
+   */
+  void _returnServerStatus(HttpRequest request) {
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Status', [], (StringBuffer buffer) {
+        if (_writeServerStatus(buffer)) {
+          _writeAnalysisStatus(buffer);
+          _writeEditStatus(buffer);
+          _writeExecutionStatus(buffer);
+          _writePluginStatus(buffer);
+          _writeRecentOutput(buffer);
+        }
+      });
+    });
+  }
+
+  /**
+   * Return an error in response to an unrecognized request received by the HTTP
+   * server.
+   */
+  void _returnUnknownRequest(HttpRequest request) {
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server', [], (StringBuffer buffer) {
+        buffer.write('<h3>Pages</h3>');
+        buffer.write('<p>');
+        buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
+        buffer.write('</p>');
+        buffer.write('<p>');
+        buffer
+            .write(makeLink(COMMUNICATION_PERFORMANCE_PATH, {}, 'Performance'));
+        buffer.write('</p>');
+        buffer.write('<p>');
+        buffer.write(makeLink(STATUS_PATH, {}, 'Server status'));
+        buffer.write('</p>');
+        buffer.write('<p>');
+        buffer.write(makeLink(OVERLAYS_PATH, {}, 'File overlays'));
+        buffer.write('</p>');
+      });
+    });
+  }
+
+  /**
+   * Return a two digit decimal representation of the given non-negative integer
+   * [value].
+   */
+  String _twoDigit(int value) {
+    if (value < 10) {
+      return '0$value';
+    }
+    return value.toString();
+  }
+
+  /**
+   * Write the status of the analysis domain (on the main status page) to the
+   * given [buffer] object.
+   */
+  void _writeAnalysisStatus(StringBuffer buffer) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    Map<Folder, AnalysisContext> folderMap = analysisServer.folderMap;
+    List<Folder> folders = folderMap.keys.toList();
+    folders.sort((Folder first, Folder second) =>
+        first.shortName.compareTo(second.shortName));
+    AnalysisOptionsImpl options =
+        analysisServer.contextDirectoryManager.defaultOptions;
+    ServerOperationQueue operationQueue = analysisServer.operationQueue;
+
+    buffer.write('<h3>Analysis Domain</h3>');
+    _writeTwoColumns(buffer, (StringBuffer buffer) {
+      if (operationQueue.isEmpty) {
+        buffer.write('<p>Status: Done analyzing</p>');
+      } else {
+        ServerOperation operation = operationQueue.peek();
+        if (operation is PerformAnalysisOperation) {
+          Folder folder = _keyForValue(folderMap, operation.context);
+          if (folder == null) {
+            buffer.write('<p>Status: Analyzing in unmapped context</p>');
+          } else {
+            buffer.write('<p>Status: Analyzing in ${folder.path}</p>');
+          }
+        } else {
+          buffer.write('<p>Status: Analyzing</p>');
+        }
+      }
+
+      buffer.write('<p><b>Analysis Contexts</b></p>');
+      buffer.write('<p>');
+      bool first = true;
+      folders.forEach((Folder folder) {
+        if (first) {
+          first = false;
+        } else {
+          buffer.write('<br>');
+        }
+        String key = folder.shortName;
+        buffer.write(makeLink(CONTEXT_PATH, {
+          CONTEXT_QUERY_PARAM: folder.path
+        }, key, _hasException(folderMap[folder])));
+      });
+      buffer.write('</p>');
+
+      buffer.write('<p><b>Options</b></p>');
+      buffer.write('<p>');
+      _writeOption(
+          buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
+      _writeOption(buffer, 'Cache size', options.cacheSize);
+      _writeOption(buffer, 'Enable null-aware operators',
+          options.enableNullAwareOperators);
+      _writeOption(
+          buffer, 'Enable strict call checks', options.enableStrictCallChecks);
+      _writeOption(buffer, 'Generate hints', options.hint);
+      _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
+      _writeOption(buffer, 'Generate errors in implicit files',
+          options.generateImplicitErrors);
+      _writeOption(
+          buffer, 'Generate errors in SDK files', options.generateSdkErrors);
+      _writeOption(buffer, 'Incremental resolution', options.incremental);
+      _writeOption(buffer, 'Incremental resolution with API changes',
+          options.incrementalApi);
+      _writeOption(buffer, 'Preserve comments', options.preserveComments,
+          last: true);
+      buffer.write('</p>');
+      int freq = AnalysisServer.performOperationDelayFreqency;
+      String delay = freq > 0 ? '1 ms every $freq ms' : 'off';
+      buffer.write('<p><b>perform operation delay:</b> $delay</p>');
+
+      buffer.write('<p><b>Performance Data</b></p>');
+      buffer.write('<p>');
+      buffer.write(makeLink(ANALYSIS_PERFORMANCE_PATH, {}, 'Task data'));
+      buffer.write('</p>');
+    }, (StringBuffer buffer) {
+      _writeSubscriptionMap(
+          buffer, AnalysisService.VALUES, analysisServer.analysisServices);
+    });
+  }
+
+  /**
+   * Write performance information about a specific completion request
+   * to the given [buffer] object.
+   */
+  void _writeCompletionPerformanceDetail(StringBuffer buffer, int index) {
+    CompletionDomainHandler handler = _completionDomainHandler;
+    CompletionPerformance performance;
+    if (handler != null) {
+      List<CompletionPerformance> list = handler.performanceList;
+      if (list != null && list.isNotEmpty) {
+        performance = list[max(0, min(list.length - 1, index))];
+      }
+    }
+    if (performance == null) {
+      buffer.write('<h3>Completion Performance Detail</h3>');
+      buffer.write('<p>No completions yet</p>');
+      return;
+    }
+    buffer.write('<h3>Completion Performance Detail</h3>');
+    buffer.write('<p>${performance.startTimeAndMs} for ${performance.source}');
+    buffer.write('<table>');
+    _writeRow(buffer, ['Elapsed', '', 'Operation'], header: true);
+    performance.operations.forEach((OperationPerformance op) {
+      String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
+      _writeRow(buffer, [elapsed, '&nbsp;&nbsp;', op.name]);
+    });
+    buffer.write('</table>');
+    buffer.write('<p><b>Compute Cache Performance</b>: ');
+    if (handler.computeCachePerformance == null) {
+      buffer.write('none');
+    } else {
+      int elapsed = handler.computeCachePerformance.elapsedInMilliseconds;
+      Source source = handler.computeCachePerformance.source;
+      buffer.write(' $elapsed ms for $source');
+    }
+    buffer.write('</p>');
+  }
+
+  /**
+   * Write a table showing summary information for the last several
+   * completion requests to the given [buffer] object.
+   */
+  void _writeCompletionPerformanceList(StringBuffer buffer) {
+    CompletionDomainHandler handler = _completionDomainHandler;
+    buffer.write('<h3>Completion Performance List</h3>');
+    if (handler == null) {
+      return;
+    }
+    buffer.write('<table>');
+    _writeRow(buffer, [
+      'Start Time',
+      '',
+      'First (ms)',
+      '',
+      'Complete (ms)',
+      '',
+      '# Notifications',
+      '',
+      '# Suggestions',
+      '',
+      'Snippet'
+    ], header: true);
+    int index = 0;
+    for (CompletionPerformance performance in handler.performanceList) {
+      String link = makeLink(COMPLETION_PATH, {
+        'index': '$index'
+      }, '${performance.startTimeAndMs}');
+      _writeRow(buffer, [
+        link,
+        '&nbsp;&nbsp;',
+        performance.firstNotificationInMilliseconds,
+        '&nbsp;&nbsp;',
+        performance.elapsedInMilliseconds,
+        '&nbsp;&nbsp;',
+        performance.notificationCount,
+        '&nbsp;&nbsp;',
+        performance.suggestionCount,
+        '&nbsp;&nbsp;',
+        HTML_ESCAPE.convert(performance.snippet)
+      ]);
+      ++index;
+    }
+
+    buffer.write('</table>');
+    buffer.write('''
+      <p><strong>First (ms)</strong> - the number of milliseconds
+        from when completion received the request until the first notification
+        with completion results was queued for sending back to the client.
+      <p><strong>Complete (ms)</strong> - the number of milliseconds
+        from when completion received the request until the final notification
+        with completion results was queued for sending back to the client.
+      <p><strong># Notifications</strong> - the total number of notifications
+        sent to the client with completion results for this request.
+      <p><strong># Suggestions</strong> - the number of suggestions
+        sent to the client in the first notification, followed by a comma,
+        followed by the number of suggestions send to the client
+        in the last notification. If there is only one notification,
+        then there will be only one number in this column.''');
+  }
+
+  /**
+   * Write the status of the edit domain (on the main status page) to the given
+   * [buffer].
+   */
+  void _writeEditStatus(StringBuffer buffer) {
+    buffer.write('<h3>Edit Domain</h3>');
+    _writeTwoColumns(buffer, (StringBuffer buffer) {
+      buffer.write('<p><b>Performance Data</b></p>');
+      buffer.write('<p>');
+      buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
+      buffer.write('</p>');
+    }, (StringBuffer buffer) {});
+  }
+
+  /**
+   * Write a representation of the given [caughtException] to the given
+   * [buffer]. If [isCause] is `true`, then the exception was a cause for
+   * another exception.
+   */
+  void _writeException(StringBuffer buffer, CaughtException caughtException,
+      {bool isCause: false}) {
+    Object exception = caughtException.exception;
+
+    if (exception is AnalysisException) {
+      buffer.write('<p>');
+      if (isCause) {
+        buffer.write('Caused by ');
+      }
+      buffer.write(exception.message);
+      buffer.write('</p>');
+      _writeStackTrace(buffer, caughtException.stackTrace);
+      CaughtException cause = exception.cause;
+      if (cause != null) {
+        buffer.write('<blockquote>');
+        _writeException(buffer, cause, isCause: true);
+        buffer.write('</blockquote>');
+      }
+    } else {
+      buffer.write('<p>');
+      if (isCause) {
+        buffer.write('Caused by ');
+      }
+      buffer.write(exception.toString());
+      buffer.write('<p>');
+      _writeStackTrace(buffer, caughtException.stackTrace);
+    }
+  }
+
+  /**
+   * Write the status of the execution domain (on the main status page) to the
+   * given [buffer].
+   */
+  void _writeExecutionStatus(StringBuffer buffer) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    ExecutionDomainHandler handler = analysisServer.handlers.firstWhere(
+        (RequestHandler handler) => handler is ExecutionDomainHandler,
+        orElse: () => null);
+    Set<ExecutionService> services = new Set<ExecutionService>();
+    if (handler.onFileAnalyzed != null) {
+      services.add(ExecutionService.LAUNCH_DATA);
+    }
+
+    if (handler != null) {
+      buffer.write('<h3>Execution Domain</h3>');
+      _writeTwoColumns(buffer, (StringBuffer buffer) {
+        _writeSubscriptionList(buffer, ExecutionService.VALUES, services);
+      }, (StringBuffer buffer) {});
+    }
+  }
+
+  /**
+   * Write a representation of an analysis option with the given [name] and
+   * [value] to the given [buffer]. The option should be separated from other
+   * options unless the [last] flag is true, indicating that this is the last
+   * option in the list of options.
+   */
+  void _writeOption(StringBuffer buffer, String name, Object value,
+      {bool last: false}) {
+    buffer.write(name);
+    buffer.write(' = ');
+    buffer.write(value.toString());
+    if (!last) {
+      buffer.write('<br>');
+    }
+  }
+
+  /**
+   * Write a standard HTML page to the given [buffer]. The page will have the
+   * given [title] and a body that is generated by the given [body] generator.
+   */
+  void _writePage(StringBuffer buffer, String title, List<String> subtitles,
+      HtmlGenerator body) {
+    DateTime now = new DateTime.now();
+    String date = "${now.month}/${now.day}/${now.year}";
+    String time =
+        "${now.hour}:${_twoDigit(now.minute)}:${_twoDigit(now.second)}.${now.millisecond}";
+
+    buffer.write('<!DOCTYPE html>');
+    buffer.write('<html>');
+    buffer.write('<head>');
+    buffer.write('<meta charset="utf-8">');
+    buffer.write(
+        '<meta name="viewport" content="width=device-width, initial-scale=1.0">');
+    buffer.write('<title>$title</title>');
+    buffer.write('<style>');
+    buffer.write('a {color: #0000DD; text-decoration: none;}');
+    buffer.write('a:link.error {background-color: #FFEEEE;}');
+    buffer.write('a:visited.error {background-color: #FFEEEE;}');
+    buffer.write('a:hover.error {background-color: #FFEEEE;}');
+    buffer.write('a:active.error {background-color: #FFEEEE;}');
+    buffer.write(
+        'h3 {background-color: #DDDDDD; margin-top: 0em; margin-bottom: 0em;}');
+    buffer.write('p {margin-top: 0.5em; margin-bottom: 0.5em;}');
+//    response.write('span.error {text-decoration-line: underline; text-decoration-color: red; text-decoration-style: wavy;}');
+    buffer.write(
+        'table.column {border: 0px solid black; width: 100%; table-layout: fixed;}');
+    buffer.write('td.column {vertical-align: top; width: 50%;}');
+    buffer.write('td.right {text-align: right;}');
+    buffer.write('</style>');
+    buffer.write('</head>');
+
+    buffer.write('<body>');
+    buffer.write(
+        '<h2>$title <small><small>(as of $time on $date)</small></small></h2>');
+    if (subtitles != null && subtitles.isNotEmpty) {
+      buffer.write('<blockquote>');
+      bool first = true;
+      for (String subtitle in subtitles) {
+        if (first) {
+          first = false;
+        } else {
+          buffer.write('<br>');
+        }
+        buffer.write('<b>');
+        buffer.write(subtitle);
+        buffer.write('</b>');
+      }
+      buffer.write('</blockquote>');
+    }
+    try {
+      body(buffer);
+    } catch (exception, stackTrace) {
+      buffer.write('<h3>Exception while creating page</h3>');
+      _writeException(buffer, new CaughtException(exception, stackTrace));
+    }
+    buffer.write('</body>');
+    buffer.write('</html>');
+  }
+
+  /**
+   * Write the recent output section (on the main status page) to the given
+   * [buffer] object.
+   */
+  void _writePluginStatus(StringBuffer buffer) {
+    void writePlugin(Plugin plugin) {
+      buffer.write(_server.serverPlugin.uniqueIdentifier);
+      buffer.write(' (');
+      buffer.write(_server.serverPlugin.runtimeType);
+      buffer.write(')<br>');
+    }
+    buffer.write('<h3>Plugin Status</h3><p>');
+    writePlugin(AnalysisEngine.instance.enginePlugin);
+    writePlugin(_server.serverPlugin);
+    for (Plugin plugin in _server.analysisServer.userDefinedPlugins) {
+      writePlugin(plugin);
+    }
+    buffer.write('<p>');
+  }
+
+  /**
+   * Write the recent output section (on the main status page) to the given
+   * [buffer] object.
+   */
+  void _writeRecentOutput(StringBuffer buffer) {
+    buffer.write('<h3>Recent Output</h3>');
+    String output = HTML_ESCAPE.convert(_printBuffer.join('\n'));
+    if (output.isEmpty) {
+      buffer.write('<i>none</i>');
+    } else {
+      buffer.write('<pre>');
+      buffer.write(output);
+      buffer.write('</pre>');
+    }
+  }
+
+  void _writeResponse(HttpRequest request, HtmlGenerator writePage) {
+    HttpResponse response = request.response;
+    response.statusCode = HttpStatus.OK;
+    response.headers.contentType = _htmlContent;
+    try {
+      StringBuffer buffer = new StringBuffer();
+      try {
+        writePage(buffer);
+      } catch (exception, stackTrace) {
+        buffer.clear();
+        _writePage(buffer, 'Internal Exception', [], (StringBuffer buffer) {
+          _writeException(buffer, new CaughtException(exception, stackTrace));
+        });
+      }
+      response.write(buffer.toString());
+    } finally {
+      response.close();
+    }
+  }
+
+  /**
+   * Write a single row within a table to the given [buffer]. The row will have
+   * one cell for each of the [columns], and will be a header row if [header] is
+   * `true`.
+   */
+  void _writeRow(StringBuffer buffer, List<Object> columns,
+      {bool header: false, List<String> classes}) {
+    buffer.write('<tr>');
+    int count = columns.length;
+    int maxClassIndex = classes == null ? 0 : classes.length - 1;
+    for (int i = 0; i < count; i++) {
+      String classAttribute = '';
+      if (classes != null) {
+        String className = classes[min(i, maxClassIndex)];
+        if (className != null) {
+          classAttribute = ' class="$className"';
+        }
+      }
+      if (header) {
+        buffer.write('<th$classAttribute>');
+      } else {
+        buffer.write('<td$classAttribute>');
+      }
+      buffer.write(columns[i]);
+      if (header) {
+        buffer.write('</th>');
+      } else {
+        buffer.write('</td>');
+      }
+    }
+    buffer.write('</tr>');
+  }
+
+  /**
+   * Write the status of the service domain (on the main status page) to the
+   * given [response] object.
+   */
+  bool _writeServerStatus(StringBuffer buffer) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    Set<ServerService> services = analysisServer.serverServices;
+
+    buffer.write('<h3>Server Domain</h3>');
+    _writeTwoColumns(buffer, (StringBuffer buffer) {
+      if (analysisServer == null) {
+        buffer.write('Status: <span style="color:red">Not running</span>');
+        return false;
+      }
+      buffer.write('<p>');
+      buffer.write('Status: Running<br>');
+      buffer.write('Instrumentation: ');
+      if (AnalysisEngine.instance.instrumentationService.isActive) {
+        buffer.write('<span style="color:red">Active</span>');
+      } else {
+        buffer.write('Inactive');
+      }
+      buffer.write('<br>');
+      buffer.write('Version: ');
+      buffer.write(AnalysisServer.VERSION);
+      buffer.write('</p>');
+
+      buffer.write('<p><b>Performance Data</b></p>');
+      buffer.write('<p>');
+      buffer.write(makeLink(
+          COMMUNICATION_PERFORMANCE_PATH, {}, 'Communication performance'));
+      buffer.write('</p>');
+    }, (StringBuffer buffer) {
+      _writeSubscriptionList(buffer, ServerService.VALUES, services);
+    });
+    return true;
+  }
+
+  /**
+   * Write a representation of the given [stackTrace] to the given [buffer].
+   */
+  void _writeStackTrace(StringBuffer buffer, StackTrace stackTrace) {
+    if (stackTrace != null) {
+      String trace = stackTrace.toString().replaceAll('#', '<br>#');
+      if (trace.startsWith('<br>#')) {
+        trace = trace.substring(4);
+      }
+      buffer.write('<p>');
+      buffer.write(trace);
+      buffer.write('</p>');
+    }
+  }
+
+  /**
+   * Given a [service] that could be subscribed to and a set of the services
+   * that are actually subscribed to ([subscribedServices]), write a
+   * representation of the service to the given [buffer].
+   */
+  void _writeSubscriptionInList(
+      StringBuffer buffer, Enum service, Set<Enum> subscribedServices) {
+    if (subscribedServices.contains(service)) {
+      buffer.write('<code>+ </code>');
+    } else {
+      buffer.write('<code>- </code>');
+    }
+    buffer.write(service.name);
+    buffer.write('<br>');
+  }
+
+  /**
+   * Given a [service] that could be subscribed to and a set of paths that are
+   * subscribed to the services ([subscribedPaths]), write a representation of
+   * the service to the given [buffer].
+   */
+  void _writeSubscriptionInMap(
+      StringBuffer buffer, Enum service, Set<String> subscribedPaths) {
+    buffer.write('<p>');
+    buffer.write(service.name);
+    buffer.write('</p>');
+    if (subscribedPaths == null || subscribedPaths.isEmpty) {
+      buffer.write('none');
+    } else {
+      List<String> paths = subscribedPaths.toList();
+      paths.sort();
+      for (String path in paths) {
+        buffer.write('<p>');
+        buffer.write(path);
+        buffer.write('</p>');
+      }
+    }
+  }
+
+  /**
+   * Given a list containing all of the services that can be subscribed to in a
+   * single domain ([allServices]) and a set of the services that are actually
+   * subscribed to ([subscribedServices]), write a representation of the
+   * subscriptions to the given [buffer].
+   */
+  void _writeSubscriptionList(StringBuffer buffer, List<Enum> allServices,
+      Set<Enum> subscribedServices) {
+    buffer.write('<p><b>Subscriptions</b></p>');
+    buffer.write('<p>');
+    for (Enum service in allServices) {
+      _writeSubscriptionInList(buffer, service, subscribedServices);
+    }
+    buffer.write('</p>');
+  }
+
+  /**
+   * Given a list containing all of the services that can be subscribed to in a
+   * single domain ([allServices]) and a set of the services that are actually
+   * subscribed to ([subscribedServices]), write a representation of the
+   * subscriptions to the given [buffer].
+   */
+  void _writeSubscriptionMap(StringBuffer buffer, List<Enum> allServices,
+      Map<Enum, Set<String>> subscribedServices) {
+    buffer.write('<p><b>Subscriptions</b></p>');
+    for (Enum service in allServices) {
+      _writeSubscriptionInMap(buffer, service, subscribedServices[service]);
+    }
+  }
+
+  /**
+   * Write two columns of information to the given [buffer], where the
+   * [leftColumn] and [rightColumn] functions are used to generate the content
+   * of those columns.
+   */
+  void _writeTwoColumns(StringBuffer buffer, HtmlGenerator leftColumn,
+      HtmlGenerator rightColumn) {
+    buffer
+        .write('<table class="column"><tr class="column"><td class="column">');
+    leftColumn(buffer);
+    buffer.write('</td><td class="column">');
+    rightColumn(buffer);
+    buffer.write('</td></tr></table>');
+  }
+
+  /**
+   * Render the given [value] as HTML and append it to the given [buffer]. The
+   * [linkParameters] will be used if the value is too large to be displayed on
+   * the current page and needs to be linked to a separate page.
+   */
+  void _writeValueAsHtml(
+      StringBuffer buffer, Object value, Map<String, String> linkParameters) {
+    if (value == null) {
+      buffer.write('<i>null</i>');
+    } else if (value is String) {
+      buffer.write('<pre>${HTML_ESCAPE.convert(value)}</pre>');
+    } else if (value is List) {
+      buffer.write('List containing ${value.length} entries');
+      buffer.write('<ul>');
+      for (var entry in value) {
+        buffer.write('<li>');
+        _writeValueAsHtml(buffer, entry, linkParameters);
+        buffer.write('</li>');
+      }
+      buffer.write('</ul>');
+    } else if (value is AstNode) {
+      String link =
+          makeLink(AST_PATH, linkParameters, value.runtimeType.toString());
+      buffer.write('<i>$link</i>');
+    } else if (value is Element) {
+      String link =
+          makeLink(ELEMENT_PATH, linkParameters, value.runtimeType.toString());
+      buffer.write('<i>$link</i>');
+    } else {
+      buffer.write(HTML_ESCAPE.convert(value.toString()));
+      buffer.write(' <i>(${value.runtimeType.toString()})</i>');
+    }
+  }
+
+  /**
+   * Create a link to [path] with query parameters [params], with inner HTML
+   * [innerHtml]. If [hasError] is `true`, then the link will have the class
+   * 'error'.
+   */
+  static String makeLink(
+      String path, Map<String, String> params, String innerHtml,
+      [bool hasError = false]) {
+    Uri uri = new Uri(path: path, queryParameters: params);
+    String href = HTML_ESCAPE.convert(uri.toString());
+    String classAttribute = hasError ? ' class="error"' : '';
+    return '<a href="$href"$classAttribute>$innerHtml</a>';
+  }
+}
diff --git a/pkg/analysis_server/test/performance/driver.dart b/pkg/analysis_server/test/performance/driver.dart
index b84aa8c..4418227 100644
--- a/pkg/analysis_server/test/performance/driver.dart
+++ b/pkg/analysis_server/test/performance/driver.dart
@@ -148,27 +148,37 @@
  */
 class Measurement {
   final String tag;
+  final bool notification;
   final List<Duration> elapsedTimes = new List<Duration>();
   int errorCount = 0;
+  int unexpectedResultCount = 0;
 
-  Measurement(this.tag);
+  Measurement(this.tag, this.notification);
+
+  int get count => elapsedTimes.length;
 
   void printSummary(int keyLen) {
     int count = 0;
+    Duration maxTime = elapsedTimes[0];
+    Duration minTime = elapsedTimes[0];
     int totalTimeMicros = 0;
     for (Duration elapsed in elapsedTimes) {
       ++count;
-      totalTimeMicros += elapsed.inMicroseconds;
+      int timeMicros = elapsed.inMicroseconds;
+      maxTime = maxTime.compareTo(elapsed) > 0 ? maxTime : elapsed;
+      minTime = minTime.compareTo(elapsed) < 0 ? minTime : elapsed;
+      totalTimeMicros += timeMicros;
     }
     int averageTimeMicros = (totalTimeMicros / count).round();
     StringBuffer sb = new StringBuffer();
     _printColumn(sb, tag, keyLen);
-    _printColumn(sb, count.toString(), 5, rightJustified: true);
-    _printColumn(sb, errorCount.toString(), 5, rightJustified: true);
-    sb.write('  ');
-    sb.write(new Duration(microseconds: averageTimeMicros));
-    sb.write(',   ');
-    sb.write(new Duration(microseconds: totalTimeMicros));
+    _printColumn(sb, count.toString(), 6, rightJustified: true);
+    _printColumn(sb, errorCount.toString(), 6, rightJustified: true);
+    _printColumn(sb, unexpectedResultCount.toString(), 6, rightJustified: true);
+    _printDuration(sb, minTime);
+    _printDuration(sb, new Duration(microseconds: averageTimeMicros));
+    _printDuration(sb, maxTime);
+    _printDuration(sb, new Duration(microseconds: totalTimeMicros));
     print(sb.toString());
   }
 
@@ -178,6 +188,16 @@
     }
     elapsedTimes.add(elapsed);
   }
+
+  void recordUnexpectedResults() {
+    ++unexpectedResultCount;
+  }
+
+  void _printDuration(StringBuffer sb, Duration duration) {
+    sb.write('  ');
+    sb.write(duration);
+    sb.write(',');
+  }
 }
 
 /**
@@ -191,39 +211,79 @@
    * Display results on stdout.
    */
   void printResults() {
+    print('');
     print('==================================================================');
+    print('');
     List<String> keys = measurements.keys.toList()..sort();
     int keyLen = keys.fold(0, (int len, String key) => max(len, key.length));
-    StringBuffer sb = new StringBuffer();
-    _printColumn(sb, 'Results', keyLen);
-    _printColumn(sb, 'count', 5);
-    _printColumn(sb, 'errors', 5);
-    sb.write('   average,          total,');
-    print(sb.toString());
+    _printGroupHeader('Request/Response', keyLen);
     int totalCount = 0;
     int totalErrorCount = 0;
+    int totalUnexpectedResultCount = 0;
     for (String tag in keys) {
       Measurement m = measurements[tag];
-      m.printSummary(keyLen);
-      totalCount += m.elapsedTimes.length;
-      totalErrorCount += m.errorCount;
+      if (!m.notification) {
+        m.printSummary(keyLen);
+        totalCount += m.count;
+        totalErrorCount += m.errorCount;
+        totalUnexpectedResultCount += m.unexpectedResultCount;
+      }
     }
-    sb.clear();
-    _printColumn(sb, 'Totals', keyLen);
-    _printColumn(sb, totalCount.toString(), 5);
-    _printColumn(sb, totalErrorCount.toString(), 5);
-    print(sb.toString());
+    _printTotals(keyLen, totalCount, totalErrorCount, totalUnexpectedResultCount);
+    print('');
+    _printGroupHeader('Notifications', keyLen);
+    for (String tag in keys) {
+      Measurement m = measurements[tag];
+      if (m.notification) {
+        m.printSummary(keyLen);
+      }
+    }
+    /// TODO(danrubel) *** print warnings if driver caches are not empty ****
+    print('');
+    print(
+        '(1) uxr = UneXpected Results, or responses received from the server');
+    print(
+        '          that do not match the recorded response for that request.');
   }
 
   /**
    * Record the elapsed time for the given operation.
    */
-  void record(String tag, Duration elapsed, {bool success: true}) {
+  void record(String tag, Duration elapsed,
+      {bool notification: false, bool success: true}) {
     Measurement measurement = measurements[tag];
     if (measurement == null) {
-      measurement = new Measurement(tag);
+      measurement = new Measurement(tag, notification);
       measurements[tag] = measurement;
     }
     measurement.record(success, elapsed);
   }
+
+  void recordUnexpectedResults(String tag) {
+    measurements[tag].recordUnexpectedResults();
+  }
+
+  void _printGroupHeader(String groupName, int keyLen) {
+    StringBuffer sb = new StringBuffer();
+        _printColumn(sb, groupName, keyLen);
+        _printColumn(sb, 'count', 6, rightJustified: true);
+        _printColumn(sb, 'error', 6, rightJustified: true);
+        _printColumn(sb, 'uxr(1)', 6, rightJustified: true);
+        sb.write('  ');
+        _printColumn(sb, 'minimum', 15);
+        _printColumn(sb, 'average', 15);
+        _printColumn(sb, 'maximum', 15);
+        _printColumn(sb, 'total', 15);
+        print(sb.toString());
+  }
+
+  void _printTotals(int keyLen, int totalCount, int totalErrorCount, int totalUnexpectedResultCount) {
+    StringBuffer sb = new StringBuffer();
+    _printColumn(sb, 'Totals', keyLen);
+    _printColumn(sb, totalCount.toString(), 6, rightJustified: true);
+    _printColumn(sb, totalErrorCount.toString(), 6, rightJustified: true);
+    _printColumn(sb, totalUnexpectedResultCount.toString(), 6,
+        rightJustified: true);
+    print(sb.toString());
+  }
 }
diff --git a/pkg/analysis_server/test/performance/input_converter.dart b/pkg/analysis_server/test/performance/input_converter.dart
index 9acf61a..ccf598e 100644
--- a/pkg/analysis_server/test/performance/input_converter.dart
+++ b/pkg/analysis_server/test/performance/input_converter.dart
@@ -4,12 +4,12 @@
 
 library input.transformer;
 
+import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
 
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/protocol.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:logging/logging.dart';
 import 'package:path/path.dart' as path;
 
@@ -26,16 +26,31 @@
   final Set<String> eventsSeen = new Set<String>();
 
   /**
-   * A mapping from request/response id to expected error message.
+   * A mapping from request/response id to request json
+   * for those requests for which a response has not been processed.
    */
-  final Map<String, dynamic> expectedErrors = new Map<String, dynamic>();
+  final Map<String, dynamic> requestMap = {};
+
+  /**
+   * A mapping from request/response id to a completer
+   * for those requests for which a response has not been processed.
+   * The completer is called with the actual json response
+   * when it becomes available.
+   */
+  final Map<String, Completer> responseCompleters = {};
+
+  /**
+   * A mapping from request/response id to the actual response result
+   * for those responses that have not been processed.
+   */
+  final Map<String, dynamic> responseMap = {};
 
   /**
    * A mapping of current overlay content
    * parallel to what is in the analysis server
    * so that we can update the file system.
    */
-  final Map<String, String> overlays = new Map<String, String>();
+  final Map<String, String> overlays = {};
 
   /**
    * The prefix used to determine if a request parameter is a file path.
@@ -87,54 +102,54 @@
    */
   Operation convertRequest(Map<String, dynamic> origJson) {
     Map<String, dynamic> json = translateSrcPaths(origJson);
+    requestMap[json['id']] = json;
     String method = json['method'];
     // Sanity check operations that modify source
     // to ensure that the operation is on source in temp space
     if (method == ANALYSIS_UPDATE_CONTENT) {
-      try {
-        validateSrcPaths(json);
-      } catch (e, s) {
-        throw new AnalysisException('invalid src path in update request\n$json',
-            new CaughtException(e, s));
-      }
       // Track overlays in parallel with the analysis server
       // so that when an overlay is removed, the file can be updated on disk
       Request request = new Request.fromJson(json);
       var params = new AnalysisUpdateContentParams.fromRequest(request);
-      params.files.forEach((String path, change) {
+      params.files.forEach((String filePath, change) {
         if (change is AddContentOverlay) {
           String content = change.content;
           if (content == null) {
             throw 'expected new overlay content\n$json';
           }
-          overlays[path] = content;
+          overlays[filePath] = content;
         } else if (change is ChangeContentOverlay) {
-          String content = overlays[path];
+          String content = overlays[filePath];
           if (content == null) {
             throw 'expected cached overlay content\n$json';
           }
-          overlays[path] = SourceEdit.applySequence(content, change.edits);
+          overlays[filePath] = SourceEdit.applySequence(content, change.edits);
         } else if (change is RemoveContentOverlay) {
-          String content = overlays.remove(path);
+          String content = overlays.remove(filePath);
           if (content == null) {
             throw 'expected cached overlay content\n$json';
           }
-          validateSrcPaths(path);
-          new File(path).writeAsStringSync(content);
+          if (!path.isWithin(tmpSrcDirPath, filePath)) {
+            throw 'found path referencing source outside temp space\n$filePath\n$json';
+          }
+          new File(filePath).writeAsStringSync(content);
         } else {
           throw 'unknown overlay change $change\n$json';
         }
       });
       return new RequestOperation(this, json);
     }
-    // TODO(danrubel) replace this with code 
+    // Track performance for completion notifications
+    if (method == COMPLETION_GET_SUGGESTIONS) {
+      return new CompletionRequestOperation(this, json);
+    }
+    // TODO(danrubel) replace this with code
     // that just forwards the translated request
     if (method == ANALYSIS_GET_HOVER ||
         method == ANALYSIS_SET_ANALYSIS_ROOTS ||
         method == ANALYSIS_SET_PRIORITY_FILES ||
         method == ANALYSIS_SET_SUBSCRIPTIONS ||
         method == ANALYSIS_UPDATE_OPTIONS ||
-        method == COMPLETION_GET_SUGGESTIONS ||
         method == EDIT_GET_ASSISTS ||
         method == EDIT_GET_AVAILABLE_REFACTORINGS ||
         method == EDIT_GET_FIXES ||
@@ -145,6 +160,7 @@
         method == EXECUTION_MAP_URI ||
         method == EXECUTION_SET_SUBSCRIPTIONS ||
         method == SEARCH_FIND_ELEMENT_REFERENCES ||
+        method == SEARCH_FIND_MEMBER_DECLARATIONS ||
         method == SERVER_GET_VERSION ||
         method == SERVER_SET_SUBSCRIPTIONS) {
       return new RequestOperation(this, json);
@@ -153,49 +169,63 @@
   }
 
   /**
-   * Determine if the given request is expected to fail
-   * and log an exception if not.
+   * Return an operation for the recorded/expected response.
    */
-  void recordErrorResponse(Map<String, dynamic> jsonRequest, exception) {
-    var actualErr;
-    if (exception is UnimplementedError) {
-      if (exception.message.startsWith(ERROR_PREFIX)) {
-        Map<String, dynamic> jsonResponse =
-            JSON.decode(exception.message.substring(ERROR_PREFIX.length));
-        actualErr = jsonResponse['error'];
-      }
-    }
-    String id = jsonRequest['id'];
-    if (id != null && actualErr != null) {
-      var expectedErr = expectedErrors[id];
-      if (expectedErr != null && actualErr == expectedErr) {
-        return;
-      }
-//      if (jsonRequest['method'] == EDIT_SORT_MEMBERS) {
-//        var params = jsonRequest['params'];
-//        if (params is Map) {
-//          var filePath = params['file'];
-//          if (filePath is String) {
-//            var content = overlays[filePath];
-//            if (content is String) {
-//              logger.log(Level.WARNING, 'sort failed: $filePath\n$content');
-//            }
-//          }
-//        }
-//      }
-    }
-    logger.log(
-        Level.SEVERE, 'Send request failed for $id\n$exception\n$jsonRequest');
+  Operation convertResponse(Map<String, dynamic> json) {
+    return new ResponseOperation(
+        this, requestMap.remove(json['id']), translateSrcPaths(json));
   }
 
   /**
-   * Examine recorded responses and record any expected errors.
+   * Process an error response from the server by either
+   * completing the associated completer in the [responseCompleters]
+   * or stashing it in [responseMap] if no completer exists.
    */
-  void recordResponse(Map<String, dynamic> json) {
-    var error = json['error'];
-    if (error != null) {
-      String id = json['id'];
-      print('expected error for $id is $error');
+  void processErrorResponse(String id, exception) {
+    var result = exception;
+    if (exception is UnimplementedError) {
+      if (exception.message.startsWith(ERROR_PREFIX)) {
+        result = JSON.decode(exception.message.substring(ERROR_PREFIX.length));
+      }
+    }
+    processResponseResult(id, result);
+  }
+
+  /**
+   * Process the expected response by completing the given completer
+   * with the result if it has alredy been received,
+   * or caching the completer to be completed when the server
+   * returns the associated result.
+   * Return a future that completes when the response is received
+   * or `null` if the response has already been received
+   * and the completer completed.
+   */
+  Future processExpectedResponse(String id, Completer completer) {
+    if (responseMap.containsKey(id)) {
+      logger.log(Level.INFO, 'processing cached response $id');
+      completer.complete(responseMap.remove(id));
+      return null;
+    } else {
+      logger.log(Level.INFO, 'waiting for response $id');
+      responseCompleters[id] = completer;
+      return completer.future;
+    }
+  }
+
+  /**
+   * Process a success response result from the server by either
+   * completing the associated completer in the [responseCompleters]
+   * or stashing it in [responseMap] if no completer exists.
+   * The response result may be `null`.
+   */
+  void processResponseResult(String id, result) {
+    Completer completer = responseCompleters[id];
+    if (completer != null) {
+      logger.log(Level.INFO, 'processing response $id');
+      completer.complete(result);
+    } else {
+      logger.log(Level.INFO, 'caching response $id');
+      responseMap[id] = result;
     }
   }
 
@@ -230,29 +260,6 @@
     }
     return json;
   }
-
-  /**
-   * Recursively verify that the source paths in the specified JSON
-   * only reference the temporary source used during performance measurement.
-   */
-  void validateSrcPaths(json) {
-    if (json is String) {
-      if (json != null &&
-          path.isWithin(rootPrefix, json) &&
-          !path.isWithin(tmpSrcDirPath, json)) {
-        throw 'found path referencing source outside temp space\n$json';
-      }
-    } else if (json is List) {
-      for (int i = json.length - 1; i >= 0; --i) {
-        validateSrcPaths(json[i]);
-      }
-    } else if (json is Map) {
-      json.forEach((String key, value) {
-        validateSrcPaths(key);
-        validateSrcPaths(value);
-      });
-    }
-  }
 }
 
 /**
diff --git a/pkg/analysis_server/test/performance/instrumentation_input_converter.dart b/pkg/analysis_server/test/performance/instrumentation_input_converter.dart
index b0f9c61..32974c2 100644
--- a/pkg/analysis_server/test/performance/instrumentation_input_converter.dart
+++ b/pkg/analysis_server/test/performance/instrumentation_input_converter.dart
@@ -65,8 +65,7 @@
       return convertRequest(decodeJson(line, fields[2]));
     } else if (opCode == InstrumentationService.TAG_RESPONSE) {
       // 1434096937454:Res:{"id"::"0","result"::{"version"::"1.7.0"}}
-      recordResponse(decodeJson(line, fields[2]));
-      return null;
+      return convertResponse(decodeJson(line, fields[2]));
     } else if (opCode == InstrumentationService.TAG_ANALYSIS_TASK) {
       // 1434096943208:Task:/Users/
       return null;
diff --git a/pkg/analysis_server/test/performance/log_file_input_converter.dart b/pkg/analysis_server/test/performance/log_file_input_converter.dart
index c15c450..6e9e74e 100644
--- a/pkg/analysis_server/test/performance/log_file_input_converter.dart
+++ b/pkg/analysis_server/test/performance/log_file_input_converter.dart
@@ -35,8 +35,9 @@
         Map<String, dynamic> json = JSON.decode(data.substring(4));
         if (json.containsKey('event')) {
           return convertNotification(json);
+        } else {
+          return convertResponse(json);
         }
-        return null;
       } else if (data.startsWith(SENT_FRAGMENT)) {
         Map<String, dynamic> json = JSON.decode(data.substring(4));
         if (json.containsKey('method')) {
diff --git a/pkg/analysis_server/test/performance/operation.dart b/pkg/analysis_server/test/performance/operation.dart
index 5952252..641cf31 100644
--- a/pkg/analysis_server/test/performance/operation.dart
+++ b/pkg/analysis_server/test/performance/operation.dart
@@ -13,6 +13,53 @@
 import 'input_converter.dart';
 
 /**
+ * A [CompletionRequestOperation] tracks response time along with 
+ * the first and last completion notifications.
+ */
+class CompletionRequestOperation extends RequestOperation {
+  Driver driver;
+  StreamSubscription<CompletionResultsParams> subscription;
+  String notificationId;
+  Stopwatch stopwatch;
+  bool firstNotification = true;
+
+  CompletionRequestOperation(
+      CommonInputConverter converter, Map<String, dynamic> json)
+      : super(converter, json);
+
+  @override
+  Future perform(Driver driver) {
+    this.driver = driver;
+    subscription = driver.onCompletionResults.listen(processNotification);
+    return super.perform(driver);
+  }
+
+  void processNotification(CompletionResultsParams event) {
+    if (event.id == notificationId) {
+      Duration elapsed = stopwatch.elapsed;
+      if (firstNotification) {
+        firstNotification = false;
+        driver.results.record('completion notification first', elapsed,
+            notification: true);
+      }
+      if (event.isLast) {
+        subscription.cancel();
+        driver.results.record('completion notification last', elapsed,
+            notification: true);
+      }
+    }
+  }
+
+  @override
+  void processResult(
+      String id, Map<String, dynamic> result, Stopwatch stopwatch) {
+    notificationId = result['id'];
+    this.stopwatch = stopwatch;
+    super.processResult(id, result, stopwatch);
+  }
+}
+
+/**
  * An [Operation] represents an action such as sending a request to the server.
  */
 abstract class Operation {
@@ -31,24 +78,103 @@
   @override
   Future perform(Driver driver) {
     Stopwatch stopwatch = new Stopwatch();
+    String originalId = json['id'];
     String method = json['method'];
     driver.logger.log(Level.FINE, 'Sending request: $method\n  $json');
     stopwatch.start();
-    void recordResponse(bool success, response) {
-      stopwatch.stop();
+
+    void recordResult(bool success, result) {
       Duration elapsed = stopwatch.elapsed;
       driver.results.record(method, elapsed, success: success);
       driver.logger.log(
-          Level.FINE, 'Response received: $method : $elapsed\n  $response');
+          Level.FINE, 'Response received: $method : $elapsed\n  $result');
     }
-    driver.send(method, json['params']).then((response) {
-      recordResponse(true, response);
-    }).catchError((e, s) {
-      recordResponse(false, e);
-      converter.recordErrorResponse(json, e);
+
+    driver.send(method, json['params']).then((Map<String, dynamic> result) {
+      recordResult(true, result);
+      processResult(originalId, result, stopwatch);
+    }).catchError((exception) {
+      recordResult(false, exception);
+      converter.processErrorResponse(originalId, exception);
     });
     return null;
   }
+
+  void processResult(
+      String id, Map<String, dynamic> result, Stopwatch stopwatch) {
+    converter.processResponseResult(id, result);
+  }
+}
+
+/**
+ * A [ResponseOperation] waits for a [JSON] response from the server.
+ */
+class ResponseOperation extends Operation {
+  static final Duration responseTimeout = new Duration(seconds: 5);
+  final CommonInputConverter converter;
+  final Map<String, dynamic> requestJson;
+  final Map<String, dynamic> responseJson;
+  final Completer completer = new Completer();
+  Driver driver;
+
+  ResponseOperation(this.converter, this.requestJson, this.responseJson) {
+    completer.future.then(_processResult).timeout(responseTimeout);
+  }
+
+  @override
+  Future perform(Driver driver) {
+    this.driver = driver;
+    return converter.processExpectedResponse(responseJson['id'], completer);
+  }
+
+  bool _equal(expectedResult, actualResult) {
+    if (expectedResult is Map && actualResult is Map) {
+      if (expectedResult.length == actualResult.length) {
+        return expectedResult.keys.every((String key) {
+          return key ==
+                  'fileStamp' || // fileStamp values will not be the same across runs
+              _equal(expectedResult[key], actualResult[key]);
+        });
+      }
+    } else if (expectedResult is List && actualResult is List) {
+      if (expectedResult.length == actualResult.length) {
+        for (int i = 0; i < expectedResult.length; ++i) {
+          if (!_equal(expectedResult[i], actualResult[i])) {
+            return false;
+          }
+        }
+        return true;
+      }
+    }
+    return expectedResult == actualResult;
+  }
+
+  /**
+   * Compare the expected and actual server response result.
+   */
+  void _processResult(actualResult) {
+    var expectedResult = responseJson['result'];
+    if (!_equal(expectedResult, actualResult)) {
+      var expectedError = responseJson['error'];
+      String format(value) {
+        String text = '\n$value';
+        if (text.endsWith('\n')) {
+          text = text.substring(0, text.length - 1);
+        }
+        return text.replaceAll('\n', '\n  ');
+      }
+      String message = 'Request:${format(requestJson)}\n'
+          'expected result:${format(expectedResult)}\n'
+          'expected error:${format(expectedError)}\n'
+          'but received:${format(actualResult)}';
+      driver.results.recordUnexpectedResults(requestJson['method']);
+      if (expectedError == null) {
+        converter.logger.log(Level.SEVERE, message);
+      } else {
+        throw message;
+      }
+    }
+  }
 }
 
 class StartServerOperation extends Operation {
@@ -79,7 +205,7 @@
           Duration delta = end.difference(start);
           driver.logger.log(Level.FINE, 'analysis complete after $delta');
           completer.complete();
-          driver.results.record('analysis complete', delta);
+          driver.results.record('analysis complete', delta, notification: true);
         }
       }
     });
diff --git a/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart b/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
index 20cdddf..aaf8a0f 100644
--- a/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
+++ b/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
@@ -5,6 +5,7 @@
 library test.source.caching_pub_package_map_provider;
 
 import 'dart:convert';
+import 'dart:core' hide Resource;
 import 'dart:io' as io;
 
 import 'package:analysis_server/src/source/caching_pub_package_map_provider.dart';
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index 9a41f81..62c158b 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -18,7 +18,7 @@
    * Watch for changes to this file
    */
   Stream<WatchEvent> get changes;
-  
+
   /**
    * Return the last-modified stamp of the file.
    * Throws [FileSystemException] if the file does not exist.
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index a68a225..b0a5469 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -6,6 +6,7 @@
 
 import 'dart:async';
 import 'dart:collection';
+import 'dart:core' hide Resource;
 
 import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
 import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 9c9d5a6..d9497df 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -5,6 +5,7 @@
 library physical_file_system;
 
 import 'dart:async';
+import 'dart:core' hide Resource;
 import 'dart:io' as io;
 
 import 'package:analyzer/src/generated/java_io.dart';
@@ -73,7 +74,7 @@
  */
 class _PhysicalFile extends _PhysicalResource implements File {
   _PhysicalFile(io.File file) : super(file);
- 
+
   @override
   Stream<WatchEvent> get changes => new FileWatcher(_entry.path).events;
 
diff --git a/pkg/analyzer/lib/source/package_map_resolver.dart b/pkg/analyzer/lib/source/package_map_resolver.dart
index 1b0f82f..82000b9 100644
--- a/pkg/analyzer/lib/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/source/package_map_resolver.dart
@@ -4,6 +4,8 @@
 
 library source.package_map_resolver;
 
+import 'dart:core' hide Resource;
+
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/util/asserts.dart' as asserts;
diff --git a/pkg/analyzer/lib/source/pub_package_map_provider.dart b/pkg/analyzer/lib/source/pub_package_map_provider.dart
index a78d4ad..3e9936d 100644
--- a/pkg/analyzer/lib/source/pub_package_map_provider.dart
+++ b/pkg/analyzer/lib/source/pub_package_map_provider.dart
@@ -6,6 +6,7 @@
 
 import 'dart:collection';
 import 'dart:convert';
+import 'dart:core' hide Resource;
 import 'dart:io' as io;
 
 import 'package:analyzer/file_system/file_system.dart';
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 0b93d03..b211067 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -313,6 +313,12 @@
   }
 
   /**
+   * Return a list of result descriptors for results whose state is not
+   * [CacheState.INVALID].
+   */
+  List<ResultDescriptor> get nonInvalidResults => _resultMap.keys.toList();
+
+  /**
    * Fix the state of the [exception] to match the current state of the entry.
    */
   void fixExceptionState() {
@@ -412,7 +418,7 @@
    * Set the state of the result represented by the given [descriptor] to the
    * given [state].
    */
-  void setState(ResultDescriptor descriptor, CacheState state) {
+  void setState(ResultDescriptor descriptor, CacheState state, {Delta delta}) {
     if (state == CacheState.ERROR) {
       throw new ArgumentError('use setErrorState() to set the state to ERROR');
     }
@@ -423,7 +429,7 @@
     if (state == CacheState.INVALID) {
       ResultData data = _resultMap[descriptor];
       if (data != null) {
-        _invalidate(descriptor);
+        _invalidate(descriptor, delta);
       }
     } else {
       ResultData data = getResultData(descriptor);
@@ -471,7 +477,7 @@
   void setValueIncremental(ResultDescriptor descriptor, dynamic value) {
     ResultData data = getResultData(descriptor);
     List<TargetedResult> dependedOn = data.dependedOnResults;
-    _invalidate(descriptor);
+    _invalidate(descriptor, null);
     setValue(descriptor, value, dependedOn);
   }
 
@@ -491,29 +497,42 @@
    * Invalidate the result represented by the given [descriptor] and propagate
    * invalidation to other results that depend on it.
    */
-  void _invalidate(ResultDescriptor descriptor) {
+  void _invalidate(ResultDescriptor descriptor, Delta delta) {
+    DeltaResult deltaResult = null;
+    if (delta != null) {
+      deltaResult = delta.validate(_partition.context, target, descriptor);
+      if (deltaResult == DeltaResult.STOP) {
+//        print('not-invalidate $descriptor for $target');
+        return;
+      }
+    }
 //    print('invalidate $descriptor for $target');
-    ResultData thisData = _resultMap.remove(descriptor);
+    ResultData thisData;
+    if (deltaResult == null || deltaResult == DeltaResult.INVALIDATE) {
+      thisData = _resultMap.remove(descriptor);
+    }
+    if (deltaResult == DeltaResult.KEEP_CONTINUE) {
+      thisData = _resultMap[descriptor];
+    }
     if (thisData == null) {
       return;
     }
     // Stop depending on other results.
     TargetedResult thisResult = new TargetedResult(target, descriptor);
-    thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) {
+    for (TargetedResult dependedOnResult in thisData.dependedOnResults) {
       ResultData data = _partition._getDataFor(dependedOnResult, orNull: true);
       if (data != null) {
         data.dependentResults.remove(thisResult);
       }
-    });
+    }
     // Invalidate results that depend on this result.
-    Set<TargetedResult> dependentResults = thisData.dependentResults;
-    thisData.dependentResults = new Set<TargetedResult>();
-    dependentResults.forEach((TargetedResult dependentResult) {
+    List<TargetedResult> dependentResults = thisData.dependentResults.toList();
+    for (TargetedResult dependentResult in dependentResults) {
       CacheEntry entry = _partition.get(dependentResult.target);
       if (entry != null) {
-        entry._invalidate(dependentResult.result);
+        entry._invalidate(dependentResult.result, delta);
       }
-    });
+    }
     // If empty, remove the entry altogether.
     if (_resultMap.isEmpty) {
       _partition._targetMap.remove(target);
@@ -530,7 +549,7 @@
   void _invalidateAll() {
     List<ResultDescriptor> results = _resultMap.keys.toList();
     for (ResultDescriptor result in results) {
-      _invalidate(result);
+      _invalidate(result, null);
     }
   }
 
@@ -960,6 +979,29 @@
 }
 
 /**
+ * The description for a change.
+ */
+class Delta {
+  final Source source;
+
+  Delta(this.source);
+
+  /**
+   * Check whether this delta affects the result described by the given
+   * [descriptor] and [target].
+   */
+  DeltaResult validate(InternalAnalysisContext context, AnalysisTarget target,
+      ResultDescriptor descriptor) {
+    return DeltaResult.INVALIDATE;
+  }
+}
+
+/**
+ * The possible results of validating analysis results againt a [Delta].
+ */
+enum DeltaResult { INVALIDATE, KEEP_CONTINUE, STOP }
+
+/**
  * [InvalidatedResult] describes an invalidated result.
  */
 class InvalidatedResult {
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index c7a5c8d..a0e7f1f 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -35,6 +35,7 @@
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/html.dart';
 import 'package:analyzer/src/task/html_work_manager.dart';
+import 'package:analyzer/src/task/incremental_element_builder.dart';
 import 'package:analyzer/src/task/manager.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/general.dart';
@@ -156,11 +157,6 @@
       new HashMap<Source, ChangeNoticeImpl>();
 
   /**
-   * Cached information used in incremental analysis or `null` if none.
-   */
-  IncrementalAnalysisCache _incrementalAnalysisCache;
-
-  /**
    * The [TypeProvider] for this context, `null` if not yet created.
    */
   TypeProvider _typeProvider;
@@ -423,14 +419,6 @@
     return statistics;
   }
 
-  IncrementalAnalysisCache get test_incrementalAnalysisCache {
-    return _incrementalAnalysisCache;
-  }
-
-  set test_incrementalAnalysisCache(IncrementalAnalysisCache value) {
-    _incrementalAnalysisCache = value;
-  }
-
   List<Source> get test_priorityOrder => _priorityOrder;
 
   @override
@@ -578,16 +566,16 @@
   List<AnalysisError> computeErrors(Source source) {
     String name = source.shortName;
     if (AnalysisEngine.isDartFileName(name)) {
-      return _computeResult(source, DART_ERRORS);
+      return computeResult(source, DART_ERRORS);
     } else if (AnalysisEngine.isHtmlFileName(name)) {
-      return _computeResult(source, HTML_ERRORS);
+      return computeResult(source, HTML_ERRORS);
     }
     return AnalysisError.NO_ERRORS;
   }
 
   @override
   List<Source> computeExportedLibraries(Source source) =>
-      _computeResult(source, EXPORTED_LIBRARIES);
+      computeResult(source, EXPORTED_LIBRARIES);
 
   @override
   @deprecated
@@ -599,13 +587,13 @@
 
   @override
   List<Source> computeImportedLibraries(Source source) =>
-      _computeResult(source, EXPLICITLY_IMPORTED_LIBRARIES);
+      computeResult(source, EXPLICITLY_IMPORTED_LIBRARIES);
 
   @override
   SourceKind computeKindOf(Source source) {
     String name = source.shortName;
     if (AnalysisEngine.isDartFileName(name)) {
-      return _computeResult(source, SOURCE_KIND);
+      return computeResult(source, SOURCE_KIND);
     } else if (AnalysisEngine.isHtmlFileName(name)) {
       return SourceKind.HTML;
     }
@@ -615,11 +603,11 @@
   @override
   LibraryElement computeLibraryElement(Source source) {
     //_computeResult(source, HtmlEntry.ELEMENT);
-    return _computeResult(source, LIBRARY_ELEMENT);
+    return computeResult(source, LIBRARY_ELEMENT);
   }
 
   @override
-  LineInfo computeLineInfo(Source source) => _computeResult(source, LINE_INFO);
+  LineInfo computeLineInfo(Source source) => computeResult(source, LINE_INFO);
 
   @override
   @deprecated
@@ -649,6 +637,21 @@
     });
   }
 
+  Object /*V*/ computeResult(
+      AnalysisTarget target, ResultDescriptor /*<V>*/ descriptor) {
+    CacheEntry entry = getCacheEntry(target);
+    CacheState state = entry.getState(descriptor);
+    if (state == CacheState.FLUSHED || state == CacheState.INVALID) {
+      driver.computeResult(target, descriptor);
+    }
+    state = entry.getState(descriptor);
+    if (state == CacheState.ERROR) {
+      throw new AnalysisException(
+          'Cannot compute $descriptor for $target', entry.exception);
+    }
+    return entry.getValue(descriptor);
+  }
+
   /**
    * Create an analysis cache based on the given source [factory].
    */
@@ -952,8 +955,6 @@
     bool changed = newContents != originalContents;
     if (newContents != null) {
       if (newContents != originalContents) {
-        _incrementalAnalysisCache =
-            IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
         if (!analysisOptions.incremental ||
             !_tryPoorMansIncrementalResolution(source, newContents)) {
           _sourceChanged(source);
@@ -964,8 +965,6 @@
         entry.modificationTime = _contentCache.getModificationStamp(source);
       }
     } else if (originalContents != null) {
-      _incrementalAnalysisCache =
-          IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
       changed = newContents != originalContents;
       // We are removing the overlay for the file, check if the file's
       // contents is the same as it was in the overlay.
@@ -1029,7 +1028,7 @@
       throw new AnalysisException('Could not get contents of $source',
           new CaughtException(exception, stackTrace));
     }
-    return _computeResult(source, PARSED_UNIT);
+    return computeResult(source, PARSED_UNIT);
   }
 
   @override
@@ -1037,7 +1036,7 @@
     if (!AnalysisEngine.isHtmlFileName(source.shortName)) {
       return null;
     }
-    return _computeResult(source, HTML_DOCUMENT);
+    return computeResult(source, HTML_DOCUMENT);
   }
 
   @override
@@ -1147,7 +1146,7 @@
         !AnalysisEngine.isDartFileName(librarySource.shortName)) {
       return null;
     }
-    return _computeResult(
+    return computeResult(
         new LibrarySpecificUnit(librarySource, unitSource), RESOLVED_UNIT);
   }
 
@@ -1248,6 +1247,7 @@
     return changedSources.length > 0;
   }
 
+  @deprecated
   @override
   void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
       DataDescriptor rowDesc, CacheState state)) {
@@ -1313,9 +1313,7 @@
 //    }
   }
 
-  /**
-   * Visit all entries of the content cache.
-   */
+  @override
   void visitContentCache(ContentCacheVisitor visitor) {
     _contentCache.accept(visitor);
   }
@@ -1347,21 +1345,6 @@
     }
   }
 
-  Object /*V*/ _computeResult(
-      AnalysisTarget target, ResultDescriptor /*<V>*/ descriptor) {
-    CacheEntry entry = getCacheEntry(target);
-    CacheState state = entry.getState(descriptor);
-    if (state == CacheState.FLUSHED || state == CacheState.INVALID) {
-      driver.computeResult(target, descriptor);
-    }
-    state = entry.getState(descriptor);
-    if (state == CacheState.ERROR) {
-      throw new AnalysisException(
-          'Cannot compute $descriptor for $target', entry.exception);
-    }
-    return entry.getValue(descriptor);
-  }
-
   /**
    * Given the encoded form of a source ([encoding]), use the source factory to
    * reconstitute the original source.
@@ -1408,12 +1391,6 @@
     String originalContents = _contentCache.setContents(source, contents);
     if (contents != null) {
       if (contents != originalContents) {
-        // TODO(brianwilkerson) Find a better way to do incremental analysis.
-//        if (_options.incremental) {
-//          _incrementalAnalysisCache = IncrementalAnalysisCache.update(
-//              _incrementalAnalysisCache, source, originalContents, contents,
-//              offset, oldLength, newLength, _cache.get(source));
-//        }
         _sourceChanged(source);
         changed = true;
         CacheEntry entry = _cache.get(source);
@@ -1423,8 +1400,6 @@
         }
       }
     } else if (originalContents != null) {
-      _incrementalAnalysisCache =
-          IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
       _sourceChanged(source);
       changed = true;
     }
@@ -1720,7 +1695,40 @@
       } catch (e) {}
     }
     // We need to invalidate the cache.
-    entry.setState(CONTENT, CacheState.INVALID);
+    {
+      Object delta = null;
+      if (AnalysisEngine.instance.limitInvalidationInTaskModel &&
+          AnalysisEngine.isDartFileName(source.fullName)) {
+        // TODO(scheglov) Incorrect implementation in general.
+        entry.setState(TOKEN_STREAM, CacheState.FLUSHED);
+        entry.setState(PARSED_UNIT, CacheState.FLUSHED);
+        List<Source> librarySources = getLibrariesContaining(source);
+        if (librarySources.length == 1) {
+          Source librarySource = librarySources[0];
+          CompilationUnit oldUnit =
+              getResolvedCompilationUnit2(source, librarySource);
+          if (oldUnit != null) {
+            CompilationUnit newUnit = parseCompilationUnit(source);
+            IncrementalCompilationUnitElementBuilder builder =
+                new IncrementalCompilationUnitElementBuilder(oldUnit, newUnit);
+            builder.build();
+            CompilationUnitElementDelta unitDelta = builder.unitDelta;
+            if (!unitDelta.hasDirectiveChange) {
+              DartDelta dartDelta = new DartDelta(source);
+              dartDelta.hasDirectiveChange = unitDelta.hasDirectiveChange;
+              unitDelta.addedDeclarations.forEach(dartDelta.elementAdded);
+              unitDelta.removedDeclarations.forEach(dartDelta.elementRemoved);
+              print(
+                  'dartDelta: add=${dartDelta.addedNames} remove=${dartDelta.removedNames}');
+              delta = dartDelta;
+              entry.setState(CONTENT, CacheState.INVALID, delta: delta);
+              return;
+            }
+          }
+        }
+      }
+      entry.setState(CONTENT, CacheState.INVALID);
+    }
     dartWorkManager.applyChange(
         Source.EMPTY_LIST, <Source>[source], Source.EMPTY_LIST);
     htmlWorkManager.applyChange(
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index e6d8100..c386c83 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -1245,7 +1245,7 @@
           cloneNodeList(node.metadata), cloneToken(node.keyword),
           cloneNode(node.type), cloneToken(node.thisKeyword),
           cloneToken(node.period), cloneNode(node.identifier),
-          cloneNode(node.parameters));
+          cloneNode(node.typeParameters), cloneNode(node.parameters));
 
   @override
   ForEachStatement visitForEachStatement(ForEachStatement node) {
@@ -1292,12 +1292,14 @@
 
   @override
   FunctionExpression visitFunctionExpression(FunctionExpression node) =>
-      new FunctionExpression(cloneNode(node.parameters), cloneNode(node.body));
+      new FunctionExpression(cloneNode(node.typeParameters),
+          cloneNode(node.parameters), cloneNode(node.body));
 
   @override
   FunctionExpressionInvocation visitFunctionExpressionInvocation(
       FunctionExpressionInvocation node) => new FunctionExpressionInvocation(
-      cloneNode(node.function), cloneNode(node.argumentList));
+      cloneNode(node.function), cloneNode(node.typeArguments),
+      cloneNode(node.argumentList));
 
   @override
   FunctionTypeAlias visitFunctionTypeAlias(FunctionTypeAlias node) =>
@@ -1312,7 +1314,7 @@
       FunctionTypedFormalParameter node) => new FunctionTypedFormalParameter(
       cloneNode(node.documentationComment), cloneNodeList(node.metadata),
       cloneNode(node.returnType), cloneNode(node.identifier),
-      cloneNode(node.parameters));
+      cloneNode(node.typeParameters), cloneNode(node.parameters));
 
   @override
   HideCombinator visitHideCombinator(HideCombinator node) => new HideCombinator(
@@ -1424,13 +1426,14 @@
           cloneNodeList(node.metadata), cloneToken(node.externalKeyword),
           cloneToken(node.modifierKeyword), cloneNode(node.returnType),
           cloneToken(node.propertyKeyword), cloneToken(node.operatorKeyword),
-          cloneNode(node.name), cloneNode(node.parameters),
-          cloneNode(node.body));
+          cloneNode(node.name), cloneNode(node.typeParameters),
+          cloneNode(node.parameters), cloneNode(node.body));
 
   @override
   MethodInvocation visitMethodInvocation(MethodInvocation node) =>
       new MethodInvocation(cloneNode(node.target), cloneToken(node.operator),
-          cloneNode(node.methodName), cloneNode(node.argumentList));
+          cloneNode(node.methodName), cloneNode(node.typeArguments),
+          cloneNode(node.argumentList));
 
   @override
   NamedExpression visitNamedExpression(NamedExpression node) =>
@@ -7129,7 +7132,7 @@
  *
  * > fieldFormalParameter ::=
  * >     ('final' [TypeName] | 'const' [TypeName] | 'var' | [TypeName])?
- * >     'this' '.' [SimpleIdentifier] [FormalParameterList]?
+ * >     'this' '.' [SimpleIdentifier] ([TypeParameterList]? [FormalParameterList])?
  */
 class FieldFormalParameter extends NormalFormalParameter {
   /**
@@ -7155,6 +7158,12 @@
   Token period;
 
   /**
+   * The type parameters associated with the method, or `null` if the method is
+   * not a generic method.
+   */
+  TypeParameterList _typeParameters;
+
+  /**
    * The parameters of the function-typed parameter, or `null` if this is not a
    * function-typed field formal parameter.
    */
@@ -7171,9 +7180,10 @@
    */
   FieldFormalParameter(Comment comment, List<Annotation> metadata, this.keyword,
       TypeName type, this.thisKeyword, this.period, SimpleIdentifier identifier,
-      FormalParameterList parameters)
+      TypeParameterList typeParameters, FormalParameterList parameters)
       : super(comment, metadata, identifier) {
     _type = _becomeParentOf(type);
+    _typeParameters = _becomeParentOf(typeParameters);
     _parameters = _becomeParentOf(parameters);
   }
 
@@ -7255,6 +7265,20 @@
     _type = _becomeParentOf(typeName);
   }
 
+  /**
+   * Return the type parameters associated with this method, or `null` if this
+   * method is not a generic method.
+   */
+  TypeParameterList get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters associated with this method to the given
+   * [typeParameters].
+   */
+  void set typeParameters(TypeParameterList typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters);
+  }
+
   @override
   accept(AstVisitor visitor) => visitor.visitFieldFormalParameter(this);
 
@@ -7263,6 +7287,7 @@
     super.visitChildren(visitor);
     _safelyVisitChild(_type, visitor);
     _safelyVisitChild(identifier, visitor);
+    _safelyVisitChild(_typeParameters, visitor);
     _safelyVisitChild(_parameters, visitor);
   }
 }
@@ -8010,10 +8035,16 @@
  * A function expression.
  *
  * > functionExpression ::=
- * >     [FormalParameterList] [FunctionBody]
+ * >     [TypeParameterList]? [FormalParameterList] [FunctionBody]
  */
 class FunctionExpression extends Expression {
   /**
+   * The type parameters associated with the method, or `null` if the method is
+   * not a generic method.
+   */
+  TypeParameterList _typeParameters;
+
+  /**
    * The parameters associated with the function.
    */
   FormalParameterList _parameters;
@@ -8032,14 +8063,18 @@
   /**
    * Initialize a newly created function declaration.
    */
-  FunctionExpression(FormalParameterList parameters, FunctionBody body) {
+  FunctionExpression(TypeParameterList typeParameters,
+      FormalParameterList parameters, FunctionBody body) {
+    _typeParameters = _becomeParentOf(typeParameters);
     _parameters = _becomeParentOf(parameters);
     _body = _becomeParentOf(body);
   }
 
   @override
   Token get beginToken {
-    if (_parameters != null) {
+    if (_typeParameters != null) {
+      return _typeParameters.beginToken;
+    } else if (_parameters != null) {
       return _parameters.beginToken;
     } else if (_body != null) {
       return _body.beginToken;
@@ -8093,11 +8128,26 @@
   @override
   int get precedence => 16;
 
+  /**
+   * Return the type parameters associated with this method, or `null` if this
+   * method is not a generic method.
+   */
+  TypeParameterList get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters associated with this method to the given
+   * [typeParameters].
+   */
+  void set typeParameters(TypeParameterList typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters);
+  }
+
   @override
   accept(AstVisitor visitor) => visitor.visitFunctionExpression(this);
 
   @override
   void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_typeParameters, visitor);
     _safelyVisitChild(_parameters, visitor);
     _safelyVisitChild(_body, visitor);
   }
@@ -8110,7 +8160,7 @@
  * by either [PrefixedIdentifier] or [PropertyAccess] nodes.
  *
  * > functionExpressionInvoction ::=
- * >     [Expression] [ArgumentList]
+ * >     [Expression] [TypeArgumentList]? [ArgumentList]
  */
 class FunctionExpressionInvocation extends Expression {
   /**
@@ -8119,6 +8169,12 @@
   Expression _function;
 
   /**
+   * The type arguments to be applied to the method being invoked, or `null` if
+   * no type arguments were provided.
+   */
+  TypeArgumentList _typeArguments;
+
+  /**
    * The list of arguments to the function.
    */
   ArgumentList _argumentList;
@@ -8140,8 +8196,10 @@
   /**
    * Initialize a newly created function expression invocation.
    */
-  FunctionExpressionInvocation(Expression function, ArgumentList argumentList) {
+  FunctionExpressionInvocation(Expression function,
+      TypeArgumentList typeArguments, ArgumentList argumentList) {
     _function = _becomeParentOf(function);
+    _typeArguments = _becomeParentOf(typeArguments);
     _argumentList = _becomeParentOf(argumentList);
   }
 
@@ -8198,12 +8256,27 @@
   @override
   int get precedence => 15;
 
+  /**
+   * Return the type arguments to be applied to the method being invoked, or
+   * `null` if no type arguments were provided.
+   */
+  TypeArgumentList get typeArguments => _typeArguments;
+
+  /**
+   * Set the type arguments to be applied to the method being invoked to the
+   * given [typeArguments].
+   */
+  void set typeArguments(TypeArgumentList typeArguments) {
+    _typeArguments = _becomeParentOf(typeArguments);
+  }
+
   @override
   accept(AstVisitor visitor) => visitor.visitFunctionExpressionInvocation(this);
 
   @override
   void visitChildren(AstVisitor visitor) {
     _safelyVisitChild(_function, visitor);
+    _safelyVisitChild(_typeArguments, visitor);
     _safelyVisitChild(_argumentList, visitor);
   }
 }
@@ -8323,7 +8396,7 @@
  * A function-typed formal parameter.
  *
  * > functionSignature ::=
- * >     [TypeName]? [SimpleIdentifier] [FormalParameterList]
+ * >     [TypeName]? [SimpleIdentifier] [TypeParameterList]? [FormalParameterList]
  */
 class FunctionTypedFormalParameter extends NormalFormalParameter {
   /**
@@ -8333,6 +8406,12 @@
   TypeName _returnType;
 
   /**
+   * The type parameters associated with the function, or `null` if the function
+   * is not a generic function.
+   */
+  TypeParameterList _typeParameters;
+
+  /**
    * The parameters of the function-typed parameter.
    */
   FormalParameterList _parameters;
@@ -8345,9 +8424,10 @@
    */
   FunctionTypedFormalParameter(Comment comment, List<Annotation> metadata,
       TypeName returnType, SimpleIdentifier identifier,
-      FormalParameterList parameters)
+      TypeParameterList typeParameters, FormalParameterList parameters)
       : super(comment, metadata, identifier) {
     _returnType = _becomeParentOf(returnType);
+    _typeParameters = _becomeParentOf(typeParameters);
     _parameters = _becomeParentOf(parameters);
   }
 
@@ -8398,6 +8478,20 @@
     _returnType = _becomeParentOf(type);
   }
 
+  /**
+   * Return the type parameters associated with this function, or `null` if
+   * this function is not a generic function.
+   */
+  TypeParameterList get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters associated with this method to the given
+   * [typeParameters].
+   */
+  void set typeParameters(TypeParameterList typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters);
+  }
+
   @override
   accept(AstVisitor visitor) => visitor.visitFunctionTypedFormalParameter(this);
 
@@ -8406,6 +8500,7 @@
     super.visitChildren(visitor);
     _safelyVisitChild(_returnType, visitor);
     _safelyVisitChild(identifier, visitor);
+    _safelyVisitChild(_typeParameters, visitor);
     _safelyVisitChild(_parameters, visitor);
   }
 }
@@ -9651,7 +9746,7 @@
           _cloneNodeList(node.metadata), _mapToken(node.keyword),
           _cloneNode(node.type), _mapToken(node.thisKeyword),
           _mapToken(node.period), _cloneNode(node.identifier),
-          _cloneNode(node.parameters));
+          _cloneNode(node.typeParameters), _cloneNode(node.parameters));
 
   @override
   ForEachStatement visitForEachStatement(ForEachStatement node) {
@@ -9699,7 +9794,8 @@
   @override
   FunctionExpression visitFunctionExpression(FunctionExpression node) {
     FunctionExpression copy = new FunctionExpression(
-        _cloneNode(node.parameters), _cloneNode(node.body));
+        _cloneNode(node.typeParameters), _cloneNode(node.parameters),
+        _cloneNode(node.body));
     copy.element = node.element;
     copy.propagatedType = node.propagatedType;
     copy.staticType = node.staticType;
@@ -9710,7 +9806,8 @@
   FunctionExpressionInvocation visitFunctionExpressionInvocation(
       FunctionExpressionInvocation node) {
     FunctionExpressionInvocation copy = new FunctionExpressionInvocation(
-        _cloneNode(node.function), _cloneNode(node.argumentList));
+        _cloneNode(node.function), _cloneNode(node.typeArguments),
+        _cloneNode(node.argumentList));
     copy.propagatedElement = node.propagatedElement;
     copy.propagatedType = node.propagatedType;
     copy.staticElement = node.staticElement;
@@ -9731,7 +9828,7 @@
       FunctionTypedFormalParameter node) => new FunctionTypedFormalParameter(
       _cloneNode(node.documentationComment), _cloneNodeList(node.metadata),
       _cloneNode(node.returnType), _cloneNode(node.identifier),
-      _cloneNode(node.parameters));
+      _cloneNode(node.typeParameters), _cloneNode(node.parameters));
 
   @override
   HideCombinator visitHideCombinator(HideCombinator node) => new HideCombinator(
@@ -9873,14 +9970,14 @@
           _cloneNodeList(node.metadata), _mapToken(node.externalKeyword),
           _mapToken(node.modifierKeyword), _cloneNode(node.returnType),
           _mapToken(node.propertyKeyword), _mapToken(node.operatorKeyword),
-          _cloneNode(node.name), _cloneNode(node.parameters),
-          _cloneNode(node.body));
+          _cloneNode(node.name), _cloneNode(node._typeParameters),
+          _cloneNode(node.parameters), _cloneNode(node.body));
 
   @override
   MethodInvocation visitMethodInvocation(MethodInvocation node) {
     MethodInvocation copy = new MethodInvocation(_cloneNode(node.target),
         _mapToken(node.operator), _cloneNode(node.methodName),
-        _cloneNode(node.argumentList));
+        _cloneNode(node.typeArguments), _cloneNode(node.argumentList));
     copy.propagatedType = node.propagatedType;
     copy.staticType = node.staticType;
     return copy;
@@ -11416,7 +11513,7 @@
  * >
  * > methodSignature ::=
  * >     'external'? ('abstract' | 'static')? [Type]? ('get' | 'set')?
- * >     methodName [FormalParameterList]
+ * >     methodName [TypeParameterList] [FormalParameterList]
  * >
  * > methodName ::=
  * >     [SimpleIdentifier]
@@ -11458,6 +11555,12 @@
   SimpleIdentifier _name;
 
   /**
+   * The type parameters associated with the method, or `null` if the method is
+   * not a generic method.
+   */
+  TypeParameterList _typeParameters;
+
+  /**
    * The parameters associated with the method, or `null` if this method
    * declares a getter.
    */
@@ -11482,10 +11585,12 @@
   MethodDeclaration(Comment comment, List<Annotation> metadata,
       this.externalKeyword, this.modifierKeyword, TypeName returnType,
       this.propertyKeyword, this.operatorKeyword, SimpleIdentifier name,
-      FormalParameterList parameters, FunctionBody body)
+      TypeParameterList typeParameters, FormalParameterList parameters,
+      FunctionBody body)
       : super(comment, metadata) {
     _returnType = _becomeParentOf(returnType);
     _name = _becomeParentOf(name);
+    _typeParameters = _becomeParentOf(typeParameters);
     _parameters = _becomeParentOf(parameters);
     _body = _becomeParentOf(body);
   }
@@ -11612,6 +11717,20 @@
     _returnType = _becomeParentOf(typeName);
   }
 
+  /**
+   * Return the type parameters associated with this method, or `null` if this
+   * method is not a generic method.
+   */
+  TypeParameterList get typeParameters => _typeParameters;
+
+  /**
+   * Set the type parameters associated with this method to the given
+   * [typeParameters].
+   */
+  void set typeParameters(TypeParameterList typeParameters) {
+    _typeParameters = _becomeParentOf(typeParameters);
+  }
+
   @override
   accept(AstVisitor visitor) => visitor.visitMethodDeclaration(this);
 
@@ -11620,6 +11739,7 @@
     super.visitChildren(visitor);
     _safelyVisitChild(_returnType, visitor);
     _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_typeParameters, visitor);
     _safelyVisitChild(_parameters, visitor);
     _safelyVisitChild(_body, visitor);
   }
@@ -11632,7 +11752,7 @@
  * represented by either [PrefixedIdentifier] or [PropertyAccess] nodes.
  *
  * > methodInvoction ::=
- * >     ([Expression] '.')? [SimpleIdentifier] [ArgumentList]
+ * >     ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentList]
  */
 class MethodInvocation extends Expression {
   /**
@@ -11655,6 +11775,12 @@
   SimpleIdentifier _methodName;
 
   /**
+   * The type arguments to be applied to the method being invoked, or `null` if
+   * no type arguments were provided.
+   */
+  TypeArgumentList _typeArguments;
+
+  /**
    * The list of arguments to the method.
    */
   ArgumentList _argumentList;
@@ -11664,9 +11790,11 @@
    * can be `null` if there is no target.
    */
   MethodInvocation(Expression target, this.operator,
-      SimpleIdentifier methodName, ArgumentList argumentList) {
+      SimpleIdentifier methodName, TypeArgumentList typeArguments,
+      ArgumentList argumentList) {
     _target = _becomeParentOf(target);
     _methodName = _becomeParentOf(methodName);
+    _typeArguments = _becomeParentOf(typeArguments);
     _argumentList = _becomeParentOf(argumentList);
   }
 
@@ -11783,6 +11911,20 @@
     _target = _becomeParentOf(expression);
   }
 
+  /**
+   * Return the type arguments to be applied to the method being invoked, or
+   * `null` if no type arguments were provided.
+   */
+  TypeArgumentList get typeArguments => _typeArguments;
+
+  /**
+   * Set the type arguments to be applied to the method being invoked to the
+   * given [typeArguments].
+   */
+  void set typeArguments(TypeArgumentList typeArguments) {
+    _typeArguments = _becomeParentOf(typeArguments);
+  }
+
   @override
   accept(AstVisitor visitor) => visitor.visitMethodInvocation(this);
 
@@ -11790,6 +11932,7 @@
   void visitChildren(AstVisitor visitor) {
     _safelyVisitChild(_target, visitor);
     _safelyVisitChild(_methodName, visitor);
+    _safelyVisitChild(_typeArguments, visitor);
     _safelyVisitChild(_argumentList, visitor);
   }
 }
@@ -12466,6 +12609,7 @@
   bool visitAwaitExpression(AwaitExpression node) {
     if (identical(node.expression, _oldNode)) {
       node.expression = _newNode as Expression;
+      return true;
     }
     return visitNode(node);
   }
@@ -13492,6 +13636,7 @@
   bool visitYieldStatement(YieldStatement node) {
     if (identical(node.expression, _oldNode)) {
       node.expression = _newNode as Expression;
+      return true;
     }
     return visitNode(node);
   }
@@ -17765,6 +17910,7 @@
     _visitNodeWithSuffix(node.type, " ");
     _writer.print("this.");
     _visitNode(node.identifier);
+    _visitNode(node.typeParameters);
     _visitNode(node.parameters);
     return null;
   }
@@ -17853,6 +17999,7 @@
 
   @override
   Object visitFunctionExpression(FunctionExpression node) {
+    _visitNode(node.typeParameters);
     _visitNode(node.parameters);
     _writer.print(' ');
     _visitNode(node.body);
@@ -17862,6 +18009,7 @@
   @override
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     _visitNode(node.function);
+    _visitNode(node.typeArguments);
     _visitNode(node.argumentList);
     return null;
   }
@@ -17882,6 +18030,7 @@
   Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
     _visitNodeWithSuffix(node.returnType, " ");
     _visitNode(node.identifier);
+    _visitNode(node.typeParameters);
     _visitNode(node.parameters);
     return null;
   }
@@ -18055,6 +18204,7 @@
     _visitTokenWithSuffix(node.operatorKeyword, " ");
     _visitNode(node.name);
     if (!node.isGetter) {
+      _visitNode(node.typeParameters);
       _visitNode(node.parameters);
     }
     _visitFunctionWithPrefix(" ", node.body);
@@ -18072,6 +18222,7 @@
       }
     }
     _visitNode(node.methodName);
+    _visitNode(node.typeArguments);
     _visitNode(node.argumentList);
     return null;
   }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 88bae32..7d3f7e6 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -20,7 +20,6 @@
 import 'package:analyzer/src/plugin/options_plugin.dart';
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/task/manager.dart';
-import 'package:analyzer/src/task/task_dart.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:html/dom.dart' show Document;
@@ -2639,6 +2638,7 @@
     return changedSources.length > 0;
   }
 
+  @deprecated
   @override
   void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
       DataDescriptor rowDesc, CacheState state)) {
@@ -2702,9 +2702,7 @@
     }
   }
 
-  /**
-   * Visit all entries of the content cache.
-   */
+  @override
   void visitContentCache(ContentCacheVisitor visitor) {
     _contentCache.accept(visitor);
   }
@@ -4248,28 +4246,6 @@
   }
 
   /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordBuildUnitElementTask(BuildUnitElementTask task) {
-    Source source = task.source;
-    Source library = task.library;
-    DartEntry dartEntry = _cache.get(source);
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      dartEntry.recordBuildElementErrorInLibrary(library, thrownException);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    dartEntry.setValueInLibrary(DartEntry.BUILT_UNIT, library, task.unit);
-    dartEntry.setValueInLibrary(
-        DartEntry.BUILT_ELEMENT, library, task.unitElement);
-    ChangeNoticeImpl notice = getNotice(source);
-    LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO);
-    notice.setErrors(dartEntry.allErrors, lineInfo);
-    return dartEntry;
-  }
-
-  /**
    * Given a [dartEntry] and a [library] element, record the library element and
    * other information gleaned from the element in the cache entry.
    */
@@ -4841,10 +4817,6 @@
   AnalysisContextImpl_AnalysisTaskResultRecorder(this.AnalysisContextImpl_this);
 
   @override
-  DartEntry visitBuildUnitElementTask(BuildUnitElementTask task) =>
-      AnalysisContextImpl_this._recordBuildUnitElementTask(task);
-
-  @override
   DartEntry visitGenerateDartErrorsTask(GenerateDartErrorsTask task) =>
       AnalysisContextImpl_this._recordGenerateDartErrorsTask(task);
 
@@ -5810,6 +5782,12 @@
   bool useTaskModel = false;
 
   /**
+   * A flag indicating whether the task model should attempt to limit
+   * invalidation after a change.
+   */
+  bool limitInvalidationInTaskModel = false;
+
+  /**
    * The task manager used to manage the tasks used to analyze code.
    */
   TaskManager _taskManager;
@@ -6110,6 +6088,11 @@
   bool get enableEnum;
 
   /**
+   * Return `true` to enable generic methods (DEP 22).
+   */
+  bool get enableGenericMethods => null;
+
+  /**
    * Return `true` to enable null-aware operators (DEP 9).
    */
   bool get enableNullAwareOperators;
@@ -6208,6 +6191,11 @@
   bool dart2jsHint = true;
 
   /**
+   * A flag indicating whether generic methods are to be supported (DEP 22).
+   */
+  bool enableGenericMethods = false;
+
+  /**
    * A flag indicating whether null-aware operators should be parsed (DEP 9).
    */
   bool enableNullAwareOperators = false;
@@ -6528,12 +6516,6 @@
    * Visit the given [task], returning the result of the visit. This method will
    * throw an AnalysisException if the visitor throws an exception.
    */
-  E visitBuildUnitElementTask(BuildUnitElementTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
   E visitGenerateDartErrorsTask(GenerateDartErrorsTask task);
 
   /**
@@ -9321,8 +9303,14 @@
   /**
    * Call the given callback function for eache cache item in the context.
    */
+  @deprecated
   void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
       DataDescriptor rowDesc, CacheState state));
+
+  /**
+   * Visit all entries of the content cache.
+   */
+  void visitContentCache(ContentCacheVisitor visitor);
 }
 
 /**
@@ -9554,6 +9542,7 @@
       AnalysisOptions options = context.analysisOptions;
       parser.parseFunctionBodies =
           options.analyzeFunctionBodiesPredicate(source);
+      parser.parseGenericMethods = options.enableGenericMethods;
       _unit = parser.parseCompilationUnit(_tokenStream);
       _unit.lineInfo = lineInfo;
       AnalysisContext analysisContext = context;
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 3a3374a..3cc0626 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -361,17 +361,19 @@
       node.name.staticElement = element;
       _setLocalElements(element, newElement);
     } on _DeclarationMismatchException {
-      _addedElements.add(newElement);
       _removeElement(element);
       // add new element
-      if (newElement is MethodElement) {
-        List<MethodElement> methods = _enclosingClass.methods;
-        methods.add(newElement);
-        _enclosingClass.methods = methods;
-      } else {
-        List<PropertyAccessorElement> accessors = _enclosingClass.accessors;
-        accessors.add(newElement);
-        _enclosingClass.accessors = accessors;
+      if (newElement != null) {
+        _addedElements.add(newElement);
+        if (newElement is MethodElement) {
+          List<MethodElement> methods = _enclosingClass.methods;
+          methods.add(newElement);
+          _enclosingClass.methods = methods;
+        } else {
+          List<PropertyAccessorElement> accessors = _enclosingClass.accessors;
+          accessors.add(newElement);
+          _enclosingClass.accessors = accessors;
+        }
       }
     }
   }
@@ -520,6 +522,29 @@
     }
   }
 
+  /**
+   * Asserts that there is an import with the same prefix as the given
+   * [prefixNode], which exposes the given [element].
+   */
+  void _assertElementVisibleWithPrefix(
+      SimpleIdentifier prefixNode, Element element) {
+    if (prefixNode == null) {
+      return;
+    }
+    String prefixName = prefixNode.name;
+    for (ImportElement import in _enclosingLibrary.imports) {
+      if (import.prefix != null && import.prefix.name == prefixName) {
+        Namespace namespace =
+            new NamespaceBuilder().createImportNamespaceForDirective(import);
+        Iterable<Element> visibleElements = namespace.definedNames.values;
+        if (visibleElements.contains(element)) {
+          return;
+        }
+      }
+    }
+    _assertTrue(false);
+  }
+
   void _assertEquals(Object a, Object b) {
     if (a != b) {
       throw new _DeclarationMismatchException();
@@ -619,29 +644,6 @@
     }
   }
 
-  /**
-   * Asserts that there is an import with the same prefix as the given
-   * [prefixNode], which exposes the given [element].
-   */
-  void _assertElementVisibleWithPrefix(
-      SimpleIdentifier prefixNode, Element element) {
-    if (prefixNode == null) {
-      return;
-    }
-    String prefixName = prefixNode.name;
-    for (ImportElement import in _enclosingLibrary.imports) {
-      if (import.prefix != null && import.prefix.name == prefixName) {
-        Namespace namespace =
-            new NamespaceBuilder().createImportNamespaceForDirective(import);
-        Iterable<Element> visibleElements = namespace.definedNames.values;
-        if (visibleElements.contains(element)) {
-          return;
-        }
-      }
-    }
-    _assertTrue(false);
-  }
-
   void _assertSameTypeParameter(
       TypeParameter node, TypeParameterElement element) {
     _assertSameType(node.bound, element.bound);
@@ -790,10 +792,12 @@
 
   static void _setLocalElements(
       ExecutableElementImpl to, ExecutableElement from) {
-    to.functions = from.functions;
-    to.labels = from.labels;
-    to.localVariables = from.localVariables;
-    to.parameters = from.parameters;
+    if (from != null) {
+      to.functions = from.functions;
+      to.labels = from.labels;
+      to.localVariables = from.localVariables;
+      to.parameters = from.parameters;
+    }
   }
 }
 
@@ -1395,9 +1399,13 @@
                     newParent is MethodDeclaration ||
                 oldParent is ConstructorDeclaration &&
                     newParent is ConstructorDeclaration) {
-              oldNode = oldParent;
-              newNode = newParent;
-              found = true;
+              Element oldElement = (oldParent as Declaration).element;
+              if (new DeclarationMatcher().matches(newParent, oldElement) ==
+                  DeclarationMatchKind.MATCH) {
+                oldNode = oldParent;
+                newNode = newParent;
+                found = true;
+              }
             }
             if (oldParent is FunctionBody && newParent is FunctionBody) {
               oldNode = oldParent;
@@ -1471,6 +1479,8 @@
       Token token = _scan(code);
       RecordingErrorListener errorListener = new RecordingErrorListener();
       Parser parser = new Parser(_unitSource, errorListener);
+      AnalysisOptions options = _unitElement.context.analysisOptions;
+      parser.parseGenericMethods = options.enableGenericMethods;
       CompilationUnit unit = parser.parseCompilationUnit(token);
       _newParseErrors = errorListener.errors;
       return unit;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 2997468..8581fa4 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -7,8 +7,8 @@
 
 library engine.parser;
 
-import "dart:math" as math;
 import 'dart:collection';
+import "dart:math" as math;
 
 import 'ast.dart';
 import 'engine.dart' show AnalysisEngine, AnalysisOptionsImpl;
@@ -263,10 +263,10 @@
       0, (Parser target) => target._parseLogicalAndExpression()),
   'parseMapLiteral_2': new MethodTrampoline(
       2, (Parser target, arg0, arg1) => target._parseMapLiteral(arg0, arg1)),
-  'parseMethodDeclarationAfterParameters_6': new MethodTrampoline(6,
-      (Parser target, arg0, arg1, arg2, arg3, arg4, arg5) => target
+  'parseMethodDeclarationAfterParameters_7': new MethodTrampoline(7,
+      (Parser target, arg0, arg1, arg2, arg3, arg4, arg5, arg6) => target
           ._parseMethodDeclarationAfterParameters(
-              arg0, arg1, arg2, arg3, arg4, arg5)),
+              arg0, arg1, arg2, arg3, arg4, arg5, arg6)),
   'parseMethodDeclarationAfterReturnType_4': new MethodTrampoline(4,
       (Parser target, arg0, arg1, arg2, arg3) => target
           ._parseMethodDeclarationAfterReturnType(arg0, arg1, arg2, arg3)),
@@ -2080,6 +2080,11 @@
   bool _inInitializer = false;
 
   /**
+   * A flag indicating whether the parser is to parse generic method syntax.
+   */
+  bool parseGenericMethods = false;
+
+  /**
    * Initialize a newly created parser to parse the content of the given
    * [_source] and to report any errors that are found to the given
    * [_errorListener].
@@ -2328,7 +2333,8 @@
           _peek().matchesAny([
         TokenType.OPEN_PAREN,
         TokenType.OPEN_CURLY_BRACKET,
-        TokenType.FUNCTION
+        TokenType.FUNCTION,
+        TokenType.LT
       ])) {
         _validateModifiersForGetterOrSetterOrMethod(modifiers);
         return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
@@ -2440,7 +2446,7 @@
         //
         return new MethodDeclaration(commentAndMetadata.comment,
             commentAndMetadata.metadata, null, null, null, null, null,
-            _createSyntheticIdentifier(), new FormalParameterList(
+            _createSyntheticIdentifier(), null, new FormalParameterList(
                 null, new List<FormalParameter>(), null, null, null),
             new EmptyFunctionBody(_createSyntheticToken(TokenType.SEMICOLON)));
       }
@@ -2466,7 +2472,7 @@
       _validateFormalParameterList(parameters);
       return _parseMethodDeclarationAfterParameters(commentAndMetadata,
           modifiers.externalKeyword, modifiers.staticKeyword, null, methodName,
-          parameters);
+          null, parameters);
     } else if (_peek()
         .matchesAny([TokenType.EQ, TokenType.COMMA, TokenType.SEMICOLON])) {
       if (modifiers.constKeyword == null &&
@@ -2483,6 +2489,12 @@
       // function type alias that was parsed.
       _parseFunctionTypeAlias(commentAndMetadata, getAndAdvance());
       return null;
+    } else if (parseGenericMethods) {
+      Token token = _skipTypeParameterList(_peek());
+      if (token != null && _tokenMatches(token, TokenType.OPEN_PAREN)) {
+        return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
+            modifiers.externalKeyword, modifiers.staticKeyword, null);
+      }
     }
     TypeName type = parseTypeName();
     if (_matchesKeyword(Keyword.GET) && _tokenMatchesIdentifier(_peek())) {
@@ -2546,7 +2558,10 @@
       _validateFormalParameterList(parameters);
       return _parseMethodDeclarationAfterParameters(commentAndMetadata,
           modifiers.externalKeyword, modifiers.staticKeyword, type, methodName,
-          parameters);
+          null, parameters);
+    } else if (parseGenericMethods && _tokenMatches(_peek(), TokenType.LT)) {
+      return _parseMethodDeclarationAfterReturnType(commentAndMetadata,
+          modifiers.externalKeyword, modifiers.staticKeyword, type);
     } else if (_tokenMatches(_peek(), TokenType.OPEN_CURLY_BRACKET)) {
       // We have found "TypeName identifier {", and are guessing that this is a
       // getter without the keyword 'get'.
@@ -3036,14 +3051,18 @@
    * parsed.
    *
    *     functionExpression ::=
-   *         formalParameterList functionExpressionBody
+   *         typeParameters? formalParameterList functionExpressionBody
    */
   FunctionExpression parseFunctionExpression() {
+    TypeParameterList typeParameters = null;
+    if (parseGenericMethods && _matches(TokenType.LT)) {
+      typeParameters = parseTypeParameterList();
+    }
     FormalParameterList parameters = parseFormalParameterList();
     _validateFormalParameterList(parameters);
     FunctionBody body =
         _parseFunctionBody(false, ParserErrorCode.MISSING_FUNCTION_BODY, true);
-    return new FunctionExpression(parameters, body);
+    return new FunctionExpression(typeParameters, parameters, body);
   }
 
   /**
@@ -3146,7 +3165,7 @@
    *       | simpleFormalParameter
    *
    *     functionSignature:
-   *         metadata returnType? identifier formalParameterList
+   *         metadata returnType? identifier typeParameters? formalParameterList
    *
    *     fieldFormalParameter ::=
    *         metadata finalConstVarOrType? 'this' '.' identifier
@@ -3165,6 +3184,10 @@
       period = _expect(TokenType.PERIOD);
     }
     SimpleIdentifier identifier = parseSimpleIdentifier();
+    TypeParameterList typeParameters = null;
+    if (parseGenericMethods && _matches(TokenType.LT)) {
+      typeParameters = parseTypeParameterList();
+    }
     if (_matches(TokenType.OPEN_PAREN)) {
       FormalParameterList parameters = parseFormalParameterList();
       if (thisKeyword == null) {
@@ -3173,12 +3196,17 @@
               ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, holder.keyword);
         }
         return new FunctionTypedFormalParameter(commentAndMetadata.comment,
-            commentAndMetadata.metadata, holder.type, identifier, parameters);
+            commentAndMetadata.metadata, holder.type, identifier,
+            typeParameters, parameters);
       } else {
         return new FieldFormalParameter(commentAndMetadata.comment,
             commentAndMetadata.metadata, holder.keyword, holder.type,
-            thisKeyword, period, identifier, parameters);
+            thisKeyword, period, identifier, typeParameters, parameters);
       }
+    } else if (typeParameters != null) {
+      // TODO(brianwilkerson) Report an error. It looks like a function-typed
+      // parameter with no parameter list.
+      //_reportErrorForToken(ParserErrorCode.MISSING_PARAMETERS, typeParameters.endToken);
     }
     TypeName type = holder.type;
     if (type != null) {
@@ -3191,9 +3219,12 @@
       }
     }
     if (thisKeyword != null) {
+      // TODO(brianwilkerson) If there are type parameters but no parameters,
+      // should we create a synthetic empty parameter list here so we can
+      // capture the type parameters?
       return new FieldFormalParameter(commentAndMetadata.comment,
           commentAndMetadata.metadata, holder.keyword, holder.type, thisKeyword,
-          period, identifier, null);
+          period, identifier, null, null);
     }
     return new SimpleFormalParameter(commentAndMetadata.comment,
         commentAndMetadata.metadata, holder.keyword, holder.type, identifier);
@@ -3482,7 +3513,8 @@
   FunctionDeclaration _convertToFunctionDeclaration(MethodDeclaration method) =>
       new FunctionDeclaration(method.documentationComment, method.metadata,
           method.externalKeyword, method.returnType, method.propertyKeyword,
-          method.name, new FunctionExpression(method.parameters, method.body));
+          method.name, new FunctionExpression(
+              method.typeParameters, method.parameters, method.body));
 
   /**
    * Return `true` if the current token could be the start of a compilation unit
@@ -3839,7 +3871,11 @@
     if (_inInitializer) {
       return false;
     }
-    Token afterParameters = _skipFormalParameterList(token);
+    Token afterTypeParameters = _skipTypeParameterList(token);
+    if (afterTypeParameters == null) {
+      afterTypeParameters = token;
+    }
+    Token afterParameters = _skipFormalParameterList(afterTypeParameters);
     if (afterParameters == null) {
       return false;
     }
@@ -3916,6 +3952,17 @@
         _tokenMatchesKeyword(token, Keyword.IN);
   }
 
+  bool _isLikelyParameterList() {
+    if (_matches(TokenType.OPEN_PAREN)) {
+      return true;
+    }
+    if (!parseGenericMethods) {
+      return false;
+    }
+    Token token = _skipTypeArgumentList(_currentToken);
+    return token != null && _tokenMatches(token, TokenType.OPEN_PAREN);
+  }
+
   /**
    * Given that we have just found bracketed text within the given [comment],
    * look to see whether that text is (a) followed by a parenthesized link
@@ -4004,7 +4051,8 @@
       // The keyword 'void' isn't a valid identifier, so it should be assumed to
       // be a type name.
       return true;
-    } else if (startToken.next != token) {
+    } else if (startToken.next != token &&
+        !_tokenMatches(token, TokenType.OPEN_PAREN)) {
       // The type is more than a simple identifier, so it should be assumed to
       // be a type name.
       return true;
@@ -4177,22 +4225,27 @@
     Expression expression = _parsePrimaryExpression();
     bool isOptional = primaryAllowed || expression is SimpleIdentifier;
     while (true) {
-      while (_matches(TokenType.OPEN_PAREN)) {
+      while (_isLikelyParameterList()) {
+        TypeArgumentList typeArguments = null;
+        if (_matches(TokenType.LT)) {
+          typeArguments = parseTypeArgumentList();
+        }
         ArgumentList argumentList = parseArgumentList();
         if (expression is SimpleIdentifier) {
-          expression = new MethodInvocation(
-              null, null, expression as SimpleIdentifier, argumentList);
+          expression = new MethodInvocation(null, null,
+              expression as SimpleIdentifier, typeArguments, argumentList);
         } else if (expression is PrefixedIdentifier) {
           PrefixedIdentifier identifier = expression as PrefixedIdentifier;
           expression = new MethodInvocation(identifier.prefix,
-              identifier.period, identifier.identifier, argumentList);
+              identifier.period, identifier.identifier, typeArguments,
+              argumentList);
         } else if (expression is PropertyAccess) {
           PropertyAccess access = expression as PropertyAccess;
           expression = new MethodInvocation(access.target, access.operator,
-              access.propertyName, argumentList);
+              access.propertyName, typeArguments, argumentList);
         } else {
-          expression =
-              new FunctionExpressionInvocation(expression, argumentList);
+          expression = new FunctionExpressionInvocation(
+              expression, typeArguments, argumentList);
         }
         if (!primaryAllowed) {
           isOptional = false;
@@ -4344,7 +4397,8 @@
    * method invocation.
    *
    *     cascadeSection ::=
-   *         '..' (cascadeSelector arguments*) (assignableSelector arguments*)* cascadeAssignment?
+   *         '..' (cascadeSelector typeArguments? arguments*)
+   *         (assignableSelector typeArguments? arguments*)* cascadeAssignment?
    *
    *     cascadeSelector ::=
    *         '[' expression ']'
@@ -4379,20 +4433,24 @@
     }
     assert((expression == null && functionName != null) ||
         (expression != null && functionName == null));
-    if (_currentToken.type == TokenType.OPEN_PAREN) {
-      while (_currentToken.type == TokenType.OPEN_PAREN) {
+    if (_isLikelyParameterList()) {
+      while (_isLikelyParameterList()) {
+        TypeArgumentList typeArguments = null;
+        if (_matches(TokenType.LT)) {
+          typeArguments = parseTypeArgumentList();
+        }
         if (functionName != null) {
-          expression = new MethodInvocation(
-              expression, period, functionName, parseArgumentList());
+          expression = new MethodInvocation(expression, period, functionName,
+              typeArguments, parseArgumentList());
           period = null;
           functionName = null;
         } else if (expression == null) {
           // It should not be possible to get here.
           expression = new MethodInvocation(expression, period,
-              _createSyntheticIdentifier(), parseArgumentList());
+              _createSyntheticIdentifier(), typeArguments, parseArgumentList());
         } else {
-          expression =
-              new FunctionExpressionInvocation(expression, parseArgumentList());
+          expression = new FunctionExpressionInvocation(
+              expression, typeArguments, parseArgumentList());
         }
       }
     } else if (functionName != null) {
@@ -4407,15 +4465,19 @@
       if (!identical(selector, expression)) {
         expression = selector;
         progress = true;
-        while (_currentToken.type == TokenType.OPEN_PAREN) {
+        while (_isLikelyParameterList()) {
+          TypeArgumentList typeArguments = null;
+          if (_matches(TokenType.LT)) {
+            typeArguments = parseTypeArgumentList();
+          }
           if (expression is PropertyAccess) {
             PropertyAccess propertyAccess = expression as PropertyAccess;
             expression = new MethodInvocation(propertyAccess.target,
                 propertyAccess.operator, propertyAccess.propertyName,
-                parseArgumentList());
+                typeArguments, parseArgumentList());
           } else {
             expression = new FunctionExpressionInvocation(
-                expression, parseArgumentList());
+                expression, typeArguments, parseArgumentList());
           }
         }
       }
@@ -5751,6 +5813,10 @@
       keyword = getAndAdvance();
     }
     SimpleIdentifier name = parseSimpleIdentifier();
+    TypeParameterList typeParameters = null;
+    if (parseGenericMethods && _matches(TokenType.LT)) {
+      typeParameters = parseTypeParameterList();
+    }
     FormalParameterList parameters = null;
     if (!isGetter) {
       if (_matches(TokenType.OPEN_PAREN)) {
@@ -5781,7 +5847,7 @@
 //        }
     return new FunctionDeclaration(commentAndMetadata.comment,
         commentAndMetadata.metadata, externalKeyword, returnType, keyword, name,
-        new FunctionExpression(parameters, body));
+        new FunctionExpression(typeParameters, parameters, body));
   }
 
   /**
@@ -5908,7 +5974,7 @@
     }
     return new MethodDeclaration(commentAndMetadata.comment,
         commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType,
-        propertyKeyword, null, name, null, body);
+        propertyKeyword, null, name, null, null, body);
   }
 
   /**
@@ -6229,7 +6295,7 @@
   MethodDeclaration _parseMethodDeclarationAfterParameters(
       CommentAndMetadata commentAndMetadata, Token externalKeyword,
       Token staticKeyword, TypeName returnType, SimpleIdentifier name,
-      FormalParameterList parameters) {
+      TypeParameterList typeParameters, FormalParameterList parameters) {
     FunctionBody body = _parseFunctionBody(
         externalKeyword != null || staticKeyword == null,
         ParserErrorCode.MISSING_FUNCTION_BODY, false);
@@ -6244,7 +6310,7 @@
     }
     return new MethodDeclaration(commentAndMetadata.comment,
         commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType,
-        null, null, name, parameters, body);
+        null, null, name, typeParameters, parameters, body);
   }
 
   /**
@@ -6263,6 +6329,10 @@
       CommentAndMetadata commentAndMetadata, Token externalKeyword,
       Token staticKeyword, TypeName returnType) {
     SimpleIdentifier methodName = parseSimpleIdentifier();
+    TypeParameterList typeParameters = null;
+    if (parseGenericMethods && _matches(TokenType.LT)) {
+      typeParameters = parseTypeParameterList();
+    }
     FormalParameterList parameters;
     if (!_matches(TokenType.OPEN_PAREN) &&
         (_matches(TokenType.OPEN_CURLY_BRACKET) ||
@@ -6277,7 +6347,8 @@
     }
     _validateFormalParameterList(parameters);
     return _parseMethodDeclarationAfterParameters(commentAndMetadata,
-        externalKeyword, staticKeyword, returnType, methodName, parameters);
+        externalKeyword, staticKeyword, returnType, methodName, typeParameters,
+        parameters);
   }
 
   /**
@@ -6633,7 +6704,7 @@
     }
     return new MethodDeclaration(commentAndMetadata.comment,
         commentAndMetadata.metadata, externalKeyword, null, returnType, null,
-        operatorKeyword, name, parameters, body);
+        operatorKeyword, name, null, parameters, body);
   }
 
   /**
@@ -6704,16 +6775,22 @@
     if (_matches(TokenType.OPEN_SQUARE_BRACKET) ||
         _matches(TokenType.PERIOD) ||
         _matches(TokenType.QUESTION_PERIOD) ||
-        _matches(TokenType.OPEN_PAREN)) {
+        _matches(TokenType.OPEN_PAREN) ||
+        (parseGenericMethods && _matches(TokenType.LT))) {
       do {
-        if (_matches(TokenType.OPEN_PAREN)) {
+        if (_isLikelyParameterList()) {
+          TypeArgumentList typeArguments = null;
+          if (_matches(TokenType.LT)) {
+            typeArguments = parseTypeArgumentList();
+          }
           ArgumentList argumentList = parseArgumentList();
           if (operand is PropertyAccess) {
             PropertyAccess access = operand as PropertyAccess;
             operand = new MethodInvocation(access.target, access.operator,
-                access.propertyName, argumentList);
+                access.propertyName, typeArguments, argumentList);
           } else {
-            operand = new FunctionExpressionInvocation(operand, argumentList);
+            operand = new FunctionExpressionInvocation(
+                operand, typeArguments, argumentList);
           }
         } else {
           operand = _parseAssignableSelector(operand, true);
@@ -6971,7 +7048,7 @@
     }
     return new MethodDeclaration(commentAndMetadata.comment,
         commentAndMetadata.metadata, externalKeyword, staticKeyword, returnType,
-        propertyKeyword, null, name, parameters, body);
+        propertyKeyword, null, name, null, parameters, body);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index 21dff72..bcdb33d 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -103,11 +103,23 @@
 
   /**
    * The name of the directory within the SDK directory that contains the
-   * libraries file.
+   * sdk_library_metadata directory.
    */
   static String _INTERNAL_DIR = "_internal";
 
   /**
+   * The name of the sdk_library_metadata directory that contains the package
+   * holding the libraries.dart file.
+   */
+  static String _SDK_LIBRARY_METADATA_DIR = "sdk_library_metadata";
+
+  /**
+   * The name of the directory within the sdk_library_metadata that contains
+   * libraries.dart.
+   */
+  static String _SDK_LIBRARY_METADATA_LIB_DIR = "lib";
+
+  /**
    * The name of the directory within the SDK directory that contains the
    * libraries.
    */
@@ -463,7 +475,11 @@
    */
   LibraryMap initialLibraryMap(bool useDart2jsPaths) {
     JavaFile librariesFile = new JavaFile.relative(
-        new JavaFile.relative(libraryDirectory, _INTERNAL_DIR),
+        new JavaFile.relative(
+          new JavaFile.relative(
+            new JavaFile.relative(libraryDirectory, _INTERNAL_DIR),
+            _SDK_LIBRARY_METADATA_DIR),
+          _SDK_LIBRARY_METADATA_LIB_DIR),
         _LIBRARIES_FILE);
     try {
       String contents = librariesFile.readAsStringSync();
@@ -515,14 +531,15 @@
 
 /**
  * An object used to read and parse the libraries file
- * (dart-sdk/lib/_internal/libraries.dart) for information about the libraries
- * in an SDK. The library information is represented as a Dart file containing a
- * single top-level variable whose value is a const map. The keys of the map are
- * the names of libraries defined in the SDK and the values in the map are info
- * objects defining the library. For example, a subset of a typical SDK might
- * have a libraries file that looks like the following:
+ * (dart-sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart) for information
+ * about the libraries in an SDK. The library information is represented as a
+ * Dart file containing a single top-level variable whose value is a const map.
+ * The keys of the map are the names of libraries defined in the SDK and the
+ * values in the map are info objects defining the library. For example, a
+ * subset of a typical SDK might have a libraries file that looks like the
+ * following:
  *
- *     final Map&lt;String, LibraryInfo&gt; LIBRARIES = const &lt;LibraryInfo&gt; {
+ *     final Map<String, LibraryInfo> LIBRARIES = const <LibraryInfo> {
  *       // Used by VM applications
  *       "builtin" : const LibraryInfo(
  *         "builtin/builtin_runtime.dart",
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
index 6125a9c..b0702c7 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
@@ -112,7 +112,7 @@
   static MethodInvocation cascadedMethodInvocation(String methodName,
       [List<Expression> arguments]) => new MethodInvocation(null,
       TokenFactory.tokenFromType(TokenType.PERIOD_PERIOD),
-      identifier3(methodName), argumentList(arguments));
+      identifier3(methodName), null, argumentList(arguments));
 
   static PropertyAccess cascadedPropertyAccess(String propertyName) =>
       new PropertyAccess(null,
@@ -362,7 +362,7 @@
       null, keyword == null ? null : TokenFactory.tokenFromKeyword(keyword),
       type, TokenFactory.tokenFromKeyword(Keyword.THIS),
       TokenFactory.tokenFromType(TokenType.PERIOD), identifier3(identifier),
-      parameterList);
+      null, parameterList);
 
   static FieldFormalParameter fieldFormalParameter2(String identifier) =>
       fieldFormalParameter(null, null, identifier);
@@ -417,20 +417,31 @@
           functionDeclaration(type, keyword, name, functionExpression));
 
   static FunctionExpression functionExpression() =>
-      new FunctionExpression(formalParameterList(), blockFunctionBody2());
+      new FunctionExpression(null, formalParameterList(), blockFunctionBody2());
 
   static FunctionExpression functionExpression2(
           FormalParameterList parameters, FunctionBody body) =>
-      new FunctionExpression(parameters, body);
+      new FunctionExpression(null, parameters, body);
+
+  static FunctionExpression functionExpression3(
+          TypeParameterList typeParameters, FormalParameterList parameters,
+          FunctionBody body) =>
+      new FunctionExpression(typeParameters, parameters, body);
 
   static FunctionExpressionInvocation functionExpressionInvocation(
           Expression function, [List<Expression> arguments]) =>
-      new FunctionExpressionInvocation(function, argumentList(arguments));
+      functionExpressionInvocation2(function, null, arguments);
+
+  static FunctionExpressionInvocation functionExpressionInvocation2(
+          Expression function,
+          [TypeArgumentList typeArguments, List<Expression> arguments]) =>
+      new FunctionExpressionInvocation(
+          function, typeArguments, argumentList(arguments));
 
   static FunctionTypedFormalParameter functionTypedFormalParameter(
       TypeName returnType, String identifier,
       [List<FormalParameter> parameters]) => new FunctionTypedFormalParameter(
-      null, null, returnType, identifier3(identifier),
+      null, null, returnType, identifier3(identifier), null,
       formalParameterList(parameters));
 
   static HideCombinator hideCombinator(List<SimpleIdentifier> identifiers) =>
@@ -610,7 +621,7 @@
       returnType,
       property == null ? null : TokenFactory.tokenFromKeyword(property),
       operator == null ? null : TokenFactory.tokenFromKeyword(operator), name,
-      parameters, emptyFunctionBody());
+      null, parameters, emptyFunctionBody());
 
   static MethodDeclaration methodDeclaration2(Keyword modifier,
       TypeName returnType, Keyword property, Keyword operator,
@@ -620,18 +631,36 @@
       returnType,
       property == null ? null : TokenFactory.tokenFromKeyword(property),
       operator == null ? null : TokenFactory.tokenFromKeyword(operator), name,
-      parameters, body);
+      null, parameters, body);
+
+  static MethodDeclaration methodDeclaration3(Keyword modifier,
+      TypeName returnType, Keyword property, Keyword operator,
+      SimpleIdentifier name, TypeParameterList typeParameters,
+      FormalParameterList parameters,
+      FunctionBody body) => new MethodDeclaration(null, null, null,
+      modifier == null ? null : TokenFactory.tokenFromKeyword(modifier),
+      returnType,
+      property == null ? null : TokenFactory.tokenFromKeyword(property),
+      operator == null ? null : TokenFactory.tokenFromKeyword(operator), name,
+      typeParameters, parameters, body);
 
   static MethodInvocation methodInvocation(Expression target, String methodName,
       [List<Expression> arguments,
       TokenType operator = TokenType.PERIOD]) => new MethodInvocation(target,
       target == null ? null : TokenFactory.tokenFromType(operator),
-      identifier3(methodName), argumentList(arguments));
+      identifier3(methodName), null, argumentList(arguments));
 
   static MethodInvocation methodInvocation2(String methodName,
           [List<Expression> arguments]) =>
       methodInvocation(null, methodName, arguments);
 
+  static MethodInvocation methodInvocation3(
+      Expression target, String methodName, TypeArgumentList typeArguments,
+      [List<Expression> arguments,
+      TokenType operator = TokenType.PERIOD]) => new MethodInvocation(target,
+      target == null ? null : TokenFactory.tokenFromType(operator),
+      identifier3(methodName), typeArguments, argumentList(arguments));
+
   static NamedExpression namedExpression(Label label, Expression expression) =>
       new NamedExpression(label, expression);
 
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
index d95454d..6269cf7 100644
--- a/pkg/analyzer/lib/src/plugin/engine_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -70,7 +70,8 @@
     registerExtension(taskId, BuildLibraryConstructorsTask.DESCRIPTOR);
     registerExtension(taskId, BuildLibraryElementTask.DESCRIPTOR);
     registerExtension(taskId, BuildPublicNamespaceTask.DESCRIPTOR);
-    registerExtension(taskId, BuildSourceClosuresTask.DESCRIPTOR);
+    registerExtension(taskId, BuildSourceExportClosureTask.DESCRIPTOR);
+    registerExtension(taskId, BuildSourceImportExportClosureTask.DESCRIPTOR);
     registerExtension(taskId, BuildTypeProviderTask.DESCRIPTOR);
     registerExtension(taskId, ComputeConstantDependenciesTask.DESCRIPTOR);
     registerExtension(taskId, ComputeConstantValueTask.DESCRIPTOR);
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index bf53bb2..849ae33 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -172,15 +172,6 @@
     new ListResultDescriptor<Source>('IMPORT_EXPORT_SOURCE_CLOSURE', null);
 
 /**
- * The sources representing the import closure of a library.
- * The [Source]s include only library sources, not their units.
- *
- * The result is only available for [Source]s representing a library.
- */
-final ListResultDescriptor<Source> IMPORT_SOURCE_CLOSURE =
-    new ListResultDescriptor<Source>('IMPORT_SOURCE_CLOSURE', null);
-
-/**
  * The partial [LibraryElement] associated with a library.
  *
  * The [LibraryElement] and its [CompilationUnitElement]s are attached to each
@@ -282,6 +273,14 @@
         'PARSE_ERRORS', AnalysisError.NO_ERRORS);
 
 /**
+ * The names (resolved and not) referenced by a unit.
+ *
+ * The result is only available for [Source]s representing a compilation unit.
+ */
+final ResultDescriptor<ReferencedNames> REFERENCED_NAMES =
+    new ResultDescriptor<ReferencedNames>('REFERENCED_NAMES', null);
+
+/**
  * The errors produced while resolving references.
  *
  * The list will be empty if there were no errors, but will not be `null`.
@@ -1507,21 +1506,65 @@
 }
 
 /**
- * A task that builds [IMPORT_SOURCE_CLOSURE] and [EXPORT_SOURCE_CLOSURE] of
- * a library.
+ * A task that builds [EXPORT_SOURCE_CLOSURE] of a library.
  */
-class BuildSourceClosuresTask extends SourceBasedAnalysisTask {
-  /**
-   * The name of the import closure.
-   */
-  static const String IMPORT_INPUT = 'IMPORT_INPUT';
-
+class BuildSourceExportClosureTask extends SourceBasedAnalysisTask {
   /**
    * The name of the export closure.
    */
   static const String EXPORT_INPUT = 'EXPORT_INPUT';
 
   /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'BuildSourceExportClosureTask', createTask, buildInputs,
+      <ResultDescriptor>[EXPORT_SOURCE_CLOSURE]);
+
+  BuildSourceExportClosureTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    List<Source> exportClosure = getRequiredInput(EXPORT_INPUT);
+    //
+    // Record output.
+    //
+    outputs[EXPORT_SOURCE_CLOSURE] = exportClosure;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given library [libSource].
+   */
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    Source source = target;
+    return <String, TaskInput>{
+      EXPORT_INPUT: new _ExportSourceClosureTaskInput(source, LIBRARY_ELEMENT2)
+    };
+  }
+
+  /**
+   * Create a [BuildSourceExportClosureTask] based on the given [target] in
+   * the given [context].
+   */
+  static BuildSourceExportClosureTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new BuildSourceExportClosureTask(context, target);
+  }
+}
+
+/**
+ * A task that builds [IMPORT_EXPORT_SOURCE_CLOSURE] of a library, and also
+ * sets [IS_CLIENT].
+ */
+class BuildSourceImportExportClosureTask extends SourceBasedAnalysisTask {
+  /**
    * The name of the import/export closure.
    */
   static const String IMPORT_EXPORT_INPUT = 'IMPORT_EXPORT_INPUT';
@@ -1530,14 +1573,10 @@
    * The task descriptor describing this kind of task.
    */
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'BuildSourceClosuresTask', createTask, buildInputs, <ResultDescriptor>[
-    IMPORT_SOURCE_CLOSURE,
-    EXPORT_SOURCE_CLOSURE,
-    IMPORT_EXPORT_SOURCE_CLOSURE,
-    IS_CLIENT
-  ]);
+      'BuildSourceImportExportClosureTask', createTask, buildInputs,
+      <ResultDescriptor>[IMPORT_EXPORT_SOURCE_CLOSURE, IS_CLIENT]);
 
-  BuildSourceClosuresTask(
+  BuildSourceImportExportClosureTask(
       InternalAnalysisContext context, AnalysisTarget target)
       : super(context, target);
 
@@ -1546,15 +1585,11 @@
 
   @override
   void internalPerform() {
-    List<Source> importClosure = getRequiredInput(IMPORT_INPUT);
-    List<Source> exportClosure = getRequiredInput(EXPORT_INPUT);
     List<Source> importExportClosure = getRequiredInput(IMPORT_EXPORT_INPUT);
     Source htmlSource = context.sourceFactory.forUri(DartSdk.DART_HTML);
     //
     // Record outputs.
     //
-    outputs[IMPORT_SOURCE_CLOSURE] = importClosure;
-    outputs[EXPORT_SOURCE_CLOSURE] = exportClosure;
     outputs[IMPORT_EXPORT_SOURCE_CLOSURE] = importExportClosure;
     outputs[IS_CLIENT] = importExportClosure.contains(htmlSource);
   }
@@ -1567,19 +1602,18 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     Source source = target;
     return <String, TaskInput>{
-      IMPORT_INPUT: new _ImportSourceClosureTaskInput(source),
-      EXPORT_INPUT: new _ExportSourceClosureTaskInput(source),
-      IMPORT_EXPORT_INPUT: new _ImportExportSourceClosureTaskInput(source)
+      IMPORT_EXPORT_INPUT:
+          new _ImportExportSourceClosureTaskInput(source, LIBRARY_ELEMENT2)
     };
   }
 
   /**
-   * Create a [BuildSourceClosuresTask] based on the given [target] in
-   * the given [context].
+   * Create a [BuildSourceImportExportClosureTask] based on the given [target]
+   * in the given [context].
    */
-  static BuildSourceClosuresTask createTask(
+  static BuildSourceImportExportClosureTask createTask(
       AnalysisContext context, AnalysisTarget target) {
-    return new BuildSourceClosuresTask(context, target);
+    return new BuildSourceImportExportClosureTask(context, target);
   }
 }
 
@@ -1900,6 +1934,102 @@
 }
 
 /**
+ * The description for a change in a Dart source.
+ */
+class DartDelta extends Delta {
+  bool hasDirectiveChange = false;
+
+  final Set<String> addedNames = new Set<String>();
+  final Set<String> changedNames = new Set<String>();
+  final Set<String> removedNames = new Set<String>();
+
+  final Set<Source> invalidatedSources = new Set<Source>();
+
+  DartDelta(Source source) : super(source) {
+    invalidatedSources.add(source);
+  }
+
+  void elementAdded(Element element) {
+    addedNames.add(element.name);
+  }
+
+  void elementChanged(Element element) {
+    changedNames.add(element.name);
+  }
+
+  void elementRemoved(Element element) {
+    removedNames.add(element.name);
+  }
+
+  bool isNameAffected(String name) {
+    return addedNames.contains(name) ||
+        changedNames.contains(name) ||
+        removedNames.contains(name);
+  }
+
+  bool nameChanged(String name) {
+    return changedNames.add(name);
+  }
+
+  @override
+  DeltaResult validate(InternalAnalysisContext context, AnalysisTarget target,
+      ResultDescriptor descriptor) {
+    if (hasDirectiveChange) {
+      return DeltaResult.INVALIDATE;
+    }
+    // Prepare target source.
+    Source targetSource = null;
+    if (target is Source) {
+      targetSource = target;
+    }
+    if (target is LibrarySpecificUnit) {
+      targetSource = target.library;
+    }
+    if (target is Element) {
+      targetSource = target.source;
+    }
+    // Keep results that are updated incrementally.
+    // If we want to analyze only some references to the source being changed,
+    // we need to keep the same instances of CompilationUnitElement and
+    // LibraryElement.
+    if (targetSource == source) {
+      if (ParseDartTask.DESCRIPTOR.results.contains(descriptor)) {
+        return DeltaResult.KEEP_CONTINUE;
+      }
+      if (BuildCompilationUnitElementTask.DESCRIPTOR.results
+          .contains(descriptor)) {
+        return DeltaResult.KEEP_CONTINUE;
+      }
+      if (BuildLibraryElementTask.DESCRIPTOR.results.contains(descriptor)) {
+        return DeltaResult.KEEP_CONTINUE;
+      }
+      return DeltaResult.INVALIDATE;
+    }
+    // Use the target library dependency information to decide whether
+    // the delta affects the library.
+    if (targetSource != null) {
+      List<Source> librarySources =
+          context.getLibrariesContaining(targetSource);
+      for (Source librarySource in librarySources) {
+        AnalysisCache cache = context.analysisCache;
+        ReferencedNames referencedNames =
+            cache.getValue(librarySource, REFERENCED_NAMES);
+        if (referencedNames == null) {
+          return DeltaResult.INVALIDATE;
+        }
+        referencedNames.addChangedElements(this);
+        if (referencedNames.isAffectedBy(this)) {
+          return DeltaResult.INVALIDATE;
+        }
+      }
+      return DeltaResult.STOP;
+    }
+    // We don't know what to do with the given target, invalidate it.
+    return DeltaResult.INVALIDATE;
+  }
+}
+
+/**
  * A task that merges all of the errors for a single source into a single list
  * of errors.
  */
@@ -2606,6 +2736,7 @@
     Parser parser = new Parser(source, errorListener);
     AnalysisOptions options = context.analysisOptions;
     parser.parseFunctionBodies = options.analyzeFunctionBodiesPredicate(source);
+    parser.parseGenericMethods = options.enableGenericMethods;
     CompilationUnit unit = parser.parseCompilationUnit(tokenStream);
     unit.lineInfo = lineInfo;
 
@@ -2776,6 +2907,104 @@
 }
 
 /**
+ * Information about a library - which names it uses, which names it defines
+ * with their externally visible dependencies.
+ */
+class ReferencedNames {
+  final Set<String> names = new Set<String>();
+  final Map<String, Set<String>> userToDependsOn = <String, Set<String>>{};
+
+  /**
+   * Updates [delta] by adding names that are changed in this library.
+   */
+  void addChangedElements(DartDelta delta) {
+    bool hasProgress = true;
+    while (hasProgress) {
+      hasProgress = false;
+      userToDependsOn.forEach((user, dependencies) {
+        for (String dependency in dependencies) {
+          if (delta.isNameAffected(dependency)) {
+            if (delta.nameChanged(user)) {
+              hasProgress = true;
+            }
+          }
+        }
+      });
+    }
+  }
+
+  /**
+   * Returns `true` if the library described by this object is affected by
+   * the given [delta].
+   */
+  bool isAffectedBy(DartDelta delta) {
+    for (String name in names) {
+      if (delta.isNameAffected(name)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
+
+/**
+ * A builder for creating [ReferencedNames].
+ *
+ * TODO(scheglov) Record dependencies for all other top-level declarations.
+ */
+class ReferencedNamesBuilder extends RecursiveAstVisitor {
+  final ReferencedNames names;
+  int bodyLevel = 0;
+  Set<String> dependsOn;
+
+  ReferencedNamesBuilder(this.names);
+
+  ReferencedNames build(CompilationUnit unit) {
+    unit.accept(this);
+    return names;
+  }
+
+  @override
+  visitBlockFunctionBody(BlockFunctionBody node) {
+    try {
+      bodyLevel++;
+      super.visitBlockFunctionBody(node);
+    } finally {
+      bodyLevel--;
+    }
+  }
+
+  @override
+  visitClassDeclaration(ClassDeclaration node) {
+    dependsOn = new Set<String>();
+    super.visitClassDeclaration(node);
+    names.userToDependsOn[node.name.name] = dependsOn;
+    dependsOn = null;
+  }
+
+  @override
+  visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    try {
+      bodyLevel++;
+      super.visitExpressionFunctionBody(node);
+    } finally {
+      bodyLevel--;
+    }
+  }
+
+  @override
+  visitSimpleIdentifier(SimpleIdentifier node) {
+    if (!node.inDeclarationContext()) {
+      String name = node.name;
+      names.names.add(name);
+      if (dependsOn != null && bodyLevel == 0) {
+        dependsOn.add(name);
+      }
+    }
+  }
+}
+
+/**
  * A task that finishes resolution by requesting [RESOLVED_UNIT_NO_CONSTANTS] for every
  * unit in the libraries closure and produces [LIBRARY_ELEMENT].
  */
@@ -2786,11 +3015,16 @@
   static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
 
   /**
+   * The name of the list of [RESOLVED_UNIT5] input.
+   */
+  static const String UNITS_INPUT = 'UNITS_INPUT';
+
+  /**
    * The task descriptor describing this kind of task.
    */
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
       'ResolveLibraryReferencesTask', createTask, buildInputs,
-      <ResultDescriptor>[LIBRARY_ELEMENT]);
+      <ResultDescriptor>[LIBRARY_ELEMENT, REFERENCED_NAMES]);
 
   ResolveLibraryReferencesTask(
       InternalAnalysisContext context, AnalysisTarget target)
@@ -2801,8 +3035,21 @@
 
   @override
   void internalPerform() {
+    //
+    // Prepare inputs.
+    //
     LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+    List<CompilationUnit> units = getRequiredInput(UNITS_INPUT);
+    // Compute referenced names.
+    ReferencedNames referencedNames = new ReferencedNames();
+    for (CompilationUnit unit in units) {
+      new ReferencedNamesBuilder(referencedNames).build(unit);
+    }
+    //
+    // Record outputs.
+    //
     outputs[LIBRARY_ELEMENT] = library;
+    outputs[REFERENCED_NAMES] = referencedNames;
   }
 
   /**
@@ -2814,6 +3061,8 @@
     Source source = target;
     return <String, TaskInput>{
       LIBRARY_INPUT: LIBRARY_ELEMENT6.of(source),
+      UNITS_INPUT: UNITS.of(source).toList((Source unit) =>
+          RESOLVED_UNIT5.of(new LibrarySpecificUnit(source, unit))),
       'resolvedUnits': IMPORT_EXPORT_SOURCE_CLOSURE
           .of(source)
           .toMapOf(UNITS)
@@ -2870,12 +3119,9 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     Source source = target;
     return <String, TaskInput>{
-      LIBRARY_INPUT: LIBRARY_ELEMENT4.of(source),
-      'resolvedUnits': IMPORT_EXPORT_SOURCE_CLOSURE
-          .of(source)
-          .toMapOf(UNITS)
-          .toFlattenList((Source library, Source unit) =>
-              RESOLVED_UNIT3.of(new LibrarySpecificUnit(library, unit))),
+      'resolvedUnit': UNITS.of(source).toList((Source unit) =>
+          RESOLVED_UNIT3.of(new LibrarySpecificUnit(source, unit))),
+      LIBRARY_INPUT: LIBRARY_ELEMENT4.of(source)
     };
   }
 
@@ -2958,6 +3204,9 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
+      'fullyBuiltLibraryElements': IMPORT_EXPORT_SOURCE_CLOSURE
+          .of(unit.library)
+          .toListOf(LIBRARY_ELEMENT6),
       LIBRARY_INPUT: LIBRARY_ELEMENT6.of(unit.library),
       UNIT_INPUT: RESOLVED_UNIT4.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
@@ -3042,7 +3291,7 @@
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
       'importsExportNamespace':
-                IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4),
+          IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4),
       LIBRARY_INPUT: LIBRARY_ELEMENT4.of(unit.library),
       UNIT_INPUT: RESOLVED_UNIT2.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
@@ -3125,11 +3374,8 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      'fullyBuiltLibraryElements': IMPORT_EXPORT_SOURCE_CLOSURE
-          .of(unit.library)
-          .toListOf(LIBRARY_ELEMENT6),
-      LIBRARY_INPUT: LIBRARY_ELEMENT6.of(unit.library),
-      UNIT_INPUT: RESOLVED_UNIT3.of(unit),
+      LIBRARY_INPUT: LIBRARY_ELEMENT1.of(unit.library),
+      UNIT_INPUT: RESOLVED_UNIT1.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
     };
   }
@@ -3176,6 +3422,21 @@
   @override
   void internalPerform() {
     Source source = getRequiredSource();
+
+    RecordingErrorListener errorListener = new RecordingErrorListener();
+    if (context.getModificationStamp(target.source) < 0) {
+      String message = 'Content could not be read';
+      if (context is InternalAnalysisContext) {
+        CacheEntry entry =
+            (context as InternalAnalysisContext).getCacheEntry(target);
+        CaughtException exception = entry.exception;
+        if (exception != null) {
+          message = exception.toString();
+        }
+      }
+      errorListener.onError(new AnalysisError(
+          source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT, [message]));
+    }
     if (target is DartScript) {
       DartScript script = target;
       List<ScriptFragment> fragments = script.fragments;
@@ -3187,7 +3448,6 @@
       }
       ScriptFragment fragment = fragments[0];
 
-      RecordingErrorListener errorListener = new RecordingErrorListener();
       Scanner scanner = new Scanner(source,
           new SubSequenceReader(fragment.content, fragment.offset),
           errorListener);
@@ -3202,7 +3462,6 @@
     } else if (target is Source) {
       String content = getRequiredInput(CONTENT_INPUT_NAME);
 
-      RecordingErrorListener errorListener = new RecordingErrorListener();
       Scanner scanner =
           new Scanner(source, new CharSequenceReader(content), errorListener);
       scanner.preserveComments = context.analysisOptions.preserveComments;
@@ -3374,44 +3633,58 @@
 /**
  * A [TaskInput] whose value is a list of library sources exported directly
  * or indirectly by the target [Source].
+ *
+ * [resultDescriptor] is the type of result which should be produced for each
+ * target [Source].
  */
 class _ExportSourceClosureTaskInput extends TaskInputImpl<List<Source>> {
   final Source target;
+  final ResultDescriptor resultDescriptor;
 
-  _ExportSourceClosureTaskInput(this.target);
+  _ExportSourceClosureTaskInput(this.target, this.resultDescriptor);
 
   @override
   TaskInputBuilder<List<Source>> createBuilder() =>
-      new _SourceClosureTaskInputBuilder(target, _SourceClosureKind.EXPORT);
+      new _SourceClosureTaskInputBuilder(
+          target, _SourceClosureKind.EXPORT, resultDescriptor);
 }
 
 /**
  * A [TaskInput] whose value is a list of library sources imported or exported,
  * directly or indirectly by the target [Source].
+ *
+ * [resultDescriptor] is the type of result which should be produced for each
+ * target [Source].
  */
 class _ImportExportSourceClosureTaskInput extends TaskInputImpl<List<Source>> {
   final Source target;
+  final ResultDescriptor resultDescriptor;
 
-  _ImportExportSourceClosureTaskInput(this.target);
+  _ImportExportSourceClosureTaskInput(this.target, this.resultDescriptor);
 
   @override
   TaskInputBuilder<List<Source>> createBuilder() =>
       new _SourceClosureTaskInputBuilder(
-          target, _SourceClosureKind.IMPORT_EXPORT);
+          target, _SourceClosureKind.IMPORT_EXPORT, resultDescriptor);
 }
 
 /**
  * A [TaskInput] whose value is a list of library sources imported directly
  * or indirectly by the target [Source].
+ *
+ * [resultDescriptor] is the type of result which should be produced for each
+ * target [Source].
  */
 class _ImportSourceClosureTaskInput extends TaskInputImpl<List<Source>> {
   final Source target;
+  final ResultDescriptor resultDescriptor;
 
-  _ImportSourceClosureTaskInput(this.target);
+  _ImportSourceClosureTaskInput(this.target, this.resultDescriptor);
 
   @override
   TaskInputBuilder<List<Source>> createBuilder() =>
-      new _SourceClosureTaskInputBuilder(target, _SourceClosureKind.IMPORT);
+      new _SourceClosureTaskInputBuilder(
+          target, _SourceClosureKind.IMPORT, resultDescriptor);
 }
 
 /**
@@ -3427,16 +3700,17 @@
   final Set<LibraryElement> _libraries = new HashSet<LibraryElement>();
   final List<Source> _newSources = <Source>[];
 
+  @override
+  final ResultDescriptor currentResult;
+
   Source currentTarget;
 
-  _SourceClosureTaskInputBuilder(Source librarySource, this.kind) {
+  _SourceClosureTaskInputBuilder(
+      Source librarySource, this.kind, this.currentResult) {
     _newSources.add(librarySource);
   }
 
   @override
-  ResultDescriptor get currentResult => LIBRARY_ELEMENT2;
-
-  @override
   void set currentValue(Object value) {
     LibraryElement library = value;
     if (_libraries.add(library)) {
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index b75bad4..0722ed4 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -18,6 +18,9 @@
 import 'package:html/dom.dart';
 import 'package:html/parser.dart';
 import 'package:source_span/source_span.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
 
 /**
  * The Dart scripts that are embedded in an HTML file.
@@ -285,19 +288,34 @@
   void internalPerform() {
     String content = getRequiredInput(CONTENT_INPUT_NAME);
 
-    HtmlParser parser = new HtmlParser(content, generateSpans: true);
-    parser.compatMode = 'quirks';
-    Document document = parser.parse();
-    List<ParseError> parseErrors = parser.errors;
-    List<AnalysisError> errors = <AnalysisError>[];
-    for (ParseError parseError in parseErrors) {
-      SourceSpan span = parseError.span;
-      errors.add(new AnalysisError(target.source, span.start.offset,
-          span.length, HtmlErrorCode.PARSE_ERROR, [parseError.message]));
-    }
+    if (context.getModificationStamp(target.source) < 0) {
+      String message = 'Content could not be read';
+      if (context is InternalAnalysisContext) {
+        CacheEntry entry = (context as InternalAnalysisContext).getCacheEntry(target);
+        CaughtException exception = entry.exception;
+        if (exception != null) {
+          message = exception.toString();
+        }
+      }
 
-    outputs[HTML_DOCUMENT] = document;
-    outputs[HTML_DOCUMENT_ERRORS] = errors;
+      outputs[HTML_DOCUMENT] = new Document();
+      outputs[HTML_DOCUMENT_ERRORS] = <AnalysisError>[new AnalysisError(
+          target.source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT, [message])];
+    } else {
+      HtmlParser parser = new HtmlParser(content, generateSpans: true);
+      parser.compatMode = 'quirks';
+      Document document = parser.parse();
+      List<ParseError> parseErrors = parser.errors;
+      List<AnalysisError> errors = <AnalysisError>[];
+      for (ParseError parseError in parseErrors) {
+        SourceSpan span = parseError.span;
+        errors.add(new AnalysisError(target.source, span.start.offset,
+            span.length, HtmlErrorCode.PARSE_ERROR, [parseError.message]));
+      }
+
+      outputs[HTML_DOCUMENT] = document;
+      outputs[HTML_DOCUMENT_ERRORS] = errors;
+    }
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/task/incremental_element_builder.dart b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
index 4896b5d..bc562a7 100644
--- a/pkg/analyzer/lib/src/task/incremental_element_builder.dart
+++ b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
@@ -214,8 +214,12 @@
         for (VariableDeclaration variable in variableList.variables) {
           TopLevelVariableElement element = variable.element;
           elements.add(element);
-          elements.add(element.getter);
-          elements.add(element.setter);
+          if (element.getter != null) {
+            elements.add(element.getter);
+          }
+          if (element.setter != null) {
+            elements.add(element.setter);
+          }
         }
       }
     } else if (node is PartDirective || node is PartOfDirective) {
diff --git a/pkg/analyzer/lib/src/task/task_dart.dart b/pkg/analyzer/lib/src/task/task_dart.dart
deleted file mode 100644
index 9192970..0000000
--- a/pkg/analyzer/lib/src/task/task_dart.dart
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library engine.task.dart;
-
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * A `BuildUnitElementTask` builds a compilation unit element for a single
- * compilation unit.
- */
-class BuildUnitElementTask extends AnalysisTask {
-  /**
-   * The source for which an element model will be built.
-   */
-  final Source source;
-
-  /**
-   * The source of the library in which an element model will be built.
-   */
-  final Source library;
-
-  /**
-   * The compilation unit from which an element model will be built.
-   */
-  final CompilationUnit unit;
-
-  /**
-   * The element model that was built.
-   */
-  CompilationUnitElement unitElement;
-
-  /**
-   * Initialize a newly created task to build a compilation unit element for
-   * the given [source] in the given [library] based on the compilation [unit]
-   * that was parsed.
-   */
-  BuildUnitElementTask(
-      InternalAnalysisContext context, this.source, this.library, this.unit)
-      : super(context);
-
-  @override
-  String get taskDescription {
-    if (source == null) {
-      return "build the unit element model for null source";
-    }
-    return "build the unit element model for " + source.fullName;
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) {
-    return visitor.visitBuildUnitElementTask(this);
-  }
-
-  /**
-   * Return the compilation unit from which the element model was built.
-   */
-  CompilationUnit getCompilationUnit() {
-    return unit;
-  }
-
-  /**
-   * Return the source that is to be parsed.
-   */
-  Source getSource() {
-    return source;
-  }
-
-  /**
-   * Return the compilation unit element that was produced, or `null` if the
-   * task has not yet been performed or if an exception occurred.
-   */
-  CompilationUnitElement getUnitElement() {
-    return unitElement;
-  }
-
-  @override
-  void internalPerform() {
-    CompilationUnitBuilder builder = new CompilationUnitBuilder();
-    unitElement = builder.buildCompilationUnit(source, unit, library);
-  }
-}
diff --git a/pkg/analyzer/test/file_system/memory_file_system_test.dart b/pkg/analyzer/test/file_system/memory_file_system_test.dart
index 83d3694..8b072fe 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -5,6 +5,7 @@
 library test.memory_file_system;
 
 import 'dart:async';
+import 'dart:core' hide Resource;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
diff --git a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
index 7d0c141..cd9cfbb 100644
--- a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
+++ b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
@@ -5,6 +5,7 @@
 library test.physical_file_system;
 
 import 'dart:async';
+import 'dart:core' hide Resource;
 import 'dart:io' as io;
 
 import 'package:analyzer/file_system/file_system.dart';
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 9eafca6..e163fd0 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -7,10 +7,7 @@
 
 library engine.all_the_rest_test;
 
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element.dart';
diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart
index e285058..115a514 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -2132,6 +2132,16 @@
             .formalParameterList([AstFactory.simpleFormalParameter3("b")])));
   }
 
+  void test_visitFieldFormalParameter_functionTyped_typeParameters() {
+    _assertSource("A this.a<E, F>(b)", new FieldFormalParameter(null, null,
+        null, AstFactory.typeName4('A'),
+        TokenFactory.tokenFromKeyword(Keyword.THIS),
+        TokenFactory.tokenFromType(TokenType.PERIOD),
+        AstFactory.identifier3('a'), AstFactory.typeParameterList(['E', 'F']),
+        AstFactory
+            .formalParameterList([AstFactory.simpleFormalParameter3("b")])));
+  }
+
   void test_visitFieldFormalParameter_keyword() {
     _assertSource(
         "var this.a", AstFactory.fieldFormalParameter(Keyword.VAR, null, "a"));
@@ -2406,6 +2416,13 @@
         null, Keyword.SET, "f", AstFactory.functionExpression()));
   }
 
+  void test_visitFunctionDeclaration_typeParameters() {
+    _assertSource("f<E>() {}", AstFactory.functionDeclaration(null, null, "f",
+        AstFactory.functionExpression3(AstFactory.typeParameterList(['E']),
+            AstFactory.formalParameterList(),
+            AstFactory.blockFunctionBody2())));
+  }
+
   void test_visitFunctionDeclaration_withMetadata() {
     FunctionDeclaration declaration = AstFactory.functionDeclaration(
         null, null, "f", AstFactory.functionExpression());
@@ -2423,11 +2440,23 @@
     _assertSource("() {}", AstFactory.functionExpression());
   }
 
-  void test_visitFunctionExpressionInvocation() {
+  void test_visitFunctionExpression_typeParameters() {
+    _assertSource("<E>() {}", AstFactory.functionExpression3(
+        AstFactory.typeParameterList(['E']), AstFactory.formalParameterList(),
+        AstFactory.blockFunctionBody2()));
+  }
+
+  void test_visitFunctionExpressionInvocation_minimal() {
     _assertSource("f()",
         AstFactory.functionExpressionInvocation(AstFactory.identifier3("f")));
   }
 
+  void test_visitFunctionExpressionInvocation_typeArguments() {
+    _assertSource("f<A>()", AstFactory.functionExpressionInvocation2(
+        AstFactory.identifier3("f"),
+        AstFactory.typeArgumentList([AstFactory.typeName4('A')])));
+  }
+
   void test_visitFunctionTypeAlias_generic() {
     _assertSource("typedef A F<B>();", AstFactory.typeAlias(
         AstFactory.typeName4("A"), "F", AstFactory.typeParameterList(["B"]),
@@ -2457,6 +2486,13 @@
         AstFactory.typeName4("T"), "f"));
   }
 
+  void test_visitFunctionTypedFormalParameter_typeParameters() {
+    _assertSource("T f<E>()", new FunctionTypedFormalParameter(null, null,
+        AstFactory.typeName4("T"), AstFactory.identifier3('f'),
+        AstFactory.typeParameterList(['E']),
+        AstFactory.formalParameterList([])));
+  }
+
   void test_visitIfStatement_withElse() {
     _assertSource("if (c) {} else {}", AstFactory.ifStatement2(
         AstFactory.identifier3("c"), AstFactory.block(), AstFactory.block()));
@@ -2758,6 +2794,12 @@
         AstFactory.blockFunctionBody2()));
   }
 
+  void test_visitMethodDeclaration_typeParameters() {
+    _assertSource("m<E>() {}", AstFactory.methodDeclaration3(null, null, null,
+        null, AstFactory.identifier3("m"), AstFactory.typeParameterList(['E']),
+        AstFactory.formalParameterList(), AstFactory.blockFunctionBody2()));
+  }
+
   void test_visitMethodDeclaration_withMetadata() {
     MethodDeclaration declaration = AstFactory.methodDeclaration2(null, null,
         null, null, AstFactory.identifier3("m"),
@@ -2781,6 +2823,11 @@
         "t.m()", AstFactory.methodInvocation(AstFactory.identifier3("t"), "m"));
   }
 
+  void test_visitMethodInvocation_typeArguments() {
+    _assertSource("m<A>()", AstFactory.methodInvocation3(
+        null, "m", AstFactory.typeArgumentList([AstFactory.typeName4('A')])));
+  }
+
   void test_visitNamedExpression() {
     _assertSource(
         "a: b", AstFactory.namedExpression2("a", AstFactory.identifier3("b")));
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index db8c17d..eb87ea7 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -33,7 +33,6 @@
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/string_source.dart';
-import 'package:analyzer/src/task/task_dart.dart';
 import 'package:analyzer/task/model.dart' hide AnalysisTask;
 import 'package:html/dom.dart' show Document;
 import 'package:path/path.dart' as pathos;
@@ -195,14 +194,6 @@
    */
   SourceFactory _sourceFactory;
 
-  void fail_extractContext() {
-    fail("Implement this");
-  }
-
-  void fail_mergeContext() {
-    fail("Implement this");
-  }
-
   void fail_performAnalysisTask_importedLibraryDelete_html() {
     Source htmlSource = _addSource("/page.html", r'''
 <html><body><script type="application/dart">
@@ -5828,11 +5819,17 @@
     return false;
   }
 
+  @deprecated
   @override
   void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
       DataDescriptor rowDesc, CacheState state)) {
     fail("Unexpected invocation of visitCacheItems");
   }
+
+  @override
+  void visitContentCache(ContentCacheVisitor visitor) {
+    fail("Unexpected invocation of visitContentCache");
+  }
 }
 
 class TestAnalysisContext_test_applyChanges extends TestAnalysisContext {
@@ -6384,12 +6381,6 @@
  */
 class TestTaskVisitor<E> implements AnalysisTaskVisitor<E> {
   @override
-  E visitBuildUnitElementTask(BuildUnitElementTask task) {
-    fail("Unexpectedly invoked visitGenerateDartErrorsTask");
-    return null;
-  }
-
-  @override
   E visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
     fail("Unexpectedly invoked visitGenerateDartErrorsTask");
     return null;
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 54bb524..98f6d23 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -4,6 +4,7 @@
 
 library engine.incremental_resolver_test;
 
+import 'package:analyzer/src/context/cache.dart' as task;
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -18,6 +19,7 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/ast_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/task/dart.dart';
 import 'package:unittest/unittest.dart';
 
 import '../reflective_tests.dart';
@@ -2473,13 +2475,22 @@
 
   @override
   void reset() {
-    analysisContext2 = AnalysisContextFactory.oldContextWithCore();
+    if (AnalysisEngine.instance.useTaskModel) {
+      analysisContext2 = AnalysisContextFactory.contextWithCore();
+    } else {
+      analysisContext2 = AnalysisContextFactory.oldContextWithCore();
+    }
   }
 
   @override
   void resetWithOptions(AnalysisOptions options) {
-    analysisContext2 =
-        AnalysisContextFactory.oldContextWithCoreAndOptions(options);
+    if (AnalysisEngine.instance.useTaskModel) {
+      analysisContext2 =
+                AnalysisContextFactory.contextWithCoreAndOptions(options);
+    } else {
+      analysisContext2 =
+          AnalysisContextFactory.oldContextWithCoreAndOptions(options);
+    }
   }
 
   void setUp() {
@@ -2812,10 +2823,19 @@
     int updateOffset = edit.offset;
     int updateEndOld = updateOffset + edit.length;
     int updateOldNew = updateOffset + edit.replacement.length;
-    IncrementalResolver resolver = new IncrementalResolver(
-        (analysisContext2 as AnalysisContextImpl)
-            .getReadableSourceEntryOrNull(source), null, null, unit.element,
-        updateOffset, updateEndOld, updateOldNew);
+    IncrementalResolver resolver;
+    if (AnalysisEngine.instance.useTaskModel) {
+      LibrarySpecificUnit lsu = new LibrarySpecificUnit(source, source);
+      task.AnalysisCache cache = analysisContext2.analysisCache;
+      resolver = new IncrementalResolver(null, cache.get(source),
+          cache.get(lsu), unit.element, updateOffset, updateEndOld,
+          updateOldNew);
+    } else {
+      resolver = new IncrementalResolver(
+          (analysisContext2 as AnalysisContextImpl)
+              .getReadableSourceEntryOrNull(source), null, null, unit.element,
+          updateOffset, updateEndOld, updateOldNew);
+    }
     bool success = resolver.resolve(newNode);
     expect(success, isTrue);
     List<AnalysisError> newErrors = analysisContext.computeErrors(source);
@@ -3079,7 +3099,7 @@
 /// aaa [main] bbb
 /// ccc [int] ddd
 main() {
-  return 2;
+  return 1;
 }
 ''');
   }
@@ -3095,7 +3115,7 @@
     _updateAndValidate(r'''
 /// aaa bbb
 main() {
-  return 2;
+  return 1;
 }
 ''');
   }
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 89de72c..5816ab8 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -173,6 +173,7 @@
         (obj) => obj is MethodInvocation, MethodInvocation,
         propertyAccess1.target);
     expect(invocation2.methodName.name, "d");
+    expect(invocation2.typeArguments, isNull);
     ArgumentList argumentList2 = invocation2.argumentList;
     expect(argumentList2, isNotNull);
     expect(argumentList2.arguments, hasLength(1));
@@ -182,6 +183,7 @@
     FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(
         (obj) => obj is FunctionExpressionInvocation,
         FunctionExpressionInvocation, invocation2.target);
+    expect(invocation3.typeArguments, isNull);
     ArgumentList argumentList3 = invocation3.argumentList;
     expect(argumentList3, isNotNull);
     expect(argumentList3.arguments, hasLength(1));
@@ -192,6 +194,45 @@
         (obj) => obj is MethodInvocation, MethodInvocation,
         invocation3.function);
     expect(invocation4.methodName.name, "a");
+    expect(invocation4.typeArguments, isNull);
+    ArgumentList argumentList4 = invocation4.argumentList;
+    expect(argumentList4, isNotNull);
+    expect(argumentList4.arguments, hasLength(1));
+  }
+
+  void test_assignableExpression_arguments_normal_chain_typeArguments() {
+    enableGenericMethods = true;
+    PropertyAccess propertyAccess1 = parseExpression("a<E>(b)<F>(c).d<G>(e).f");
+    expect(propertyAccess1.propertyName.name, "f");
+    //
+    // a<E>(b)<F>(c).d>G?(e)
+    //
+    MethodInvocation invocation2 = EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation, MethodInvocation,
+        propertyAccess1.target);
+    expect(invocation2.methodName.name, "d");
+    expect(invocation2.typeArguments, isNotNull);
+    ArgumentList argumentList2 = invocation2.argumentList;
+    expect(argumentList2, isNotNull);
+    expect(argumentList2.arguments, hasLength(1));
+    //
+    // a<E>(b)<F>(c)
+    //
+    FunctionExpressionInvocation invocation3 = EngineTestCase.assertInstanceOf(
+        (obj) => obj is FunctionExpressionInvocation,
+        FunctionExpressionInvocation, invocation2.target);
+    expect(invocation3.typeArguments, isNotNull);
+    ArgumentList argumentList3 = invocation3.argumentList;
+    expect(argumentList3, isNotNull);
+    expect(argumentList3.arguments, hasLength(1));
+    //
+    // a(b)
+    //
+    MethodInvocation invocation4 = EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation, MethodInvocation,
+        invocation3.function);
+    expect(invocation4.methodName.name, "a");
+    expect(invocation4.typeArguments, isNotNull);
     ArgumentList argumentList4 = invocation4.argumentList;
     expect(argumentList4, isNotNull);
     expect(argumentList4.arguments, hasLength(1));
@@ -1750,6 +1791,17 @@
         "parseCascadeSection", "..()", [ParserErrorCode.MISSING_IDENTIFIER]);
     expect(methodInvocation.target, isNull);
     expect(methodInvocation.methodName.name, "");
+    expect(methodInvocation.typeArguments, isNull);
+    expect(methodInvocation.argumentList.arguments, hasLength(0));
+  }
+
+  void test_parseCascadeSection_missingIdentifier_typeArguments() {
+    enableGenericMethods = true;
+    MethodInvocation methodInvocation = parse4(
+        "parseCascadeSection", "..<E>()", [ParserErrorCode.MISSING_IDENTIFIER]);
+    expect(methodInvocation.target, isNull);
+    expect(methodInvocation.methodName.name, "");
+    expect(methodInvocation.typeArguments, isNotNull);
     expect(methodInvocation.argumentList.arguments, hasLength(0));
   }
 
@@ -2528,6 +2580,12 @@
   static bool parseFunctionBodies = true;
 
   /**
+   * A flag indicating whether generic method support should be enabled for a
+   * specific test.
+   */
+  bool enableGenericMethods = false;
+
+  /**
    * If non-null, this value is used to override the default value of
    * [Scanner.enableNullAwareOperators] before scanning.
    */
@@ -2585,6 +2643,7 @@
     // Parse the source.
     //
     Parser parser = createParser(listener);
+    parser.parseGenericMethods = enableGenericMethods;
     parser.parseFunctionBodies = parseFunctionBodies;
     Object result =
         invokeParserMethodImpl(parser, methodName, objects, tokenStream);
@@ -2718,6 +2777,7 @@
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     Token token = scanner.tokenize();
     Parser parser = createParser(listener);
+    parser.parseGenericMethods = enableGenericMethods;
     Expression expression = parser.parseExpression(token);
     expect(expression, isNotNull);
     listener.assertErrorsWithCodes(errorCodes);
@@ -4654,6 +4714,16 @@
     expect(_isFunctionDeclaration("f() => e"), isTrue);
   }
 
+  void test_isFunctionDeclaration_nameButNoReturn_typeParameters_block() {
+    enableGenericMethods = true;
+    expect(_isFunctionDeclaration("f<E>() {}"), isTrue);
+  }
+
+  void test_isFunctionDeclaration_nameButNoReturn_typeParameters_expression() {
+    enableGenericMethods = true;
+    expect(_isFunctionDeclaration("f<E>() => e"), isTrue);
+  }
+
   void test_isFunctionDeclaration_normalReturn_block() {
     expect(_isFunctionDeclaration("C f() {}"), isTrue);
   }
@@ -4662,6 +4732,16 @@
     expect(_isFunctionDeclaration("C f() => e"), isTrue);
   }
 
+  void test_isFunctionDeclaration_normalReturn_typeParameters_block() {
+    enableGenericMethods = true;
+    expect(_isFunctionDeclaration("C f<E>() {}"), isTrue);
+  }
+
+  void test_isFunctionDeclaration_normalReturn_typeParameters_expression() {
+    enableGenericMethods = true;
+    expect(_isFunctionDeclaration("C f<E>() => e"), isTrue);
+  }
+
   void test_isFunctionDeclaration_voidReturn_block() {
     expect(_isFunctionDeclaration("void f() {}"), isTrue);
   }
@@ -4670,6 +4750,16 @@
     expect(_isFunctionDeclaration("void f() => e"), isTrue);
   }
 
+  void test_isFunctionDeclaration_voidReturn_typeParameters_block() {
+    enableGenericMethods = true;
+    expect(_isFunctionDeclaration("void f<E>() {}"), isTrue);
+  }
+
+  void test_isFunctionDeclaration_voidReturn_typeParameters_expression() {
+    enableGenericMethods = true;
+    expect(_isFunctionDeclaration("void f<E>() => e"), isTrue);
+  }
+
   void test_isFunctionExpression_false_noBody() {
     expect(_isFunctionExpression("f();"), isFalse);
   }
@@ -4678,14 +4768,24 @@
     expect(_isFunctionExpression("(a + b) {"), isFalse);
   }
 
-  void test_isFunctionExpression_noName_block() {
+  void test_isFunctionExpression_noParameters_block() {
     expect(_isFunctionExpression("() {}"), isTrue);
   }
 
-  void test_isFunctionExpression_noName_expression() {
+  void test_isFunctionExpression_noParameters_expression() {
     expect(_isFunctionExpression("() => e"), isTrue);
   }
 
+  void test_isFunctionExpression_noParameters_typeParameters_block() {
+    enableGenericMethods = true;
+    expect(_isFunctionExpression("<E>() {}"), isTrue);
+  }
+
+  void test_isFunctionExpression_noParameters_typeParameters_expression() {
+    enableGenericMethods = true;
+    expect(_isFunctionExpression("<E>() => e"), isTrue);
+  }
+
   void test_isFunctionExpression_parameter_final() {
     expect(_isFunctionExpression("(final a) {}"), isTrue);
     expect(_isFunctionExpression("(final a, b) {}"), isTrue);
@@ -4935,6 +5035,22 @@
     FunctionExpressionInvocation invocation =
         propertyAccess.target as FunctionExpressionInvocation;
     expect(invocation.function, isNotNull);
+    expect(invocation.typeArguments, isNull);
+    ArgumentList argumentList = invocation.argumentList;
+    expect(argumentList, isNotNull);
+    expect(argumentList.arguments, hasLength(1));
+    expect(propertyAccess.operator, isNotNull);
+    expect(propertyAccess.propertyName, isNotNull);
+  }
+
+  void test_parseAssignableExpression_expression_args_dot_typeParameters() {
+    enableGenericMethods = true;
+    PropertyAccess propertyAccess =
+        parse("parseAssignableExpression", <Object>[false], "(x)<F>(y).z");
+    FunctionExpressionInvocation invocation =
+        propertyAccess.target as FunctionExpressionInvocation;
+    expect(invocation.function, isNotNull);
+    expect(invocation.typeArguments, isNotNull);
     ArgumentList argumentList = invocation.argumentList;
     expect(argumentList, isNotNull);
     expect(argumentList.arguments, hasLength(1));
@@ -4979,6 +5095,21 @@
         parse("parseAssignableExpression", <Object>[false], "x(y).z");
     MethodInvocation invocation = propertyAccess.target as MethodInvocation;
     expect(invocation.methodName.name, "x");
+    expect(invocation.typeArguments, isNull);
+    ArgumentList argumentList = invocation.argumentList;
+    expect(argumentList, isNotNull);
+    expect(argumentList.arguments, hasLength(1));
+    expect(propertyAccess.operator, isNotNull);
+    expect(propertyAccess.propertyName, isNotNull);
+  }
+
+  void test_parseAssignableExpression_identifier_args_dot_typeParameters() {
+    enableGenericMethods = true;
+    PropertyAccess propertyAccess =
+        parse("parseAssignableExpression", <Object>[false], "x<E>(y).z");
+    MethodInvocation invocation = propertyAccess.target as MethodInvocation;
+    expect(invocation.methodName.name, "x");
+    expect(invocation.typeArguments, isNotNull);
     ArgumentList argumentList = invocation.argumentList;
     expect(argumentList, isNotNull);
     expect(argumentList.arguments, hasLength(1));
@@ -5193,6 +5324,17 @@
         parse4("parseCascadeSection", "..[i](b)");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is IndexExpression, IndexExpression, section.function);
+    expect(section.typeArguments, isNull);
+    expect(section.argumentList, isNotNull);
+  }
+
+  void test_parseCascadeSection_ia_typeArguments() {
+    enableGenericMethods = true;
+    FunctionExpressionInvocation section =
+        parse4("parseCascadeSection", "..[i]<E>(b)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is IndexExpression, IndexExpression, section.function);
+    expect(section.typeArguments, isNotNull);
     expect(section.argumentList, isNotNull);
   }
 
@@ -5202,6 +5344,20 @@
         (obj) => obj is MethodInvocation, MethodInvocation, section.target);
     expect(section.operator, isNotNull);
     expect(section.methodName, isNotNull);
+    expect(section.typeArguments, isNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
+  void test_parseCascadeSection_ii_typeArguments() {
+    enableGenericMethods = true;
+    MethodInvocation section =
+        parse4("parseCascadeSection", "..a<E>(b).c<F>(d)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation, MethodInvocation, section.target);
+    expect(section.operator, isNotNull);
+    expect(section.methodName, isNotNull);
+    expect(section.typeArguments, isNotNull);
     expect(section.argumentList, isNotNull);
     expect(section.argumentList.arguments, hasLength(1));
   }
@@ -5231,6 +5387,17 @@
         (obj) => obj is IntegerLiteral, IntegerLiteral, rhs);
   }
 
+  void test_parseCascadeSection_p_assign_withCascade_typeArguments() {
+    enableGenericMethods = true;
+    AssignmentExpression section =
+        parse4("parseCascadeSection", "..a = 3..m<E>()");
+    expect(section.leftHandSide, isNotNull);
+    expect(section.operator, isNotNull);
+    Expression rhs = section.rightHandSide;
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is IntegerLiteral, IntegerLiteral, rhs);
+  }
+
   void test_parseCascadeSection_p_builtIn() {
     PropertyAccess section = parse4("parseCascadeSection", "..as");
     expect(section.target, isNull);
@@ -5243,6 +5410,18 @@
     expect(section.target, isNull);
     expect(section.operator, isNotNull);
     expect(section.methodName, isNotNull);
+    expect(section.typeArguments, isNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
+  void test_parseCascadeSection_pa_typeArguments() {
+    enableGenericMethods = true;
+    MethodInvocation section = parse4("parseCascadeSection", "..a<E>(b)");
+    expect(section.target, isNull);
+    expect(section.operator, isNotNull);
+    expect(section.methodName, isNotNull);
+    expect(section.typeArguments, isNotNull);
     expect(section.argumentList, isNotNull);
     expect(section.argumentList.arguments, hasLength(1));
   }
@@ -5252,6 +5431,18 @@
         parse4("parseCascadeSection", "..a(b)(c)");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is MethodInvocation, MethodInvocation, section.function);
+    expect(section.typeArguments, isNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
+  void test_parseCascadeSection_paa_typeArguments() {
+    enableGenericMethods = true;
+    FunctionExpressionInvocation section =
+        parse4("parseCascadeSection", "..a<E>(b)<F>(c)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation, MethodInvocation, section.function);
+    expect(section.typeArguments, isNotNull);
     expect(section.argumentList, isNotNull);
     expect(section.argumentList.arguments, hasLength(1));
   }
@@ -5261,6 +5452,18 @@
         parse4("parseCascadeSection", "..a(b)(c).d(e)(f)");
     EngineTestCase.assertInstanceOf(
         (obj) => obj is MethodInvocation, MethodInvocation, section.function);
+    expect(section.typeArguments, isNull);
+    expect(section.argumentList, isNotNull);
+    expect(section.argumentList.arguments, hasLength(1));
+  }
+
+  void test_parseCascadeSection_paapaa_typeArguments() {
+    enableGenericMethods = true;
+    FunctionExpressionInvocation section =
+        parse4("parseCascadeSection", "..a<E>(b)<F>(c).d<G>(e)<H>(f)");
+    EngineTestCase.assertInstanceOf(
+        (obj) => obj is MethodInvocation, MethodInvocation, section.function);
+    expect(section.typeArguments, isNotNull);
     expect(section.argumentList, isNotNull);
     expect(section.argumentList.arguments, hasLength(1));
   }
@@ -5272,6 +5475,14 @@
     expect(section.propertyName, isNotNull);
   }
 
+  void test_parseCascadeSection_pap_typeArguments() {
+    enableGenericMethods = true;
+    PropertyAccess section = parse4("parseCascadeSection", "..a<E>(b).c");
+    expect(section.target, isNotNull);
+    expect(section.operator, isNotNull);
+    expect(section.propertyName, isNotNull);
+  }
+
   void test_parseClassDeclaration_abstract() {
     ClassDeclaration declaration = parse("parseClassDeclaration", <Object>[
       emptyCommentAndMetadata(),
@@ -5581,6 +5792,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNull);
@@ -5595,11 +5807,60 @@
     expect(method.modifierKeyword, isNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, isNotNull);
   }
 
+  void test_parseClassMember_method_generic_noReturnType() {
+    enableGenericMethods = true;
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "m<T>() {}");
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType, isNull);
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
+  void test_parseClassMember_method_generic_returnType() {
+    enableGenericMethods = true;
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "T m<T>() {}");
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType, isNotNull);
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
+  void test_parseClassMember_method_generic_void() {
+    enableGenericMethods = true;
+    MethodDeclaration method =
+        parse("parseClassMember", <Object>["C"], "void m<T>() {}");
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType, isNotNull);
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
   void test_parseClassMember_method_get_noType() {
     MethodDeclaration method =
         parse("parseClassMember", <Object>["C"], "get() {}");
@@ -5610,6 +5871,7 @@
     expect(method.returnType, isNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -5624,6 +5886,7 @@
     expect(method.returnType, isNotNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -5638,6 +5901,7 @@
     expect(method.returnType, isNotNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -5652,6 +5916,7 @@
     expect(method.returnType, isNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -5666,6 +5931,7 @@
     expect(method.returnType, isNotNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -5680,6 +5946,7 @@
     expect(method.returnType, isNotNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -5694,6 +5961,7 @@
     expect(method.returnType, isNotNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -5708,6 +5976,7 @@
     expect(method.returnType, isNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -5722,6 +5991,7 @@
     expect(method.returnType, isNotNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -5736,6 +6006,7 @@
     expect(method.returnType, isNotNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -5750,6 +6021,7 @@
     expect(method.returnType, isNotNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNotNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -5764,6 +6036,7 @@
     expect(method.returnType, isNotNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNotNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.body, isNotNull);
   }
@@ -6978,6 +7251,7 @@
     FunctionExpression expression = invocation.function as FunctionExpression;
     expect(expression.parameters, isNotNull);
     expect(expression.body, isNotNull);
+    expect(invocation.typeArguments, isNull);
     ArgumentList list = invocation.argumentList;
     expect(list, isNotNull);
     expect(list.arguments, hasLength(1));
@@ -6986,12 +7260,24 @@
   void test_parseExpression_nonAwait() {
     MethodInvocation expression = parseExpression("await()");
     expect(expression.methodName.name, 'await');
+    expect(expression.typeArguments, isNull);
+    expect(expression.argumentList, isNotNull);
   }
 
   void test_parseExpression_superMethodInvocation() {
     MethodInvocation invocation = parse4("parseExpression", "super.m()");
     expect(invocation.target, isNotNull);
     expect(invocation.methodName, isNotNull);
+    expect(invocation.typeArguments, isNull);
+    expect(invocation.argumentList, isNotNull);
+  }
+
+  void test_parseExpression_superMethodInvocation_typeArguments() {
+    enableGenericMethods = true;
+    MethodInvocation invocation = parse4("parseExpression", "super.m<E>()");
+    expect(invocation.target, isNotNull);
+    expect(invocation.methodName, isNotNull);
+    expect(invocation.typeArguments, isNotNull);
     expect(invocation.argumentList, isNotNull);
   }
 
@@ -7029,6 +7315,17 @@
         parse4("parseExpressionWithoutCascade", "super.m()");
     expect(invocation.target, isNotNull);
     expect(invocation.methodName, isNotNull);
+    expect(invocation.typeArguments, isNull);
+    expect(invocation.argumentList, isNotNull);
+  }
+
+  void test_parseExpressionWithoutCascade_superMethodInvocation_typeArguments() {
+    enableGenericMethods = true;
+    MethodInvocation invocation =
+        parse4("parseExpressionWithoutCascade", "super.m<E>()");
+    expect(invocation.target, isNotNull);
+    expect(invocation.methodName, isNotNull);
+    expect(invocation.typeArguments, isNotNull);
     expect(invocation.argumentList, isNotNull);
   }
 
@@ -7765,6 +8062,24 @@
     FunctionExpression expression = declaration.functionExpression;
     expect(expression, isNotNull);
     expect(expression.body, isNotNull);
+    expect(expression.typeParameters, isNull);
+    expect(expression.parameters, isNotNull);
+    expect(declaration.propertyKeyword, isNull);
+  }
+
+  void test_parseFunctionDeclaration_functionWithTypeParameters() {
+    enableGenericMethods = true;
+    Comment comment = Comment.createDocumentationComment(new List<Token>(0));
+    TypeName returnType = new TypeName(new SimpleIdentifier(null), null);
+    FunctionDeclaration declaration = parse("parseFunctionDeclaration",
+        <Object>[commentAndMetadata(comment), null, returnType], "f<E>() {}");
+    expect(declaration.documentationComment, comment);
+    expect(declaration.returnType, returnType);
+    expect(declaration.name, isNotNull);
+    FunctionExpression expression = declaration.functionExpression;
+    expect(expression, isNotNull);
+    expect(expression.body, isNotNull);
+    expect(expression.typeParameters, isNotNull);
     expect(expression.parameters, isNotNull);
     expect(declaration.propertyKeyword, isNull);
   }
@@ -7780,6 +8095,7 @@
     FunctionExpression expression = declaration.functionExpression;
     expect(expression, isNotNull);
     expect(expression.body, isNotNull);
+    expect(expression.typeParameters, isNull);
     expect(expression.parameters, isNull);
     expect(declaration.propertyKeyword, isNotNull);
   }
@@ -7795,6 +8111,7 @@
     FunctionExpression expression = declaration.functionExpression;
     expect(expression, isNotNull);
     expect(expression.body, isNotNull);
+    expect(expression.typeParameters, isNull);
     expect(expression.parameters, isNotNull);
     expect(declaration.propertyKeyword, isNotNull);
   }
@@ -7805,10 +8122,28 @@
     expect(statement.functionDeclaration, isNotNull);
   }
 
+  void test_parseFunctionDeclarationStatement_typeParameters() {
+    enableGenericMethods = true;
+    FunctionDeclarationStatement statement =
+        parse4("parseFunctionDeclarationStatement", "E f<E>(E p) => p * 2;");
+    expect(statement.functionDeclaration, isNotNull);
+  }
+
   void test_parseFunctionExpression_body_inExpression() {
     FunctionExpression expression =
         parse4("parseFunctionExpression", "(int i) => i++");
     expect(expression.body, isNotNull);
+    expect(expression.typeParameters, isNull);
+    expect(expression.parameters, isNotNull);
+    expect((expression.body as ExpressionFunctionBody).semicolon, isNull);
+  }
+
+  void test_parseFunctionExpression_typeParameters() {
+    enableGenericMethods = true;
+    FunctionExpression expression =
+        parse4("parseFunctionExpression", "<E>(E i) => i++");
+    expect(expression.body, isNotNull);
+    expect(expression.typeParameters, isNotNull);
     expect(expression.parameters, isNotNull);
     expect((expression.body as ExpressionFunctionBody).semicolon, isNull);
   }
@@ -7849,6 +8184,7 @@
     expect(method.modifierKeyword, staticKeyword);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNull);
     expect(method.propertyKeyword, isNotNull);
     expect(method.returnType, returnType);
@@ -8433,6 +8769,7 @@
     FunctionExpression expression = invocation.function as FunctionExpression;
     expect(expression.parameters, isNotNull);
     expect(expression.body, isNotNull);
+    expect(invocation.typeArguments, isNull);
     ArgumentList list = invocation.argumentList;
     expect(list, isNotNull);
     expect(list.arguments, hasLength(1));
@@ -8550,6 +8887,17 @@
         parse4("parseNormalFormalParameter", "a())");
     expect(parameter.returnType, isNull);
     expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNull);
+    expect(parameter.parameters, isNotNull);
+  }
+
+  void test_parseNormalFormalParameter_function_noType_typeParameters() {
+    enableGenericMethods = true;
+    FunctionTypedFormalParameter parameter =
+        parse4("parseNormalFormalParameter", "a<E>())");
+    expect(parameter.returnType, isNull);
+    expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNotNull);
     expect(parameter.parameters, isNotNull);
   }
 
@@ -8558,6 +8906,17 @@
         parse4("parseNormalFormalParameter", "A a())");
     expect(parameter.returnType, isNotNull);
     expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNull);
+    expect(parameter.parameters, isNotNull);
+  }
+
+  void test_parseNormalFormalParameter_function_type_typeParameters() {
+    enableGenericMethods = true;
+    FunctionTypedFormalParameter parameter =
+        parse4("parseNormalFormalParameter", "A a<E>())");
+    expect(parameter.returnType, isNotNull);
+    expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNotNull);
     expect(parameter.parameters, isNotNull);
   }
 
@@ -8566,6 +8925,17 @@
         parse4("parseNormalFormalParameter", "void a())");
     expect(parameter.returnType, isNotNull);
     expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNull);
+    expect(parameter.parameters, isNotNull);
+  }
+
+  void test_parseNormalFormalParameter_function_void_typeParameters() {
+    enableGenericMethods = true;
+    FunctionTypedFormalParameter parameter =
+        parse4("parseNormalFormalParameter", "void a<E>())");
+    expect(parameter.returnType, isNotNull);
+    expect(parameter.identifier, isNotNull);
+    expect(parameter.typeParameters, isNotNull);
     expect(parameter.parameters, isNotNull);
   }
 
@@ -8631,6 +9001,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNotNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.propertyKeyword, isNull);
     expect(method.returnType, returnType);
@@ -8682,6 +9053,7 @@
     expect(expression.target, isNotNull);
     expect(expression.operator.type, TokenType.PERIOD);
     expect(expression.methodName, isNotNull);
+    expect(expression.typeArguments, isNull);
     expect(expression.argumentList, isNotNull);
   }
 
@@ -8691,6 +9063,28 @@
     expect(expression.target, isNotNull);
     expect(expression.operator.type, TokenType.QUESTION_PERIOD);
     expect(expression.methodName, isNotNull);
+    expect(expression.typeArguments, isNull);
+    expect(expression.argumentList, isNotNull);
+  }
+
+  void test_parsePostfixExpression_none_methodInvocation_question_dot_typeArguments() {
+    enableGenericMethods = true;
+    _enableNullAwareOperators = true;
+    MethodInvocation expression = parse4('parsePostfixExpression', 'a?.m<E>()');
+    expect(expression.target, isNotNull);
+    expect(expression.operator.type, TokenType.QUESTION_PERIOD);
+    expect(expression.methodName, isNotNull);
+    expect(expression.typeArguments, isNotNull);
+    expect(expression.argumentList, isNotNull);
+  }
+
+  void test_parsePostfixExpression_none_methodInvocation_typeArguments() {
+    enableGenericMethods = true;
+    MethodInvocation expression = parse4("parsePostfixExpression", "a.m<E>()");
+    expect(expression.target, isNotNull);
+    expect(expression.operator.type, TokenType.PERIOD);
+    expect(expression.methodName, isNotNull);
+    expect(expression.typeArguments, isNotNull);
     expect(expression.argumentList, isNotNull);
   }
 
@@ -8961,6 +9355,7 @@
     expect(method.modifierKeyword, isNull);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.propertyKeyword, isNotNull);
     expect(method.returnType, returnType);
@@ -8982,6 +9377,7 @@
     expect(method.modifierKeyword, staticKeyword);
     expect(method.name, isNotNull);
     expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNull);
     expect(method.parameters, isNotNull);
     expect(method.propertyKeyword, isNotNull);
     expect(method.returnType, returnType);
@@ -9033,13 +9429,33 @@
     expect(argumentList.rightBracket, isNotNull);
   }
 
-  void test_parseStatement_functionDeclaration() {
+  void test_parseStatement_functionDeclaration_noReturnType() {
+    FunctionDeclarationStatement statement =
+        parse4("parseStatement", "f(a, b) {};");
+    expect(statement.functionDeclaration, isNotNull);
+  }
+
+  void test_parseStatement_functionDeclaration_noReturnType_typeParameters() {
+    enableGenericMethods = true;
+    FunctionDeclarationStatement statement =
+        parse4("parseStatement", "f(a, b) {};");
+    expect(statement.functionDeclaration, isNotNull);
+  }
+
+  void test_parseStatement_functionDeclaration_returnType() {
     // TODO(brianwilkerson) Implement more tests for this method.
     FunctionDeclarationStatement statement =
         parse4("parseStatement", "int f(a, b) {};");
     expect(statement.functionDeclaration, isNotNull);
   }
 
+  void test_parseStatement_functionDeclaration_returnType_typeParameters() {
+    enableGenericMethods = true;
+    FunctionDeclarationStatement statement =
+        parse4("parseStatement", "int f<E>(a, b) {};");
+    expect(statement.functionDeclaration, isNotNull);
+  }
+
   void test_parseStatement_mulipleLabels() {
     LabeledStatement statement = parse4("parseStatement", "l: m: return x;");
     expect(statement.labels, hasLength(2));
diff --git a/pkg/analyzer/test/generated/source_factory_test.dart b/pkg/analyzer/test/generated/source_factory_test.dart
index 67ec71e..26b3942 100644
--- a/pkg/analyzer/test/generated/source_factory_test.dart
+++ b/pkg/analyzer/test/generated/source_factory_test.dart
@@ -31,32 +31,33 @@
   void test_creation() {
     expect(new SourceFactory([]), isNotNull);
   }
+
   void test_fromEncoding_invalidUri() {
     SourceFactory factory = new SourceFactory([]);
-    try {
-      factory.fromEncoding("<:&%>");
-      fail("Expected IllegalArgumentException");
-    } on IllegalArgumentException {}
+    expect(() => factory.fromEncoding("<:&%>"),
+        throwsA(new isInstanceOf<IllegalArgumentException>()));
   }
+
   void test_fromEncoding_noResolver() {
     SourceFactory factory = new SourceFactory([]);
-    try {
-      factory.fromEncoding("foo:/does/not/exist.dart");
-      fail("Expected IllegalArgumentException");
-    } on IllegalArgumentException {}
+    expect(() => factory.fromEncoding("foo:/does/not/exist.dart"),
+        throwsA(new isInstanceOf<IllegalArgumentException>()));
   }
+
   void test_fromEncoding_valid() {
     String encoding = "file:///does/not/exist.dart";
     SourceFactory factory = new SourceFactory(
         [new UriResolver_SourceFactoryTest_test_fromEncoding_valid(encoding)]);
     expect(factory.fromEncoding(encoding), isNotNull);
   }
+
   void test_resolveUri_absolute() {
     UriResolver_absolute resolver = new UriResolver_absolute();
     SourceFactory factory = new SourceFactory([resolver]);
     factory.resolveUri(null, "dart:core");
     expect(resolver.invoked, isTrue);
   }
+
   void test_resolveUri_nonAbsolute_absolute() {
     SourceFactory factory =
         new SourceFactory([new UriResolver_nonAbsolute_absolute()]);
@@ -67,6 +68,7 @@
     expect(result.fullName,
         FileUtilities2.createFile(absolutePath).getAbsolutePath());
   }
+
   void test_resolveUri_nonAbsolute_relative() {
     SourceFactory factory =
         new SourceFactory([new UriResolver_nonAbsolute_relative()]);
@@ -146,9 +148,7 @@
 
 class UriResolver_restoreUri extends UriResolver {
   Source source1;
-
   Uri expected1;
-
   UriResolver_restoreUri(this.source1, this.expected1);
 
   @override
@@ -166,7 +166,6 @@
 class UriResolver_SourceFactoryTest_test_fromEncoding_valid
     extends UriResolver {
   String encoding;
-
   UriResolver_SourceFactoryTest_test_fromEncoding_valid(this.encoding);
 
   @override
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 2552ea7..666b233 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -551,7 +551,7 @@
 class TestSource extends Source {
   String _name;
   String _contents;
-  int modificationStamp = 0;
+  int _modificationStamp = 0;
   bool exists2 = true;
 
   /**
@@ -560,6 +560,9 @@
    */
   bool generateExceptionOnRead = false;
 
+  @override
+  int get modificationStamp => generateExceptionOnRead ? -1 : _modificationStamp;
+
   /**
    * The number of times that the contents of this source have been requested.
    */
@@ -611,7 +614,8 @@
     return new Uri(scheme: 'file', path: _name).resolveUri(uri);
   }
   void setContents(String value) {
-    modificationStamp = new DateTime.now().millisecondsSinceEpoch;
+    generateExceptionOnRead = false;
+    _modificationStamp = new DateTime.now().millisecondsSinceEpoch;
     _contents = value;
   }
   @override
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 24d1d96..3219e90 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1943,6 +1943,12 @@
   Expression get(AssignmentExpression node) => node.leftHandSide;
 }
 
+class Getter_NodeReplacerTest_test_awaitExpression
+    implements NodeReplacerTest_Getter {
+  @override
+  Expression get(AwaitExpression node) => node.expression;
+}
+
 class Getter_NodeReplacerTest_test_binaryExpression
     implements NodeReplacerTest_Getter {
   @override
@@ -2762,6 +2768,12 @@
   StringLiteral get(UriBasedDirective node) => node.uri;
 }
 
+class Getter_NodeReplacerTest_test_yieldStatement
+    implements NodeReplacerTest_Getter {
+  @override
+  Expression get(YieldStatement node) => node.expression;
+}
+
 @reflectiveTest
 class LineInfoTest {
   void test_creation() {
@@ -3278,6 +3290,11 @@
         node, new Getter_NodeReplacerTest_test_assignmentExpression());
   }
 
+  void test_awaitExpression() {
+    var node = AstFactory.awaitExpression(AstFactory.identifier3("A"));
+    _assertReplace(node, new Getter_NodeReplacerTest_test_awaitExpression());
+  }
+
   void test_binaryExpression() {
     BinaryExpression node = AstFactory.binaryExpression(
         AstFactory.identifier3("l"), TokenType.PLUS,
@@ -4092,6 +4109,11 @@
     _assertReplace(node, new Getter_NodeReplacerTest_testUriBasedDirective());
     _testAnnotatedNode(node);
   }
+
+  void test_yieldStatement() {
+    var node = AstFactory.yieldStatement(AstFactory.identifier3("A"));
+    _assertReplace(node, new Getter_NodeReplacerTest_test_yieldStatement());
+  }
 }
 
 abstract class NodeReplacerTest_Getter<P, C> {
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 60e430c..af84f24 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -29,14 +29,15 @@
         IncrementalAnalysisCache,
         TimestampedData;
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as ht;
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/task/html.dart';
 import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart';
 import 'package:html/dom.dart' show Document;
-import 'package:path/path.dart' as pathos;
 import 'package:unittest/unittest.dart';
 import 'package:watcher/src/utils.dart';
 
@@ -48,106 +49,11 @@
 main() {
   groupSep = ' | ';
   runReflectiveTests(AnalysisContextImplTest);
+  runReflectiveTests(LimitedInvalidateTest);
 }
 
 @reflectiveTest
 class AnalysisContextImplTest extends AbstractContextTest {
-  void fail_applyChanges_empty() {
-    context.applyChanges(new ChangeSet());
-    expect(context.performAnalysisTask().changeNotices, isNull);
-    // This test appears to be flaky. If it is named "test_" it fails, if it's
-    // named "fail_" it doesn't fail. I'm guessing that it's dependent on
-    // whether some other test is run.
-    fail('Should have failed');
-  }
-
-  void fail_extractContext() {
-    fail("Implement this");
-  }
-
-  void fail_mergeContext() {
-    fail("Implement this");
-  }
-
-  void fail_parseHtmlUnit_resolveDirectives() {
-    Source libSource = addSource("/lib.dart", r'''
-library lib;
-class ClassA {}''');
-    Source source = addSource("/lib.html", r'''
-<!DOCTYPE html>
-<html>
-<head>
-  <script type='application/dart'>
-    import 'lib.dart';
-    ClassA v = null;
-  </script>
-</head>
-<body>
-</body>
-</html>''');
-    // TODO(brianwilkerson) Rewrite this. We need a way to get the AST for the
-    // script.
-    ht.HtmlUnit unit = context.parseHtmlUnit(source);
-    expect(unit, isNotNull);
-    // import directive should be resolved
-    ht.XmlTagNode htmlNode = unit.tagNodes[0];
-    ht.XmlTagNode headNode = htmlNode.tagNodes[0];
-    ht.HtmlScriptTagNode scriptNode = headNode.tagNodes[0];
-    CompilationUnit script = scriptNode.script;
-    ImportDirective importNode = script.directives[0] as ImportDirective;
-    expect(importNode.uriContent, isNotNull);
-    expect(importNode.source, libSource);
-  }
-
-  void fail_performAnalysisTask_getContentException_dart() {
-    Source source = _addSourceWithException('test.dart');
-    // prepare errors
-    _analyzeAll_assertFinished();
-    List<AnalysisError> errors = context.getErrors(source).errors;
-    // validate errors
-    expect(errors, hasLength(1));
-    AnalysisError error = errors[0];
-    expect(error.source, same(source));
-    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
-  }
-
-  void fail_performAnalysisTask_getContentException_html() {
-    Source source = _addSourceWithException('test.html');
-    // prepare errors
-    _analyzeAll_assertFinished();
-    List<AnalysisError> errors = context.getErrors(source).errors;
-    // validate errors
-    expect(errors, hasLength(1));
-    AnalysisError error = errors[0];
-    expect(error.source, same(source));
-    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
-  }
-
-  void test_performAnalysisTask_importedLibraryAdd_html() {
-    Source htmlSource = addSource("/page.html", r'''
-<html><body><script type="application/dart">
-  import '/libB.dart';
-  main() {print('hello dart');}
-</script></body></html>''');
-    _analyzeAll_assertFinished();
-    context.computeErrors(htmlSource);
-    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)),
-        isTrue, reason: "htmlSource has an error");
-    // add libB.dart and analyze
-    Source libBSource = addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(
-        context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 2");
-    // TODO (danrubel) commented out to fix red bots
-//    context.computeErrors(htmlSource);
-//    AnalysisErrorInfo errors = _context.getErrors(htmlSource);
-//    expect(
-//        !_hasAnalysisErrorWithErrorSeverity(errors),
-//        isTrue,
-//        reason: "htmlSource doesn't have errors");
-  }
-
   void fail_performAnalysisTask_importedLibraryDelete_html() {
     // NOTE: This was failing before converting to the new task model.
     Source htmlSource = addSource("/page.html", r'''
@@ -172,111 +78,10 @@
         reason: "htmlSource has an error");
   }
 
-  void fail_performAnalysisTask_IOException() {
-    TestSource source = _addSourceWithException2("/test.dart", "library test;");
-    int oldTimestamp = context.getModificationStamp(source);
-    source.generateExceptionOnRead = false;
-    _analyzeAll_assertFinished();
-    expect(source.readCount, 1);
-    source.generateExceptionOnRead = true;
-    do {
-      _changeSource(source, "");
-      // Ensure that the timestamp differs,
-      // so that analysis engine notices the change
-    } while (oldTimestamp == context.getModificationStamp(source));
-    _analyzeAll_assertFinished();
-    expect(source.readCount, 2);
-  }
-
   void fail_recordLibraryElements() {
     fail("Implement this");
   }
 
-  void fail_setAnalysisOptions_reduceAnalysisPriorityOrder() {
-    AnalysisOptionsImpl options =
-        new AnalysisOptionsImpl.from(context.analysisOptions);
-    List<Source> sources = new List<Source>();
-    for (int index = 0; index < options.cacheSize; index++) {
-      sources.add(addSource("/lib.dart$index", ""));
-    }
-    context.analysisPriorityOrder = sources;
-    int oldPriorityOrderSize = _getPriorityOrder(context).length;
-    options.cacheSize = options.cacheSize - 10;
-    context.analysisOptions = options;
-    expect(oldPriorityOrderSize > _getPriorityOrder(context).length, isTrue);
-  }
-
-  void fail_setAnalysisPriorityOrder_lessThanCacheSize() {
-    AnalysisOptions options = context.analysisOptions;
-    List<Source> sources = new List<Source>();
-    for (int index = 0; index < options.cacheSize; index++) {
-      sources.add(addSource("/lib.dart$index", ""));
-    }
-    context.analysisPriorityOrder = sources;
-    expect(options.cacheSize > _getPriorityOrder(context).length, isTrue);
-  }
-
-  Future fail_setChangedContents_libraryWithPart() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.incremental = true;
-    context.analysisOptions = options;
-    SourcesChangedListener listener = new SourcesChangedListener();
-    context.onSourcesChanged.listen(listener.onData);
-    String oldCode = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
-    Source librarySource = addSource("/lib.dart", oldCode);
-    String partContents = r'''
-part of lib;
-int b = a;''';
-    Source partSource = addSource("/part.dart", partContents);
-    LibraryElement element = context.computeLibraryElement(librarySource);
-    CompilationUnit unit =
-        context.getResolvedCompilationUnit(librarySource, element);
-    expect(unit, isNotNull);
-    int offset = oldCode.indexOf("int a") + 4;
-    String newCode = r'''
-library lib;
-part 'part.dart';
-int ya = 0;''';
-    expect(_getIncrementalAnalysisCache(context), isNull);
-    context.setChangedContents(librarySource, newCode, offset, 0, 1);
-    expect(context.getContents(librarySource).data, newCode);
-    IncrementalAnalysisCache incrementalCache =
-        _getIncrementalAnalysisCache(context);
-    expect(incrementalCache.librarySource, librarySource);
-    expect(incrementalCache.resolvedUnit, same(unit));
-    expect(
-        context.getResolvedCompilationUnit2(partSource, librarySource), isNull);
-    expect(incrementalCache.newContents, newCode);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [partSource]);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void fail_unreadableSource() {
-    Source test1 = addSource("/test1.dart", r'''
-import 'test2.dart';
-library test1;''');
-    Source test2 = addSource("/test2.dart", r'''
-import 'test1.dart';
-import 'test3.dart';
-library test2;''');
-    Source test3 = _addSourceWithException("/test3.dart");
-    _analyzeAll_assertFinished();
-    // test1 and test2 should have been successfully analyzed
-    // despite the fact that test3 couldn't be read.
-    expect(context.computeLibraryElement(test1), isNotNull);
-    expect(context.computeLibraryElement(test2), isNotNull);
-    expect(context.computeLibraryElement(test3), isNull);
-  }
-
   @override
   void tearDown() {
     context = null;
@@ -420,6 +225,11 @@
     });
   }
 
+  void test_applyChanges_empty() {
+    context.applyChanges(new ChangeSet());
+    expect(context.performAnalysisTask().changeNotices, isNull);
+  }
+
   void test_applyChanges_overriddenSource() {
     // Note: addSource adds the source to the contentCache.
     Source source = addSource("/test.dart", "library test;");
@@ -1446,6 +1256,32 @@
     expect(document, isNotNull);
   }
 
+  void test_parseHtmlUnit_resolveDirectives() {
+    Source libSource = addSource("/lib.dart", r'''
+library lib;
+class ClassA {}''');
+    Source source = addSource("/lib.html", r'''
+<!DOCTYPE html>
+<html>
+<head>
+  <script type='application/dart'>
+    import 'lib.dart';
+    ClassA v = null;
+  </script>
+</head>
+<body>
+</body>
+</html>''');
+    Document document = context.parseHtmlDocument(source);
+    expect(document, isNotNull);
+    List<DartScript> scripts = context.computeResult(source, DART_SCRIPTS);
+    expect(scripts, hasLength(1));
+    CompilationUnit unit = context.computeResult(scripts[0], PARSED_UNIT);
+    ImportDirective importNode = unit.directives[0] as ImportDirective;
+    expect(importNode.uriContent, isNotNull);
+    expect(importNode.source, libSource);
+  }
+
   void test_performAnalysisTask_addPart() {
     Source libSource = addSource("/lib.dart", r'''
 library lib;
@@ -1604,28 +1440,72 @@
         reason: "part resolved 1");
     // update and analyze #1
     context.setContents(partSource, "part of lib; // 1");
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(
-        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 2");
+    if (AnalysisEngine.instance.limitInvalidationInTaskModel) {
+      expect(
+          context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
+          reason: "library changed 2");
+      expect(
+          context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
+          reason: "part changed 2");
+    } else {
+      expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
+          reason: "library changed 2");
+      expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
+          reason: "part changed 2");
+      _analyzeAll_assertFinished();
+      expect(
+          context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
+          reason: "library resolved 2");
+      expect(
+          context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
+          reason: "part resolved 2");
+    }
     // update and analyze #2
     context.setContents(partSource, "part of lib; // 12");
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 3");
-    expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 3");
+    if (AnalysisEngine.instance.limitInvalidationInTaskModel) {
+      expect(
+          context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
+          reason: "library changed 3");
+      expect(
+          context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
+          reason: "part changed 3");
+    } else {
+      expect(context.getResolvedCompilationUnit2(libSource, libSource), isNull,
+          reason: "library changed 3");
+      expect(context.getResolvedCompilationUnit2(partSource, libSource), isNull,
+          reason: "part changed 3");
+      _analyzeAll_assertFinished();
+      expect(
+          context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
+          reason: "library resolved 3");
+      expect(
+          context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
+          reason: "part resolved 3");
+    }
+  }
+
+  void test_performAnalysisTask_getContentException_dart() {
+    Source source = _addSourceWithException('test.dart');
+    // prepare errors
     _analyzeAll_assertFinished();
-    expect(context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 3");
-    expect(
-        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 3");
+    List<AnalysisError> errors = context.getErrors(source).errors;
+    // validate errors
+    expect(errors, hasLength(1));
+    AnalysisError error = errors[0];
+    expect(error.source, same(source));
+    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
+  }
+
+  void test_performAnalysisTask_getContentException_html() {
+    Source source = _addSourceWithException('test.html');
+    // prepare errors
+    _analyzeAll_assertFinished();
+    List<AnalysisError> errors = context.getErrors(source).errors;
+    // validate errors
+    expect(errors, hasLength(1));
+    AnalysisError error = errors[0];
+    expect(error.source, same(source));
+    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
   }
 
   void test_performAnalysisTask_importedLibraryAdd() {
@@ -1650,6 +1530,31 @@
         isFalse, reason: "libA doesn't have errors");
   }
 
+  void test_performAnalysisTask_importedLibraryAdd_html() {
+    Source htmlSource = addSource("/page.html", r'''
+<html><body><script type="application/dart">
+  import '/libB.dart';
+  main() {print('hello dart');}
+</script></body></html>''');
+    _analyzeAll_assertFinished();
+    context.computeErrors(htmlSource);
+    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(htmlSource)),
+        isTrue, reason: "htmlSource has an error");
+    // add libB.dart and analyze
+    Source libBSource = addSource("/libB.dart", "library libB;");
+    _analyzeAll_assertFinished();
+    expect(
+        context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
+        reason: "libB resolved 2");
+    // TODO (danrubel) commented out to fix red bots
+//    context.computeErrors(htmlSource);
+//    AnalysisErrorInfo errors = _context.getErrors(htmlSource);
+//    expect(
+//        !_hasAnalysisErrorWithErrorSeverity(errors),
+//        isTrue,
+//        reason: "htmlSource doesn't have errors");
+  }
+
   void test_performAnalysisTask_importedLibraryDelete() {
     Source libASource =
         addSource("/libA.dart", "library libA; import 'libB.dart';");
@@ -1673,6 +1578,21 @@
         isTrue, reason: "libA has an error");
   }
 
+  void test_performAnalysisTask_IOException() {
+    TestSource source = _addSourceWithException2("/test.dart", "library test;");
+    source.generateExceptionOnRead = false;
+    _analyzeAll_assertFinished();
+    expect(source.readCount, 1);
+    _changeSource(source, "");
+    source.generateExceptionOnRead = true;
+    _analyzeAll_assertFinished();
+    if (AnalysisEngine.instance.limitInvalidationInTaskModel) {
+      expect(source.readCount, 5);
+    } else {
+      expect(source.readCount, 3);
+    }
+  }
+
   void test_performAnalysisTask_missingPart() {
     Source source =
         addSource("/test.dart", "library lib; part 'no-such-file.dart';");
@@ -1729,17 +1649,6 @@
     expect(resolvedUnitUris, contains('file:///test.dart'));
   }
 
-//  void test_resolveCompilationUnit_sourceChangeDuringResolution() {
-//    _context = new _AnalysisContext_sourceChangeDuringResolution();
-//    AnalysisContextFactory.initContextWithCore(_context);
-//    _sourceFactory = _context.sourceFactory;
-//    Source source = _addSource("/lib.dart", "library lib;");
-//    CompilationUnit compilationUnit =
-//        _context.resolveCompilationUnit2(source, source);
-//    expect(compilationUnit, isNotNull);
-//    expect(_context.getLineInfo(source), isNotNull);
-//  }
-
   void test_resolveCompilationUnit_import_relative() {
     Source sourceA =
         addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
@@ -1780,6 +1689,17 @@
     ]);
   }
 
+//  void test_resolveCompilationUnit_sourceChangeDuringResolution() {
+//    _context = new _AnalysisContext_sourceChangeDuringResolution();
+//    AnalysisContextFactory.initContextWithCore(_context);
+//    _sourceFactory = _context.sourceFactory;
+//    Source source = _addSource("/lib.dart", "library lib;");
+//    CompilationUnit compilationUnit =
+//        _context.resolveCompilationUnit2(source, source);
+//    expect(compilationUnit, isNotNull);
+//    expect(_context.getLineInfo(source), isNotNull);
+//  }
+
   void test_resolveCompilationUnit_library() {
     Source source = addSource("/lib.dart", "library lib;");
     LibraryElement library = context.computeLibraryElement(source);
@@ -1808,6 +1728,16 @@
     expect(result.hint, options.hint);
   }
 
+  void test_setAnalysisPriorityOrder() {
+    int priorityCount = 4;
+    List<Source> sources = new List<Source>();
+    for (int index = 0; index < priorityCount; index++) {
+      sources.add(addSource("/lib.dart$index", ""));
+    }
+    context.analysisPriorityOrder = sources;
+    expect(_getPriorityOrder(context).length, priorityCount);
+  }
+
   void test_setAnalysisPriorityOrder_empty() {
     context.analysisPriorityOrder = new List<Source>();
   }
@@ -1818,6 +1748,42 @@
     context.analysisPriorityOrder = sources;
   }
 
+  Future test_setChangedContents_libraryWithPart() {
+    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+    options.incremental = true;
+    context.analysisOptions = options;
+    SourcesChangedListener listener = new SourcesChangedListener();
+    context.onSourcesChanged.listen(listener.onData);
+    String oldCode = r'''
+library lib;
+part 'part.dart';
+int a = 0;''';
+    Source librarySource = addSource("/lib.dart", oldCode);
+    String partContents = r'''
+part of lib;
+int b = a;''';
+    Source partSource = addSource("/part.dart", partContents);
+    LibraryElement element = context.computeLibraryElement(librarySource);
+    CompilationUnit unit =
+        context.resolveCompilationUnit(librarySource, element);
+    expect(unit, isNotNull);
+    int offset = oldCode.indexOf("int a") + 4;
+    String newCode = r'''
+library lib;
+part 'part.dart';
+int ya = 0;''';
+    context.setChangedContents(librarySource, newCode, offset, 0, 1);
+    expect(context.getContents(librarySource).data, newCode);
+    expect(
+        context.getResolvedCompilationUnit2(partSource, librarySource), isNull);
+    return pumpEventQueue().then((_) {
+      listener.assertEvent(wereSourcesAdded: true);
+      listener.assertEvent(wereSourcesAdded: true);
+      listener.assertEvent(changedSources: [librarySource]);
+      listener.assertNoMoreEvents();
+    });
+  }
+
   void test_setChangedContents_notResolved() {
     AnalysisOptionsImpl options =
         new AnalysisOptionsImpl.from(context.analysisOptions);
@@ -1833,7 +1799,6 @@
 int ya = 0;''';
     context.setChangedContents(librarySource, newCode, offset, 0, 1);
     expect(context.getContents(librarySource).data, newCode);
-    expect(_getIncrementalAnalysisCache(context), isNull);
   }
 
   Future test_setContents_libraryWithPart() {
@@ -1849,10 +1814,6 @@
 int b = a;''';
     Source partSource = addSource("/part.dart", partContents1);
     context.computeLibraryElement(librarySource);
-    IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
-        librarySource, librarySource, null, null, null, 0, 0, 0);
-    _setIncrementalAnalysisCache(context, incrementalCache);
-    expect(_getIncrementalAnalysisCache(context), same(incrementalCache));
     String libraryContents2 = r'''
 library lib;
 part 'part.dart';
@@ -1860,7 +1821,6 @@
     context.setContents(librarySource, libraryContents2);
     expect(
         context.getResolvedCompilationUnit2(partSource, librarySource), isNull);
-    expect(_getIncrementalAnalysisCache(context), isNull);
     return pumpEventQueue().then((_) {
       listener.assertEvent(wereSourcesAdded: true);
       listener.assertEvent(wereSourcesAdded: true);
@@ -1875,14 +1835,9 @@
 int a = 0;''');
     context.setContents(librarySource, '// different');
     context.computeLibraryElement(librarySource);
-    IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
-        librarySource, librarySource, null, null, null, 0, 0, 0);
-    _setIncrementalAnalysisCache(context, incrementalCache);
-    expect(_getIncrementalAnalysisCache(context), same(incrementalCache));
     context.setContents(librarySource, null);
     expect(context.getResolvedCompilationUnit2(librarySource, librarySource),
         isNull);
-    expect(_getIncrementalAnalysisCache(context), isNull);
   }
 
   void test_setContents_unchanged_consistentModificationTime() {
@@ -2009,11 +1964,6 @@
     entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
   }
 
-  IncrementalAnalysisCache _getIncrementalAnalysisCache(
-      AnalysisContextImpl context2) {
-    return context2.test_incrementalAnalysisCache;
-  }
-
   List<Source> _getPriorityOrder(AnalysisContextImpl context2) {
     return context2.test_priorityOrder;
   }
@@ -2033,11 +1983,6 @@
     context.applyChanges(changeSet);
   }
 
-  void _setIncrementalAnalysisCache(
-      AnalysisContextImpl context, IncrementalAnalysisCache incrementalCache) {
-    context.test_incrementalAnalysisCache = incrementalCache;
-  }
-
   /**
    * Returns `true` if there is an [AnalysisError] with [ErrorSeverity.ERROR] in
    * the given [AnalysisErrorInfo].
@@ -2053,6 +1998,278 @@
   }
 }
 
+@reflectiveTest
+class LimitedInvalidateTest extends AbstractContextTest {
+  @override
+  void setUp() {
+    AnalysisEngine.instance.limitInvalidationInTaskModel = true;
+    super.setUp();
+    AnalysisOptionsImpl options =
+        new AnalysisOptionsImpl.from(context.analysisOptions);
+    options.incremental = true;
+    context.analysisOptions = options;
+  }
+
+  @override
+  void tearDown() {
+    AnalysisEngine.instance.limitInvalidationInTaskModel = false;
+    super.tearDown();
+  }
+
+  void test_noChange_thenChange() {
+    Source sourceA = addSource("/a.dart", r'''
+library lib_a;
+
+class A {
+  A();
+}
+class B {
+  B();
+}
+''');
+    Source sourceB = addSource("/b.dart", r'''
+library lib_b;
+import 'a.dart';
+main() {
+  new A();
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(sourceA).errors, hasLength(0));
+    expect(context.getErrors(sourceB).errors, hasLength(0));
+    var unitA = context.getResolvedCompilationUnit2(sourceA, sourceA);
+    var unitElementA = unitA.element;
+    var libraryElementA = unitElementA.library;
+    // Update a.dart, no declaration changes.
+    context.setContents(sourceA, r'''
+library lib_a;
+class A {
+  A();
+}
+class B {
+  B();
+}
+''');
+    _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+    _assertValid(sourceB, LIBRARY_ERRORS_READY);
+    // The a.dart's unit and element are updated incrementally.
+    // They are the same instances as initially.
+    // So, all the references from other units are still valid.
+    {
+      LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA);
+      expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA));
+      expect(unitA.element, same(unitElementA));
+      expect(unitElementA.library, same(libraryElementA));
+    }
+    // Analyze.
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(sourceA).errors, hasLength(0));
+    expect(context.getErrors(sourceB).errors, hasLength(0));
+    // The a.dart's unit and element are the same.
+    {
+      LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA);
+      expect(analysisCache.getValue(target, RESOLVED_UNIT), same(unitA));
+      expect(unitA.element, same(unitElementA));
+      expect(unitElementA.library, same(libraryElementA));
+    }
+    // Update a.dart, rename A to A2, invalidates b.dart, so
+    // we know that the previous update did not damage dependencies.
+    context.setContents(sourceA, r'''
+library lib_a;
+class A {
+  A();
+  m() {}
+}
+class B {
+  B();
+}
+''');
+    _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+    _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+    // The a.dart's unit and element are the same.
+    {
+      LibrarySpecificUnit target = new LibrarySpecificUnit(sourceA, sourceA);
+      expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA));
+      expect(unitA.element, same(unitElementA));
+      expect(unitElementA.library, same(libraryElementA));
+    }
+    // Analyze.
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(sourceA).errors, hasLength(0));
+    expect(context.getErrors(sourceB).errors, hasLength(0));
+  }
+
+  void test_unusedName() {
+    Source sourceA = addSource("/a.dart", r'''
+library lib_a;
+class A {}
+class B {}
+class C {}
+''');
+    Source sourceB = addSource("/b.dart", r'''
+library lib_b;
+import 'a.dart';
+main() {
+  new A();
+  new C();
+}
+''');
+    _performPendingAnalysisTasks();
+    // Update A.
+    context.setContents(sourceA, r'''
+library lib_a;
+class A {}
+class B2 {}
+class C {}
+''');
+    // Only a.dart is invalidated.
+    // Because b.dart does not use B, so it is valid.
+    _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+    _assertValid(sourceB, LIBRARY_ERRORS_READY);
+  }
+
+  void test_usedName_directUser() {
+    Source sourceA = addSource("/a.dart", r'''
+library lib_a;
+class A {}
+class B {}
+class C {}
+''');
+    Source sourceB = addSource("/b.dart", r'''
+library lib_b;
+import 'a.dart';
+main() {
+  new A();
+  new C2();
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(sourceB).errors, hasLength(1));
+    // Update a.dart, invalidates b.dart because it references "C2".
+    context.setContents(sourceA, r'''
+library lib_a;
+class A {}
+class B {}
+class C2 {}
+''');
+    _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+    _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+    // Now b.dart is analyzed and the error is fixed.
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(sourceB).errors, hasLength(0));
+    // Update a.dart, invalidates b.dart because it references "C".
+    context.setContents(sourceA, r'''
+library lib_a;
+class A {}
+class B {}
+class C {}
+''');
+    _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+    _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+    _performPendingAnalysisTasks();
+    // Now b.dart is analyzed and it again has the error.
+    expect(context.getErrors(sourceB).errors, hasLength(1));
+  }
+
+  void test_usedName_directUser_withIncremental() {
+    Source sourceA = addSource("/a.dart", r'''
+library lib_a;
+class A {
+  m() {}
+}
+''');
+    Source sourceB = addSource("/b.dart", r'''
+library lib_b;
+import 'a.dart';
+main() {
+  A a = new A();
+  a.m();
+}
+''');
+    _performPendingAnalysisTasks();
+    // Update A.
+    context.setContents(sourceA, r'''
+library lib_a;
+class A {
+  m2() {}
+}
+''');
+    _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+    _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+  }
+
+  void test_usedName_indirectUser() {
+    Source sourceA = addSource("/a.dart", r'''
+library lib_a;
+class A {
+  m() {}
+}
+''');
+    Source sourceB = addSource("/b.dart", r'''
+library lib_b;
+import 'a.dart';
+class B extends A {}
+''');
+    Source sourceC = addSource("/c.dart", r'''
+library lib_c;
+import 'b.dart';
+class C extends B {
+  main() {
+    m();
+  }
+}
+''');
+    // No errors, "A.m" exists.
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(sourceC).errors, hasLength(0));
+    // Replace "A.m" with "A.m2", invalidate both b.dart and c.dart files.
+    context.setContents(sourceA, r'''
+library lib_a;
+class A {
+  m2() {}
+}
+''');
+    _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+    _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+    _assertInvalid(sourceC, LIBRARY_ERRORS_READY);
+    // There is an error in c.dart, "A.m" does not exist.
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(sourceB).errors, hasLength(0));
+    expect(context.getErrors(sourceC).errors, hasLength(1));
+    // Restore "A.m", invalidate both b.dart and c.dart files.
+    context.setContents(sourceA, r'''
+library lib_a;
+class A {
+  m() {}
+}
+''');
+    _assertInvalid(sourceA, LIBRARY_ERRORS_READY);
+    _assertInvalid(sourceB, LIBRARY_ERRORS_READY);
+    _assertInvalid(sourceC, LIBRARY_ERRORS_READY);
+    // No errors, "A.m" exists.
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(sourceC).errors, hasLength(0));
+  }
+
+  void _assertInvalid(AnalysisTarget target, ResultDescriptor descriptor) {
+    CacheState state = analysisCache.getState(target, descriptor);
+    expect(state, CacheState.INVALID);
+  }
+
+  void _assertValid(AnalysisTarget target, ResultDescriptor descriptor) {
+    CacheState state = analysisCache.getState(target, descriptor);
+    expect(state, CacheState.VALID);
+  }
+
+  void _performPendingAnalysisTasks([int maxTasks = 512]) {
+    for (int i = 0; context.performAnalysisTask().hasMoreWork; i++) {
+      if (i > maxTasks) {
+        fail('Analysis did not terminate.');
+      }
+    }
+  }
+}
+
 class _AnalysisContextImplTest_test_applyChanges_removeContainer
     implements SourceContainer {
   Source libB;
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index e8b5813..c89e6e9 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -32,7 +32,8 @@
   runReflectiveTests(BuildCompilationUnitElementTaskTest);
   runReflectiveTests(BuildDirectiveElementsTaskTest);
   runReflectiveTests(BuildEnumMemberElementsTaskTest);
-  runReflectiveTests(BuildSourceClosuresTaskTest);
+  runReflectiveTests(BuildSourceExportClosureTaskTest);
+  runReflectiveTests(BuildSourceImportExportClosureTaskTest);
   runReflectiveTests(BuildExportNamespaceTaskTest);
   runReflectiveTests(BuildLibraryConstructorsTaskTest);
   runReflectiveTests(BuildLibraryElementTaskTest);
@@ -1098,7 +1099,7 @@
 }
 
 @reflectiveTest
-class BuildSourceClosuresTaskTest extends _AbstractDartTaskTest {
+class BuildSourceExportClosureTaskTest extends _AbstractDartTaskTest {
   test_perform_exportClosure() {
     Source sourceA = newSource('/a.dart', '''
 library lib_a;
@@ -1118,73 +1119,29 @@
     // a.dart
     {
       computeResult(sourceA, EXPORT_SOURCE_CLOSURE);
-      expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+      expect(task, new isInstanceOf<BuildSourceExportClosureTask>());
       List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
       expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
     }
     // c.dart
     {
       computeResult(sourceC, EXPORT_SOURCE_CLOSURE);
-      expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+      expect(task, new isInstanceOf<BuildSourceExportClosureTask>());
       List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
       expect(closure, unorderedEquals([sourceA, sourceB, sourceC]));
     }
     // d.dart
     {
       computeResult(sourceD, EXPORT_SOURCE_CLOSURE);
-      expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+      expect(task, new isInstanceOf<BuildSourceExportClosureTask>());
       List<Source> closure = outputs[EXPORT_SOURCE_CLOSURE];
       expect(closure, unorderedEquals([sourceD]));
     }
   }
+}
 
-  test_perform_importClosure() {
-    Source sourceA = newSource('/a.dart', '''
-library lib_a;
-import 'b.dart';
-''');
-    Source sourceB = newSource('/b.dart', '''
-library lib_b;
-import 'c.dart';
-''');
-    Source sourceC = newSource('/c.dart', '''
-library lib_c;
-import 'a.dart';
-''');
-    Source sourceD = newSource('/d.dart', '''
-library lib_d;
-''');
-    Source coreSource = context.sourceFactory.resolveUri(null, 'dart:core');
-    // a.dart
-    {
-      computeResult(sourceA, IMPORT_SOURCE_CLOSURE);
-      expect(task, new isInstanceOf<BuildSourceClosuresTask>());
-      List<Source> closure = outputs[IMPORT_SOURCE_CLOSURE];
-      expect(closure, contains(sourceA));
-      expect(closure, contains(sourceB));
-      expect(closure, contains(sourceC));
-      expect(closure, contains(coreSource));
-    }
-    // c.dart
-    {
-      computeResult(sourceC, IMPORT_SOURCE_CLOSURE);
-      expect(task, new isInstanceOf<BuildSourceClosuresTask>());
-      List<Source> closure = outputs[IMPORT_SOURCE_CLOSURE];
-      expect(closure, contains(sourceA));
-      expect(closure, contains(sourceB));
-      expect(closure, contains(sourceC));
-      expect(closure, contains(coreSource));
-    }
-    // d.dart
-    {
-      computeResult(sourceD, IMPORT_SOURCE_CLOSURE);
-      expect(task, new isInstanceOf<BuildSourceClosuresTask>());
-      List<Source> closure = outputs[IMPORT_SOURCE_CLOSURE];
-      expect(closure, contains(sourceD));
-      expect(closure, contains(coreSource));
-    }
-  }
-
+@reflectiveTest
+class BuildSourceImportExportClosureTaskTest extends _AbstractDartTaskTest {
   test_perform_importExportClosure() {
     Source sourceA = newSource('/a.dart', '''
 library lib_a;
@@ -1201,7 +1158,7 @@
     // c.dart
     {
       computeResult(sourceC, IMPORT_EXPORT_SOURCE_CLOSURE);
-      expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+      expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
       List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE];
       expect(closure, contains(sourceA));
       expect(closure, contains(sourceB));
@@ -1211,7 +1168,7 @@
     // b.dart
     {
       computeResult(sourceB, IMPORT_EXPORT_SOURCE_CLOSURE);
-      expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+      expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
       List<Source> closure = outputs[IMPORT_EXPORT_SOURCE_CLOSURE];
       expect(closure, contains(sourceA));
       expect(closure, contains(sourceB));
@@ -1228,7 +1185,7 @@
 library lib_b;
 ''');
     computeResult(sourceA, IS_CLIENT);
-    expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+    expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
     expect(outputs[IS_CLIENT], isFalse);
   }
 
@@ -1241,7 +1198,7 @@
 import 'exports_html.dart';
 ''');
     computeResult(source, IS_CLIENT);
-    expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+    expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
     expect(outputs[IS_CLIENT], isTrue);
   }
 
@@ -1251,7 +1208,7 @@
 import 'dart:html';
 ''');
     computeResult(sourceA, IS_CLIENT);
-    expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+    expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
     expect(outputs[IS_CLIENT], isTrue);
   }
 
@@ -1265,7 +1222,7 @@
 import 'dart:html';
 ''');
     computeResult(sourceA, IS_CLIENT);
-    expect(task, new isInstanceOf<BuildSourceClosuresTask>());
+    expect(task, new isInstanceOf<BuildSourceImportExportClosureTask>());
     expect(outputs[IS_CLIENT], isTrue);
   }
 }
@@ -2338,7 +2295,7 @@
     }
   }
 
-  test_perform_deep() {
+  test_perform_external() {
     Source sourceA = newSource('/a.dart', '''
 library a;
 import 'b.dart';
@@ -2346,18 +2303,10 @@
 ''');
     newSource('/b.dart', '''
 library b;
-import 'c.dart';
-part 'b2.dart';
-class B extends B2 {}
+class B {}
 ''');
-    newSource('/b2.dart', '''
-part of b;
-class B2 extends C {}
-''');
-    newSource('/c.dart', '''
-library c;
-class C {}
-''');
+    // The reference A to B should be resolved, but there's no requirement that
+    // the full class hierarchy be resolved.
     computeResult(sourceA, LIBRARY_ELEMENT5);
     expect(task, new isInstanceOf<ResolveLibraryTypeNamesTask>());
     // validate
@@ -2367,13 +2316,6 @@
       expect(clazz.displayName, 'A');
       clazz = clazz.supertype.element;
       expect(clazz.displayName, 'B');
-      clazz = clazz.supertype.element;
-      expect(clazz.displayName, 'B2');
-      clazz = clazz.supertype.element;
-      expect(clazz.displayName, 'C');
-      clazz = clazz.supertype.element;
-      expect(clazz.displayName, 'Object');
-      expect(clazz.supertype, isNull);
     }
   }
 }
diff --git a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
index 415e031..cc6e95b 100644
--- a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
+++ b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
@@ -543,6 +543,54 @@
     expect(unitDelta.removedDeclarations, unorderedEquals([]));
   }
 
+  test_unitMembers_topLevelVariable() {
+    _buildOldUnit(r'''
+bool a = 1, b = 2;
+int c = 3;
+''');
+    List<CompilationUnitMember> oldNodes = oldUnit.declarations.toList();
+    _buildNewUnit(r'''
+int c = 3;
+
+bool a =1, b = 2;
+''');
+    List<CompilationUnitMember> newNodes = newUnit.declarations;
+    {
+      TopLevelVariableDeclaration newNode = newNodes[0];
+      expect(newNode, same(oldNodes[1]));
+      expect(getNodeText(newNode), 'int c = 3;');
+      {
+        TopLevelVariableElement element =
+            newNode.variables.variables[0].element;
+        expect(element, isNotNull);
+        expect(element.name, 'c');
+        expect(element.nameOffset, newCode.indexOf('c = 3'));
+      }
+    }
+    {
+      TopLevelVariableDeclaration newNode = newNodes[1];
+      expect(newNode, same(oldNodes[0]));
+      expect(getNodeText(newNode), 'bool a =1, b = 2;');
+      {
+        TopLevelVariableElement element =
+            newNode.variables.variables[0].element;
+        expect(element, isNotNull);
+        expect(element.name, 'a');
+        expect(element.nameOffset, newCode.indexOf('a =1'));
+      }
+      {
+        TopLevelVariableElement element =
+            newNode.variables.variables[1].element;
+        expect(element, isNotNull);
+        expect(element.name, 'b');
+        expect(element.nameOffset, newCode.indexOf('b = 2'));
+      }
+    }
+    // verify delta
+    expect(unitDelta.addedDeclarations, unorderedEquals([]));
+    expect(unitDelta.removedDeclarations, unorderedEquals([]));
+  }
+
   test_unitMembers_topLevelVariable_add() {
     _buildOldUnit(r'''
 int a, b;
@@ -585,47 +633,25 @@
     ]));
   }
 
-  test_unitMembers_topLevelVariableDeclaration() {
+  test_unitMembers_topLevelVariable_final() {
     _buildOldUnit(r'''
-bool a = 1, b = 2;
-int c = 3;
+final int a = 1;
 ''');
     List<CompilationUnitMember> oldNodes = oldUnit.declarations.toList();
     _buildNewUnit(r'''
-int c = 3;
-
-bool a =1, b = 2;
+final int a =  1;
 ''');
     List<CompilationUnitMember> newNodes = newUnit.declarations;
     {
       TopLevelVariableDeclaration newNode = newNodes[0];
-      expect(newNode, same(oldNodes[1]));
-      expect(getNodeText(newNode), 'int c = 3;');
-      {
-        TopLevelVariableElement element =
-            newNode.variables.variables[0].element;
-        expect(element, isNotNull);
-        expect(element.name, 'c');
-        expect(element.nameOffset, newCode.indexOf('c = 3'));
-      }
-    }
-    {
-      TopLevelVariableDeclaration newNode = newNodes[1];
       expect(newNode, same(oldNodes[0]));
-      expect(getNodeText(newNode), 'bool a =1, b = 2;');
+      expect(getNodeText(newNode), 'final int a =  1;');
       {
         TopLevelVariableElement element =
             newNode.variables.variables[0].element;
         expect(element, isNotNull);
         expect(element.name, 'a');
-        expect(element.nameOffset, newCode.indexOf('a =1'));
-      }
-      {
-        TopLevelVariableElement element =
-            newNode.variables.variables[1].element;
-        expect(element, isNotNull);
-        expect(element.name, 'b');
-        expect(element.nameOffset, newCode.indexOf('b = 2'));
+        expect(element.nameOffset, newCode.indexOf('a =  1'));
       }
     }
     // verify delta
diff --git a/pkg/analyzer/test/task/task_dart_test.dart b/pkg/analyzer/test/task/task_dart_test.dart
deleted file mode 100644
index e7c03be..0000000
--- a/pkg/analyzer/test/task/task_dart_test.dart
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.engine.task.dart;
-
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/task/task_dart.dart';
-import 'package:unittest/unittest.dart';
-
-import '../generated/engine_test.dart';
-import '../generated/resolver_test.dart';
-import '../generated/test_support.dart';
-
-main() {
-  groupSep = ' | ';
-//  runReflectiveTests(BuildUnitElementTaskTest);
-}
-
-class BuildUnitElementTaskTest extends EngineTestCase {
-  CompilationUnit parseUnit(
-      InternalAnalysisContext context, Source source, String content) {
-    ScanDartTask scanTask = new ScanDartTask(context, source, content);
-    scanTask.perform(new ScanDartTaskTestTV_accept());
-    ParseDartTask parseTask = new ParseDartTask(
-        context, source, scanTask.tokenStream, scanTask.lineInfo);
-    parseTask.perform(new ParseDartTaskTestTV_accept());
-    return parseTask.compilationUnit;
-  }
-
-  void test_accept() {
-    BuildUnitElementTask task =
-        new BuildUnitElementTask(null, null, null, null);
-    expect(task.accept(new BuildUnitElementTaskTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    BuildUnitElementTask task =
-        new BuildUnitElementTask(null, null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getLibrarySource() {
-    Source source = new TestSource('/part.dart');
-    Source library = new TestSource('/lib.dart');
-    BuildUnitElementTask task =
-        new BuildUnitElementTask(null, source, library, null);
-    expect(task.library, equals(library));
-  }
-
-  void test_getUnitSource() {
-    Source source = new TestSource('/part.dart');
-    Source library = new TestSource('/lib.dart');
-    BuildUnitElementTask task =
-        new BuildUnitElementTask(null, source, library, null);
-    expect(task.source, equals(source));
-  }
-
-  void test_perform_exception() {
-    TestSource source = new TestSource();
-    source.generateExceptionOnRead = true;
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    CompilationUnit unit = parseUnit(context, source, "");
-    BuildUnitElementTask task =
-        new BuildUnitElementTask(context, null, source, unit);
-    task.perform(new BuildUnitElementTaskTV_perform_exception());
-  }
-
-  void test_perform_valid() {
-    var content = """
-library lib;
-class A {}""";
-    Source source = new TestSource('/test.dart', content);
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    CompilationUnit unit = parseUnit(context, source, content);
-    BuildUnitElementTask task =
-        new BuildUnitElementTask(context, source, source, unit);
-    task.perform(new BuildUnitElementTaskTV_perform_valid(source, unit));
-  }
-}
-
-class BuildUnitElementTaskTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitBuildUnitElementTask(BuildUnitElementTask task) => true;
-}
-
-class BuildUnitElementTaskTV_perform_exception extends TestTaskVisitor<bool> {
-  @override
-  bool visitBuildUnitElementTask(BuildUnitElementTask task) {
-    expect(task.exception, isNotNull);
-    return true;
-  }
-}
-
-class BuildUnitElementTaskTV_perform_valid extends TestTaskVisitor<bool> {
-  Source source;
-
-  CompilationUnit unit;
-
-  BuildUnitElementTaskTV_perform_valid(this.source, this.unit);
-
-  @override
-  bool visitBuildUnitElementTask(BuildUnitElementTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.source, equals(source));
-    expect(task.library, equals(source));
-    expect(task.unit, equals(unit));
-    expect(task.unitElement, isNotNull);
-    return true;
-  }
-}
diff --git a/pkg/analyzer/test/task/test_all.dart b/pkg/analyzer/test/task/test_all.dart
deleted file mode 100644
index 9ecd162..0000000
--- a/pkg/analyzer/test/task/test_all.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.task;
-
-import 'package:unittest/unittest.dart';
-
-import 'task_dart_test.dart' as task_dart_test;
-
-/// Utility for manually running all tests.
-main() {
-  groupSep = ' | ';
-  group('generated tests', () {
-    task_dart_test.main();
-  });
-}
diff --git a/pkg/analyzer/test/test_all.dart b/pkg/analyzer/test/test_all.dart
index 222beb8..cde1f38 100644
--- a/pkg/analyzer/test/test_all.dart
+++ b/pkg/analyzer/test/test_all.dart
@@ -14,7 +14,6 @@
 import 'parse_compilation_unit_test.dart' as parse_compilation_unit;
 import 'source/test_all.dart' as source;
 import 'src/test_all.dart' as src;
-import 'task/test_all.dart' as task;
 
 /// Utility for manually running all tests.
 main() {
@@ -28,6 +27,5 @@
     parse_compilation_unit.main();
     source.main();
     src.main();
-    task.main();
   });
 }
diff --git a/pkg/analyzer2dart/lib/src/cps_generator.dart b/pkg/analyzer2dart/lib/src/cps_generator.dart
index 8bd4c0a..1e5bb6d 100644
--- a/pkg/analyzer2dart/lib/src/cps_generator.dart
+++ b/pkg/analyzer2dart/lib/src/cps_generator.dart
@@ -1,589 +1,589 @@
-// 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 analyzer2dart.cps_generator;

-

-import 'package:analyzer/analyzer.dart';

-

-import 'package:compiler/src/dart_types.dart' as dart2js;

-import 'package:compiler/src/elements/elements.dart' as dart2js;

-import 'package:analyzer/src/generated/source.dart';

-import 'package:analyzer/src/generated/element.dart' as analyzer;

-

-import 'package:compiler/src/constant_system_dart.dart'

-    show DART_CONSTANT_SYSTEM;

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

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

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

-

-import 'semantic_visitor.dart';

-import 'element_converter.dart';

-import 'util.dart';

-import 'identifier_semantics.dart';

-

-/// Visitor that converts the AST node of an analyzer element into a CPS ir

-/// node.

-class CpsElementVisitor extends analyzer.SimpleElementVisitor<ir.Node> {

-  final ElementConverter converter;

-  final AstNode node;

-

-  CpsElementVisitor(this.converter, this.node);

-

-  @override

-  ir.FunctionDefinition visitFunctionElement(analyzer.FunctionElement element) {

-    CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);

-    FunctionDeclaration functionDeclaration = node;

-    return visitor.handleFunctionDeclaration(

-        element, functionDeclaration.functionExpression.body);

-  }

-

-  @override

-  ir.FunctionDefinition visitMethodElement(analyzer.MethodElement element) {

-    CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);

-    MethodDeclaration methodDeclaration = node;

-    return visitor.handleFunctionDeclaration(element, methodDeclaration.body);

-  }

-

-  @override

-  ir.FieldDefinition visitTopLevelVariableElement(

-      analyzer.TopLevelVariableElement element) {

-    CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);

-    VariableDeclaration variableDeclaration = node;

-    return visitor.handleFieldDeclaration(element, variableDeclaration);

-  }

-

-  @override

-  ir.RootNode visitConstructorElement(analyzer.ConstructorElement element) {

-    CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);

-    if (!element.isFactory) {

-      ConstructorDeclaration constructorDeclaration = node;

-      FunctionBody body;

-      if (constructorDeclaration != null) {

-        body = constructorDeclaration.body;

-      } else {

-        assert(element.isSynthetic);

-      }

-      return visitor.handleConstructorDeclaration(element, body);

-    }

-    // TODO(johnniwinther): Support factory constructors.

-    return null;

-  }

-}

-

-/// Visitor that converts analyzer AST nodes into CPS ir nodes.

-class CpsGeneratingVisitor extends SemanticVisitor<ir.Node>

-    with IrBuilderMixin<AstNode> {

-  /// Promote the type of [irBuilder] to [DartIrBuilder].

-  /// The JS backend requires closure conversion which we do not support yet.

-  DartIrBuilder get irBuilder => super.irBuilder;

-  final analyzer.Element element;

-  final ElementConverter converter;

-

-  CpsGeneratingVisitor(this.converter, this.element);

-

-  Source get currentSource => element.source;

-

-  analyzer.LibraryElement get currentLibrary => element.library;

-

-  ir.Node visit(AstNode node) => node.accept(this);

-

-  ir.ConstructorDefinition handleConstructorDeclaration(

-      analyzer.ConstructorElement constructor, FunctionBody body) {

-    dart2js.ConstructorElement element = converter.convertElement(constructor);

-    return withBuilder(

-        new DartIrBuilder(DART_CONSTANT_SYSTEM,

-                          element,

-                          // TODO(johnniwinther): Support closure variables.

-                          new Set<dart2js.Local>()),

-        () {

-      irBuilder.buildFunctionHeader(

-          constructor.parameters.map(converter.convertElement));

-      // Visit the body directly to avoid processing the signature as

-      // expressions.

-      // Call to allow for `body == null` in case of synthesized constructors.

-      build(body);

-      return irBuilder.makeConstructorDefinition(const [], const []);

-    });

-  }

-

-  ir.FieldDefinition handleFieldDeclaration(

-      analyzer.PropertyInducingElement field, VariableDeclaration node) {

-    dart2js.FieldElement element = converter.convertElement(field);

-    return withBuilder(

-        new DartIrBuilder(DART_CONSTANT_SYSTEM,

-                          element,

-                          // TODO(johnniwinther): Support closure variables.

-                          new Set<dart2js.Local>()),

-        () {

-      irBuilder.buildFieldInitializerHeader();

-      ir.Primitive initializer = build(node.initializer);

-      return irBuilder.makeFieldDefinition(initializer);

-    });

-  }

-

-  ir.FunctionDefinition handleFunctionDeclaration(

-      analyzer.ExecutableElement function, FunctionBody body) {

-    dart2js.FunctionElement element = converter.convertElement(function);

-    return withBuilder(

-        new DartIrBuilder(DART_CONSTANT_SYSTEM,

-                          element,

-                          // TODO(johnniwinther): Support closure variables.

-                          new Set<dart2js.Local>()),

-        () {

-      irBuilder.buildFunctionHeader(

-          function.parameters.map(converter.convertElement));

-      // Visit the body directly to avoid processing the signature as

-      // expressions.

-      visit(body);

-      return irBuilder.makeFunctionDefinition(const []);

-    });

-  }

-

-  @override

-  ir.Primitive visitFunctionExpression(FunctionExpression node) {

-    return irBuilder.buildFunctionExpression(

-        handleFunctionDeclaration(node.element, node.body));

-  }

-

-  @override

-  ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) {

-    return handleFunctionDeclaration(

-        node.element, node.functionExpression.body);

-  }

-

-  @override

-  visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {

-    FunctionDeclaration functionDeclaration = node.functionDeclaration;

-    analyzer.FunctionElement function = functionDeclaration.element;

-    dart2js.FunctionElement element = converter.convertElement(function);

-    ir.FunctionDefinition definition = handleFunctionDeclaration(

-        function, functionDeclaration.functionExpression.body);

-    irBuilder.declareLocalFunction(element, definition);

-  }

-

-  List<ir.Primitive> visitArguments(ArgumentList argumentList) {

-    List<ir.Primitive> arguments = <ir.Primitive>[];

-    for (Expression argument in argumentList.arguments) {

-      ir.Primitive value = build(argument);

-      if (value == null) {

-        giveUp(argument,

-            'Unsupported argument: $argument (${argument.runtimeType}).');

-      }

-      arguments.add(value);

-    }

-    return arguments;

-  }

-

-  @override

-  ir.Node visitMethodInvocation(MethodInvocation node) {

-    // Overridden to avoid eager visits of the receiver and arguments.

-    return handleMethodInvocation(node);

-  }

-

-  @override

-  ir.Primitive visitDynamicInvocation(MethodInvocation node,

-                                      AccessSemantics semantics) {

-    // TODO(johnniwinther): Handle implicit `this`.

-    ir.Primitive receiver = build(semantics.target);

-    List<ir.Primitive> arguments = visitArguments(node.argumentList);

-    return irBuilder.buildDynamicInvocation(

-        receiver,

-        createSelectorFromMethodInvocation(

-            node.argumentList, node.methodName.name),

-        arguments);

-  }

-

-  @override

-  ir.Primitive visitStaticMethodInvocation(MethodInvocation node,

-                                           AccessSemantics semantics) {

-    analyzer.Element staticElement = semantics.element;

-    dart2js.Element element = converter.convertElement(staticElement);

-    List<ir.Primitive> arguments = visitArguments(node.argumentList);

-    return irBuilder.buildStaticFunctionInvocation(

-        element,

-        createCallStructureFromMethodInvocation(node.argumentList),

-        arguments);

-  }

-

-  @override

-  ir.Node visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {

-    return handleLocalAccess(node, semantics);

-  }

-

-  ir.Primitive handleLocalInvocation(MethodInvocation node,

-                                     AccessSemantics semantics) {

-    analyzer.Element staticElement = semantics.element;

-    dart2js.Element element = converter.convertElement(staticElement);

-    List<ir.Definition> arguments = visitArguments(node.argumentList);

-    CallStructure callStructure = createCallStructureFromMethodInvocation(

-        node.argumentList);

-    if (semantics.kind == AccessKind.LOCAL_FUNCTION) {

-      return irBuilder.buildLocalFunctionInvocation(

-          element, callStructure, arguments);

-    } else {

-      return irBuilder.buildLocalVariableInvocation(

-        element, callStructure, arguments);

-    }

-  }

-

-  @override

-  ir.Node visitLocalVariableInvocation(MethodInvocation node,

-                                       AccessSemantics semantics) {

-    return handleLocalInvocation(node, semantics);

-  }

-

-  @override

-  ir.Primitive visitLocalFunctionInvocation(MethodInvocation node,

-                                            AccessSemantics semantics) {

-    return handleLocalInvocation(node, semantics);

-  }

-

-  @override

-  ir.Primitive visitFunctionExpressionInvocation(

-      FunctionExpressionInvocation node) {

-    ir.Primitive target = build(node.function);

-    List<ir.Definition> arguments = visitArguments(node.argumentList);

-    return irBuilder.buildCallInvocation(

-        target,

-        createCallStructureFromMethodInvocation(node.argumentList),

-        arguments);

-  }

-

-  @override

-  ir.Primitive visitInstanceCreationExpression(

-      InstanceCreationExpression node) {

-    analyzer.Element staticElement = node.staticElement;

-    if (staticElement != null) {

-      dart2js.Element element = converter.convertElement(staticElement);

-      dart2js.DartType type = converter.convertType(node.staticType);

-      List<ir.Primitive> arguments = visitArguments(node.argumentList);

-      return irBuilder.buildConstructorInvocation(

-          element,

-          createCallStructureFromMethodInvocation(node.argumentList),

-          type,

-          arguments);

-    }

-    return giveUp(node, "Unresolved constructor invocation.");

-  }

-

-  @override

-  ir.Constant visitNullLiteral(NullLiteral node) {

-    return irBuilder.buildNullConstant();

-  }

-

-  @override

-  ir.Constant visitBooleanLiteral(BooleanLiteral node) {

-    return irBuilder.buildBooleanConstant(node.value);

-  }

-

-  @override

-  ir.Constant visitDoubleLiteral(DoubleLiteral node) {

-    return irBuilder.buildDoubleConstant(node.value);

-  }

-

-  @override

-  ir.Constant visitIntegerLiteral(IntegerLiteral node) {

-    return irBuilder.buildIntegerConstant(node.value);

-  }

-

-  @override

-  visitAdjacentStrings(AdjacentStrings node) {

-    String value = node.stringValue;

-    if (value != null) {

-      return irBuilder.buildStringConstant(value);

-    }

-    giveUp(node, "Non constant adjacent strings.");

-  }

-

-  @override

-  ir.Constant visitSimpleStringLiteral(SimpleStringLiteral node) {

-    return irBuilder.buildStringConstant(node.value);

-  }

-

-  @override

-  visitStringInterpolation(StringInterpolation node) {

-    giveUp(node, "String interpolation.");

-  }

-

-  @override

-  visitReturnStatement(ReturnStatement node) {

-    irBuilder.buildReturn(build(node.expression));

-  }

-

-  @override

-  ir.Node visitPropertyAccess(PropertyAccess node) {

-    // Overridden to avoid eager visits of the receiver.

-    return handlePropertyAccess(node);

-  }

-

-  @override

-  ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {

-    return handleLocalAccess(node, semantics);

-  }

-

-  @override

-  ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) {

-    return handleLocalAccess(node, semantics);

-  }

-

-  @override

-  visitVariableDeclaration(VariableDeclaration node) {

-    // TODO(johnniwinther): Handle constant local variables.

-    ir.Node initialValue = build(node.initializer);

-    irBuilder.declareLocalVariable(

-        converter.convertElement(node.element),

-        initialValue: initialValue);

-  }

-

-  dart2js.Element getLocal(AstNode node, AccessSemantics semantics) {

-    analyzer.Element element = semantics.element;

-    dart2js.Element target = converter.convertElement(element);

-    assert(invariant(node, target.isLocal, '$target expected to be local.'));

-    return target;

-  }

-

-  ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) {

-    dart2js.Element local = getLocal(node, semantics);

-    if (semantics.kind == AccessKind.LOCAL_FUNCTION) {

-      return irBuilder.buildLocalFunctionGet(local);

-    } else {

-      return irBuilder.buildLocalVariableGet(local);

-    }

-  }

-

-  ir.Primitive handleLocalAssignment(AssignmentExpression node,

-                                     AccessSemantics semantics) {

-    if (node.operator.lexeme != '=') {

-      return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');

-    }

-    return irBuilder.buildLocalVariableSet(

-        getLocal(node, semantics),

-        build(node.rightHandSide));

-  }

-

-  @override

-  ir.Node visitAssignmentExpression(AssignmentExpression node) {

-    // Avoid eager visiting of left and right hand side.

-    return handleAssignmentExpression(node);

-  }

-

-  @override

-  ir.Node visitLocalVariableAssignment(AssignmentExpression node,

-                                       AccessSemantics semantics) {

-    return handleLocalAssignment(node, semantics);

-  }

-

-  @override

-  ir.Node visitParameterAssignment(AssignmentExpression node,

-                                   AccessSemantics semantics) {

-    return handleLocalAssignment(node, semantics);

-  }

-

-  @override

-  ir.Node visitStaticFieldAssignment(AssignmentExpression node,

-                                     AccessSemantics semantics) {

-    if (node.operator.lexeme != '=') {

-      return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');

-    }

-    analyzer.Element element = semantics.element;

-    dart2js.Element target = converter.convertElement(element);

-    // TODO(johnniwinther): Selector information should be computed in the

-    // [TreeShaker] and shared with the [CpsGeneratingVisitor].

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

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

-    return irBuilder.buildStaticFieldSet(target, build(node.rightHandSide));

-  }

-

-  @override

-  ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) {

-    // TODO(johnniwinther): Handle implicit `this`.

-    ir.Primitive receiver = build(semantics.target);

-    return irBuilder.buildDynamicGet(receiver,

-        new Selector.getter(semantics.identifier.name,

-                            converter.convertElement(element.library)));

-  }

-

-  @override

-  ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {

-    analyzer.Element element = semantics.element;

-    dart2js.Element target = converter.convertElement(element);

-    // TODO(johnniwinther): Selector information should be computed in the

-    // [TreeShaker] and shared with the [CpsGeneratingVisitor].

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

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

-    return irBuilder.buildStaticFieldLazyGet(target, null);

-  }

-

-  ir.Primitive handleBinaryExpression(BinaryExpression node,

-                                      String op) {

-    ir.Primitive left = build(node.leftOperand);

-    ir.Primitive right = build(node.rightOperand);

-    Selector selector = new Selector.binaryOperator(op);

-    return irBuilder.buildDynamicInvocation(

-        left, selector, <ir.Primitive>[right]);

-  }

-

-  ir.Node handleLazyOperator(BinaryExpression node, {bool isLazyOr: false}) {

-    return irBuilder.buildLogicalOperator(

-        build(node.leftOperand),

-        subbuild(node.rightOperand),

-        isLazyOr: isLazyOr);

-  }

-

-  @override

-  ir.Node visitBinaryExpression(BinaryExpression node) {

-    // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be

-    // available through an enum.

-    String op = node.operator.lexeme;

-    switch (op) {

-    case '||':

-    case '&&':

-      return handleLazyOperator(node, isLazyOr: op == '||');

-    case '!=':

-      return irBuilder.buildNegation(handleBinaryExpression(node, '=='));

-    default:

-      return handleBinaryExpression(node, op);

-    }

-  }

-

-  @override

-  ir.Node visitConditionalExpression(ConditionalExpression node) {

-    return irBuilder.buildConditional(

-        build(node.condition),

-        subbuild(node.thenExpression),

-        subbuild(node.elseExpression));

-  }

-

-  @override

-  visitIfStatement(IfStatement node) {

-    irBuilder.buildIf(

-        build(node.condition),

-        subbuild(node.thenStatement),

-        subbuild(node.elseStatement));

-  }

-

-  @override

-  visitBlock(Block node) {

-    irBuilder.buildBlock(node.statements, build);

-  }

-

-  @override

-  ir.Node visitListLiteral(ListLiteral node) {

-    dart2js.InterfaceType type = converter.convertType(node.staticType);

-    // TODO(johnniwinther): Use `build` instead of `(e) => build(e)` when issue

-    // 18630 has been resolved.

-    Iterable<ir.Primitive> values = node.elements.map((e) => build(e));

-    return irBuilder.buildListLiteral(type, values);

-  }

-

-  @override

-  ir.Node visitMapLiteral(MapLiteral node) {

-    dart2js.InterfaceType type = converter.convertType(node.staticType);

-    return irBuilder.buildMapLiteral(

-        type,

-        node.entries.map((e) => e.key),

-        node.entries.map((e) => e.value),

-        build);

-  }

-

-  @override

-  visitForStatement(ForStatement node) {

-    // TODO(johnniwinther): Support `for` as a jump target.

-    List<dart2js.LocalElement> loopVariables = <dart2js.LocalElement>[];

-    SubbuildFunction buildInitializer;

-    if (node.variables != null) {

-      buildInitializer = subbuild(node.variables);

-      for (VariableDeclaration variable in node.variables.variables) {

-        loopVariables.add(converter.convertElement(variable.element));

-      }

-    } else {

-      buildInitializer = subbuild(node.initialization);

-    }

-    irBuilder.buildFor(buildInitializer: buildInitializer,

-                       buildCondition: subbuild(node.condition),

-                       buildBody: subbuild(node.body),

-                       buildUpdate: subbuildSequence(node.updaters),

-                       loopVariables: loopVariables);

-  }

-

-  @override

-  visitWhileStatement(WhileStatement node) {

-    // TODO(johnniwinther): Support `while` as a jump target.

-    irBuilder.buildWhile(buildCondition: subbuild(node.condition),

-                         buildBody: subbuild(node.body));

-  }

-

-  @override

-  visitDeclaredIdentifier(DeclaredIdentifier node) {

-    giveUp(node, "Unexpected node: DeclaredIdentifier");

-  }

-

-  @override

-  visitForEachStatement(ForEachStatement node) {

-    SubbuildFunction buildVariableDeclaration;

-    dart2js.Element variableElement;

-    Selector variableSelector;

-    if (node.identifier != null) {

-       AccessSemantics accessSemantics =

-           node.identifier.accept(ACCESS_SEMANTICS_VISITOR);

-       if (accessSemantics.kind == AccessKind.DYNAMIC) {

-         variableSelector = new Selector.setter(

-             node.identifier.name, converter.convertElement(currentLibrary));

-       } else if (accessSemantics.element != null) {

-         variableElement = converter.convertElement(accessSemantics.element);

-         variableSelector = new Selector.setter(

-             variableElement.name,

-             converter.convertElement(accessSemantics.element.library));

-       } else {

-         giveUp(node, 'For-in of unresolved variable: $accessSemantics');

-       }

-    } else {

-      assert(invariant(

-          node, node.loopVariable != null, "Loop variable expected"));

-      variableElement = converter.convertElement(node.loopVariable.element);

-      buildVariableDeclaration = (IrBuilder builder) {

-        builder.declareLocalVariable(variableElement);

-      };

-    }

-    // TODO(johnniwinther): Support `for-in` as a jump target.

-    irBuilder.buildForIn(

-        buildExpression: subbuild(node.iterable),

-        buildVariableDeclaration: buildVariableDeclaration,

-        variableElement: variableElement,

-        variableSelector: variableSelector,

-        buildBody: subbuild(node.body));

-  }

-  @override

-  ir.Primitive visitIsExpression(IsExpression node) {

-    return irBuilder.buildTypeOperator(

-        visit(node.expression),

-        converter.convertType(node.type.type),

-        isTypeTest: true,

-        isNotCheck: node.notOperator != null);

-  }

-

-  @override

-  ir.Primitive visitAsExpression(AsExpression node) {

-    return irBuilder.buildTypeOperator(

-        visit(node.expression),

-        converter.convertType(node.type.type),

-        isTypeTest: false);

-  }

-

-  @override

-  visitTryStatement(TryStatement node) {

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

-    for (CatchClause catchClause in node.catchClauses) {

-      catchClauseInfos.add(new CatchClauseInfo(

-          exceptionVariable: converter.convertElement(

-              catchClause.exceptionParameter.staticElement),

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

-

-    }

-    irBuilder.buildTry(

-        tryStatementInfo: new TryStatementInfo(),

-        buildTryBlock: subbuild(node.body),

-        catchClauseInfos: catchClauseInfos);

-  }

-}

+// 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 analyzer2dart.cps_generator;
+
+import 'package:analyzer/analyzer.dart';
+
+import 'package:compiler/src/dart_types.dart' as dart2js;
+import 'package:compiler/src/elements/elements.dart' as dart2js;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/element.dart' as analyzer;
+
+import 'package:compiler/src/constant_system_dart.dart'
+    show DART_CONSTANT_SYSTEM;
+import 'package:compiler/src/cps_ir/cps_ir_nodes.dart' as ir;
+import 'package:compiler/src/cps_ir/cps_ir_builder.dart';
+import 'package:compiler/src/universe/universe.dart';
+
+import 'semantic_visitor.dart';
+import 'element_converter.dart';
+import 'util.dart';
+import 'identifier_semantics.dart';
+
+/// Visitor that converts the AST node of an analyzer element into a CPS ir
+/// node.
+class CpsElementVisitor extends analyzer.SimpleElementVisitor<ir.Node> {
+  final ElementConverter converter;
+  final AstNode node;
+
+  CpsElementVisitor(this.converter, this.node);
+
+  @override
+  ir.FunctionDefinition visitFunctionElement(analyzer.FunctionElement element) {
+    CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
+    FunctionDeclaration functionDeclaration = node;
+    return visitor.handleFunctionDeclaration(
+        element, functionDeclaration.functionExpression.body);
+  }
+
+  @override
+  ir.FunctionDefinition visitMethodElement(analyzer.MethodElement element) {
+    CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
+    MethodDeclaration methodDeclaration = node;
+    return visitor.handleFunctionDeclaration(element, methodDeclaration.body);
+  }
+
+  @override
+  ir.FieldDefinition visitTopLevelVariableElement(
+      analyzer.TopLevelVariableElement element) {
+    CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
+    VariableDeclaration variableDeclaration = node;
+    return visitor.handleFieldDeclaration(element, variableDeclaration);
+  }
+
+  @override
+  ir.RootNode visitConstructorElement(analyzer.ConstructorElement element) {
+    CpsGeneratingVisitor visitor = new CpsGeneratingVisitor(converter, element);
+    if (!element.isFactory) {
+      ConstructorDeclaration constructorDeclaration = node;
+      FunctionBody body;
+      if (constructorDeclaration != null) {
+        body = constructorDeclaration.body;
+      } else {
+        assert(element.isSynthetic);
+      }
+      return visitor.handleConstructorDeclaration(element, body);
+    }
+    // TODO(johnniwinther): Support factory constructors.
+    return null;
+  }
+}
+
+/// Visitor that converts analyzer AST nodes into CPS ir nodes.
+class CpsGeneratingVisitor extends SemanticVisitor<ir.Node>
+    with IrBuilderMixin<AstNode> {
+  /// Promote the type of [irBuilder] to [DartIrBuilder].
+  /// The JS backend requires closure conversion which we do not support yet.
+  DartIrBuilder get irBuilder => super.irBuilder;
+  final analyzer.Element element;
+  final ElementConverter converter;
+
+  CpsGeneratingVisitor(this.converter, this.element);
+
+  Source get currentSource => element.source;
+
+  analyzer.LibraryElement get currentLibrary => element.library;
+
+  ir.Node visit(AstNode node) => node.accept(this);
+
+  ir.ConstructorDefinition handleConstructorDeclaration(
+      analyzer.ConstructorElement constructor, FunctionBody body) {
+    dart2js.ConstructorElement element = converter.convertElement(constructor);
+    return withBuilder(
+        new DartIrBuilder(DART_CONSTANT_SYSTEM,
+                          element,
+                          // TODO(johnniwinther): Support closure variables.
+                          new Set<dart2js.Local>()),
+        () {
+      irBuilder.buildFunctionHeader(
+          constructor.parameters.map(converter.convertElement));
+      // Visit the body directly to avoid processing the signature as
+      // expressions.
+      // Call to allow for `body == null` in case of synthesized constructors.
+      build(body);
+      return irBuilder.makeConstructorDefinition(const [], const []);
+    });
+  }
+
+  ir.FieldDefinition handleFieldDeclaration(
+      analyzer.PropertyInducingElement field, VariableDeclaration node) {
+    dart2js.FieldElement element = converter.convertElement(field);
+    return withBuilder(
+        new DartIrBuilder(DART_CONSTANT_SYSTEM,
+                          element,
+                          // TODO(johnniwinther): Support closure variables.
+                          new Set<dart2js.Local>()),
+        () {
+      irBuilder.buildFieldInitializerHeader();
+      ir.Primitive initializer = build(node.initializer);
+      return irBuilder.makeFieldDefinition(initializer);
+    });
+  }
+
+  ir.FunctionDefinition handleFunctionDeclaration(
+      analyzer.ExecutableElement function, FunctionBody body) {
+    dart2js.FunctionElement element = converter.convertElement(function);
+    return withBuilder(
+        new DartIrBuilder(DART_CONSTANT_SYSTEM,
+                          element,
+                          // TODO(johnniwinther): Support closure variables.
+                          new Set<dart2js.Local>()),
+        () {
+      irBuilder.buildFunctionHeader(
+          function.parameters.map(converter.convertElement));
+      // Visit the body directly to avoid processing the signature as
+      // expressions.
+      visit(body);
+      return irBuilder.makeFunctionDefinition(const []);
+    });
+  }
+
+  @override
+  ir.Primitive visitFunctionExpression(FunctionExpression node) {
+    return irBuilder.buildFunctionExpression(
+        handleFunctionDeclaration(node.element, node.body));
+  }
+
+  @override
+  ir.FunctionDefinition visitFunctionDeclaration(FunctionDeclaration node) {
+    return handleFunctionDeclaration(
+        node.element, node.functionExpression.body);
+  }
+
+  @override
+  visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
+    FunctionDeclaration functionDeclaration = node.functionDeclaration;
+    analyzer.FunctionElement function = functionDeclaration.element;
+    dart2js.FunctionElement element = converter.convertElement(function);
+    ir.FunctionDefinition definition = handleFunctionDeclaration(
+        function, functionDeclaration.functionExpression.body);
+    irBuilder.declareLocalFunction(element, definition);
+  }
+
+  List<ir.Primitive> visitArguments(ArgumentList argumentList) {
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    for (Expression argument in argumentList.arguments) {
+      ir.Primitive value = build(argument);
+      if (value == null) {
+        giveUp(argument,
+            'Unsupported argument: $argument (${argument.runtimeType}).');
+      }
+      arguments.add(value);
+    }
+    return arguments;
+  }
+
+  @override
+  ir.Node visitMethodInvocation(MethodInvocation node) {
+    // Overridden to avoid eager visits of the receiver and arguments.
+    return handleMethodInvocation(node);
+  }
+
+  @override
+  ir.Primitive visitDynamicInvocation(MethodInvocation node,
+                                      AccessSemantics semantics) {
+    // TODO(johnniwinther): Handle implicit `this`.
+    ir.Primitive receiver = build(semantics.target);
+    List<ir.Primitive> arguments = visitArguments(node.argumentList);
+    return irBuilder.buildDynamicInvocation(
+        receiver,
+        createSelectorFromMethodInvocation(
+            node.argumentList, node.methodName.name),
+        arguments);
+  }
+
+  @override
+  ir.Primitive visitStaticMethodInvocation(MethodInvocation node,
+                                           AccessSemantics semantics) {
+    analyzer.Element staticElement = semantics.element;
+    dart2js.Element element = converter.convertElement(staticElement);
+    List<ir.Primitive> arguments = visitArguments(node.argumentList);
+    return irBuilder.buildStaticFunctionInvocation(
+        element,
+        createCallStructureFromMethodInvocation(node.argumentList),
+        arguments);
+  }
+
+  @override
+  ir.Node visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
+    return handleLocalAccess(node, semantics);
+  }
+
+  ir.Primitive handleLocalInvocation(MethodInvocation node,
+                                     AccessSemantics semantics) {
+    analyzer.Element staticElement = semantics.element;
+    dart2js.Element element = converter.convertElement(staticElement);
+    List<ir.Definition> arguments = visitArguments(node.argumentList);
+    CallStructure callStructure = createCallStructureFromMethodInvocation(
+        node.argumentList);
+    if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
+      return irBuilder.buildLocalFunctionInvocation(
+          element, callStructure, arguments);
+    } else {
+      return irBuilder.buildLocalVariableInvocation(
+        element, callStructure, arguments);
+    }
+  }
+
+  @override
+  ir.Node visitLocalVariableInvocation(MethodInvocation node,
+                                       AccessSemantics semantics) {
+    return handleLocalInvocation(node, semantics);
+  }
+
+  @override
+  ir.Primitive visitLocalFunctionInvocation(MethodInvocation node,
+                                            AccessSemantics semantics) {
+    return handleLocalInvocation(node, semantics);
+  }
+
+  @override
+  ir.Primitive visitFunctionExpressionInvocation(
+      FunctionExpressionInvocation node) {
+    ir.Primitive target = build(node.function);
+    List<ir.Definition> arguments = visitArguments(node.argumentList);
+    return irBuilder.buildCallInvocation(
+        target,
+        createCallStructureFromMethodInvocation(node.argumentList),
+        arguments);
+  }
+
+  @override
+  ir.Primitive visitInstanceCreationExpression(
+      InstanceCreationExpression node) {
+    analyzer.Element staticElement = node.staticElement;
+    if (staticElement != null) {
+      dart2js.Element element = converter.convertElement(staticElement);
+      dart2js.DartType type = converter.convertType(node.staticType);
+      List<ir.Primitive> arguments = visitArguments(node.argumentList);
+      return irBuilder.buildConstructorInvocation(
+          element,
+          createCallStructureFromMethodInvocation(node.argumentList),
+          type,
+          arguments);
+    }
+    return giveUp(node, "Unresolved constructor invocation.");
+  }
+
+  @override
+  ir.Constant visitNullLiteral(NullLiteral node) {
+    return irBuilder.buildNullConstant();
+  }
+
+  @override
+  ir.Constant visitBooleanLiteral(BooleanLiteral node) {
+    return irBuilder.buildBooleanConstant(node.value);
+  }
+
+  @override
+  ir.Constant visitDoubleLiteral(DoubleLiteral node) {
+    return irBuilder.buildDoubleConstant(node.value);
+  }
+
+  @override
+  ir.Constant visitIntegerLiteral(IntegerLiteral node) {
+    return irBuilder.buildIntegerConstant(node.value);
+  }
+
+  @override
+  visitAdjacentStrings(AdjacentStrings node) {
+    String value = node.stringValue;
+    if (value != null) {
+      return irBuilder.buildStringConstant(value);
+    }
+    giveUp(node, "Non constant adjacent strings.");
+  }
+
+  @override
+  ir.Constant visitSimpleStringLiteral(SimpleStringLiteral node) {
+    return irBuilder.buildStringConstant(node.value);
+  }
+
+  @override
+  visitStringInterpolation(StringInterpolation node) {
+    giveUp(node, "String interpolation.");
+  }
+
+  @override
+  visitReturnStatement(ReturnStatement node) {
+    irBuilder.buildReturn(build(node.expression));
+  }
+
+  @override
+  ir.Node visitPropertyAccess(PropertyAccess node) {
+    // Overridden to avoid eager visits of the receiver.
+    return handlePropertyAccess(node);
+  }
+
+  @override
+  ir.Node visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
+    return handleLocalAccess(node, semantics);
+  }
+
+  @override
+  ir.Node visitParameterAccess(AstNode node, AccessSemantics semantics) {
+    return handleLocalAccess(node, semantics);
+  }
+
+  @override
+  visitVariableDeclaration(VariableDeclaration node) {
+    // TODO(johnniwinther): Handle constant local variables.
+    ir.Node initialValue = build(node.initializer);
+    irBuilder.declareLocalVariable(
+        converter.convertElement(node.element),
+        initialValue: initialValue);
+  }
+
+  dart2js.Element getLocal(AstNode node, AccessSemantics semantics) {
+    analyzer.Element element = semantics.element;
+    dart2js.Element target = converter.convertElement(element);
+    assert(invariant(node, target.isLocal, '$target expected to be local.'));
+    return target;
+  }
+
+  ir.Primitive handleLocalAccess(AstNode node, AccessSemantics semantics) {
+    dart2js.Element local = getLocal(node, semantics);
+    if (semantics.kind == AccessKind.LOCAL_FUNCTION) {
+      return irBuilder.buildLocalFunctionGet(local);
+    } else {
+      return irBuilder.buildLocalVariableGet(local);
+    }
+  }
+
+  ir.Primitive handleLocalAssignment(AssignmentExpression node,
+                                     AccessSemantics semantics) {
+    if (node.operator.lexeme != '=') {
+      return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
+    }
+    return irBuilder.buildLocalVariableSet(
+        getLocal(node, semantics),
+        build(node.rightHandSide));
+  }
+
+  @override
+  ir.Node visitAssignmentExpression(AssignmentExpression node) {
+    // Avoid eager visiting of left and right hand side.
+    return handleAssignmentExpression(node);
+  }
+
+  @override
+  ir.Node visitLocalVariableAssignment(AssignmentExpression node,
+                                       AccessSemantics semantics) {
+    return handleLocalAssignment(node, semantics);
+  }
+
+  @override
+  ir.Node visitParameterAssignment(AssignmentExpression node,
+                                   AccessSemantics semantics) {
+    return handleLocalAssignment(node, semantics);
+  }
+
+  @override
+  ir.Node visitStaticFieldAssignment(AssignmentExpression node,
+                                     AccessSemantics semantics) {
+    if (node.operator.lexeme != '=') {
+      return giveUp(node, 'Assignment operator: ${node.operator.lexeme}');
+    }
+    analyzer.Element element = semantics.element;
+    dart2js.Element target = converter.convertElement(element);
+    // TODO(johnniwinther): Selector information should be computed in the
+    // [TreeShaker] and shared with the [CpsGeneratingVisitor].
+    assert(invariant(node, target.isTopLevel || target.isStatic,
+                     '$target expected to be top-level or static.'));
+    return irBuilder.buildStaticFieldSet(target, build(node.rightHandSide));
+  }
+
+  @override
+  ir.Node visitDynamicAccess(AstNode node, AccessSemantics semantics) {
+    // TODO(johnniwinther): Handle implicit `this`.
+    ir.Primitive receiver = build(semantics.target);
+    return irBuilder.buildDynamicGet(receiver,
+        new Selector.getter(semantics.identifier.name,
+                            converter.convertElement(element.library)));
+  }
+
+  @override
+  ir.Node visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
+    analyzer.Element element = semantics.element;
+    dart2js.Element target = converter.convertElement(element);
+    // TODO(johnniwinther): Selector information should be computed in the
+    // [TreeShaker] and shared with the [CpsGeneratingVisitor].
+    assert(invariant(node, target.isTopLevel || target.isStatic,
+                     '$target expected to be top-level or static.'));
+    return irBuilder.buildStaticFieldLazyGet(target, null);
+  }
+
+  ir.Primitive handleBinaryExpression(BinaryExpression node,
+                                      String op) {
+    ir.Primitive left = build(node.leftOperand);
+    ir.Primitive right = build(node.rightOperand);
+    Selector selector = new Selector.binaryOperator(op);
+    return irBuilder.buildDynamicInvocation(
+        left, selector, <ir.Primitive>[right]);
+  }
+
+  ir.Node handleLazyOperator(BinaryExpression node, {bool isLazyOr: false}) {
+    return irBuilder.buildLogicalOperator(
+        build(node.leftOperand),
+        subbuild(node.rightOperand),
+        isLazyOr: isLazyOr);
+  }
+
+  @override
+  ir.Node visitBinaryExpression(BinaryExpression node) {
+    // TODO(johnniwinther,paulberry,brianwilkerson): The operator should be
+    // available through an enum.
+    String op = node.operator.lexeme;
+    switch (op) {
+    case '||':
+    case '&&':
+      return handleLazyOperator(node, isLazyOr: op == '||');
+    case '!=':
+      return irBuilder.buildNegation(handleBinaryExpression(node, '=='));
+    default:
+      return handleBinaryExpression(node, op);
+    }
+  }
+
+  @override
+  ir.Node visitConditionalExpression(ConditionalExpression node) {
+    return irBuilder.buildConditional(
+        build(node.condition),
+        subbuild(node.thenExpression),
+        subbuild(node.elseExpression));
+  }
+
+  @override
+  visitIfStatement(IfStatement node) {
+    irBuilder.buildIf(
+        build(node.condition),
+        subbuild(node.thenStatement),
+        subbuild(node.elseStatement));
+  }
+
+  @override
+  visitBlock(Block node) {
+    irBuilder.buildBlock(node.statements, build);
+  }
+
+  @override
+  ir.Node visitListLiteral(ListLiteral node) {
+    dart2js.InterfaceType type = converter.convertType(node.staticType);
+    // TODO(johnniwinther): Use `build` instead of `(e) => build(e)` when issue
+    // 18630 has been resolved.
+    Iterable<ir.Primitive> values = node.elements.map((e) => build(e));
+    return irBuilder.buildListLiteral(type, values);
+  }
+
+  @override
+  ir.Node visitMapLiteral(MapLiteral node) {
+    dart2js.InterfaceType type = converter.convertType(node.staticType);
+    return irBuilder.buildMapLiteral(
+        type,
+        node.entries.map((e) => e.key),
+        node.entries.map((e) => e.value),
+        build);
+  }
+
+  @override
+  visitForStatement(ForStatement node) {
+    // TODO(johnniwinther): Support `for` as a jump target.
+    List<dart2js.LocalElement> loopVariables = <dart2js.LocalElement>[];
+    SubbuildFunction buildInitializer;
+    if (node.variables != null) {
+      buildInitializer = subbuild(node.variables);
+      for (VariableDeclaration variable in node.variables.variables) {
+        loopVariables.add(converter.convertElement(variable.element));
+      }
+    } else {
+      buildInitializer = subbuild(node.initialization);
+    }
+    irBuilder.buildFor(buildInitializer: buildInitializer,
+                       buildCondition: subbuild(node.condition),
+                       buildBody: subbuild(node.body),
+                       buildUpdate: subbuildSequence(node.updaters),
+                       loopVariables: loopVariables);
+  }
+
+  @override
+  visitWhileStatement(WhileStatement node) {
+    // TODO(johnniwinther): Support `while` as a jump target.
+    irBuilder.buildWhile(buildCondition: subbuild(node.condition),
+                         buildBody: subbuild(node.body));
+  }
+
+  @override
+  visitDeclaredIdentifier(DeclaredIdentifier node) {
+    giveUp(node, "Unexpected node: DeclaredIdentifier");
+  }
+
+  @override
+  visitForEachStatement(ForEachStatement node) {
+    SubbuildFunction buildVariableDeclaration;
+    dart2js.Element variableElement;
+    Selector variableSelector;
+    if (node.identifier != null) {
+       AccessSemantics accessSemantics =
+           node.identifier.accept(ACCESS_SEMANTICS_VISITOR);
+       if (accessSemantics.kind == AccessKind.DYNAMIC) {
+         variableSelector = new Selector.setter(
+             node.identifier.name, converter.convertElement(currentLibrary));
+       } else if (accessSemantics.element != null) {
+         variableElement = converter.convertElement(accessSemantics.element);
+         variableSelector = new Selector.setter(
+             variableElement.name,
+             converter.convertElement(accessSemantics.element.library));
+       } else {
+         giveUp(node, 'For-in of unresolved variable: $accessSemantics');
+       }
+    } else {
+      assert(invariant(
+          node, node.loopVariable != null, "Loop variable expected"));
+      variableElement = converter.convertElement(node.loopVariable.element);
+      buildVariableDeclaration = (IrBuilder builder) {
+        builder.declareLocalVariable(variableElement);
+      };
+    }
+    // TODO(johnniwinther): Support `for-in` as a jump target.
+    irBuilder.buildForIn(
+        buildExpression: subbuild(node.iterable),
+        buildVariableDeclaration: buildVariableDeclaration,
+        variableElement: variableElement,
+        variableSelector: variableSelector,
+        buildBody: subbuild(node.body));
+  }
+  @override
+  ir.Primitive visitIsExpression(IsExpression node) {
+    return irBuilder.buildTypeOperator(
+        visit(node.expression),
+        converter.convertType(node.type.type),
+        isTypeTest: true,
+        isNotCheck: node.notOperator != null);
+  }
+
+  @override
+  ir.Primitive visitAsExpression(AsExpression node) {
+    return irBuilder.buildTypeOperator(
+        visit(node.expression),
+        converter.convertType(node.type.type),
+        isTypeTest: false);
+  }
+
+  @override
+  visitTryStatement(TryStatement node) {
+    List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
+    for (CatchClause catchClause in node.catchClauses) {
+      catchClauseInfos.add(new CatchClauseInfo(
+          exceptionVariable: converter.convertElement(
+              catchClause.exceptionParameter.staticElement),
+          buildCatchBlock: subbuild(catchClause.body)));
+
+    }
+    irBuilder.buildTry(
+        tryStatementInfo: new TryStatementInfo(),
+        buildTryBlock: subbuild(node.body),
+        catchClauseInfos: catchClauseInfos);
+  }
+}
diff --git a/pkg/analyzer2dart/lib/src/semantic_visitor.dart b/pkg/analyzer2dart/lib/src/semantic_visitor.dart
index 2e1c170..b5edd6a 100644
--- a/pkg/analyzer2dart/lib/src/semantic_visitor.dart
+++ b/pkg/analyzer2dart/lib/src/semantic_visitor.dart
@@ -1,271 +1,271 @@
-// 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 analyzer2dart.semantic_visitor;

-

-import 'package:analyzer/analyzer.dart';

-import 'package:analyzer/src/generated/source.dart';

-

-import 'util.dart';

-import 'identifier_semantics.dart';

-

-/// An AST visitor which uses the [AccessSemantics] of invocations and accesses

-/// to fine-grain visitor methods.

-abstract class SemanticVisitor<R> extends RecursiveAstVisitor<R> {

-

-  Source get currentSource;

-

-  void reportMessage(AstNode node, String message) {

-    reportSourceMessage(currentSource, node, message);

-  }

-

-  giveUp(AstNode node, String message) {

-    reportMessage(node, message);

-    throw new UnimplementedError(message);

-  }

-

-  bool invariant(AstNode node, condition, String message) {

-    if (condition is Function) {

-      condition = condition();

-    }

-    if (!condition) {

-      reportMessage(node, message);

-      return false;

-    }

-    return true;

-  }

-

-  R visitDynamicInvocation(MethodInvocation node,

-                           AccessSemantics semantics) {

-    return giveUp(node, 'visitDynamicInvocation of $semantics');

-  }

-

-  R visitLocalFunctionInvocation(MethodInvocation node,

-                                 AccessSemantics semantics) {

-    return giveUp(node, 'visitLocalFunctionInvocation of $semantics');

-  }

-

-  R visitLocalVariableInvocation(MethodInvocation node,

-                                 AccessSemantics semantics) {

-    return giveUp(node, 'visitLocalVariableInvocation of $semantics');

-  }

-

-  R visitParameterInvocation(MethodInvocation node,

-                             AccessSemantics semantics) {

-    return giveUp(node, 'visitParameterInvocation of $semantics');

-  }

-

-  R visitStaticFieldInvocation(MethodInvocation node,

-                               AccessSemantics semantics) {

-    return giveUp(node, 'visitStaticFieldInvocation of $semantics');

-  }

-

-  R visitStaticMethodInvocation(MethodInvocation node,

-                                AccessSemantics semantics) {

-    return giveUp(node, 'visitStaticMethodInvocation of $semantics');

-  }

-

-  R visitStaticPropertyInvocation(MethodInvocation node,

-                                  AccessSemantics semantics) {

-    return giveUp(node, 'visitStaticPropertyInvocation of $semantics');

-  }

-

-  @override

-  R visitMethodInvocation(MethodInvocation node) {

-    if (node.target != null) {

-      node.target.accept(this);

-    }

-    node.argumentList.accept(this);

-    return handleMethodInvocation(node);

-  }

-

-  R handleMethodInvocation(MethodInvocation node) {

-    AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);

-    switch (semantics.kind) {

-      case AccessKind.DYNAMIC:

-        return visitDynamicInvocation(node, semantics);

-      case AccessKind.LOCAL_FUNCTION:

-        return visitLocalFunctionInvocation(node, semantics);

-      case AccessKind.LOCAL_VARIABLE:

-        return visitLocalVariableInvocation(node, semantics);

-      case AccessKind.PARAMETER:

-        return visitParameterInvocation(node, semantics);

-      case AccessKind.STATIC_FIELD:

-        return visitStaticFieldInvocation(node, semantics);

-      case AccessKind.STATIC_METHOD:

-        return visitStaticMethodInvocation(node, semantics);

-      case AccessKind.STATIC_PROPERTY:

-        return visitStaticPropertyInvocation(node, semantics);

-      default:

-        // Unexpected access kind.

-        return giveUp(node,

-            'Unexpected ${semantics} in visitMethodInvocation.');

-    }

-  }

-

-  @override

-  R visitPropertyAccess(PropertyAccess node) {

-    if (node.target != null) {

-      node.target.accept(this);

-    }

-    return handlePropertyAccess(node);

-  }

-

-  R handlePropertyAccess(PropertyAccess node) {

-    return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));

-  }

-

-  @override

-  R visitPrefixedIdentifier(PrefixedIdentifier node) {

-    node.prefix.accept(this);

-    return handlePrefixedIdentifier(node);

-  }

-

-  R handlePrefixedIdentifier(PrefixedIdentifier node) {

-    return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));

-  }

-

-  @override

-  R visitSimpleIdentifier(SimpleIdentifier node) {

-    AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);

-    if (semantics != null) {

-      return _handlePropertyAccess(node, semantics);

-    } else {

-      return null;

-    }

-  }

-

-  R visitDynamicAccess(AstNode node, AccessSemantics semantics) {

-    return giveUp(node, 'visitDynamicAccess of $semantics');

-  }

-

-  R visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {

-    return giveUp(node, 'visitLocalFunctionAccess of $semantics');

-  }

-

-  R visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {

-    return giveUp(node, 'visitLocalVariableAccess of $semantics');

-  }

-

-  R visitParameterAccess(AstNode node, AccessSemantics semantics) {

-    return giveUp(node, 'visitParameterAccess of $semantics');

-  }

-

-  R visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {

-    return giveUp(node, 'visitStaticFieldAccess of $semantics');

-  }

-

-  R visitStaticMethodAccess(AstNode node, AccessSemantics semantics) {

-    return giveUp(node, 'visitStaticMethodAccess of $semantics');

-  }

-

-  R visitStaticPropertyAccess(AstNode node, AccessSemantics semantics) {

-    return giveUp(node, 'visitStaticPropertyAccess of $semantics');

-  }

-

-  R visitToplevelClassAccess(AstNode node, AccessSemantics semantics) {

-    return giveUp(node, 'visitToplevelClassAccess of $semantics');

-  }

-

-  R visitTypeParameterAccess(AstNode node, AccessSemantics semantics) {

-    return giveUp(node, 'visitTypeParameterAccess of $semantics');

-  }

-

-  R _handlePropertyAccess(AstNode node, AccessSemantics semantics) {

-    switch (semantics.kind) {

-      case AccessKind.DYNAMIC:

-        return visitDynamicAccess(node, semantics);

-      case AccessKind.LOCAL_FUNCTION:

-        return visitLocalFunctionAccess(node, semantics);

-      case AccessKind.LOCAL_VARIABLE:

-        return visitLocalVariableAccess(node, semantics);

-      case AccessKind.PARAMETER:

-        return visitParameterAccess(node, semantics);

-      case AccessKind.STATIC_FIELD:

-        return visitStaticFieldAccess(node, semantics);

-      case AccessKind.STATIC_METHOD:

-        return visitStaticMethodAccess(node, semantics);

-      case AccessKind.STATIC_PROPERTY:

-        return visitStaticPropertyAccess(node, semantics);

-      case AccessKind.TOPLEVEL_TYPE:

-        return visitToplevelClassAccess(node, semantics);

-      case AccessKind.TYPE_PARAMETER:

-        return visitTypeParameterAccess(node, semantics);

-      default:

-        // Unexpected access kind.

-        return giveUp(node,

-            'Unexpected ${semantics} in _handlePropertyAccess.');

-    }

-  }

-

-  R visitDynamicPropertyAssignment(AssignmentExpression node,

-                                   AccessSemantics semantics) {

-    return giveUp(node, 'visitDynamicPropertyAssignment of $semantics');

-  }

-

-  R visitLocalFunctionAssignment(AssignmentExpression node,

-                                 AccessSemantics semantics) {

-    return giveUp(node, 'visitLocalFunctionAssignment of $semantics');

-  }

-

-  R visitLocalVariableAssignment(AssignmentExpression node,

-                                 AccessSemantics semantics) {

-    return giveUp(node, 'visitLocalVariableAssignment of $semantics');

-  }

-

-  R visitParameterAssignment(AssignmentExpression node,

-                             AccessSemantics semantics) {

-    return giveUp(node, 'visitParameterAssignment of $semantics');

-  }

-

-  R visitStaticFieldAssignment(AssignmentExpression node,

-                               AccessSemantics semantics) {

-    return giveUp(node, 'visitStaticFieldAssignment of $semantics');

-  }

-

-  R visitStaticMethodAssignment(AssignmentExpression node,

-                                AccessSemantics semantics) {

-    return giveUp(node, 'visitStaticMethodAssignment of $semantics');

-  }

-

-  R visitStaticPropertyAssignment(AssignmentExpression node,

-                                  AccessSemantics semantics) {

-    return giveUp(node, 'visitStaticPropertyAssignment of $semantics');

-  }

-

-  @override

-  R visitAssignmentExpression(AssignmentExpression node) {

-    super.visitAssignmentExpression(node);

-    return handleAssignmentExpression(node);

-  }

-

-  R handleAssignmentExpression(AssignmentExpression node) {

-    AccessSemantics semantics =

-        node.leftHandSide.accept(ACCESS_SEMANTICS_VISITOR);

-    if (semantics == null) {

-      return giveUp(node, 'handleAssignmentExpression with no AccessSemantics');

-    } else {

-      switch (semantics.kind) {

-        case AccessKind.DYNAMIC:

-          return visitDynamicPropertyAssignment(node, semantics);

-        case AccessKind.LOCAL_FUNCTION:

-          return visitLocalFunctionAssignment(node, semantics);

-        case AccessKind.LOCAL_VARIABLE:

-          return visitLocalVariableAssignment(node, semantics);

-        case AccessKind.PARAMETER:

-          return visitParameterAssignment(node, semantics);

-        case AccessKind.STATIC_FIELD:

-          return visitStaticFieldAssignment(node, semantics);

-        case AccessKind.STATIC_METHOD:

-          return visitStaticMethodAssignment(node, semantics);

-        case AccessKind.STATIC_PROPERTY:

-          return visitStaticPropertyAssignment(node, semantics);

-        default:

-          // Unexpected access kind.

-          return giveUp(node,

-              'Unexpected ${semantics} in _handlePropertyAccess.');

-      }

-    }

-  }

-}

+// 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 analyzer2dart.semantic_visitor;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+import 'util.dart';
+import 'identifier_semantics.dart';
+
+/// An AST visitor which uses the [AccessSemantics] of invocations and accesses
+/// to fine-grain visitor methods.
+abstract class SemanticVisitor<R> extends RecursiveAstVisitor<R> {
+
+  Source get currentSource;
+
+  void reportMessage(AstNode node, String message) {
+    reportSourceMessage(currentSource, node, message);
+  }
+
+  giveUp(AstNode node, String message) {
+    reportMessage(node, message);
+    throw new UnimplementedError(message);
+  }
+
+  bool invariant(AstNode node, condition, String message) {
+    if (condition is Function) {
+      condition = condition();
+    }
+    if (!condition) {
+      reportMessage(node, message);
+      return false;
+    }
+    return true;
+  }
+
+  R visitDynamicInvocation(MethodInvocation node,
+                           AccessSemantics semantics) {
+    return giveUp(node, 'visitDynamicInvocation of $semantics');
+  }
+
+  R visitLocalFunctionInvocation(MethodInvocation node,
+                                 AccessSemantics semantics) {
+    return giveUp(node, 'visitLocalFunctionInvocation of $semantics');
+  }
+
+  R visitLocalVariableInvocation(MethodInvocation node,
+                                 AccessSemantics semantics) {
+    return giveUp(node, 'visitLocalVariableInvocation of $semantics');
+  }
+
+  R visitParameterInvocation(MethodInvocation node,
+                             AccessSemantics semantics) {
+    return giveUp(node, 'visitParameterInvocation of $semantics');
+  }
+
+  R visitStaticFieldInvocation(MethodInvocation node,
+                               AccessSemantics semantics) {
+    return giveUp(node, 'visitStaticFieldInvocation of $semantics');
+  }
+
+  R visitStaticMethodInvocation(MethodInvocation node,
+                                AccessSemantics semantics) {
+    return giveUp(node, 'visitStaticMethodInvocation of $semantics');
+  }
+
+  R visitStaticPropertyInvocation(MethodInvocation node,
+                                  AccessSemantics semantics) {
+    return giveUp(node, 'visitStaticPropertyInvocation of $semantics');
+  }
+
+  @override
+  R visitMethodInvocation(MethodInvocation node) {
+    if (node.target != null) {
+      node.target.accept(this);
+    }
+    node.argumentList.accept(this);
+    return handleMethodInvocation(node);
+  }
+
+  R handleMethodInvocation(MethodInvocation node) {
+    AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC:
+        return visitDynamicInvocation(node, semantics);
+      case AccessKind.LOCAL_FUNCTION:
+        return visitLocalFunctionInvocation(node, semantics);
+      case AccessKind.LOCAL_VARIABLE:
+        return visitLocalVariableInvocation(node, semantics);
+      case AccessKind.PARAMETER:
+        return visitParameterInvocation(node, semantics);
+      case AccessKind.STATIC_FIELD:
+        return visitStaticFieldInvocation(node, semantics);
+      case AccessKind.STATIC_METHOD:
+        return visitStaticMethodInvocation(node, semantics);
+      case AccessKind.STATIC_PROPERTY:
+        return visitStaticPropertyInvocation(node, semantics);
+      default:
+        // Unexpected access kind.
+        return giveUp(node,
+            'Unexpected ${semantics} in visitMethodInvocation.');
+    }
+  }
+
+  @override
+  R visitPropertyAccess(PropertyAccess node) {
+    if (node.target != null) {
+      node.target.accept(this);
+    }
+    return handlePropertyAccess(node);
+  }
+
+  R handlePropertyAccess(PropertyAccess node) {
+    return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
+  }
+
+  @override
+  R visitPrefixedIdentifier(PrefixedIdentifier node) {
+    node.prefix.accept(this);
+    return handlePrefixedIdentifier(node);
+  }
+
+  R handlePrefixedIdentifier(PrefixedIdentifier node) {
+    return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR));
+  }
+
+  @override
+  R visitSimpleIdentifier(SimpleIdentifier node) {
+    AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR);
+    if (semantics != null) {
+      return _handlePropertyAccess(node, semantics);
+    } else {
+      return null;
+    }
+  }
+
+  R visitDynamicAccess(AstNode node, AccessSemantics semantics) {
+    return giveUp(node, 'visitDynamicAccess of $semantics');
+  }
+
+  R visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) {
+    return giveUp(node, 'visitLocalFunctionAccess of $semantics');
+  }
+
+  R visitLocalVariableAccess(AstNode node, AccessSemantics semantics) {
+    return giveUp(node, 'visitLocalVariableAccess of $semantics');
+  }
+
+  R visitParameterAccess(AstNode node, AccessSemantics semantics) {
+    return giveUp(node, 'visitParameterAccess of $semantics');
+  }
+
+  R visitStaticFieldAccess(AstNode node, AccessSemantics semantics) {
+    return giveUp(node, 'visitStaticFieldAccess of $semantics');
+  }
+
+  R visitStaticMethodAccess(AstNode node, AccessSemantics semantics) {
+    return giveUp(node, 'visitStaticMethodAccess of $semantics');
+  }
+
+  R visitStaticPropertyAccess(AstNode node, AccessSemantics semantics) {
+    return giveUp(node, 'visitStaticPropertyAccess of $semantics');
+  }
+
+  R visitToplevelClassAccess(AstNode node, AccessSemantics semantics) {
+    return giveUp(node, 'visitToplevelClassAccess of $semantics');
+  }
+
+  R visitTypeParameterAccess(AstNode node, AccessSemantics semantics) {
+    return giveUp(node, 'visitTypeParameterAccess of $semantics');
+  }
+
+  R _handlePropertyAccess(AstNode node, AccessSemantics semantics) {
+    switch (semantics.kind) {
+      case AccessKind.DYNAMIC:
+        return visitDynamicAccess(node, semantics);
+      case AccessKind.LOCAL_FUNCTION:
+        return visitLocalFunctionAccess(node, semantics);
+      case AccessKind.LOCAL_VARIABLE:
+        return visitLocalVariableAccess(node, semantics);
+      case AccessKind.PARAMETER:
+        return visitParameterAccess(node, semantics);
+      case AccessKind.STATIC_FIELD:
+        return visitStaticFieldAccess(node, semantics);
+      case AccessKind.STATIC_METHOD:
+        return visitStaticMethodAccess(node, semantics);
+      case AccessKind.STATIC_PROPERTY:
+        return visitStaticPropertyAccess(node, semantics);
+      case AccessKind.TOPLEVEL_TYPE:
+        return visitToplevelClassAccess(node, semantics);
+      case AccessKind.TYPE_PARAMETER:
+        return visitTypeParameterAccess(node, semantics);
+      default:
+        // Unexpected access kind.
+        return giveUp(node,
+            'Unexpected ${semantics} in _handlePropertyAccess.');
+    }
+  }
+
+  R visitDynamicPropertyAssignment(AssignmentExpression node,
+                                   AccessSemantics semantics) {
+    return giveUp(node, 'visitDynamicPropertyAssignment of $semantics');
+  }
+
+  R visitLocalFunctionAssignment(AssignmentExpression node,
+                                 AccessSemantics semantics) {
+    return giveUp(node, 'visitLocalFunctionAssignment of $semantics');
+  }
+
+  R visitLocalVariableAssignment(AssignmentExpression node,
+                                 AccessSemantics semantics) {
+    return giveUp(node, 'visitLocalVariableAssignment of $semantics');
+  }
+
+  R visitParameterAssignment(AssignmentExpression node,
+                             AccessSemantics semantics) {
+    return giveUp(node, 'visitParameterAssignment of $semantics');
+  }
+
+  R visitStaticFieldAssignment(AssignmentExpression node,
+                               AccessSemantics semantics) {
+    return giveUp(node, 'visitStaticFieldAssignment of $semantics');
+  }
+
+  R visitStaticMethodAssignment(AssignmentExpression node,
+                                AccessSemantics semantics) {
+    return giveUp(node, 'visitStaticMethodAssignment of $semantics');
+  }
+
+  R visitStaticPropertyAssignment(AssignmentExpression node,
+                                  AccessSemantics semantics) {
+    return giveUp(node, 'visitStaticPropertyAssignment of $semantics');
+  }
+
+  @override
+  R visitAssignmentExpression(AssignmentExpression node) {
+    super.visitAssignmentExpression(node);
+    return handleAssignmentExpression(node);
+  }
+
+  R handleAssignmentExpression(AssignmentExpression node) {
+    AccessSemantics semantics =
+        node.leftHandSide.accept(ACCESS_SEMANTICS_VISITOR);
+    if (semantics == null) {
+      return giveUp(node, 'handleAssignmentExpression with no AccessSemantics');
+    } else {
+      switch (semantics.kind) {
+        case AccessKind.DYNAMIC:
+          return visitDynamicPropertyAssignment(node, semantics);
+        case AccessKind.LOCAL_FUNCTION:
+          return visitLocalFunctionAssignment(node, semantics);
+        case AccessKind.LOCAL_VARIABLE:
+          return visitLocalVariableAssignment(node, semantics);
+        case AccessKind.PARAMETER:
+          return visitParameterAssignment(node, semantics);
+        case AccessKind.STATIC_FIELD:
+          return visitStaticFieldAssignment(node, semantics);
+        case AccessKind.STATIC_METHOD:
+          return visitStaticMethodAssignment(node, semantics);
+        case AccessKind.STATIC_PROPERTY:
+          return visitStaticPropertyAssignment(node, semantics);
+        default:
+          // Unexpected access kind.
+          return giveUp(node,
+              'Unexpected ${semantics} in _handlePropertyAccess.');
+      }
+    }
+  }
+}
diff --git a/pkg/analyzer2dart/lib/src/util.dart b/pkg/analyzer2dart/lib/src/util.dart
index 67ee97e..fd1c20b 100644
--- a/pkg/analyzer2dart/lib/src/util.dart
+++ b/pkg/analyzer2dart/lib/src/util.dart
@@ -1,42 +1,42 @@
-// 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.

-

-// Utility function shared between different parts of analyzer2dart.

-

-library analyzer2dart.util;

-

-import 'package:analyzer/analyzer.dart';

-import 'package:analyzer/src/generated/source.dart';

-import 'package:compiler/src/elements/elements.dart' show PublicName;

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

-import 'package:compiler/src/io/source_file.dart';

-

-CallStructure createCallStructureFromMethodInvocation(ArgumentList node) {

-  int arity = 0;

-  List<String> namedArguments = <String>[];

-  for (Expression argument in node.arguments) {

-    if (argument is NamedExpression) {

-      namedArguments.add(argument.name.label.name);

-    } else {

-      arity++;

-    }

-  }

-  return new CallStructure(arity, namedArguments);

-}

-

-Selector createSelectorFromMethodInvocation(ArgumentList node,

-                                            String name) {

-  CallStructure callStructure = createCallStructureFromMethodInvocation(node);

-  // TODO(johnniwinther): Support private names.

-  return new Selector(SelectorKind.CALL, new PublicName(name), callStructure);

-}

-

-/// Prints [message] together with source code pointed to by [node] from

-/// [source].

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

-  SourceFile sourceFile =

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

-

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

-}

+// 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.
+
+// Utility function shared between different parts of analyzer2dart.
+
+library analyzer2dart.util;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:compiler/src/elements/elements.dart' show PublicName;
+import 'package:compiler/src/universe/universe.dart';
+import 'package:compiler/src/io/source_file.dart';
+
+CallStructure createCallStructureFromMethodInvocation(ArgumentList node) {
+  int arity = 0;
+  List<String> namedArguments = <String>[];
+  for (Expression argument in node.arguments) {
+    if (argument is NamedExpression) {
+      namedArguments.add(argument.name.label.name);
+    } else {
+      arity++;
+    }
+  }
+  return new CallStructure(arity, namedArguments);
+}
+
+Selector createSelectorFromMethodInvocation(ArgumentList node,
+                                            String name) {
+  CallStructure callStructure = createCallStructureFromMethodInvocation(node);
+  // TODO(johnniwinther): Support private names.
+  return new Selector(SelectorKind.CALL, new PublicName(name), callStructure);
+}
+
+/// Prints [message] together with source code pointed to by [node] from
+/// [source].
+void reportSourceMessage(Source source, AstNode node, String message) {
+  SourceFile sourceFile =
+      new StringSourceFile.fromName(source.fullName, source.contents.data);
+
+  print(sourceFile.getLocationMessage(message, node.offset, node.end));
+}
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index a36ee9a..a940dbf 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -11,8 +11,8 @@
 import 'dart2jslib.dart' as leg;
 import 'tree/tree.dart' as tree;
 import 'elements/elements.dart' as elements;
-import 'package:_internal/libraries.dart' hide LIBRARIES;
-import 'package:_internal/libraries.dart' as library_info show LIBRARIES;
+import 'package:sdk_library_metadata/libraries.dart' hide LIBRARIES;
+import 'package:sdk_library_metadata/libraries.dart' as library_info show LIBRARIES;
 import 'io/source_file.dart';
 import 'package:package_config/packages.dart';
 import 'package:package_config/packages_file.dart' as pkgs;
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index b0c7502..4b0be2d 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -779,7 +779,7 @@
       Node node,
       CallStructure callStructure,
       Link<Node> arguments,
-      FunctionElement target,
+      ConstructorElement target,
       {AstConstant compileArgument(Node node)}) {
     assert(invariant(node, target.isImplementation));
 
@@ -790,7 +790,8 @@
     }
     target.computeType(compiler);
 
-    if (!callStructure.signatureApplies(target)) {
+    FunctionSignature signature = target.functionSignature;
+    if (!callStructure.signatureApplies(signature)) {
       String name = Elements.constructorNameForDiagnostics(
           target.enclosingClass.name, target.name);
       compiler.reportError(
@@ -1028,8 +1029,10 @@
                    "effective target: $constructor"));
       return new ErroneousAstConstant(context, node);
     }
-    assert(invariant(node, callStructure.signatureApplies(constructor) ||
-                     compiler.compilationFailed,
+    assert(invariant(
+        node,
+        callStructure.signatureApplies(constructor.functionSignature) ||
+            compiler.compilationFailed,
         message: "Call structure $callStructure does not apply to constructor "
                  "$constructor."));
 
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 7e42649..88368dd 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -1196,7 +1196,7 @@
     } else if (node is Element) {
       return spanFromElement(node);
     } else if (node is MetadataAnnotation) {
-      Uri uri = node.annotatedElement.compilationUnit.script.readableUri;
+      Uri uri = node.annotatedElement.compilationUnit.script.resourceUri;
       return spanFromTokens(node.beginToken, node.endToken, uri);
     } else if (node is Local) {
       Local local = node;
@@ -1922,7 +1922,7 @@
       throw 'Cannot find tokens to produce error message.';
     }
     if (uri == null && currentElement != null) {
-      uri = currentElement.compilationUnit.script.readableUri;
+      uri = currentElement.compilationUnit.script.resourceUri;
     }
     return SourceSpan.withCharacterOffsets(begin, end,
       (beginOffset, endOffset) => new SourceSpan(uri, beginOffset, endOffset));
@@ -1962,7 +1962,7 @@
       return element.sourcePosition;
     }
     Token position = element.position;
-    Uri uri = element.compilationUnit.script.readableUri;
+    Uri uri = element.compilationUnit.script.resourceUri;
     return (position == null)
         ? new SourceSpan(uri, 0, 0)
         : spanFromTokens(position, position, uri);
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 5644b0f..dc0a3d9 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -18,6 +18,7 @@
 import '../resolution/operators.dart';
 import '../tree/tree.dart' show DartString;
 import '../universe/universe.dart' show CallStructure;
+import '../util/util.dart';
 import 'values.dart';
 
 enum ConstantExpressionKind {
@@ -141,6 +142,23 @@
     return appliedFieldMap;
   }
 
+  int get hashCode {
+    int hash = Hashing.objectHash(type);
+    hash = Hashing.mapHash(defaultValues, hash);
+    hash = Hashing.mapHash(fieldMap, hash);
+    return Hashing.objectHash(superConstructorInvocation, hash);
+  }
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! GenerativeConstantConstructor) return false;
+    return
+        type == other.type &&
+        superConstructorInvocation == other.superConstructorInvocation &&
+        mapEquals(defaultValues, other.defaultValues) &&
+        mapEquals(fieldMap, other.fieldMap);
+  }
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write("{'type': $type");
@@ -157,6 +175,16 @@
     return sb.toString();
   }
 
+  static bool mapEquals(Map map1, Map map2) {
+    if (map1.length != map1.length) return false;
+    for (var key in map1.keys) {
+      if (map1[key] != map2[key]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
   /// Creates the field-to-constant map from applying [args] to
   /// [constructorInvocation]. If [constructorInvocation] is `null`, an empty
   /// map is created.
@@ -205,6 +233,20 @@
     return appliedFieldMap;
   }
 
+  int get hashCode {
+    int hash = Hashing.objectHash(thisConstructorInvocation);
+    return Hashing.mapHash(defaultValues, hash);
+  }
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! RedirectingGenerativeConstantConstructor) return false;
+    return
+        thisConstructorInvocation == other.thisConstructorInvocation &&
+        GenerativeConstantConstructor.mapEquals(
+            defaultValues, other.defaultValues);
+  }
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write("{'type': ${thisConstructorInvocation.type}");
@@ -240,6 +282,16 @@
     return constantConstructor.computeInstanceFields(arguments, callStructure);
   }
 
+  int get hashCode {
+    return Hashing.objectHash(targetConstructorInvocation);
+  }
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    if (other is! RedirectingFactoryConstantConstructor) return false;
+    return targetConstructorInvocation == other.targetConstructorInvocation;
+  }
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write("{");
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index f5e5cc9..dd10751 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -31,7 +31,7 @@
 import '../types/types.dart' show TypeMask;
 import '../util/util.dart';
 
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
+import 'package:js_runtime/shared/embedded_names.dart'
     show JsBuiltin, JsGetName;
 import '../constants/values.dart';
 
@@ -339,24 +339,19 @@
 
   ir.Primitive visitVariableDefinitions(ast.VariableDefinitions node) {
     assert(irBuilder.isOpen);
-    if (node.modifiers.isConst) {
-      // Do nothing.
-      // handleLocalConstantGet inlines the constant at use-site.
-    } else {
-      for (ast.Node definition in node.definitions.nodes) {
-        Element element = elements[definition];
-        ir.Primitive initialValue;
-        // Definitions are either SendSets if there is an initializer, or
-        // Identifiers if there is no initializer.
-        if (definition is ast.SendSet) {
-          assert(!definition.arguments.isEmpty);
-          assert(definition.arguments.tail.isEmpty);
-          initialValue = visit(definition.arguments.head);
-        } else {
-          assert(definition is ast.Identifier);
-        }
-        irBuilder.declareLocalVariable(element, initialValue: initialValue);
+    for (ast.Node definition in node.definitions.nodes) {
+      Element element = elements[definition];
+      ir.Primitive initialValue;
+      // Definitions are either SendSets if there is an initializer, or
+      // Identifiers if there is no initializer.
+      if (definition is ast.SendSet) {
+        assert(!definition.arguments.isEmpty);
+        assert(definition.arguments.tail.isEmpty);
+        initialValue = visit(definition.arguments.head);
+      } else {
+        assert(definition is ast.Identifier);
       }
+      irBuilder.declareLocalVariable(element, initialValue: initialValue);
     }
     return null;
   }
@@ -2528,6 +2523,14 @@
         }
       });
     }
+    // If this is a mixin constructor, it does not have its own parameter list
+    // or initializer list. Directly forward to the super constructor.
+    // Note that the declaration-site initializers originating from the
+    // mixed-in class were handled above.
+    if (enclosingClass.isMixinApplication) {
+      forwardSynthesizedMixinConstructor(constructor, supers, fieldValues);
+      return;
+    }
     // Evaluate initializing parameters, e.g. `Foo(this.x)`.
     constructor.functionSignature.orderedForEachParameter(
         (ParameterElement parameter) {
@@ -2594,12 +2597,32 @@
       List<ConstructorElement> supers,
       Map<FieldElement, ir.Primitive> fieldValues) {
     JsIrBuilderVisitor visitor = makeVisitorForContext(target);
-    return visitor.withBuilder(irBuilder, () {
+    visitor.withBuilder(irBuilder, () {
       visitor.loadArguments(target, call, arguments);
       visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
     });
   }
 
+  /// Evaluate the implicit super call in the given mixin constructor.
+  void forwardSynthesizedMixinConstructor(
+        ConstructorElement constructor,
+        List<ConstructorElement> supers,
+        Map<FieldElement, ir.Primitive> fieldValues) {
+    assert(constructor.enclosingClass.implementation.isMixinApplication);
+    assert(constructor.isSynthesized);
+    ConstructorElement target =
+        constructor.definingConstructor.implementation;
+    // The resolver gives us the exact same FunctionSignature for the two
+    // constructors. The parameters for the synthesized constructor
+    // are already in the environment, so the target constructor's parameters
+    // are also in the environment since their elements are the same.
+    assert(constructor.functionSignature == target.functionSignature);
+    JsIrBuilderVisitor visitor = makeVisitorForContext(target);
+    visitor.withBuilder(irBuilder, () {
+      visitor.evaluateConstructorFieldInitializers(target, supers, fieldValues);
+    });
+  }
+
   /// Loads the type variables for all super classes of [superClass] into the
   /// IR builder's environment with their corresponding values.
   ///
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index fa33169..fec259b 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -289,9 +289,7 @@
   final SourceInformation sourceInformation;
 
   /// If true, it is known that the receiver cannot be `null`.
-  ///
-  /// This field is `null` until initialized by optimization phases.
-  bool receiverIsNotNull;
+  bool receiverIsNotNull = false;
 
   InvokeMethod(Primitive receiver,
                this.selector,
@@ -616,7 +614,7 @@
   final Reference<Primitive> object;
   FieldElement field;
 
-  /// True if the receiver is known not to be null.
+  /// True if the object is known not to be null.
   // TODO(asgerf): This is a placeholder until we agree on how to track
   //               side effects.
   bool objectIsNotNull = false;
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
index 56d5896..1c5adcf 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
@@ -371,8 +371,8 @@
     String arguments = node.arguments.map(formatReference).join(', ');
     String continuation = node.continuation == null ? ''
         : ' ${formatReference(node.continuation)}';
-    printStmt(id, "ForeignCode ${node.type} ${node.codeTemplate} $arguments"
-        "$continuation");
+    printStmt(id, "ForeignCode ${node.type} ${node.codeTemplate.source} "
+        "$arguments $continuation");
   }
 }
 
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index a8a7ee2..f93f493 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -53,6 +53,11 @@
     return mask.locateSingleElement(selector, mask, classWorld.compiler);
   }
 
+  TypeMask getReceiverType(MethodElement method) {
+    assert(method.isInstanceMember);
+    return nonNullSubclass(method.enclosingClass);
+  }
+
   TypeMask getParameterType(ParameterElement parameter) {
     return inferrer.getGuaranteedTypeOfElement(parameter);
   }
@@ -82,7 +87,12 @@
     // closure conversion, so just treat those as a subtypes of Function.
     // TODO(asgerf): Maybe closure conversion should create a new ClassWorld?
     if (element.isClosure) return functionType;
-    return new TypeMask.nonNullExact(element, classWorld);
+    return new TypeMask.nonNullExact(element.declaration, classWorld);
+  }
+
+  TypeMask nonNullSubclass(ClassElement element) {
+    if (element.isClosure) return functionType;
+    return new TypeMask.nonNullSubclass(element.declaration, classWorld);
   }
 
   bool isDefinitelyBool(TypeMask t, {bool allowNull: false}) {
@@ -502,6 +512,7 @@
     InvokeContinuation invoke =
         new InvokeContinuation(continuation, <Primitive>[primitive]);
     letPrim.body = invoke;
+    values[primitive] = values[continuation.parameters.single];
     primitive.hint = continuation.parameters.single.hint;
 
     return letPrim;
@@ -566,7 +577,6 @@
   /// True if all uses of [prim] only use its value after boolean conversion.
   bool isAlwaysBoolified(Primitive prim) {
     for (Reference ref = prim.firstRef; ref != null; ref = ref.next) {
-      Node use = ref.parent;
       if (!isBoolifyingUse(ref)) return false;
     }
     return true;
@@ -1045,8 +1055,8 @@
 
   void visitFunctionDefinition(FunctionDefinition node) {
     if (node.thisParameter != null) {
-      // TODO(asgerf): Use a more precise type for 'this'.
-      setValue(node.thisParameter, nonConstant(typeSystem.nonNullType));
+      setValue(node.thisParameter,
+               nonConstant(typeSystem.getReceiverType(node.element)));
     }
     node.parameters.forEach(visit);
     setReachable(node.body);
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 9db2af5..3b351af 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -18,7 +18,7 @@
 import 'util/uri_extras.dart';
 import 'util/util.dart' show stackTraceFilePrefix;
 import 'util/command_line.dart';
-import 'package:_internal/libraries.dart';
+import 'package:sdk_library_metadata/libraries.dart';
 import 'package:package_config/discovery.dart' show findPackages;
 
 const String LIBRARY_ROOT = '../../../../../sdk';
diff --git a/pkg/compiler/lib/src/elements/common.dart b/pkg/compiler/lib/src/elements/common.dart
index 13ea3b6..8c8c4ff 100644
--- a/pkg/compiler/lib/src/elements/common.dart
+++ b/pkg/compiler/lib/src/elements/common.dart
@@ -1,472 +1,472 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file

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

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

-

-/// Mixins that implement convenience methods on [Element] subclasses.

-

-library elements.common;

-

-import '../dart2jslib.dart' show Compiler, isPrivateName;

-import '../dart_types.dart' show DartType, InterfaceType, FunctionType;

-import '../util/util.dart' show Link;

-

-import 'elements.dart';

-

-abstract class ElementCommon implements Element {

-  @override

-  bool get isLibrary => kind == ElementKind.LIBRARY;

-

-  @override

-  bool get isCompilationUnit => kind == ElementKind.COMPILATION_UNIT;

-

-  @override

-  bool get isPrefix => kind == ElementKind.PREFIX;

-

-  @override

-  bool get isClass => kind == ElementKind.CLASS;

-

-  @override

-  bool get isTypeVariable => kind == ElementKind.TYPE_VARIABLE;

-

-  @override

-  bool get isTypedef => kind == ElementKind.TYPEDEF;

-

-  @override

-  bool get isFunction => kind == ElementKind.FUNCTION;

-

-  @override

-  bool get isAccessor => isGetter || isSetter;

-

-  @override

-  bool get isGetter => kind == ElementKind.GETTER;

-

-  @override

-  bool get isSetter => kind == ElementKind.SETTER;

-

-  @override

-  bool get isConstructor => isGenerativeConstructor ||  isFactoryConstructor;

-

-  @override

-  bool get isGenerativeConstructor =>

-      kind == ElementKind.GENERATIVE_CONSTRUCTOR;

-

-  @override

-  bool get isGenerativeConstructorBody =>

-      kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY;

-

-  @override

-  bool get isVariable => kind == ElementKind.VARIABLE;

-

-  @override

-  bool get isField => kind == ElementKind.FIELD;

-

-  @override

-  bool get isAbstractField => kind == ElementKind.ABSTRACT_FIELD;

-

-  @override

-  bool get isParameter => kind == ElementKind.PARAMETER;

-

-  @override

-  bool get isInitializingFormal => kind == ElementKind.INITIALIZING_FORMAL;

-

-  @override

-  bool get isErroneous => kind == ElementKind.ERROR;

-

-  @override

-  bool get isAmbiguous => kind == ElementKind.AMBIGUOUS;

-

-  @override

-  bool get isWarnOnUse => kind == ElementKind.WARN_ON_USE;

-

-  @override

-  bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;

-

-  @override

-  Element get declaration => this;

-

-  @override

-  Element get implementation => this;

-

-  @override

-  bool get isDeclaration => true;

-

-  @override

-  bool get isPatched => false;

-

-  @override

-  bool get isPatch => false;

-

-  @override

-  bool get isImplementation => true;

-

-  @override

-  bool get isInjected => !isPatch && implementationLibrary.isPatch;

-

-  @override

-  Element get patch {

-    throw new UnsupportedError('patch is not supported on $this');

-  }

-

-  @override

-  Element get origin {

-    throw new UnsupportedError('origin is not supported on $this');

-  }

-}

-

-abstract class LibraryElementCommon implements LibraryElement {

-  @override

-  bool get isDartCore => canonicalUri == Compiler.DART_CORE;

-

-  @override

-  bool get isPlatformLibrary => canonicalUri.scheme == 'dart';

-

-  @override

-  bool get isPackageLibrary => canonicalUri.scheme == 'package';

-

-  @override

-  bool get isInternalLibrary =>

-      isPlatformLibrary && canonicalUri.path.startsWith('_');

-}

-

-abstract class ClassElementCommon implements ClassElement {

-

-  @override

-  Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes;

-

-  @override

-  int get hierarchyDepth => allSupertypesAndSelf.maxDepth;

-

-  @override

-  InterfaceType asInstanceOf(ClassElement cls) {

-    if (cls == this) return thisType;

-    return allSupertypesAndSelf.asInstanceOf(cls);

-  }

-

-  @override

-  ConstructorElement lookupConstructor(String name) {

-    Element result = localLookup(name);

-    return result != null && result.isConstructor ? result : null;

-  }

-

-

-  /**

-   * Find the first member in the class chain with the given [memberName].

-   *

-   * This method is NOT to be used for resolving

-   * unqualified sends because it does not implement the scoping

-   * rules, where library scope comes before superclass scope.

-   *

-   * When called on the implementation element both members declared in the

-   * origin and the patch class are returned.

-   */

-  Element lookupByName(Name memberName) {

-    return internalLookupByName(memberName, isSuperLookup: false);

-  }

-

-  Element lookupSuperByName(Name memberName) {

-    return internalLookupByName(memberName, isSuperLookup: true);

-  }

-

-  Element internalLookupByName(Name memberName, {bool isSuperLookup}) {

-    String name = memberName.text;

-    bool isPrivate = memberName.isPrivate;

-    LibraryElement library = memberName.library;

-    for (ClassElement current = isSuperLookup ? superclass : this;

-         current != null;

-         current = current.superclass) {

-      Element member = current.lookupLocalMember(name);

-      if (member == null && current.isPatched) {

-        // Doing lookups on selectors is done after resolution, so it

-        // is safe to look in the patch class.

-        member = current.patch.lookupLocalMember(name);

-      }

-      if (member == null) continue;

-      // Private members from a different library are not visible.

-      if (isPrivate && !identical(library, member.library)) continue;

-      // Static members are not inherited.

-      if (member.isStatic && !identical(this, current)) continue;

-      // If we find an abstract field we have to make sure that it has

-      // the getter or setter part we're actually looking

-      // for. Otherwise, we continue up the superclass chain.

-      if (member.isAbstractField) {

-        AbstractFieldElement field = member;

-        FunctionElement getter = field.getter;

-        FunctionElement setter = field.setter;

-        if (memberName.isSetter) {

-          // Abstract members can be defined in a super class.

-          if (setter != null && !setter.isAbstract) {

-            return setter;

-          }

-        } else {

-          if (getter != null && !getter.isAbstract) {

-            return getter;

-          }

-        }

-      // Abstract members can be defined in a super class.

-      } else if (!member.isAbstract) {

-        return member;

-      }

-    }

-    return null;

-  }

-

-  /**

-   * Find the first member in the class chain with the given

-   * [memberName]. This method is NOT to be used for resolving

-   * unqualified sends because it does not implement the scoping

-   * rules, where library scope comes before superclass scope.

-   */

-  @override

-  Element lookupMember(String memberName) {

-    Element localMember = lookupLocalMember(memberName);

-    return localMember == null ? lookupSuperMember(memberName) : localMember;

-  }

-

-  @override

-  Link<Element> get constructors {

-    // TODO(ajohnsen): See if we can avoid this method at some point.

-    Link<Element> result = const Link<Element>();

-    // TODO(johnniwinther): Should we include injected constructors?

-    forEachMember((_, Element member) {

-      if (member.isConstructor) result = result.prepend(member);

-    });

-    return result;

-  }

-

-  /**

-   * Lookup super members for the class. This will ignore constructors.

-   */

-  @override

-  Element lookupSuperMember(String memberName) {

-    return lookupSuperMemberInLibrary(memberName, library);

-  }

-

-  /**

-   * Lookup super members for the class that is accessible in [library].

-   * This will ignore constructors.

-   */

-  @override

-  Element lookupSuperMemberInLibrary(String memberName,

-                                     LibraryElement library) {

-    bool isPrivate = isPrivateName(memberName);

-    for (ClassElement s = superclass; s != null; s = s.superclass) {

-      // Private members from a different library are not visible.

-      if (isPrivate && !identical(library, s.library)) continue;

-      Element e = s.lookupLocalMember(memberName);

-      if (e == null) continue;

-      // Static members are not inherited.

-      if (e.isStatic) continue;

-      return e;

-    }

-    return null;

-  }

-

-  /**

-   * Lookup local members in the class. This will ignore constructors.

-   */

-  @override

-  Element lookupLocalMember(String memberName) {

-    var result = localLookup(memberName);

-    if (result != null && result.isConstructor) return null;

-    return result;

-  }

-

-  /**

-   * Runs through all members of this class.

-   *

-   * The enclosing class is passed to the callback. This is useful when

-   * [includeSuperAndInjectedMembers] is [:true:].

-   *

-   * When called on an implementation element both the members in the origin

-   * and patch class are included.

-   */

-  // TODO(johnniwinther): Clean up lookup to get rid of the include predicates.

-  @override

-  void forEachMember(void f(ClassElement enclosingClass, Element member),

-                     {includeBackendMembers: false,

-                      includeSuperAndInjectedMembers: false}) {

-    bool includeInjectedMembers = includeSuperAndInjectedMembers || isPatch;

-    ClassElement classElement = declaration;

-    do {

-      // Iterate through the members in textual order, which requires

-      // to reverse the data structure [localMembers] we created.

-      // Textual order may be important for certain operations, for

-      // example when emitting the initializers of fields.

-      classElement.forEachLocalMember((e) => f(classElement, e));

-      if (includeBackendMembers) {

-        classElement.forEachBackendMember((e) => f(classElement, e));

-      }

-      if (includeInjectedMembers) {

-        if (classElement.patch != null) {

-          classElement.patch.forEachLocalMember((e) {

-            if (!e.isPatch) f(classElement, e);

-          });

-        }

-      }

-      classElement = includeSuperAndInjectedMembers

-          ? classElement.superclass

-          : null;

-    } while (classElement != null);

-  }

-

-  /**

-   * Runs through all instance-field members of this class.

-   *

-   * The enclosing class is passed to the callback. This is useful when

-   * [includeSuperAndInjectedMembers] is [:true:].

-   *

-   * When called on the implementation element both the fields declared in the

-   * origin and in the patch are included.

-   */

-  @override

-  void forEachInstanceField(void f(ClassElement enclosingClass,

-                                   FieldElement field),

-                            {bool includeSuperAndInjectedMembers: false}) {

-    // Filters so that [f] is only invoked with instance fields.

-    void fieldFilter(ClassElement enclosingClass, Element member) {

-      if (member.isInstanceMember && member.kind == ElementKind.FIELD) {

-        f(enclosingClass, member);

-      }

-    }

-

-    forEachMember(fieldFilter,

-        includeSuperAndInjectedMembers: includeSuperAndInjectedMembers);

-  }

-

-  /// Similar to [forEachInstanceField] but visits static fields.

-  @override

-  void forEachStaticField(void f(ClassElement enclosingClass, Element field)) {

-    // Filters so that [f] is only invoked with static fields.

-    void fieldFilter(ClassElement enclosingClass, Element member) {

-      if (!member.isInstanceMember && member.kind == ElementKind.FIELD) {

-        f(enclosingClass, member);

-      }

-    }

-

-    forEachMember(fieldFilter);

-  }

-

-  /**

-   * Returns true if the [fieldMember] shadows another field.  The given

-   * [fieldMember] must be a member of this class, i.e. if there is a field of

-   * the same name in the superclass chain.

-   *

-   * This method also works if the [fieldMember] is private.

-   */

-  @override

-  bool hasFieldShadowedBy(Element fieldMember) {

-    assert(fieldMember.isField);

-    String fieldName = fieldMember.name;

-    bool isPrivate = isPrivateName(fieldName);

-    LibraryElement memberLibrary = fieldMember.library;

-    ClassElement lookupClass = this.superclass;

-    while (lookupClass != null) {

-      Element foundMember = lookupClass.lookupLocalMember(fieldName);

-      if (foundMember != null) {

-        if (foundMember.isField) {

-          if (!isPrivate || memberLibrary == foundMember.library) {

-            // Private fields can only be shadowed by a field declared in the

-            // same library.

-            return true;

-          }

-        }

-      }

-      lookupClass = lookupClass.superclass;

-    }

-    return false;

-  }

-

-  @override

-  bool implementsInterface(ClassElement intrface) {

-    for (DartType implementedInterfaceType in allSupertypes) {

-      ClassElement implementedInterface = implementedInterfaceType.element;

-      if (identical(implementedInterface, intrface)) {

-        return true;

-      }

-    }

-    return false;

-  }

-

-  /**

-   * Returns true if [this] is a subclass of [cls].

-   *

-   * This method is not to be used for checking type hierarchy and

-   * assignments, because it does not take parameterized types into

-   * account.

-   */

-  bool isSubclassOf(ClassElement cls) {

-    // Use [declaration] for both [this] and [cls], because

-    // declaration classes hold the superclass hierarchy.

-    cls = cls.declaration;

-    for (ClassElement s = declaration; s != null; s = s.superclass) {

-      if (identical(s, cls)) return true;

-    }

-    return false;

-  }

-

-  FunctionType get callType {

-    MemberSignature member =

-        lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));

-    return member != null && member.isMethod ? member.type : null;

-  }

-}

-

-abstract class FunctionSignatureCommon implements FunctionSignature {

-  void forEachRequiredParameter(void function(Element parameter)) {

-    requiredParameters.forEach(function);

-  }

-

-  void forEachOptionalParameter(void function(Element parameter)) {

-    optionalParameters.forEach(function);

-  }

-

-  Element get firstOptionalParameter => optionalParameters.first;

-

-  void forEachParameter(void function(Element parameter)) {

-    forEachRequiredParameter(function);

-    forEachOptionalParameter(function);

-  }

-

-  void orderedForEachParameter(void function(Element parameter)) {

-    forEachRequiredParameter(function);

-    orderedOptionalParameters.forEach(function);

-  }

-

-  int get parameterCount => requiredParameterCount + optionalParameterCount;

-

-  /**

-   * Check whether a function with this signature can be used instead of a

-   * function with signature [signature] without causing a `noSuchMethod`

-   * exception/call.

-   */

-  bool isCompatibleWith(FunctionSignature signature) {

-    if (optionalParametersAreNamed) {

-      if (!signature.optionalParametersAreNamed) {

-        return requiredParameterCount == signature.parameterCount;

-      }

-      // If both signatures have named parameters, then they must have

-      // the same number of required parameters, and the names in

-      // [signature] must all be in [:this:].

-      if (requiredParameterCount != signature.requiredParameterCount) {

-        return false;

-      }

-      Set<String> names = optionalParameters.map(

-          (Element element) => element.name).toSet();

-      for (Element namedParameter in signature.optionalParameters) {

-        if (!names.contains(namedParameter.name)) {

-          return false;

-        }

-      }

-    } else {

-      if (signature.optionalParametersAreNamed) return false;

-      // There must be at least as many arguments as in the other signature, but

-      // this signature must not have more required parameters.  Having more

-      // optional parameters is not a problem, they simply are never provided

-      // by call sites of a call to a method with the other signature.

-      int otherTotalCount = signature.parameterCount;

-      return requiredParameterCount <= otherTotalCount

-          && parameterCount >= otherTotalCount;

-    }

-    return true;

-  }

-}

+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/// Mixins that implement convenience methods on [Element] subclasses.
+
+library elements.common;
+
+import '../dart2jslib.dart' show Compiler, isPrivateName;
+import '../dart_types.dart' show DartType, InterfaceType, FunctionType;
+import '../util/util.dart' show Link;
+
+import 'elements.dart';
+
+abstract class ElementCommon implements Element {
+  @override
+  bool get isLibrary => kind == ElementKind.LIBRARY;
+
+  @override
+  bool get isCompilationUnit => kind == ElementKind.COMPILATION_UNIT;
+
+  @override
+  bool get isPrefix => kind == ElementKind.PREFIX;
+
+  @override
+  bool get isClass => kind == ElementKind.CLASS;
+
+  @override
+  bool get isTypeVariable => kind == ElementKind.TYPE_VARIABLE;
+
+  @override
+  bool get isTypedef => kind == ElementKind.TYPEDEF;
+
+  @override
+  bool get isFunction => kind == ElementKind.FUNCTION;
+
+  @override
+  bool get isAccessor => isGetter || isSetter;
+
+  @override
+  bool get isGetter => kind == ElementKind.GETTER;
+
+  @override
+  bool get isSetter => kind == ElementKind.SETTER;
+
+  @override
+  bool get isConstructor => isGenerativeConstructor ||  isFactoryConstructor;
+
+  @override
+  bool get isGenerativeConstructor =>
+      kind == ElementKind.GENERATIVE_CONSTRUCTOR;
+
+  @override
+  bool get isGenerativeConstructorBody =>
+      kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY;
+
+  @override
+  bool get isVariable => kind == ElementKind.VARIABLE;
+
+  @override
+  bool get isField => kind == ElementKind.FIELD;
+
+  @override
+  bool get isAbstractField => kind == ElementKind.ABSTRACT_FIELD;
+
+  @override
+  bool get isParameter => kind == ElementKind.PARAMETER;
+
+  @override
+  bool get isInitializingFormal => kind == ElementKind.INITIALIZING_FORMAL;
+
+  @override
+  bool get isErroneous => kind == ElementKind.ERROR;
+
+  @override
+  bool get isAmbiguous => kind == ElementKind.AMBIGUOUS;
+
+  @override
+  bool get isWarnOnUse => kind == ElementKind.WARN_ON_USE;
+
+  @override
+  bool get impliesType => (kind.category & ElementCategory.IMPLIES_TYPE) != 0;
+
+  @override
+  Element get declaration => this;
+
+  @override
+  Element get implementation => this;
+
+  @override
+  bool get isDeclaration => true;
+
+  @override
+  bool get isPatched => false;
+
+  @override
+  bool get isPatch => false;
+
+  @override
+  bool get isImplementation => true;
+
+  @override
+  bool get isInjected => !isPatch && implementationLibrary.isPatch;
+
+  @override
+  Element get patch {
+    throw new UnsupportedError('patch is not supported on $this');
+  }
+
+  @override
+  Element get origin {
+    throw new UnsupportedError('origin is not supported on $this');
+  }
+}
+
+abstract class LibraryElementCommon implements LibraryElement {
+  @override
+  bool get isDartCore => canonicalUri == Compiler.DART_CORE;
+
+  @override
+  bool get isPlatformLibrary => canonicalUri.scheme == 'dart';
+
+  @override
+  bool get isPackageLibrary => canonicalUri.scheme == 'package';
+
+  @override
+  bool get isInternalLibrary =>
+      isPlatformLibrary && canonicalUri.path.startsWith('_');
+}
+
+abstract class ClassElementCommon implements ClassElement {
+
+  @override
+  Link<DartType> get allSupertypes => allSupertypesAndSelf.supertypes;
+
+  @override
+  int get hierarchyDepth => allSupertypesAndSelf.maxDepth;
+
+  @override
+  InterfaceType asInstanceOf(ClassElement cls) {
+    if (cls == this) return thisType;
+    return allSupertypesAndSelf.asInstanceOf(cls);
+  }
+
+  @override
+  ConstructorElement lookupConstructor(String name) {
+    Element result = localLookup(name);
+    return result != null && result.isConstructor ? result : null;
+  }
+
+
+  /**
+   * Find the first member in the class chain with the given [memberName].
+   *
+   * This method is NOT to be used for resolving
+   * unqualified sends because it does not implement the scoping
+   * rules, where library scope comes before superclass scope.
+   *
+   * When called on the implementation element both members declared in the
+   * origin and the patch class are returned.
+   */
+  Element lookupByName(Name memberName) {
+    return internalLookupByName(memberName, isSuperLookup: false);
+  }
+
+  Element lookupSuperByName(Name memberName) {
+    return internalLookupByName(memberName, isSuperLookup: true);
+  }
+
+  Element internalLookupByName(Name memberName, {bool isSuperLookup}) {
+    String name = memberName.text;
+    bool isPrivate = memberName.isPrivate;
+    LibraryElement library = memberName.library;
+    for (ClassElement current = isSuperLookup ? superclass : this;
+         current != null;
+         current = current.superclass) {
+      Element member = current.lookupLocalMember(name);
+      if (member == null && current.isPatched) {
+        // Doing lookups on selectors is done after resolution, so it
+        // is safe to look in the patch class.
+        member = current.patch.lookupLocalMember(name);
+      }
+      if (member == null) continue;
+      // Private members from a different library are not visible.
+      if (isPrivate && !identical(library, member.library)) continue;
+      // Static members are not inherited.
+      if (member.isStatic && !identical(this, current)) continue;
+      // If we find an abstract field we have to make sure that it has
+      // the getter or setter part we're actually looking
+      // for. Otherwise, we continue up the superclass chain.
+      if (member.isAbstractField) {
+        AbstractFieldElement field = member;
+        FunctionElement getter = field.getter;
+        FunctionElement setter = field.setter;
+        if (memberName.isSetter) {
+          // Abstract members can be defined in a super class.
+          if (setter != null && !setter.isAbstract) {
+            return setter;
+          }
+        } else {
+          if (getter != null && !getter.isAbstract) {
+            return getter;
+          }
+        }
+      // Abstract members can be defined in a super class.
+      } else if (!member.isAbstract) {
+        return member;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Find the first member in the class chain with the given
+   * [memberName]. This method is NOT to be used for resolving
+   * unqualified sends because it does not implement the scoping
+   * rules, where library scope comes before superclass scope.
+   */
+  @override
+  Element lookupMember(String memberName) {
+    Element localMember = lookupLocalMember(memberName);
+    return localMember == null ? lookupSuperMember(memberName) : localMember;
+  }
+
+  @override
+  Link<Element> get constructors {
+    // TODO(ajohnsen): See if we can avoid this method at some point.
+    Link<Element> result = const Link<Element>();
+    // TODO(johnniwinther): Should we include injected constructors?
+    forEachMember((_, Element member) {
+      if (member.isConstructor) result = result.prepend(member);
+    });
+    return result;
+  }
+
+  /**
+   * Lookup super members for the class. This will ignore constructors.
+   */
+  @override
+  Element lookupSuperMember(String memberName) {
+    return lookupSuperMemberInLibrary(memberName, library);
+  }
+
+  /**
+   * Lookup super members for the class that is accessible in [library].
+   * This will ignore constructors.
+   */
+  @override
+  Element lookupSuperMemberInLibrary(String memberName,
+                                     LibraryElement library) {
+    bool isPrivate = isPrivateName(memberName);
+    for (ClassElement s = superclass; s != null; s = s.superclass) {
+      // Private members from a different library are not visible.
+      if (isPrivate && !identical(library, s.library)) continue;
+      Element e = s.lookupLocalMember(memberName);
+      if (e == null) continue;
+      // Static members are not inherited.
+      if (e.isStatic) continue;
+      return e;
+    }
+    return null;
+  }
+
+  /**
+   * Lookup local members in the class. This will ignore constructors.
+   */
+  @override
+  Element lookupLocalMember(String memberName) {
+    var result = localLookup(memberName);
+    if (result != null && result.isConstructor) return null;
+    return result;
+  }
+
+  /**
+   * Runs through all members of this class.
+   *
+   * The enclosing class is passed to the callback. This is useful when
+   * [includeSuperAndInjectedMembers] is [:true:].
+   *
+   * When called on an implementation element both the members in the origin
+   * and patch class are included.
+   */
+  // TODO(johnniwinther): Clean up lookup to get rid of the include predicates.
+  @override
+  void forEachMember(void f(ClassElement enclosingClass, Element member),
+                     {includeBackendMembers: false,
+                      includeSuperAndInjectedMembers: false}) {
+    bool includeInjectedMembers = includeSuperAndInjectedMembers || isPatch;
+    ClassElement classElement = declaration;
+    do {
+      // Iterate through the members in textual order, which requires
+      // to reverse the data structure [localMembers] we created.
+      // Textual order may be important for certain operations, for
+      // example when emitting the initializers of fields.
+      classElement.forEachLocalMember((e) => f(classElement, e));
+      if (includeBackendMembers) {
+        classElement.forEachBackendMember((e) => f(classElement, e));
+      }
+      if (includeInjectedMembers) {
+        if (classElement.patch != null) {
+          classElement.patch.forEachLocalMember((e) {
+            if (!e.isPatch) f(classElement, e);
+          });
+        }
+      }
+      classElement = includeSuperAndInjectedMembers
+          ? classElement.superclass
+          : null;
+    } while (classElement != null);
+  }
+
+  /**
+   * Runs through all instance-field members of this class.
+   *
+   * The enclosing class is passed to the callback. This is useful when
+   * [includeSuperAndInjectedMembers] is [:true:].
+   *
+   * When called on the implementation element both the fields declared in the
+   * origin and in the patch are included.
+   */
+  @override
+  void forEachInstanceField(void f(ClassElement enclosingClass,
+                                   FieldElement field),
+                            {bool includeSuperAndInjectedMembers: false}) {
+    // Filters so that [f] is only invoked with instance fields.
+    void fieldFilter(ClassElement enclosingClass, Element member) {
+      if (member.isInstanceMember && member.kind == ElementKind.FIELD) {
+        f(enclosingClass, member);
+      }
+    }
+
+    forEachMember(fieldFilter,
+        includeSuperAndInjectedMembers: includeSuperAndInjectedMembers);
+  }
+
+  /// Similar to [forEachInstanceField] but visits static fields.
+  @override
+  void forEachStaticField(void f(ClassElement enclosingClass, Element field)) {
+    // Filters so that [f] is only invoked with static fields.
+    void fieldFilter(ClassElement enclosingClass, Element member) {
+      if (!member.isInstanceMember && member.kind == ElementKind.FIELD) {
+        f(enclosingClass, member);
+      }
+    }
+
+    forEachMember(fieldFilter);
+  }
+
+  /**
+   * Returns true if the [fieldMember] shadows another field.  The given
+   * [fieldMember] must be a member of this class, i.e. if there is a field of
+   * the same name in the superclass chain.
+   *
+   * This method also works if the [fieldMember] is private.
+   */
+  @override
+  bool hasFieldShadowedBy(Element fieldMember) {
+    assert(fieldMember.isField);
+    String fieldName = fieldMember.name;
+    bool isPrivate = isPrivateName(fieldName);
+    LibraryElement memberLibrary = fieldMember.library;
+    ClassElement lookupClass = this.superclass;
+    while (lookupClass != null) {
+      Element foundMember = lookupClass.lookupLocalMember(fieldName);
+      if (foundMember != null) {
+        if (foundMember.isField) {
+          if (!isPrivate || memberLibrary == foundMember.library) {
+            // Private fields can only be shadowed by a field declared in the
+            // same library.
+            return true;
+          }
+        }
+      }
+      lookupClass = lookupClass.superclass;
+    }
+    return false;
+  }
+
+  @override
+  bool implementsInterface(ClassElement intrface) {
+    for (DartType implementedInterfaceType in allSupertypes) {
+      ClassElement implementedInterface = implementedInterfaceType.element;
+      if (identical(implementedInterface, intrface)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Returns true if [this] is a subclass of [cls].
+   *
+   * This method is not to be used for checking type hierarchy and
+   * assignments, because it does not take parameterized types into
+   * account.
+   */
+  bool isSubclassOf(ClassElement cls) {
+    // Use [declaration] for both [this] and [cls], because
+    // declaration classes hold the superclass hierarchy.
+    cls = cls.declaration;
+    for (ClassElement s = declaration; s != null; s = s.superclass) {
+      if (identical(s, cls)) return true;
+    }
+    return false;
+  }
+
+  FunctionType get callType {
+    MemberSignature member =
+        lookupInterfaceMember(const PublicName(Compiler.CALL_OPERATOR_NAME));
+    return member != null && member.isMethod ? member.type : null;
+  }
+}
+
+abstract class FunctionSignatureCommon implements FunctionSignature {
+  void forEachRequiredParameter(void function(Element parameter)) {
+    requiredParameters.forEach(function);
+  }
+
+  void forEachOptionalParameter(void function(Element parameter)) {
+    optionalParameters.forEach(function);
+  }
+
+  Element get firstOptionalParameter => optionalParameters.first;
+
+  void forEachParameter(void function(Element parameter)) {
+    forEachRequiredParameter(function);
+    forEachOptionalParameter(function);
+  }
+
+  void orderedForEachParameter(void function(Element parameter)) {
+    forEachRequiredParameter(function);
+    orderedOptionalParameters.forEach(function);
+  }
+
+  int get parameterCount => requiredParameterCount + optionalParameterCount;
+
+  /**
+   * Check whether a function with this signature can be used instead of a
+   * function with signature [signature] without causing a `noSuchMethod`
+   * exception/call.
+   */
+  bool isCompatibleWith(FunctionSignature signature) {
+    if (optionalParametersAreNamed) {
+      if (!signature.optionalParametersAreNamed) {
+        return requiredParameterCount == signature.parameterCount;
+      }
+      // If both signatures have named parameters, then they must have
+      // the same number of required parameters, and the names in
+      // [signature] must all be in [:this:].
+      if (requiredParameterCount != signature.requiredParameterCount) {
+        return false;
+      }
+      Set<String> names = optionalParameters.map(
+          (Element element) => element.name).toSet();
+      for (Element namedParameter in signature.optionalParameters) {
+        if (!names.contains(namedParameter.name)) {
+          return false;
+        }
+      }
+    } else {
+      if (signature.optionalParametersAreNamed) return false;
+      // There must be at least as many arguments as in the other signature, but
+      // this signature must not have more required parameters.  Having more
+      // optional parameters is not a problem, they simply are never provided
+      // by call sites of a call to a method with the other signature.
+      int otherTotalCount = signature.parameterCount;
+      return requiredParameterCount <= otherTotalCount
+          && parameterCount >= otherTotalCount;
+    }
+    return true;
+  }
+}
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index cf96f4e..fc1f93b 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -8,6 +8,7 @@
 import 'elements.dart';
 import '../constants/expressions.dart';
 import '../constants/constructors.dart';
+import '../helpers/helpers.dart';
 import '../tree/tree.dart';
 import '../util/util.dart';
 import '../resolution/resolution.dart';
@@ -114,7 +115,7 @@
 
   SourceSpan get sourcePosition {
     if (position == null) return null;
-    Uri uri = compilationUnit.script.readableUri;
+    Uri uri = compilationUnit.script.resourceUri;
     return new SourceSpan(
         uri, position.charOffset, position.charOffset + position.charCount);
   }
@@ -1248,16 +1249,16 @@
 }
 
 abstract class ConstantVariableMixin implements VariableElement {
-  ConstantExpression _constant;
+  ConstantExpression constantCache;
 
   ConstantExpression get constant {
     if (isPatch) {
       ConstantVariableMixin originVariable = origin;
       return originVariable.constant;
     }
-    assert(invariant(this, _constant != null,
+    assert(invariant(this, constantCache != null,
         message: "Constant has not been computed for $this."));
-    return _constant;
+    return constantCache;
   }
 
   void set constant(ConstantExpression value) {
@@ -1266,9 +1267,9 @@
       originVariable.constant = value;
       return null;
     }
-    assert(invariant(this, _constant == null || _constant == value,
+    assert(invariant(this, constantCache == null || constantCache == value,
         message: "Constant has already been computed for $this."));
-    _constant = value;
+    constantCache = value;
   }
 }
 
@@ -1966,6 +1967,25 @@
     return _constantConstructor;
   }
 
+  void set constantConstructor(ConstantConstructor value) {
+    if (isPatch) {
+      ConstantConstructorMixin originConstructor = origin;
+      originConstructor.constantConstructor = value;
+    } else {
+      assert(invariant(this, isConst,
+          message: "Constant constructor set on non-constant "
+                   "constructor $this."));
+      assert(invariant(this, !isFromEnvironmentConstructor,
+          message: "Constant constructor set on fromEnvironment "
+                   "constructor: $this."));
+      assert(invariant(this,
+          _constantConstructor == null || _constantConstructor == value,
+          message: "Constant constructor already computed for $this:"
+                   "Existing: $_constantConstructor, new: $value"));
+      _constantConstructor = value;
+    }
+  }
+
   bool get isFromEnvironmentConstructor {
     return name == 'fromEnvironment' &&
            library.isDartCore &&
diff --git a/pkg/compiler/lib/src/io/line_column_provider.dart b/pkg/compiler/lib/src/io/line_column_provider.dart
index 4d17583..fb3d5db 100644
--- a/pkg/compiler/lib/src/io/line_column_provider.dart
+++ b/pkg/compiler/lib/src/io/line_column_provider.dart
@@ -1,77 +1,77 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file

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

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

-

-library dart2js.io.line_column;

-

-import 'code_output.dart';

-

-/// Interface for providing line/column information.

-abstract class LineColumnProvider {

-  /// Returns the line number (0-based) for [offset].

-  int getLine(int offset);

-

-  /// Returns the column number (0-based) for [offset] at the given [line].

-  int getColumn(int line, int offset);

-}

-

-/// [CodeOutputListener] that collects line information.

-class LineColumnCollector extends CodeOutputListener

-    implements LineColumnProvider {

-  int length = 0;

-  List<int> lineStarts = <int>[0];

-

-  void _collect(String text) {

-    int index = 0;

-    while (index < text.length) {

-      // Unix uses '\n' and Windows uses '\r\n', so this algorithm works for

-      // both platforms.

-      index = text.indexOf('\n', index) + 1;

-      if (index <= 0) break;

-      lineStarts.add(length + index);

-    }

-    length += text.length;

-  }

-

-  @override

-  void onText(String text) {

-    _collect(text);

-  }

-

-  @override

-  int getLine(int offset) {

-    List<int> starts = lineStarts;

-    if (offset < 0 || starts.last <= offset) {

-      throw 'bad position #$offset in buffer with length ${length}.';

-    }

-    int first = 0;

-    int count = starts.length;

-    while (count > 1) {

-      int step = count ~/ 2;

-      int middle = first + step;

-      int lineStart = starts[middle];

-      if (offset < lineStart) {

-        count = step;

-      } else {

-        first = middle;

-        count -= step;

-      }

-    }

-    return first;

-  }

-

-  @override

-  int getColumn(int line, int offset) {

-    return offset - lineStarts[line];

-  }

-

-  @override

-  void onDone(int length) {

-    lineStarts.add(length + 1);

-    this.length = length;

-  }

-

-  String toString() {

-    return 'lineStarts=$lineStarts,length=$length';

-  }

-}

+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.io.line_column;
+
+import 'code_output.dart';
+
+/// Interface for providing line/column information.
+abstract class LineColumnProvider {
+  /// Returns the line number (0-based) for [offset].
+  int getLine(int offset);
+
+  /// Returns the column number (0-based) for [offset] at the given [line].
+  int getColumn(int line, int offset);
+}
+
+/// [CodeOutputListener] that collects line information.
+class LineColumnCollector extends CodeOutputListener
+    implements LineColumnProvider {
+  int length = 0;
+  List<int> lineStarts = <int>[0];
+
+  void _collect(String text) {
+    int index = 0;
+    while (index < text.length) {
+      // Unix uses '\n' and Windows uses '\r\n', so this algorithm works for
+      // both platforms.
+      index = text.indexOf('\n', index) + 1;
+      if (index <= 0) break;
+      lineStarts.add(length + index);
+    }
+    length += text.length;
+  }
+
+  @override
+  void onText(String text) {
+    _collect(text);
+  }
+
+  @override
+  int getLine(int offset) {
+    List<int> starts = lineStarts;
+    if (offset < 0 || starts.last <= offset) {
+      throw 'bad position #$offset in buffer with length ${length}.';
+    }
+    int first = 0;
+    int count = starts.length;
+    while (count > 1) {
+      int step = count ~/ 2;
+      int middle = first + step;
+      int lineStart = starts[middle];
+      if (offset < lineStart) {
+        count = step;
+      } else {
+        first = middle;
+        count -= step;
+      }
+    }
+    return first;
+  }
+
+  @override
+  int getColumn(int line, int offset) {
+    return offset - lineStarts[line];
+  }
+
+  @override
+  void onDone(int length) {
+    lineStarts.add(length + 1);
+    this.length = length;
+  }
+
+  String toString() {
+    return 'lineStarts=$lineStarts,length=$length';
+  }
+}
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index e29c104..41a8466 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -7,7 +7,7 @@
 import "dart:math" show max;
 import 'dart:collection';
 
-import 'package:_internal/compiler/js_lib/shared/async_await_error_codes.dart'
+import 'package:js_runtime/shared/async_await_error_codes.dart'
     as error_codes;
 
 import "js.dart" as js;
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index bd40919..cbead55 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -46,10 +46,7 @@
   /// Variable names that have already been used. Used to avoid name clashes.
   Set<String> usedVariableNames = new Set<String>();
 
-  /// Input to [visitStatement]. Denotes the statement that will execute next
-  /// if the statements produced by [visitStatement] complete normally.
-  /// Set to null if control will fall over the end of the method.
-  tree_ir.Statement fallthrough = null;
+  final tree_ir.FallthroughStack fallthrough = new tree_ir.FallthroughStack();
 
   Set<tree_ir.Label> usedLabels = new Set<tree_ir.Label>();
 
@@ -341,6 +338,14 @@
       glue.registerIsCheck(type, registry);
       ClassElement clazz = type.element;
 
+      // Handle some special checks against classes that exist only in
+      // the compile-time class hierarchy, not at runtime.
+      if (clazz == glue.jsExtendableArrayClass) {
+        return js.js(r'!#.fixed$length', <js.Expression>[value]);
+      } else if (clazz == glue.jsMutableArrayClass) {
+        return js.js(r'!#.immutable$list', <js.Expression>[value]);
+      }
+
       // We use one of the two helpers:
       //
       //     checkSubtype(value, $isT, typeArgs, $asT)
@@ -400,12 +405,13 @@
 
   @override
   void visitContinue(tree_ir.Continue node) {
-    tree_ir.Statement fallthrough = this.fallthrough;
-    if (node.target.binding == fallthrough) {
+    tree_ir.Statement next = fallthrough.target;
+    if (node.target.binding == next) {
       // Fall through to continue target
-    } else if (fallthrough is tree_ir.Continue &&
-               fallthrough.target == node.target) {
+      fallthrough.use();
+    } else if (next is tree_ir.Continue && next.target == node.target) {
       // Fall through to equivalent continue
+      fallthrough.use();
     } else {
       usedLabels.add(node.target);
       accumulator.add(new js.Continue(node.target.name));
@@ -413,6 +419,21 @@
   }
 
   @override
+  void visitBreak(tree_ir.Break node) {
+    tree_ir.Statement next = fallthrough.target;
+    if (node.target.binding.next == next) {
+      // Fall through to break target
+      fallthrough.use();
+    } else if (next is tree_ir.Break && next.target == node.target) {
+      // Fall through to equivalent break
+      fallthrough.use();
+    } else {
+      usedLabels.add(node.target);
+      accumulator.add(new js.Break(node.target.name));
+    }
+  }
+
+  @override
   void visitExpressionStatement(tree_ir.ExpressionStatement node) {
     accumulator.add(new js.ExpressionStatement(
         visitExpression(node.expression)));
@@ -421,9 +442,19 @@
 
   @override
   void visitIf(tree_ir.If node) {
-    accumulator.add(new js.If(visitExpression(node.condition),
-                              buildBodyStatement(node.thenStatement),
-                              buildBodyStatement(node.elseStatement)));
+    js.Expression condition = visitExpression(node.condition);
+    int usesBefore = fallthrough.useCount;
+    js.Statement thenBody = buildBodyStatement(node.thenStatement);
+    bool thenHasFallthrough = (fallthrough.useCount > usesBefore);
+    if (thenHasFallthrough) {
+      js.Statement elseBody = buildBodyStatement(node.elseStatement);
+      accumulator.add(new js.If(condition, thenBody, elseBody));
+    } else {
+      // The 'then' body cannot complete normally, so emit a short 'if'
+      // and put the 'else' body after it.
+      accumulator.add(new js.If.noElse(condition, thenBody));
+      visitStatement(node.elseStatement);
+    }
   }
 
   @override
@@ -435,32 +466,17 @@
   }
 
   js.Statement buildLabeled(js.Statement buildBody(),
-                tree_ir.Label label,
-                tree_ir.Statement fallthroughStatement) {
-    tree_ir.Statement savedFallthrough = fallthrough;
-    fallthrough = fallthroughStatement;
+                            tree_ir.Label label,
+                            tree_ir.Statement fallthroughStatement) {
+    fallthrough.push(fallthroughStatement);
     js.Statement result = buildBody();
     if (usedLabels.remove(label)) {
       result = new js.LabeledStatement(label.name, result);
     }
-    fallthrough = savedFallthrough;
+    fallthrough.pop();
     return result;
   }
 
-  @override
-  void visitBreak(tree_ir.Break node) {
-    tree_ir.Statement fallthrough = this.fallthrough;
-    if (node.target.binding.next == fallthrough) {
-      // Fall through to break target
-    } else if (fallthrough is tree_ir.Break &&
-               fallthrough.target == node.target) {
-      // Fall through to equivalent break
-    } else {
-      usedLabels.add(node.target);
-      accumulator.add(new js.Break(node.target.name));
-    }
-  }
-
   /// Returns the current [accumulator] wrapped in a block if neccessary.
   js.Statement _bodyAsStatement() {
     if (accumulator.length == 0) {
@@ -516,9 +532,19 @@
         buildWhile(new js.LiteralBool(true), node.body, node.label, node));
   }
 
+  bool isNull(tree_ir.Expression node) {
+    return node is tree_ir.Constant && node.value.isNull;
+  }
+
   @override
   void visitReturn(tree_ir.Return node) {
-    accumulator.add(new js.Return(visitExpression(node.value)));
+    if (isNull(node.value) && fallthrough.target == null) {
+      // Do nothing. Implicitly return JS undefined by falling over the end.
+      registry.registerCompileTimeConstant(new NullConstantValue());
+      fallthrough.use();
+    } else {
+      accumulator.add(new js.Return(visitExpression(node.value)));
+    }
   }
 
   @override
@@ -609,6 +635,7 @@
 
   @override
   js.Expression visitGetField(tree_ir.GetField node) {
+    registry.registerFieldGetter(node.field);
     return new js.PropertyAccess(
         visitExpression(node.object),
         glue.instanceFieldPropertyName(node.field));
@@ -616,6 +643,7 @@
 
   @override
   js.Assignment visitSetField(tree_ir.SetField node) {
+    registry.registerFieldSetter(node.field);
     js.PropertyAccess field =
         new js.PropertyAccess(
             visitExpression(node.object),
@@ -701,8 +729,8 @@
   }
 
   @override
-  visitForeignStatement(tree_ir.ForeignStatement node) {
-    return handleForeignCode(node);
+  void visitForeignStatement(tree_ir.ForeignStatement node) {
+    accumulator.add(handleForeignCode(node));
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/codegen/glue.dart b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
index bb7ce13..641660b 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
@@ -234,4 +234,7 @@
   bool hasStrictSubtype(ClassElement element) {
     return _compiler.world.hasAnyStrictSubtype(element);
   }
+
+  ClassElement get jsExtendableArrayClass => _backend.jsExtendableArrayClass;
+  ClassElement get jsMutableArrayClass => _backend.jsMutableArrayClass;
 }
diff --git a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
new file mode 100644
index 0000000..1666ca5
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
@@ -0,0 +1,238 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of js_backend;
+
+abstract class _MinifiedFieldNamer implements Namer {
+  _FieldNamingRegistry get fieldRegistry;
+
+  // Returns a minimal name for the field that is globally unique along
+  // the given element's class inheritance chain.
+  //
+  // The inheritance scope based naming might not yield a name. For instance,
+  // this could be because the field belongs to a mixin. In such a case this
+  // will return `null` and a normal field name has to be used.
+  jsAst.Name _minifiedInstanceFieldPropertyName(Element element) {
+    if (element.hasFixedBackendName) {
+      return new StringBackedName(element.fixedBackendName);
+    }
+
+    _FieldNamingScope names;
+    if (element is BoxFieldElement) {
+      names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
+    } else {
+      ClassElement cls = element is ClosureFieldElement
+          ? element.closureClass
+          : element.enclosingClass;
+      names =
+          new _FieldNamingScope.forClass(cls, compiler.world, fieldRegistry);
+    }
+
+    if (names.containsField(element)) {
+      return names[element];
+    }
+    return null;
+  }
+}
+
+/**
+ * Encapsulates the global state of field naming.
+ *
+ * The field naming registry allocates names to be used along a path in the
+ * inheritance hierarchy of fields, starting with the object class. The actual
+ * hierarchy is encoded using instances of [_FieldNamingScope].
+ */
+class _FieldNamingRegistry {
+  final MinifyNamer namer;
+
+  final Map<Entity, _FieldNamingScope> scopes =
+      new Map<Entity, _FieldNamingScope>();
+
+  final Map<Entity, jsAst.Name> globalNames = new Map<Entity, jsAst.Name>();
+
+  int globalCount = 0;
+
+  final List<jsAst.Name> nameStore = new List<jsAst.Name>();
+
+  _FieldNamingRegistry(this.namer);
+
+  // Returns the name to be used for a field with distance [index] from the
+  // root of the object hierarchy. The distance thereby is computed as the
+  // number of fields preceding the current field in its classes inheritance
+  // chain.
+  //
+  // The implementation assumes that names are requedsted in order, that is the
+  // name at position i+1 is requested after the name at position i was
+  // requested.
+  jsAst.Name getName(int index) {
+    if (index >= nameStore.length) {
+      // The namer usually does not use certain names as they clash with
+      // existing properties on JS objects (see [_reservedNativeProperties]).
+      // However, some of them are really short and safe to use for fields.
+      // Thus, we shortcut the namer to use those first.
+      assert(index == nameStore.length);
+      if (index < MinifyNamer._reservedNativeProperties.length &&
+          MinifyNamer._reservedNativeProperties[index].length <= 2) {
+        nameStore.add(
+            new StringBackedName(MinifyNamer._reservedNativeProperties[index]));
+      } else {
+        nameStore.add(namer.getFreshName("field$index", namer.usedInstanceNames,
+            namer.suggestedInstanceNames));
+      }
+    }
+
+    return nameStore[index];
+  }
+}
+
+/**
+ * A [_FieldNamingScope] encodes a node in the inheritance tree of the current
+ * class hierarchy. The root node typically is the node corresponding to the
+ * `Object` class. It is used to assign a unique name to each field of a class.
+ * Unique here means unique wrt. all fields along the path back to the root.
+ * This is achieved at construction time via the [_fieldNameCounter] field that
+ * counts the number of fields on the path to the root node that have been
+ * encountered so far.
+ *
+ * Obviously, this only works if no fields are added to a parent node after its
+ * children have added their first field.
+ */
+class _FieldNamingScope {
+  final _FieldNamingScope superScope;
+  final Entity container;
+  final Map<Element, jsAst.Name> names = new Maplet<Element, jsAst.Name>();
+  final _FieldNamingRegistry registry;
+
+  /// Naming counter used for fields of ordinary classes.
+  int _fieldNameCounter;
+
+  /// The number of fields along the superclass chain that use inheritance
+  /// based naming, including the ones allocated for this scope.
+  int get inheritanceBasedFieldNameCounter => _fieldNameCounter;
+
+  /// The number of locally used fields. Depending on the naming source
+  /// (e.g. inheritance based or globally unique for mixixns) this
+  /// might be different from [inheritanceBasedFieldNameCounter].
+  int get _localFieldNameCounter => _fieldNameCounter;
+  void set _localFieldNameCounter(int val) {
+    _fieldNameCounter = val;
+  }
+
+  factory _FieldNamingScope.forClass(
+      ClassElement cls, ClassWorld world, _FieldNamingRegistry registry) {
+    _FieldNamingScope result = registry.scopes[cls];
+    if (result != null) return result;
+
+    if (world.isUsedAsMixin(cls)) {
+      result = new _MixinFieldNamingScope.mixin(cls, registry);
+    } else {
+      if (cls.superclass == null) {
+        result = new _FieldNamingScope.rootScope(cls, registry);
+      } else {
+        _FieldNamingScope superScope =
+            new _FieldNamingScope.forClass(cls.superclass, world, registry);
+        if (cls.isMixinApplication) {
+          result =
+              new _MixinFieldNamingScope.mixedIn(cls, superScope, registry);
+        } else {
+          result = new _FieldNamingScope.inherit(cls, superScope, registry);
+        }
+      }
+    }
+
+    cls.forEachInstanceField((cls, field) => result.add(field));
+
+    registry.scopes[cls] = result;
+    return result;
+  }
+
+  factory _FieldNamingScope.forBox(Local box, _FieldNamingRegistry registry) {
+    return registry.scopes.putIfAbsent(
+        box, () => new _BoxFieldNamingScope(box, registry));
+  }
+
+  _FieldNamingScope.rootScope(this.container, this.registry)
+      : superScope = null,
+        _fieldNameCounter = 0;
+
+  _FieldNamingScope.inherit(this.container, this.superScope, this.registry) {
+    _fieldNameCounter = superScope.inheritanceBasedFieldNameCounter;
+  }
+
+  /**
+   * Checks whether [name] is already used in the current scope chain.
+   */
+  _isNameUnused(jsAst.Name name) {
+    return !names.values.contains(name) &&
+        ((superScope == null) || superScope._isNameUnused(name));
+  }
+
+  jsAst.Name _nextName() => registry.getName(_localFieldNameCounter++);
+
+  jsAst.Name operator [](Element field) {
+    jsAst.Name name = names[field];
+    if (name == null && superScope != null) return superScope[field];
+    return name;
+  }
+
+  void add(Element field) {
+    if (names.containsKey(field)) return;
+
+    jsAst.Name value = _nextName();
+    assert(invariant(field, _isNameUnused(value)));
+    names[field] = value;
+  }
+
+  bool containsField(Element field) => names.containsKey(field);
+}
+
+/**
+ * Field names for mixins have two constraints: They need to be unique in the
+ * hierarchy of each application of a mixin and they need to be the same for
+ * all applications of a mixin. To achieve this, we use global naming for
+ * mixins from the same name pool as fields and add a `$` at the end to ensure
+ * they do not collide with normal field names. The `$` sign is typically used
+ * as a separator between method names and argument counts and does not appear
+ * in generated names themselves.
+ */
+class _MixinFieldNamingScope extends _FieldNamingScope {
+  int get _localFieldNameCounter => registry.globalCount;
+  void set _localFieldNameCounter(int val) {
+    registry.globalCount = val;
+  }
+
+  @override
+  Map<Entity, jsAst.Name> get names => registry.globalNames;
+
+  _MixinFieldNamingScope.mixin(ClassElement cls, _FieldNamingRegistry registry)
+      : super.rootScope(cls, registry);
+
+  _MixinFieldNamingScope.mixedIn(MixinApplicationElement container,
+      _FieldNamingScope superScope, _FieldNamingRegistry registry)
+      : super.inherit(container, superScope, registry);
+
+  jsAst.Name _nextName() {
+    jsAst.Name proposed = super._nextName();
+    return new CompoundName([proposed, Namer._literalDollar]);
+  }
+}
+
+/**
+ * [BoxFieldElement] fields work differently in that they do not belong to an
+ * actual class but an anonymous box associated to a [Local]. As there is no
+ * inheritance chain, we do not need to compute fields a priori but can assign
+ * names on the fly.
+ */
+class _BoxFieldNamingScope extends _FieldNamingScope {
+  _BoxFieldNamingScope(Local box, _FieldNamingRegistry registry)
+      : super.rootScope(box, registry);
+
+  @override
+  bool containsField(_) => true;
+
+  jsAst.Name operator [](Element field) {
+    if (!names.containsKey(field)) add(field);
+    return names[field];
+  }
+}
diff --git a/pkg/compiler/lib/src/js_backend/js_backend.dart b/pkg/compiler/lib/src/js_backend/js_backend.dart
index d44688a..36e75ab 100644
--- a/pkg/compiler/lib/src/js_backend/js_backend.dart
+++ b/pkg/compiler/lib/src/js_backend/js_backend.dart
@@ -7,10 +7,8 @@
 import 'dart:async' show EventSink, Future;
 import 'dart:collection' show HashMap;
 
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
-    as embeddedNames;
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
-    show JsGetName;
+import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
+import 'package:js_runtime/shared/embedded_names.dart' show JsGetName;
 
 import '../closure.dart';
 import '../compile_time_constants.dart';
@@ -55,6 +53,7 @@
 part 'constant_emitter.dart';
 part 'constant_handler_javascript.dart';
 part 'custom_elements_analysis.dart';
+part 'field_naming_mixin.dart';
 part 'minify_namer.dart';
 part 'namer.dart';
 part 'no_such_method_registry.dart';
diff --git a/pkg/compiler/lib/src/js_backend/minify_namer.dart b/pkg/compiler/lib/src/js_backend/minify_namer.dart
index 2f0b37c..9a2d1e3 100644
--- a/pkg/compiler/lib/src/js_backend/minify_namer.dart
+++ b/pkg/compiler/lib/src/js_backend/minify_namer.dart
@@ -7,12 +7,14 @@
 /**
  * Assigns JavaScript identifiers to Dart variables, class-names and members.
  */
-class MinifyNamer extends Namer {
+class MinifyNamer extends Namer with _MinifiedFieldNamer {
   MinifyNamer(Compiler compiler) : super(compiler) {
     reserveBackendNames();
     fieldRegistry = new _FieldNamingRegistry(this);
   }
 
+  _FieldNamingRegistry fieldRegistry;
+
   String get isolateName => 'I';
   String get isolatePropertiesName => 'p';
   bool get shouldMinify => true;
@@ -24,18 +26,17 @@
   final ALPHABET_CHARACTERS = 52;  // a-zA-Z.
   final ALPHANUMERIC_CHARACTERS = 62;  // a-zA-Z0-9.
 
-  _FieldNamingRegistry fieldRegistry;
-
   /// You can pass an invalid identifier to this and unlike its non-minifying
   /// counterpart it will never return the proposedName as the new fresh name.
   ///
   /// [sanitizeForNatives] and [sanitizeForAnnotations] are ignored because the
   /// minified names will always avoid clashing with annotated names or natives.
+  @override
   jsAst.Name getFreshName(String proposedName,
-                             Set<String> usedNames,
-                             Map<String, String> suggestedNames,
-                             {bool sanitizeForNatives: false,
-                              bool sanitizeForAnnotations: false}) {
+                          Set<String> usedNames,
+                          Map<String, String> suggestedNames,
+                          {bool sanitizeForNatives: false,
+                           bool sanitizeForAnnotations: false}) {
     String freshName;
     String suggestion = suggestedNames[proposedName];
     if (suggestion != null && !usedNames.contains(suggestion)) {
@@ -244,209 +245,13 @@
     return $0 + x - 52;
   }
 
+  @override
   jsAst.Name instanceFieldPropertyName(Element element) {
-    if (element.hasFixedBackendName) {
-      return new StringBackedName(element.fixedBackendName);
+    jsAst.Name proposed = _minifiedInstanceFieldPropertyName(element);
+    if (proposed != null) {
+      return proposed;
     }
-
-    _FieldNamingScope names;
-    if (element is BoxFieldElement) {
-      names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
-    } else {
-      ClassElement cls = element is ClosureFieldElement
-          ? element.closureClass : element.enclosingClass;
-      names = new _FieldNamingScope.forClass(cls, compiler.world,
-          fieldRegistry);
-    }
-
-    // The inheritance scope based naming did not yield a name. For instance,
-    // this could be because the field belongs to a mixin.
-    if (!names.containsField(element)) {
-      return super.instanceFieldPropertyName(element);
-    }
-
-    return names[element];
+    return super.instanceFieldPropertyName(element);
   }
 }
 
-/**
- * Encapsulates the global state of field naming.
- */
-class _FieldNamingRegistry {
-  final MinifyNamer namer;
-
-  final Map<Entity, _FieldNamingScope> scopes =
-      new Map<Entity, _FieldNamingScope>();
-
-  final Map<Entity, jsAst.Name> globalNames = new Map<Entity, jsAst.Name>();
-
-  int globalCount = 0;
-
-  final List<jsAst.Name> nameStore = new List<jsAst.Name>();
-
-  _FieldNamingRegistry(this.namer);
-
-  jsAst.Name getName(int count) {
-    if (count >= nameStore.length) {
-      // The namer usually does not use certain names as they clash with
-      // existing properties on JS objects (see [_reservedNativeProperties]).
-      // However, some of them are really short and safe to use for fields.
-      // Thus, we shortcut the namer to use those first.
-      if (count < MinifyNamer._reservedNativeProperties.length &&
-          MinifyNamer._reservedNativeProperties[count].length <= 2) {
-        nameStore.add(new StringBackedName(
-            MinifyNamer._reservedNativeProperties[count]));
-      } else {
-        nameStore.add(namer.getFreshName("field$count",
-            namer.usedInstanceNames, namer.suggestedInstanceNames));
-      }
-    }
-
-    return nameStore[count];
-  }
-}
-
-/**
- * A [_FieldNamingScope] encodes a node in the inheritance tree of the current
- * class hierarchy. The root node typically is the node corresponding to the
- * `Object` class. It is used to assign a unique name to each field of a class.
- * Unique here means unique wrt. all fields along the path back to the root.
- * This is achieved at construction time via the [_fieldNameCounter] field that
- * counts the number of fields on the path to the root node that have been
- * encountered so far.
- *
- * Obviously, this only works if no fields are added to a parent node after its
- * children have added their first field.
- */
-class _FieldNamingScope {
-  final _FieldNamingScope superScope;
-  final Entity container;
-  final Map<Element, jsAst.Name> names = new Maplet<Element, jsAst.Name>();
-  final _FieldNamingRegistry registry;
-
-  /// Naming counter used for fields of ordinary classes.
-  int _fieldNameCounter;
-
-  /// The number of fields along the superclass chain that use inheritance
-  /// based naming, including the ones allocated for this scope.
-  int get inheritanceBasedFieldNameCounter => _fieldNameCounter;
-
-  /// The number of locally used fields. Depending on the naming source
-  /// (e.g. inheritance based or globally unique for mixixns) this
-  /// might be different from [inheritanceBasedFieldNameCounter].
-  int get _localFieldNameCounter => _fieldNameCounter;
-  void set _localFieldNameCounter(int val) { _fieldNameCounter = val; }
-
-  factory _FieldNamingScope.forClass(ClassElement cls, ClassWorld world,
-      _FieldNamingRegistry registry) {
-    _FieldNamingScope result = registry.scopes[cls];
-    if (result != null) return result;
-
-    if (world.isUsedAsMixin(cls)) {
-      result = new _MixinFieldNamingScope.mixin(cls, registry);
-    } else {
-      if (cls.superclass == null) {
-        result = new _FieldNamingScope.rootScope(cls, registry);
-      } else {
-        _FieldNamingScope superScope = new _FieldNamingScope.forClass(
-            cls.superclass, world, registry);
-        if (cls.isMixinApplication) {
-          result = new _MixinFieldNamingScope.mixedIn(cls, superScope,
-              registry);
-        } else {
-          result = new _FieldNamingScope.inherit(cls, superScope, registry);
-        }
-      }
-    }
-
-    cls.forEachInstanceField((cls, field) => result.add(field));
-
-    registry.scopes[cls] = result;
-    return result;
-  }
-
-  factory _FieldNamingScope.forBox(Local box, _FieldNamingRegistry registry) {
-    return registry.scopes.putIfAbsent(box,
-        () => new _BoxFieldNamingScope(box, registry));
-  }
-
-  _FieldNamingScope.rootScope(this.container, this.registry)
-    : superScope = null,
-      _fieldNameCounter = 0;
-
-  _FieldNamingScope.inherit(this.container, this.superScope, this.registry) {
-    _fieldNameCounter = superScope.inheritanceBasedFieldNameCounter;
-  }
-
-  /**
-   * Checks whether [name] is already used in the current scope chain.
-   */
-  _isNameUnused(jsAst.Name name) {
-    return !names.values.contains(name) &&
-        ((superScope == null) || superScope._isNameUnused(name));
-  }
-
-  jsAst.Name _nextName() => registry.getName(_localFieldNameCounter++);
-
-  jsAst.Name operator[](Element field) {
-    jsAst.Name name = names[field];
-    if (name == null && superScope != null) return superScope[field];
-    return name;
-  }
-
-  void add(Element field) {
-    if (names.containsKey(field)) return;
-
-    jsAst.Name value = _nextName();
-    assert(invariant(field, _isNameUnused(value)));
-    names[field] = value;
-  }
-
-  bool containsField(Element field) => names.containsKey(field);
-}
-
-/**
- * Field names for mixins have two constraints: They need to be unique in the
- * hierarchy of each application of a mixin and they need to be the same for
- * all applications of a mixin. To achieve this, we use global naming for
- * mixins from the same name pool as fields and add a `$` at the end to ensure
- * they do not collide with normal field names. The `$` sign is typically used
- * as a separator between method names and argument counts and does not appear
- * in generated names themselves.
- */
-class _MixinFieldNamingScope extends _FieldNamingScope {
-  int get _localFieldNameCounter => registry.globalCount;
-  void set _localFieldNameCounter(int val) { registry.globalCount = val; }
-
-  Map<Entity, jsAst.Name> get names => registry.globalNames;
-
-  _MixinFieldNamingScope.mixin(ClassElement cls, _FieldNamingRegistry registry)
-    : super.rootScope(cls, registry);
-
-  _MixinFieldNamingScope.mixedIn(MixinApplicationElement container,
-      _FieldNamingScope superScope, _FieldNamingRegistry registry)
-    : super.inherit(container, superScope, registry);
-
-  jsAst.Name _nextName() {
-    jsAst.Name proposed = super._nextName();
-    return new CompoundName([proposed, Namer._literalDollar]);
-  }
-}
-
-/**
- * [BoxFieldElement] fields work differently in that they do not belong to an
- * actual class but an anonymous box associated to a [Local]. As there is no
- * inheritance chain, we do not need to compute fields a priori but can assign
- * names on the fly.
- */
-class _BoxFieldNamingScope extends _FieldNamingScope {
-  _BoxFieldNamingScope(Local box, _FieldNamingRegistry registry) :
-    super.rootScope(box, registry);
-
-  bool containsField(_) => true;
-
-  jsAst.Name operator[](Element field) {
-    if (!names.containsKey(field)) add(field);
-    return names[field];
-  }
-}
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index 45604fde1..366d769 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -12,7 +12,7 @@
   ClassStubGenerator(this.compiler, this.namer, this.backend);
 
   jsAst.Expression generateClassConstructor(ClassElement classElement,
-                                            Iterable<String> fields) {
+                                            Iterable<jsAst.Name> fields) {
     // TODO(sra): Implement placeholders in VariableDeclaration position:
     //
     //     String constructorName = namer.getNameOfClass(classElement);
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
index 89b615d..09d9d18 100644
--- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -93,10 +93,8 @@
 import '../deferred_load.dart' show
     OutputUnit;
 
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
-    as embeddedNames;
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show
-    JsBuiltin;
+import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
+import 'package:js_runtime/shared/embedded_names.dart' show JsBuiltin;
 
 import '../native/native.dart' as native;
 part 'class_stub_generator.dart';
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart
index d3425bf..b431c6d 100644
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/emitter.dart
@@ -4,7 +4,7 @@
 
 library dart2js.new_js_emitter.emitter;
 
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show
+import 'package:js_runtime/shared/embedded_names.dart' show
     JsBuiltin,
     METADATA,
     TYPES;
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
index 8ccd680..f34051c1 100644
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart
@@ -15,7 +15,7 @@
 
 import '../js_emitter.dart' show AstContainer, NativeEmitter;
 
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show
+import 'package:js_runtime/shared/embedded_names.dart' show
     CREATE_NEW_ISOLATE,
     DEFERRED_LIBRARY_URIS,
     DEFERRED_LIBRARY_HASHES,
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
index a4417c1..47bd9ff 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
@@ -60,7 +60,7 @@
   * Emits the precompiled constructor when in CSP mode.
   */
   void emitConstructorsForCSP(Class cls) {
-    List<String> fieldNames = <String>[];
+    List<jsAst.Name> fieldNames = <jsAst.Name>[];
 
     if (!compiler.useContentSecurityPolicy) return;
 
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
index 2749850..552fd27 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
@@ -1018,14 +1018,19 @@
   void assemblePrecompiledConstructor(OutputUnit outputUnit,
                                       jsAst.Name constructorName,
                                       jsAst.Expression constructorAst,
-                                      List<String> fields) {
+                                      List<jsAst.Name> fields) {
     cspPrecompiledFunctionFor(outputUnit).add(
         new jsAst.FunctionDeclaration(constructorName, constructorAst));
 
     String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
     bool hasIsolateSupport = compiler.hasIsolateSupport;
-    jsAst.Node fieldNamesArray =
-        hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull();
+    jsAst.Node fieldNamesArray;
+    if (hasIsolateSupport) {
+      fieldNamesArray =
+          new jsAst.ArrayInitializer(fields.map(js.quoteName).toList());
+    } else {
+      fieldNamesArray = new jsAst.LiteralNull();
+    }
 
     cspPrecompiledFunctionFor(outputUnit).add(js.statement(r'''
         {
@@ -1084,7 +1089,7 @@
       // Also emit a trivial constructor for CSP mode.
       jsAst.Name constructorName = mangledName;
       jsAst.Expression constructorAst = js('function() {}');
-      List<String> fieldNames = [];
+      List<jsAst.Name> fieldNames = [];
       assemblePrecompiledConstructor(mainOutputUnit,
                                      constructorName,
                                      constructorAst,
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index a566d3f..227030a 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -102,9 +102,10 @@
  * 'dart:core' and 'dart:_js_helper' are not readable themselves but are instead
  * resolved into a readable URI using the library root URI provided from the
  * command line and the list of platform libraries found in
- * 'sdk/lib/_internal/libraries.dart'. This is done through the
- * [Compiler.translateResolvedUri] method which checks whether a library by that
- * name exists and in case of internal libraries whether access is granted.
+ * 'sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart'. This is done
+ * through the [Compiler.translateResolvedUri] method which checks whether a
+ * library by that name exists and in case of internal libraries whether access
+ * is granted.
  *
  * ## Resource URI ##
  *
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
index 51ab110..5bf4b1e 100644
--- a/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
+++ b/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
@@ -193,11 +193,11 @@
     Script script = getScript();
     SourceSpan span;
     if (beginToken == null) {
-      span = new SourceSpan(script.readableUri, 0, 0);
+      span = new SourceSpan(script.resourceUri, 0, 0);
     } else {
       Token endToken = getEndToken();
       span = mirrorSystem.compiler.spanFromTokens(
-          beginToken, endToken, script.readableUri);
+          beginToken, endToken, script.resourceUri);
     }
     return new Dart2JsSourceLocation(script, span);
   }
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
index f64c5de..b0bde83 100644
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -9,7 +9,7 @@
  * [FunctionElement]. Patches are introduced in patch libraries which are loaded
  * together with the corresponding origin library. Which libraries that are
  * patched is determined by the dart2jsPatchPath field of LibraryInfo found
- * in [:lib/_internal/libraries.dart:].
+ * in [:lib/_internal/sdk_library_metadata/lib/libraries.dart:].
  *
  * Patch libraries are parsed like regular library and thus provided with their
  * own elements. These elements which are distinct from the elements from the
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 977b688..bcf6113 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -6,12 +6,18 @@
 
 class InitializerResolver {
   final ResolverVisitor visitor;
-  final Map<Element, Node> initialized;
+  final ConstructorElementX constructor;
+  final FunctionExpression functionNode;
+  final Map<FieldElement, Node> initialized = <FieldElement, Node>{};
+  final Map<FieldElement, ConstantExpression> fieldInitializers =
+      <FieldElement, ConstantExpression>{};
   Link<Node> initializers;
-  bool hasSuper;
+  bool hasSuper = false;
+  bool isValidAsConstant = true;
 
-  InitializerResolver(this.visitor)
-    : initialized = new Map<Element, Node>(), hasSuper = false;
+  bool get isConst => constructor.isConst;
+
+  InitializerResolver(this.visitor, this.constructor, this.functionNode);
 
   ResolutionRegistry get registry => visitor.registry;
 
@@ -37,6 +43,7 @@
     visitor.compiler.reportInfo(
         existing,
         MessageKind.ALREADY_INITIALIZED, {'fieldName': field.name});
+    isValidAsConstant = false;
   }
 
   void checkForDuplicateInitializers(FieldElementX field, Node init) {
@@ -54,12 +61,13 @@
     initialized[field] = init;
   }
 
-  void resolveFieldInitializer(FunctionElement constructor, SendSet init) {
+  void resolveFieldInitializer(SendSet init) {
     // init is of the form [this.]field = value.
     final Node selector = init.selector;
     final String name = selector.asIdentifier().source;
     // Lookup target field.
     Element target;
+    FieldElement field;
     if (isFieldInitializer(init)) {
       target = constructor.enclosingClass.lookupLocalMember(name);
       if (target == null) {
@@ -72,6 +80,8 @@
             selector.asIdentifier(), constructor.enclosingClass);
       } else if (!target.isInstanceMember) {
         error(selector, MessageKind.INIT_STATIC_FIELD, {'fieldName': name});
+      } else {
+        field = target;
       }
     } else {
       error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER);
@@ -80,38 +90,44 @@
     registry.registerStaticUse(target);
     checkForDuplicateInitializers(target, init);
     // Resolve initializing value.
-    visitor.visitInStaticContext(init.arguments.head);
-  }
-
-  ClassElement getSuperOrThisLookupTarget(FunctionElement constructor,
-                                          bool isSuperCall,
-                                          Node diagnosticNode) {
-    ClassElement lookupTarget = constructor.enclosingClass;
-    if (isSuperCall) {
-      // Calculate correct lookup target and constructor name.
-      if (identical(lookupTarget, visitor.compiler.objectClass)) {
-        error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
+    ResolutionResult result = visitor.visitInStaticContext(
+        init.arguments.head,
+        inConstantInitializer: isConst);
+    if (isConst) {
+      if (result.isConstant && field != null) {
+        // TODO(johnniwinther): Report error if `result.constant` is `null`.
+        fieldInitializers[field] = result.constant;
       } else {
-        return lookupTarget.supertype.element;
+        isValidAsConstant = false;
       }
     }
-    return lookupTarget;
   }
 
-  Element resolveSuperOrThisForSend(FunctionElement constructor,
-                                    FunctionExpression functionNode,
-                                    Send call) {
-    // Resolve the selector and the arguments.
-    visitor.inStaticContext(() {
-      visitor.resolveSelector(call, null);
-      visitor.resolveArguments(call.argumentsNode);
-    });
-    Selector selector = registry.getSelector(call);
-    bool isSuperCall = Initializers.isSuperConstructorCall(call);
+  InterfaceType getSuperOrThisLookupTarget(Node diagnosticNode,
+                                           {bool isSuperCall}) {
+    if (isSuperCall) {
+      // Calculate correct lookup target and constructor name.
+      if (identical(constructor.enclosingClass, visitor.compiler.objectClass)) {
+        error(diagnosticNode, MessageKind.SUPER_INITIALIZER_IN_OBJECT);
+        isValidAsConstant = false;
+      } else {
+        return constructor.enclosingClass.supertype;
+      }
+    }
+    return constructor.enclosingClass.thisType;
+  }
 
-    ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
-                                                           isSuperCall,
-                                                           call);
+  ResolutionResult resolveSuperOrThisForSend(Send call) {
+    // Resolve the selector and the arguments.
+    ArgumentsResult argumentsResult = visitor.inStaticContext(() {
+      visitor.resolveSelector(call, null);
+      return visitor.resolveArguments(call.argumentsNode);
+    }, inConstantInitializer: isConst);
+
+    bool isSuperCall = Initializers.isSuperConstructorCall(call);
+    InterfaceType targetType =
+        getSuperOrThisLookupTarget(call, isSuperCall: isSuperCall);
+    ClassElement lookupTarget = targetType.element;
     Selector constructorSelector =
         visitor.getRedirectingThisOrSuperConstructorSelector(call);
     FunctionElement calledConstructor =
@@ -119,9 +135,8 @@
 
     final bool isImplicitSuperCall = false;
     final String className = lookupTarget.name;
-    verifyThatConstructorMatchesCall(constructor,
-                                     calledConstructor,
-                                     selector.callStructure,
+    verifyThatConstructorMatchesCall(calledConstructor,
+                                     argumentsResult.callStructure,
                                      isImplicitSuperCall,
                                      call,
                                      className,
@@ -129,11 +144,28 @@
 
     registry.useElement(call, calledConstructor);
     registry.registerStaticUse(calledConstructor);
-    return calledConstructor;
+    if (isConst) {
+      if (isValidAsConstant &&
+          calledConstructor.isConst &&
+          argumentsResult.isValidAsConstant) {
+        CallStructure callStructure = argumentsResult.callStructure;
+        List<ConstantExpression> arguments = argumentsResult.constantArguments;
+        return new ConstantResult(
+            call,
+            new ConstructedConstantExpression(
+                targetType,
+                calledConstructor,
+                callStructure,
+                arguments),
+            element: calledConstructor);
+      } else {
+        isValidAsConstant = false;
+      }
+    }
+    return new ResolutionResult.forElement(calledConstructor);
   }
 
-  void resolveImplicitSuperConstructorSend(FunctionElement constructor,
-                                           FunctionExpression functionNode) {
+  ConstructedConstantExpression resolveImplicitSuperConstructorSend() {
     // If the class has a super resolve the implicit super call.
     ClassElement classElement = constructor.enclosingClass;
     ClassElement superClass = classElement.superclass;
@@ -141,18 +173,16 @@
       assert(superClass != null);
       assert(superClass.isResolved);
 
-      final bool isSuperCall = true;
-      ClassElement lookupTarget = getSuperOrThisLookupTarget(constructor,
-                                                             isSuperCall,
-                                                             functionNode);
+      InterfaceType targetType =
+          getSuperOrThisLookupTarget(functionNode, isSuperCall: true);
+      ClassElement lookupTarget = targetType.element;
       Selector constructorSelector = new Selector.callDefaultConstructor();
       Element calledConstructor = lookupTarget.lookupConstructor(
           constructorSelector.name);
 
       final String className = lookupTarget.name;
       final bool isImplicitSuperCall = true;
-      verifyThatConstructorMatchesCall(constructor,
-                                       calledConstructor,
+      verifyThatConstructorMatchesCall(calledConstructor,
                                        CallStructure.NO_ARGS,
                                        isImplicitSuperCall,
                                        functionNode,
@@ -160,19 +190,27 @@
                                        constructorSelector);
       registry.registerImplicitSuperCall(calledConstructor);
       registry.registerStaticUse(calledConstructor);
+
+      if (isConst && isValidAsConstant) {
+        return new ConstructedConstantExpression(
+            targetType,
+            calledConstructor,
+            CallStructure.NO_ARGS,
+            const <ConstantExpression>[]);
+      }
     }
+    return null;
   }
 
   void verifyThatConstructorMatchesCall(
-      FunctionElement caller,
       ConstructorElementX lookedupConstructor,
       CallStructure call,
       bool isImplicitSuperCall,
       Node diagnosticNode,
       String className,
       Selector constructorSelector) {
-    if (lookedupConstructor == null
-        || !lookedupConstructor.isGenerativeConstructor) {
+    if (lookedupConstructor == null ||
+        !lookedupConstructor.isGenerativeConstructor) {
       String fullConstructorName = Elements.constructorNameForDiagnostics(
               className,
               constructorSelector.name);
@@ -181,19 +219,22 @@
           : MessageKind.CANNOT_RESOLVE_CONSTRUCTOR;
       visitor.compiler.reportError(
           diagnosticNode, kind, {'constructorName': fullConstructorName});
+      isValidAsConstant = false;
     } else {
       lookedupConstructor.computeSignature(visitor.compiler);
-      if (!call.signatureApplies(lookedupConstructor)) {
+      if (!call.signatureApplies(lookedupConstructor.functionSignature)) {
         MessageKind kind = isImplicitSuperCall
                            ? MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT
                            : MessageKind.NO_MATCHING_CONSTRUCTOR;
         visitor.compiler.reportError(diagnosticNode, kind);
-      } else if (caller.isConst
+        isValidAsConstant = false;
+      } else if (constructor.isConst
                  && !lookedupConstructor.isConst) {
         MessageKind kind = isImplicitSuperCall
                            ? MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT
                            : MessageKind.CONST_CALLS_NON_CONST;
         visitor.compiler.reportError(diagnosticNode, kind);
+        isValidAsConstant = false;
       }
     }
   }
@@ -202,16 +243,50 @@
    * Resolve all initializers of this constructor. In the case of a redirecting
    * constructor, the resolved constructor's function element is returned.
    */
-  ConstructorElement resolveInitializers(ConstructorElementX constructor,
-                                         FunctionExpression functionNode) {
+  ConstructorElement resolveInitializers() {
+    Map<dynamic/*String|int*/, ConstantExpression> defaultValues =
+        <dynamic/*String|int*/, ConstantExpression>{};
+    ConstructedConstantExpression constructorInvocation;
     // Keep track of all "this.param" parameters specified for constructor so
     // that we can ensure that fields are initialized only once.
     FunctionSignature functionParameters = constructor.functionSignature;
-    functionParameters.forEachParameter((ParameterElement element) {
+    functionParameters.forEachParameter((ParameterElementX element) {
+      if (isConst) {
+        if (element.isOptional) {
+          if (element.constantCache == null) {
+            // TODO(johnniwinther): Remove this when all constant expressions
+            // can be computed during resolution.
+            isValidAsConstant = false;
+          } else {
+            ConstantExpression defaultValue = element.constant;
+            if (defaultValue != null) {
+              if (element.isNamed) {
+                defaultValues[element.name] = defaultValue;
+              } else {
+                int index =
+                    element.functionDeclaration.parameters.indexOf(element);
+                defaultValues[index] = defaultValue;
+              }
+            } else {
+              isValidAsConstant = false;
+            }
+          }
+        }
+      }
       if (element.isInitializingFormal) {
-        InitializingFormalElement initializingFormal = element;
-        checkForDuplicateInitializers(initializingFormal.fieldElement,
-                                      element.initializer);
+        InitializingFormalElementX initializingFormal = element;
+        FieldElement field = initializingFormal.fieldElement;
+        checkForDuplicateInitializers(field, element.initializer);
+        if (isConst) {
+          if (element.isNamed) {
+            fieldInitializers[field] = new NamedArgumentReference(element.name);
+          } else {
+            int index = element.functionDeclaration.parameters.indexOf(element);
+            fieldInitializers[field] = new PositionalArgumentReference(index);
+          }
+        } else {
+          isValidAsConstant = false;
+        }
       }
     });
 
@@ -224,7 +299,7 @@
     for (Link<Node> link = initializers; !link.isEmpty; link = link.tail) {
       if (link.head.asSendSet() != null) {
         final SendSet init = link.head.asSendSet();
-        resolveFieldInitializer(constructor, init);
+        resolveFieldInitializer(init);
       } else if (link.head.asSend() != null) {
         final Send call = link.head.asSend();
         if (call.argumentsNode == null) {
@@ -235,7 +310,14 @@
           if (resolvedSuper) {
             error(call, MessageKind.DUPLICATE_SUPER_INITIALIZER);
           }
-          resolveSuperOrThisForSend(constructor, functionNode, call);
+          ResolutionResult result = resolveSuperOrThisForSend(call);
+          if (isConst) {
+            if (result.isConstant) {
+              constructorInvocation = result.constant;
+            } else {
+              isValidAsConstant = false;
+            }
+          }
           resolvedSuper = true;
         } else if (Initializers.isConstructorRedirect(call)) {
           // Check that there is no body (Language specification 7.5.1).  If the
@@ -256,9 +338,24 @@
             if (parameter.isInitializingFormal) {
               Node node = parameter.node;
               error(node, MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED);
+              isValidAsConstant = false;
             }
           });
-          return resolveSuperOrThisForSend(constructor, functionNode, call);
+          ResolutionResult result = resolveSuperOrThisForSend(call);
+          if (isConst) {
+            if (result.isConstant) {
+              constructorInvocation = result.constant;
+            } else {
+              isValidAsConstant = false;
+            }
+            if (isConst && isValidAsConstant) {
+              constructor.constantConstructor =
+                  new RedirectingGenerativeConstantConstructor(
+                      defaultValues,
+                      constructorInvocation);
+            }
+          }
+          return result.element;
         } else {
           visitor.error(call, MessageKind.CONSTRUCTOR_CALL_EXPECTED);
           return null;
@@ -268,7 +365,14 @@
       }
     }
     if (!resolvedSuper) {
-      resolveImplicitSuperConstructorSend(constructor, functionNode);
+      constructorInvocation = resolveImplicitSuperConstructorSend();
+    }
+    if (isConst && isValidAsConstant) {
+      constructor.constantConstructor = new GenerativeConstantConstructor(
+          constructor.enclosingClass.thisType,
+          defaultValues,
+          fieldInitializers,
+          constructorInvocation);
     }
     return null;  // If there was no redirection always return null.
   }
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 5e5bf53..7c1bdf9 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -4,6 +4,24 @@
 
 part of resolution;
 
+/// The state of constants in resolutions.
+enum ConstantState {
+  /// Expressions are not required to be constants.
+  NON_CONSTANT,
+
+  /// Expressions are required to be constants.
+  ///
+  /// For instance the values of a constant list literal.
+  CONSTANT,
+
+  /// Expressions are required to be constants and parameter references are
+  /// also considered constant.
+  ///
+  /// This is used for resolving constructor initializers of constant
+  /// constructors.
+  CONSTANT_INITIALIZER,
+}
+
 /**
  * Core implementation of resolution.
  *
@@ -23,6 +41,7 @@
   bool inInstanceContext;
   bool inCheckContext;
   bool inCatchBlock;
+  ConstantState constantState;
 
   Scope scope;
   ClassElement currentClass;
@@ -100,6 +119,8 @@
           !element.isTypedef &&
           !element.enclosingElement.isTypedef,
       inCatchBlock = false,
+      constantState = element.isConst
+          ? ConstantState.CONSTANT : ConstantState.NON_CONSTANT,
       super(compiler, registry);
 
   CoreTypes get coreTypes => compiler.coreTypes;
@@ -153,14 +174,6 @@
     return result;
   }
 
-  inStaticContext(action()) {
-    bool wasInstanceContext = inInstanceContext;
-    inInstanceContext = false;
-    var result = action();
-    inInstanceContext = wasInstanceContext;
-    return result;
-  }
-
   doInPromotionScope(Node node, action()) {
     promotionScope = promotionScope.prepend(node);
     var result = action();
@@ -168,8 +181,47 @@
     return result;
   }
 
-  ResolutionResult visitInStaticContext(Node node) {
-    return inStaticContext(() => visit(node));
+  inStaticContext(action(),
+                  {bool inConstantInitializer: false}) {
+    bool wasInstanceContext = inInstanceContext;
+    ConstantState oldConstantState = constantState;
+    constantState = inConstantInitializer
+        ? ConstantState.CONSTANT_INITIALIZER
+        : constantState;
+    inInstanceContext = false;
+    var result = action();
+    inInstanceContext = wasInstanceContext;
+    constantState = oldConstantState;
+    return result;
+  }
+
+  ResolutionResult visitInStaticContext(Node node,
+                                        {bool inConstantInitializer: false}) {
+    return inStaticContext(
+        () => visit(node),
+        inConstantInitializer: inConstantInitializer);
+  }
+
+  /// Execute [action] where the constant state is `ConstantState.CONSTANT` if
+  /// not already `ConstantState.CONSTANT_INITIALIZER`.
+  inConstantContext(action()) {
+    ConstantState oldConstantState = constantState;
+    if (constantState != ConstantState.CONSTANT_INITIALIZER) {
+      constantState = ConstantState.CONSTANT;
+    }
+    var result = action();
+    constantState = oldConstantState;
+    return result;
+  }
+
+  /// Visit [node] where the constant state is `ConstantState.CONSTANT` if
+  /// not already `ConstantState.CONSTANT_INITIALIZER`.
+  ResolutionResult visitInConstantContext(Node node) {
+    ResolutionResult result = inConstantContext(() => visit(node));
+    assert(invariant(node, result != null,
+        message: "No resolution result for $node."));
+
+    return result;
   }
 
   ErroneousElement reportAndCreateErroneousElement(
@@ -324,7 +376,7 @@
     FunctionSignature functionParameters = function.functionSignature;
     Link<Node> parameterNodes = (node.parameters == null)
         ? const Link<Node>() : node.parameters.nodes;
-    functionParameters.forEachParameter((ParameterElement element) {
+    functionParameters.forEachParameter((ParameterElementX element) {
       // TODO(karlklose): should be a list of [FormalElement]s, but the actual
       // implementation uses [Element].
       List<Element> optionals = functionParameters.optionalParameters;
@@ -332,7 +384,16 @@
         NodeList nodes = parameterNodes.head;
         parameterNodes = nodes.nodes;
       }
-      visit(element.initializer);
+      if (element.isOptional) {
+        if (element.initializer != null) {
+          ResolutionResult result = visitInConstantContext(element.initializer);
+          if (result.isConstant) {
+            element.constant = result.constant;
+          }
+        } else {
+          element.constant = new NullConstantExpression();
+        }
+      }
       VariableDefinitions variableDefinitions = parameterNodes.head;
       Node parameterNode = variableDefinitions.definitions.nodes.head;
       // Field parameters (this.x) are not visible inside the constructor. The
@@ -340,7 +401,7 @@
       if (element.isInitializingFormal) {
         registry.useElement(parameterNode, element);
       } else {
-        LocalParameterElement parameterElement = element;
+        LocalParameterElementX parameterElement = element;
         defineLocalVariable(parameterNode, parameterElement);
         addToScope(parameterElement);
       }
@@ -715,8 +776,10 @@
     return selector;
   }
 
-  CallStructure resolveArguments(NodeList list) {
+  ArgumentsResult resolveArguments(NodeList list) {
     if (list == null) return null;
+    bool isValidAsConstant = true;
+    List<ResolutionResult> argumentResults = <ResolutionResult>[];
     bool oldSendIsMemberAccess = sendIsMemberAccess;
     sendIsMemberAccess = false;
     Map<String, Node> seenNamedArguments = new Map<String, Node>();
@@ -724,7 +787,12 @@
     List<String> namedArguments = <String>[];
     for (Link<Node> link = list.nodes; !link.isEmpty; link = link.tail) {
       Expression argument = link.head;
-      visit(argument);
+      ResolutionResult result = visit(argument);
+      if (!result.isConstant) {
+        isValidAsConstant = false;
+      }
+      argumentResults.add(result);
+
       NamedArgument namedArgument = argument.asNamedArgument();
       if (namedArgument != null) {
         String source = namedArgument.name.source;
@@ -734,16 +802,21 @@
               source,
               argument,
               seenNamedArguments[source]);
+          isValidAsConstant = false;
         } else {
           seenNamedArguments[source] = namedArgument;
         }
       } else if (!seenNamedArguments.isEmpty) {
         error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED);
+        isValidAsConstant = false;
       }
       argumentCount++;
     }
     sendIsMemberAccess = oldSendIsMemberAccess;
-    return new CallStructure(argumentCount, namedArguments);
+    return new ArgumentsResult(
+        new CallStructure(argumentCount, namedArguments),
+        argumentResults,
+        isValidAsConstant: isValidAsConstant);
   }
 
   void registerTypeLiteralAccess(Send node, Element target) {
@@ -1380,7 +1453,8 @@
         message: "Unexpected expression: $node"));
     Node expression = node.selector;
     visitExpression(expression);
-    CallStructure callStructure = resolveArguments(node.argumentsNode);
+    CallStructure callStructure =
+        resolveArguments(node.argumentsNode).callStructure;
     Selector selector = callStructure.callSelector;
     // TODO(johnniwinther): Remove this when all information goes through the
     // [SendStructure].
@@ -1398,7 +1472,8 @@
     // If this send is of the form "assert(expr);", then
     // this is an assertion.
 
-    CallStructure callStructure = resolveArguments(node.argumentsNode);
+    CallStructure callStructure =
+        resolveArguments(node.argumentsNode).callStructure;
     SendStructure sendStructure = const AssertStructure();
     if (callStructure.argumentCount != 1) {
       compiler.reportError(
@@ -1430,7 +1505,8 @@
   ResolutionResult handleThisAccess(Send node) {
     AccessSemantics accessSemantics = new AccessSemantics.thisAccess();
     if (node.isCall) {
-      CallStructure callStructure = resolveArguments(node.argumentsNode);
+      CallStructure callStructure =
+          resolveArguments(node.argumentsNode).callStructure;
       Selector selector = callStructure.callSelector;
       // TODO(johnniwinther): Handle invalid this access as an
       // [AccessSemantics].
@@ -1456,7 +1532,8 @@
     Selector selector;
     CallStructure callStructure = CallStructure.NO_ARGS;
     if (node.isCall) {
-      callStructure = resolveArguments(node.argumentsNode);
+      callStructure =
+          resolveArguments(node.argumentsNode).callStructure;
       selector = new Selector(SelectorKind.CALL, name, callStructure);
     } else {
       selector = new Selector(SelectorKind.GETTER, name, callStructure);
@@ -1470,7 +1547,8 @@
           case AccessKind.SUPER_METHOD:
             MethodElementX superMethod = semantics.element;
             superMethod.computeSignature(compiler);
-            if (!callStructure.signatureApplies(superMethod)) {
+            if (!callStructure.signatureApplies(
+                    superMethod.functionSignature)) {
               registry.registerThrowNoSuchMethod();
               registry.registerDynamicInvocation(
                   new UniverseSelector(selector, null));
@@ -1710,7 +1788,8 @@
     SendStructure sendStructure;
     Selector selector;
     if (node.isCall) {
-      CallStructure callStructure = resolveArguments(node.argumentsNode);
+      CallStructure callStructure =
+          resolveArguments(node.argumentsNode).callStructure;
       selector = new Selector(SelectorKind.CALL, name, callStructure);
       registry.registerDynamicInvocation(
           new UniverseSelector(selector, null));
@@ -1802,7 +1881,8 @@
     SendStructure sendStructure;
     Selector selector;
     if (node.isCall) {
-      CallStructure callStructure = resolveArguments(node.argumentsNode);
+      CallStructure callStructure =
+          resolveArguments(node.argumentsNode).callStructure;
       selector = new Selector(SelectorKind.CALL, name, callStructure);
       registry.registerDynamicInvocation(
           new UniverseSelector(selector, null));
@@ -1863,22 +1943,19 @@
 
   /// Handle access of a parameter, local variable or local function.
   ResolutionResult handleLocalAccess(Send node, Name name, Element element) {
+    ResolutionResult result = const NoneResult();
     AccessSemantics semantics = computeLocalAccessSemantics(node, element);
     Selector selector;
-    CallStructure callStructure = CallStructure.NO_ARGS;
     if (node.isCall) {
-      callStructure = resolveArguments(node.argumentsNode);
+      CallStructure callStructure =
+          resolveArguments(node.argumentsNode).callStructure;
       selector = new Selector(SelectorKind.CALL, name, callStructure);
-    } else {
-      selector = new Selector(SelectorKind.GETTER, name, callStructure);
-    }
-    if (node.isCall) {
       bool isIncompatibleInvoke = false;
       switch (semantics.kind) {
         case AccessKind.LOCAL_FUNCTION:
           LocalFunctionElementX function = semantics.element;
           function.computeSignature(compiler);
-          if (!callStructure.signatureApplies(function)) {
+          if (!callStructure.signatureApplies(function.functionSignature)) {
             registry.registerThrowNoSuchMethod();
             registry.registerDynamicInvocation(
                 new UniverseSelector(selector, null));
@@ -1903,6 +1980,48 @@
               ? new IncompatibleInvokeStructure(semantics, selector)
               : new InvokeStructure(semantics, selector));
     } else {
+      switch (semantics.kind) {
+        case AccessKind.LOCAL_VARIABLE:
+        case AccessKind.LOCAL_FUNCTION:
+          result = new ElementResult(element);
+          break;
+        case AccessKind.PARAMETER:
+        case AccessKind.FINAL_PARAMETER:
+          if (constantState == ConstantState.CONSTANT_INITIALIZER) {
+            ParameterElement parameter = element;
+            if (parameter.isNamed) {
+              result = new ConstantResult(
+                  node,
+                  new NamedArgumentReference(parameter.name),
+                  element: element);
+            } else {
+              result = new ConstantResult(
+                  node,
+                  new PositionalArgumentReference(
+                      parameter.functionDeclaration.parameters.indexOf(
+                          parameter)),
+                  element: element);
+            }
+          } else {
+            result = new ElementResult(element);
+          }
+          break;
+        case AccessKind.FINAL_LOCAL_VARIABLE:
+          if (element.isConst) {
+            result = new ConstantResult(
+                node,
+                new VariableConstantExpression(element),
+                element: element);
+          } else {
+            result = new ElementResult(element);
+          }
+          break;
+        default:
+          internalError(node,
+              "Unexpected local access $semantics.");
+          break;
+      }
+      selector = new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS);
       registry.registerSendStructure(node,
           new GetStructure(semantics, selector));
     }
@@ -1914,14 +2033,13 @@
 
     registerPotentialAccessInClosure(node, element);
 
-    return node.isPropertyAccess
-        ? new ElementResult(element) : const NoneResult();
+    return result;
   }
 
   /// Handle access of a static or top level [element].
   ResolutionResult handleStaticOrTopLevelAccess(
         Send node, Name name, Element element) {
-
+    ResolutionResult result = const NoneResult();
     MemberElement member;
     if (element.isAbstractField) {
       AbstractFieldElement abstractField = element;
@@ -1938,23 +2056,21 @@
     member.computeType(compiler);
 
     Selector selector;
-    CallStructure callStructure = CallStructure.NO_ARGS;
-    if (node.isCall) {
-      callStructure = resolveArguments(node.argumentsNode);
-      selector = new Selector(SelectorKind.CALL, name, callStructure);
-    } else {
-      selector = new Selector(SelectorKind.GETTER, name, callStructure);
-    }
     AccessSemantics semantics =
         computeStaticOrTopLevelAccessSemantics(node, member);
     if (node.isCall) {
+      ArgumentsResult argumentsResult =
+          resolveArguments(node.argumentsNode);
+      CallStructure callStructure = argumentsResult.callStructure;
+      selector = new Selector(SelectorKind.CALL, name, callStructure);
+
       bool isIncompatibleInvoke = false;
       switch (semantics.kind) {
         case AccessKind.STATIC_METHOD:
         case AccessKind.TOPLEVEL_METHOD:
           MethodElementX method = semantics.element;
           method.computeSignature(compiler);
-          if (!callStructure.signatureApplies(method)) {
+          if (!callStructure.signatureApplies(method.functionSignature)) {
             registry.registerThrowNoSuchMethod();
             registry.registerDynamicInvocation(
                 new UniverseSelector(selector, null));
@@ -1962,6 +2078,13 @@
           } else {
             registry.registerStaticUse(semantics.element);
             handleForeignCall(node, semantics.element, selector);
+            if (method == compiler.identicalFunction &&
+                argumentsResult.isValidAsConstant) {
+              result = new ConstantResult(node,
+                  new IdenticalConstantExpression(
+                      argumentsResult.argumentResults[0].constant,
+                      argumentsResult.argumentResults[1].constant));
+            }
           }
           break;
         case AccessKind.STATIC_FIELD:
@@ -1993,6 +2116,7 @@
               ? new IncompatibleInvokeStructure(semantics, selector)
               : new InvokeStructure(semantics, selector));
     } else {
+      selector = new Selector(SelectorKind.GETTER, name, CallStructure.NO_ARGS);
       switch (semantics.kind) {
         case AccessKind.STATIC_METHOD:
         case AccessKind.TOPLEVEL_METHOD:
@@ -2024,6 +2148,13 @@
       }
       registry.registerSendStructure(node,
           new GetStructure(semantics, selector));
+      if (member.isConst) {
+        FieldElement field = member;
+        result = new ConstantResult(
+            node, new VariableConstantExpression(field), element: field);
+      } else {
+        result = new ElementResult(member);
+      }
     }
 
     // TODO(johnniwinther): Remove these when all information goes through
@@ -2031,8 +2162,7 @@
     registry.useElement(node, member);
     registry.setSelector(node, selector);
 
-    return node.isPropertyAccess
-        ? new ElementResult(member) : const NoneResult();
+    return result;
   }
 
   /// Handle access to resolved [element].
@@ -2534,6 +2664,7 @@
     }
     ConstructorElementX constructor = enclosingElement;
     bool isConstConstructor = constructor.isConst;
+    bool isValidAsConstant = isConstConstructor;
     ConstructorElement redirectionTarget = resolveRedirectingFactory(
         node, inConstContext: isConstConstructor);
     constructor.immediateRedirectionTarget = redirectionTarget;
@@ -2553,9 +2684,13 @@
       if (isConstConstructor &&
           !redirectionTarget.isConst) {
         compiler.reportError(node, MessageKind.CONSTRUCTOR_IS_NOT_CONST);
+        isValidAsConstant = false;
       }
       if (redirectionTarget == constructor) {
         compiler.reportError(node, MessageKind.CYCLIC_REDIRECTING_FACTORY);
+        // TODO(johnniwinther): Create constant constructor for this case and
+        // let evaluation detect the cyclicity.
+        isValidAsConstant = false;
       }
     }
 
@@ -2570,6 +2705,8 @@
     if (!isSubtype) {
       warning(node, MessageKind.NOT_ASSIGNABLE,
               {'fromType': targetType, 'toType': constructorType});
+      // TODO(johnniwinther): Handle this (potentially) erroneous case.
+      isValidAsConstant = false;
     }
 
     redirectionTarget.computeType(compiler);
@@ -2579,6 +2716,7 @@
     if (!targetSignature.isCompatibleWith(constructorSignature)) {
       assert(!isSubtype);
       registry.registerThrowNoSuchMethod();
+      isValidAsConstant = false;
     }
 
     // Register a post process to check for cycles in the redirection chain and
@@ -2594,6 +2732,30 @@
     if (isSymbolConstructor) {
       registry.registerSymbolConstructor();
     }
+    if (isValidAsConstant) {
+      List<String> names = <String>[];
+      List<ConstantExpression> arguments = <ConstantExpression>[];
+      int index = 0;
+      constructorSignature.forEachParameter((ParameterElement parameter) {
+        if (parameter.isNamed) {
+          String name = parameter.name;
+          names.add(name);
+          arguments.add(new NamedArgumentReference(name));
+        } else {
+          arguments.add(new PositionalArgumentReference(index));
+        }
+        index++;
+      });
+      CallStructure callStructure =
+          new CallStructure(constructorSignature.parameterCount, names);
+      constructor.constantConstructor =
+          new RedirectingFactoryConstantConstructor(
+              new ConstructedConstantExpression(
+                  type,
+                  redirectionTarget,
+                  callStructure,
+                  arguments));
+    }
     return const NoneResult();
   }
 
@@ -2681,12 +2843,19 @@
   }
 
   ResolutionResult visitNewExpression(NewExpression node) {
+    bool isValidAsConstant = true;
     FunctionElement constructor = resolveConstructor(node);
     final bool isSymbolConstructor = constructor == compiler.symbolConstructor;
     final bool isMirrorsUsedConstant =
         node.isConst && (constructor == compiler.mirrorsUsedConstructor);
     Selector callSelector = resolveSelector(node.send, constructor);
-    resolveArguments(node.send.argumentsNode);
+    ArgumentsResult argumentsResult;
+    if (node.isConst) {
+      argumentsResult =
+          inConstantContext(() => resolveArguments(node.send.argumentsNode));
+    } else {
+      argumentsResult = resolveArguments(node.send.argumentsNode);
+    }
     registry.useElement(node.send, constructor);
     if (Elements.isUnresolved(constructor)) {
       return new ResolutionResult.forElement(constructor);
@@ -2704,12 +2873,14 @@
       compiler.reportError(node,
                            MessageKind.CANNOT_INSTANTIATE_ENUM,
                            {'enumName': cls.name});
+      isValidAsConstant = false;
     }
 
     InterfaceType type = registry.getType(node);
     if (node.isConst && type.containsTypeVariables) {
       compiler.reportError(node.send.selector,
                            MessageKind.TYPE_VARIABLE_IN_CONSTANT);
+      isValidAsConstant = false;
     }
     // TODO(johniwinther): Avoid registration of `type` in face of redirecting
     // factory constructors.
@@ -2717,6 +2888,7 @@
     if (constructor.isGenerativeConstructor && cls.isAbstract) {
       warning(node, MessageKind.ABSTRACT_CLASS_INSTANTIATION);
       registry.registerAbstractClassInstantiation();
+      isValidAsConstant = false;
     }
 
     if (isSymbolConstructor) {
@@ -2751,6 +2923,19 @@
     }
     if (node.isConst) {
       analyzeConstantDeferred(node);
+      if (isValidAsConstant &&
+          constructor.isConst &&
+          argumentsResult.isValidAsConstant) {
+        CallStructure callStructure = argumentsResult.callStructure;
+        List<ConstantExpression> arguments = argumentsResult.constantArguments;
+        ConstructedConstantExpression constant =
+            new ConstructedConstantExpression(
+                type,
+                constructor,
+                callStructure,
+                arguments);
+        return new ConstantResult(node, constant);
+      }
     }
 
     return const NoneResult();
@@ -2897,14 +3082,16 @@
     registry.registerRequiredType(listType, enclosingElement);
     if (node.isConst) {
       List<ConstantExpression> constantExpressions = <ConstantExpression>[];
-      for (Node element in node.elements) {
-        ResolutionResult elementResult = visit(element);
-        if (isValidAsConstant && elementResult.isConstant) {
-          constantExpressions.add(elementResult.constant);
-        } else {
-          isValidAsConstant = false;
+      inConstantContext(() {
+        for (Node element in node.elements) {
+          ResolutionResult elementResult = visit(element);
+          if (isValidAsConstant && elementResult.isConstant) {
+            constantExpressions.add(elementResult.constant);
+          } else {
+            isValidAsConstant = false;
+          }
         }
-      }
+      });
       analyzeConstantDeferred(node);
       sendIsMemberAccess = false;
       if (isValidAsConstant) {
@@ -3196,20 +3383,23 @@
     registry.registerMapLiteral(node, mapType, node.isConst);
     registry.registerRequiredType(mapType, enclosingElement);
     if (node.isConst) {
+
       List<ConstantExpression> keyExpressions = <ConstantExpression>[];
       List<ConstantExpression> valueExpressions = <ConstantExpression>[];
-      for (LiteralMapEntry entry in node.entries) {
-        ResolutionResult keyResult = visit(entry.key);
-        ResolutionResult valueResult = visit(entry.value);
-        if (isValidAsConstant &&
-            keyResult.isConstant &&
-            valueResult.isConstant) {
-          keyExpressions.add(keyResult.constant);
-          valueExpressions.add(valueResult.constant);
-        } else {
-          isValidAsConstant = false;
+      inConstantContext(() {
+        for (LiteralMapEntry entry in node.entries) {
+          ResolutionResult keyResult = visit(entry.key);
+          ResolutionResult valueResult = visit(entry.value);
+          if (isValidAsConstant &&
+              keyResult.isConstant &&
+              valueResult.isConstant) {
+            keyExpressions.add(keyResult.constant);
+            valueExpressions.add(valueResult.constant);
+          } else {
+            isValidAsConstant = false;
+          }
         }
-      }
+      });
       analyzeConstantDeferred(node);
       sendIsMemberAccess = false;
       if (isValidAsConstant) {
diff --git a/pkg/compiler/lib/src/resolution/resolution_common.dart b/pkg/compiler/lib/src/resolution/resolution_common.dart
index cb045cf..0f1a778 100644
--- a/pkg/compiler/lib/src/resolution/resolution_common.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_common.dart
@@ -160,9 +160,9 @@
       if (element.isGenerativeConstructor) {
         // Even if there is no initializer list we still have to do the
         // resolution in case there is an implicit super constructor call.
-        InitializerResolver resolver = new InitializerResolver(visitor);
-        FunctionElement redirection =
-            resolver.resolveInitializers(element, tree);
+        InitializerResolver resolver =
+            new InitializerResolver(visitor, element, tree);
+        FunctionElement redirection = resolver.resolveInitializers();
         if (redirection != null) {
           resolveRedirectingConstructor(resolver, tree, element, redirection);
         }
diff --git a/pkg/compiler/lib/src/resolution/resolution_result.dart b/pkg/compiler/lib/src/resolution/resolution_result.dart
index 5426fe3..ba2b74c 100644
--- a/pkg/compiler/lib/src/resolution/resolution_result.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_result.dart
@@ -23,6 +23,7 @@
   }
 
   ResultKind get kind;
+  Node get node => null;
   Element get element => null;
   DartType get type => null;
   ConstantExpression get constant => null;
@@ -64,11 +65,16 @@
   String toString() => 'AssertResult()';
 }
 
+/// The result for resolving a constant expression.
 class ConstantResult extends ResolutionResult {
   final Node node;
   final ConstantExpression constant;
+  final Element element;
 
-  ConstantResult(this.node, this.constant);
+  /// Creates a result for the [constant] expression. [node] is provided for
+  /// error reporting on the constant and [element] is provided if the
+  /// expression additionally serves an [Element] like [ElementResult].
+  ConstantResult(this.node, this.constant, {this.element});
 
   bool get isConstant => true;
 
@@ -83,4 +89,31 @@
   ResultKind get kind => ResultKind.NONE;
 
   String toString() => 'NoneResult()';
+}
+
+/// The result of resolving a list of arguments.
+class ArgumentsResult {
+  /// The call structure of the arguments.
+  final CallStructure callStructure;
+
+  /// The resolutions results for each argument.
+  final List<ResolutionResult> argumentResults;
+
+  /// `true` if the arguments are valid as arguments to a constructed constant
+  /// expression.
+  final bool isValidAsConstant;
+
+  ArgumentsResult(
+      this.callStructure,
+      this.argumentResults,
+      {this.isValidAsConstant});
+
+  /// Returns the list of [ConstantExpression]s for each of the arguments. If
+  /// [isValidAsConstant] is `false`, `null` is returned.
+  List<ConstantExpression> get constantArguments {
+    if (!isValidAsConstant) return null;
+    return argumentResults.map((ResolutionResult result) {
+      return result.constant;
+    }).toList();
+  }
 }
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/resolution/send_resolver.dart b/pkg/compiler/lib/src/resolution/send_resolver.dart
index fa8cacc..d3f4e61 100644
--- a/pkg/compiler/lib/src/resolution/send_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/send_resolver.dart
@@ -333,7 +333,9 @@
           case AccessKind.SUPER_METHOD:
           case AccessKind.TOPLEVEL_METHOD:
             // TODO(johnniwinther): Should local function also be handled here?
-            if (!selector.callStructure.signatureApplies(semantics.element)) {
+            FunctionElement function = semantics.element;
+            FunctionSignature signature = function.functionSignature;
+            if (!selector.callStructure.signatureApplies(signature)) {
               return new IncompatibleInvokeStructure(semantics, selector);
             }
             break;
@@ -586,7 +588,7 @@
           type,
           effectiveTargetSemantics);
     } else {
-      if (!callStructure.signatureApplies(constructor)) {
+      if (!callStructure.signatureApplies(constructor.functionSignature)) {
         return new ConstructorAccessSemantics(
             ConstructorAccessKind.INCOMPATIBLE,
             constructor,
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 50fa510..07e7793 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -1019,12 +1019,18 @@
 /**
  * This class builds SSA nodes for functions represented in AST.
  */
-class SsaBuilder extends NewResolvedVisitor {
+class SsaBuilder extends ast.Visitor
+    with BaseImplementationOfCompoundsMixin,
+         SendResolverMixin,
+         SemanticSendResolvedMixin,
+         NewBulkMixin
+    implements SemanticSendVisitor {
   final Compiler compiler;
   final JavaScriptBackend backend;
   final ConstantSystem constantSystem;
   final CodegenWorkItem work;
   final RuntimeTypes rti;
+  TreeElements elements;
   SourceInformationBuilder sourceInformationBuilder;
   bool inLazyInitializerExpression = false;
 
@@ -1119,13 +1125,26 @@
       this.constantSystem = backend.constantSystem,
       this.work = work,
       this.rti = backend.rti,
-      super(work.resolutionTree) {
+      this.elements = work.resolutionTree {
     localsHandler = new LocalsHandler(this, work.element, null);
     sourceElementStack.add(work.element);
     sourceInformationBuilder =
         sourceInformationFactory.forContext(work.element.implementation);
   }
 
+  @override
+  SemanticSendVisitor get sendVisitor => this;
+
+  @override
+  void visitNode(ast.Node node) {
+    internalError(node, "Unhandled node: $node");
+  }
+
+  @override
+  void apply(ast.Node node, [_]) {
+    node.accept(this);
+  }
+
   CodegenRegistry get registry => work.registry;
 
   /// Returns the current source element.
@@ -1940,12 +1959,13 @@
       }
 
       Element target = constructor.definingConstructor.implementation;
-      bool match = CallStructure.addForwardingElementArgumentsToList(
-          constructor,
-          arguments,
-          target,
-          compileArgument,
-          handleConstantForOptionalParameter);
+      bool match = !target.isErroneous &&
+          CallStructure.addForwardingElementArgumentsToList(
+              constructor,
+              arguments,
+              target,
+              compileArgument,
+              handleConstantForOptionalParameter);
       if (!match) {
         if (compiler.elementHasCompileTimeError(constructor)) {
           return;
@@ -3123,9 +3143,14 @@
     localsHandler.updateLocal(localFunction, pop());
   }
 
+  @override
+  void visitThisGet(ast.Identifier node, [_]) {
+    stack.add(localsHandler.readThis());
+  }
+
   visitIdentifier(ast.Identifier node) {
     if (node.isThis()) {
-      stack.add(localsHandler.readThis());
+      visitThisGet(node);
     } else {
       compiler.internalError(node,
           "SsaFromAstMixin.visitIdentifier on non-this.");
@@ -3401,8 +3426,6 @@
     // TODO(5346): Try to avoid the need for calling [declaration] before
     // creating an [HStatic].
     push(new HStatic(function.declaration, backend.nonNullType));
-    // TODO(ahe): This should be registered in codegen.
-    registry.registerGetOfStaticFunction(function.declaration);
   }
 
   /// Read a local variable, function or parameter.
@@ -4401,18 +4424,6 @@
     generateSuperNoSuchMethodSend(node, selector, arguments);
   }
 
-  /// Handle super constructor invocation.
-  @override
-  void handleSuperConstructorInvoke(ast.Send node) {
-    Selector selector = elements.getSelector(node);
-    Element element = elements[node];
-    if (selector.applies(element, compiler.world)) {
-      generateSuperInvoke(node, element);
-    } else {
-      generateWrongArgumentCountError(node, element, node.arguments);
-    }
-  }
-
   @override
   void visitUnresolvedSuperIndex(
       ast.Send node,
@@ -4575,6 +4586,20 @@
       ast.NodeList arguments,
       CallStructure callStructure,
       _) {
+    handleInvalidSuperInvoke(node, arguments);
+  }
+
+  @override
+  void visitSuperSetterInvoke(
+      ast.Send node,
+      SetterElement setter,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
+    handleInvalidSuperInvoke(node, arguments);
+  }
+
+  void handleInvalidSuperInvoke(ast.Send node, ast.NodeList arguments) {
     Selector selector = elements.getSelector(node);
     List<HInstruction> inputs = <HInstruction>[];
     addGenericSendArgumentsToList(arguments.nodes, inputs);
@@ -4760,7 +4785,7 @@
     return pop();
   }
 
-  handleNewSend(ast.NewExpression node) {
+  void handleNewSend(ast.NewExpression node) {
     ast.Send send = node.send;
     generateIsDeferredLoadedCheckOfSend(send);
 
@@ -4860,13 +4885,16 @@
     }
     // TODO(5347): Try to avoid the need for calling [implementation] before
     // calling [makeStaticArgumentList].
-    if (!callStructure.signatureApplies(constructor.implementation)) {
+    constructorImplementation = constructor.implementation;
+    if (constructorImplementation.isErroneous ||
+        !callStructure.signatureApplies(
+            constructorImplementation.functionSignature)) {
       generateWrongArgumentCountError(send, constructor, send.arguments);
       return;
     }
     inputs.addAll(makeStaticArgumentList(callStructure,
                                          send.arguments,
-                                         constructor.implementation));
+                                         constructorImplementation));
 
     TypeMask elementType = computeType(constructor);
     if (isFixedListConstructorCall) {
@@ -5427,7 +5455,12 @@
   }
 
   @override
-  handleNewExpression(ast.NewExpression node) {
+  void bulkHandleNode(ast.Node node, String message, _) {
+    internalError(node, "Unexpected bulk handled node: $node");
+  }
+
+  @override
+  void bulkHandleNew(ast.NewExpression node, [_]) {
     Element element = elements[node.send];
     final bool isSymbolConstructor = element == compiler.symbolConstructor;
     if (!Elements.isErroneous(element)) {
@@ -5463,6 +5496,17 @@
     }
   }
 
+  @override
+  void errorNonConstantConstructorInvoke(
+      ast.NewExpression node,
+      Element element,
+      DartType type,
+      ast.NodeList arguments,
+      CallStructure callStructure,
+      _) {
+    bulkHandleNew(node);
+  }
+
   void pushInvokeDynamic(ast.Node node,
                          Selector selector,
                          TypeMask mask,
@@ -5690,6 +5734,369 @@
   }
 
   @override
+  void handleSuperCompounds(
+      ast.SendSet node,
+      Element getter,
+      CompoundGetter getterKind,
+      Element setter,
+      CompoundSetter setterKind,
+      CompoundRhs rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitFinalSuperFieldSet(
+      ast.SendSet node,
+      FieldElement field,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperFieldSet(
+      ast.SendSet node,
+      FieldElement field,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperGetterSet(
+      ast.SendSet node,
+      FunctionElement getter,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperIndexSet(
+      ast.SendSet node,
+      FunctionElement function,
+      ast.Node index,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperMethodSet(
+      ast.Send node,
+      MethodElement method,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperSetterSet(
+      ast.SendSet node,
+      FunctionElement setter,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperIndexSet(
+      ast.Send node,
+      Element element,
+      ast.Node index,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperIndexPrefix(
+      ast.Send node,
+      MethodElement indexFunction,
+      MethodElement indexSetFunction,
+      ast.Node index,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperIndexPostfix(
+      ast.Send node,
+      MethodElement indexFunction,
+      MethodElement indexSetFunction,
+      ast.Node index,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperGetterIndexPrefix(
+      ast.Send node,
+      Element element,
+      MethodElement setter,
+      ast.Node index,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperGetterIndexPostfix(
+      ast.Send node,
+      Element element,
+      MethodElement setter,
+      ast.Node index,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperSetterIndexPrefix(
+      ast.Send node,
+      MethodElement indexFunction,
+      Element element,
+      ast.Node index,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperSetterIndexPostfix(
+      ast.Send node,
+      MethodElement indexFunction,
+      Element element,
+      ast.Node index,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperIndexPrefix(
+      ast.Send node,
+      Element element,
+      ast.Node index,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperIndexPostfix(
+      ast.Send node,
+      Element element,
+      ast.Node index,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperCompoundIndexSet(
+      ast.SendSet node,
+      MethodElement getter,
+      MethodElement setter,
+      ast.Node index,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperGetterCompoundIndexSet(
+      ast.Send node,
+      Element element,
+      MethodElement setter,
+      ast.Node index,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperSetterCompoundIndexSet(
+      ast.Send node,
+      MethodElement getter,
+      Element element,
+      ast.Node index,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperCompoundIndexSet(
+      ast.Send node,
+      Element element,
+      ast.Node index,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperFieldCompound(
+      ast.Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitFinalSuperFieldCompound(
+      ast.Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitFinalSuperFieldPrefix(
+      ast.Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperPrefix(
+      ast.Send node,
+      Element element,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperPostfix(
+      ast.Send node,
+      Element element,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperCompound(
+      ast.Send node,
+      Element element,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitFinalSuperFieldPostfix(
+      ast.Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperFieldFieldCompound(
+      ast.Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperGetterSetterCompound(
+      ast.Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperMethodSetterCompound(
+      ast.Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperMethodCompound(
+      ast.Send node,
+      FunctionElement method,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperGetterCompound(
+      ast.Send node,
+      Element element,
+      MethodElement setter,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitUnresolvedSuperSetterCompound(
+      ast.Send node,
+      MethodElement getter,
+      Element element,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperFieldSetterCompound(
+      ast.Send node,
+      FieldElement field,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
+  void visitSuperGetterFieldCompound(
+      ast.Send node,
+      FunctionElement getter,
+      FieldElement field,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    handleSuperSendSet(node);
+  }
+
+  @override
   void visitIndexSet(
       ast.SendSet node,
       ast.Node receiver,
@@ -5699,6 +6106,40 @@
     generateDynamicSend(node);
   }
 
+  @override
+  void visitCompoundIndexSet(
+      ast.SendSet node,
+      ast.Node receiver,
+      ast.Node index,
+      AssignmentOperator operator,
+      ast.Node rhs,
+      _) {
+    generateIsDeferredLoadedCheckOfSend(node);
+    handleIndexSendSet(node);
+  }
+
+  @override
+  void visitIndexPrefix(
+      ast.Send node,
+      ast.Node receiver,
+      ast.Node index,
+      IncDecOperator operator,
+      _) {
+    generateIsDeferredLoadedCheckOfSend(node);
+    handleIndexSendSet(node);
+  }
+
+  @override
+  void visitIndexPostfix(
+      ast.Send node,
+      ast.Node receiver,
+      ast.Node index,
+      IncDecOperator operator,
+      _) {
+    generateIsDeferredLoadedCheckOfSend(node);
+    handleIndexSendSet(node);
+  }
+
   void handleIndexSendSet(ast.SendSet node) {
     ast.Operator op = node.assignmentOperator;
     if ("=" == op.source) {
@@ -6108,27 +6549,36 @@
   }
 
   @override
-  handleSendSet(ast.SendSet node) {
-    ast.Operator op = node.assignmentOperator;
-    generateIsDeferredLoadedCheckOfSend(node);
-    Element element = elements[node];
-    if (!Elements.isUnresolved(element) && element.impliesType) {
-      ast.Identifier selector = node.selector;
-      generateThrowNoSuchMethod(node, selector.source,
-                                argumentNodes: node.arguments);
-    } else if (node.isSuperCall) {
-      handleSuperSendSet(node);
-    } else if (node.isIndex) {
-      handleIndexSendSet(node);
-    } else if ("=" == op.source) {
-      internalError(node, "Unexpected assignment.");
-    } else if (identical(op.source, "is")) {
-      compiler.internalError(op, "is-operator as SendSet.");
-    } else {
-      assert("++" == op.source || "--" == op.source ||
-             node.assignmentOperator.source.endsWith("="));
-      handleCompoundSendSet(node);
-    }
+  void handleDynamicCompounds(
+      ast.Send node,
+      ast.Node receiver,
+      CompoundRhs rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      _) {
+    handleCompoundSendSet(node);
+  }
+
+  @override
+  void handleLocalCompounds(
+      ast.SendSet node,
+      LocalElement local,
+      CompoundRhs rhs,
+      _,
+      {bool isSetterValid}) {
+    handleCompoundSendSet(node);
+  }
+
+  @override
+  void handleStaticCompounds(
+      ast.SendSet node,
+      Element getter,
+      CompoundGetter getterKind,
+      Element setter,
+      CompoundSetter setterKind,
+      CompoundRhs rhs,
+      _) {
+    handleCompoundSendSet(node);
   }
 
   void visitLiteralInt(ast.LiteralInt node) {
@@ -7571,6 +8021,80 @@
       localsHandler.updateLocal(returnLocal, value);
     }
   }
+
+  @override
+  void handleTypeLiteralConstantCompounds(
+      ast.SendSet node,
+      ConstantExpression constant,
+      CompoundRhs rhs,
+      _) {
+    if (rhs.operator.kind == BinaryOperatorKind.IF_NULL) {
+      handleCompoundSendSet(node);
+    } else {
+      handleTypeLiteralCompound(node);
+    }
+  }
+
+  @override
+  void handleTypeVariableTypeLiteralCompounds(
+      ast.SendSet node,
+      TypeVariableElement typeVariable,
+      CompoundRhs rhs,
+      _) {
+    handleTypeLiteralCompound(node);
+  }
+
+  void handleTypeLiteralCompound(ast.SendSet node) {
+    generateIsDeferredLoadedCheckOfSend(node);
+    ast.Identifier selector = node.selector;
+    generateThrowNoSuchMethod(node, selector.source,
+                              argumentNodes: node.arguments);
+  }
+
+  @override
+  void visitConstantGet(
+    ast.Send node,
+    ConstantExpression constant,
+    _) {
+    visitNode(node);
+  }
+
+  @override
+  void visitConstantInvoke(
+    ast.Send node,
+    ConstantExpression constant,
+    ast.NodeList arguments,
+    CallStructure callStreucture,
+    _) {
+    visitNode(node);
+  }
+
+  @override
+  void errorInvalidAssert(
+      ast.Send node,
+      ast.NodeList arguments,
+      _) {
+    visitNode(node);
+  }
+
+  @override
+  void errorUndefinedBinaryExpression(
+      ast.Send node,
+      ast.Node left,
+      ast.Operator operator,
+      ast.Node right,
+      _) {
+    visitNode(node);
+  }
+
+  @override
+  void errorUndefinedUnaryExpression(
+      ast.Send node,
+      ast.Operator operator,
+      ast.Node expression,
+      _) {
+    visitNode(node);
+  }
 }
 
 /**
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index c588a00..2524fdf 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -2136,9 +2136,10 @@
     Element element = node.element;
     assert(element.isFunction || element.isField);
     if (element.isFunction) {
-      push(backend.emitter.isolateStaticClosureAccess(node.element));
+      push(backend.emitter.isolateStaticClosureAccess(element));
+      registry.registerGetOfStaticFunction(element);
     } else {
-      push(backend.emitter.staticFieldAccess(node.element));
+      push(backend.emitter.staticFieldAccess(element));
     }
     registry.registerStaticUse(element);
   }
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index a40d75e..c1d4dac 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -25,13 +25,14 @@
 import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter;
 import '../native/native.dart' as native;
 import '../resolution/operators.dart';
+import '../resolution/semantic_visitor.dart';
 import '../tree/tree.dart' as ast;
 import '../types/types.dart';
 import '../types/constants.dart' show computeTypeMask;
 import '../universe/universe.dart';
 import '../util/util.dart';
 import '../js/rewrite_async.dart';
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart';
+import 'package:js_runtime/shared/embedded_names.dart';
 
 part 'builder.dart';
 part 'codegen.dart';
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
index 65ca23a..2b614ae 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
@@ -61,27 +61,41 @@
     node.body = visitStatement(node.body);
   }
 
-  /// Statement to be executed next by natural fallthrough. Although fallthrough
-  /// is not introduced in this phase, we need to reason about fallthrough when
-  /// evaluating the benefit of swapping the branches of an [If].
-  Statement fallthrough;
+  final FallthroughStack fallthrough = new FallthroughStack();
 
   @override
   void visitInnerFunction(FunctionDefinition node) {
     new LogicalRewriter().rewrite(node);
   }
 
-  Statement visitLabeledStatement(LabeledStatement node) {
-    Statement savedFallthrough = fallthrough;
-    fallthrough = node.next;
-    node.body = visitStatement(node.body);
-    fallthrough = savedFallthrough;
-    node.next = visitStatement(node.next);
-    return node;
+  /// True if the given statement is equivalent to its fallthrough semantics.
+  ///
+  /// This means it will ultimately translate to an empty statement.
+  bool isFallthrough(Statement node) {
+    return node is Break && isFallthroughBreak(node) ||
+           node is Continue && isFallthroughContinue(node) ||
+           node is Return && isFallthroughReturn(node);
   }
 
-  bool isFallthroughBreak(Statement node) {
-    return node is Break && node.target.binding.next == fallthrough;
+  bool isFallthroughBreak(Break node) {
+    Statement target = fallthrough.target;
+    return node.target.binding.next == target ||
+           target is Break && target.target == node.target;
+  }
+
+  bool isFallthroughContinue(Continue node) {
+    Statement target = fallthrough.target;
+    return node.target.binding == target ||
+           target is Continue && target.target == node.target;
+  }
+
+  bool isFallthroughReturn(Return node) {
+    return isNull(node.value) && fallthrough.target == null;
+  }
+
+  bool isTerminator(Statement node) {
+    return (node is Jump || node is Return) && !isFallthrough(node) ||
+           (node is ExpressionStatement && node.next is Unreachable);
   }
 
   Statement visitIf(If node) {
@@ -94,27 +108,64 @@
     // In the tree language, empty statements do not exist yet, so we must check
     // if one branch contains a break that can be eliminated by fallthrough.
 
-    // Swap branches if then is a fallthrough break.
-    if (isFallthroughBreak(node.thenStatement)) {
+    // Rewrite each branch and keep track of which ones might fall through.
+    int usesBefore = fallthrough.useCount;
+    node.thenStatement = visitStatement(node.thenStatement);
+    int usesAfterThen = fallthrough.useCount;
+    node.elseStatement = visitStatement(node.elseStatement);
+    bool thenHasFallthrough = (fallthrough.useCount > usesBefore);
+    bool elseHasFallthrough = (fallthrough.useCount > usesAfterThen);
+
+    // Determine which branch is most beneficial as 'then' branch.
+    const int THEN = 1;
+    const int NEITHER = 0;
+    const int ELSE = -1;
+    int bestThenBranch = NEITHER;
+    if (isFallthrough(node.thenStatement) &&
+        !isFallthrough(node.elseStatement)) {
+      // Put the empty statement in the 'else' branch.
+      // if (E) {} else {S} ==> if (!E) {S}
+      bestThenBranch = ELSE;
+    } else if (isFallthrough(node.elseStatement) &&
+               !isFallthrough(node.thenStatement)) {
+      // Keep the empty statement in the 'else' branch.
+      // if (E) {S} else {}
+      bestThenBranch = THEN;
+    } else if (thenHasFallthrough && !elseHasFallthrough) {
+      // Put abrupt termination in the 'then' branch to omit 'else'.
+      // if (E) {S1} else {S2; return v} ==> if (!E) {S2; return v}; S1
+      bestThenBranch = ELSE;
+    } else if (!thenHasFallthrough && elseHasFallthrough) {
+      // Keep abrupt termination in the 'then' branch to omit 'else'.
+      // if (E) {S1; return v}; S2
+      bestThenBranch = THEN;
+    } else if (isTerminator(node.elseStatement) &&
+               !isTerminator(node.thenStatement)) {
+      // Put early termination in the 'then' branch to reduce nesting depth.
+      // if (E) {S}; return v ==> if (!E) return v; S
+      bestThenBranch = ELSE;
+    } else if (isTerminator(node.thenStatement) &&
+               !isTerminator(node.elseStatement)) {
+      // Keep early termination in the 'then' branch to reduce nesting depth.
+      // if (E) {return v;} S
+      bestThenBranch = THEN;
+    }
+
+    // Swap branches if 'else' is better as 'then'
+    if (bestThenBranch == ELSE) {
       node.condition = new Not(node.condition);
       Statement tmp = node.thenStatement;
       node.thenStatement = node.elseStatement;
       node.elseStatement = tmp;
     }
 
-    // Can the else part be eliminated?
-    // (Either due to the above swap or if the break was already there).
-    bool emptyElse = isFallthroughBreak(node.elseStatement);
-
-    node.condition = makeCondition(node.condition, true, liftNots: !emptyElse);
-    node.thenStatement = visitStatement(node.thenStatement);
-    node.elseStatement = visitStatement(node.elseStatement);
-
-    // If neither branch is empty, eliminate a negation in the condition
+    // If neither branch is better, eliminate a negation in the condition
     // if (!E) S1 else S2
     //   ==>
     // if (E) S2 else S1
-    if (!emptyElse && node.condition is Not) {
+    node.condition = makeCondition(node.condition, true,
+                                   liftNots: bestThenBranch == NEITHER);
+    if (bestThenBranch == NEITHER && node.condition is Not) {
       node.condition = (node.condition as Not).operand;
       Statement tmp = node.thenStatement;
       node.thenStatement = node.elseStatement;
@@ -124,13 +175,52 @@
     return node;
   }
 
+  Statement visitLabeledStatement(LabeledStatement node) {
+    fallthrough.push(node.next);
+    node.body = visitStatement(node.body);
+    fallthrough.pop();
+    node.next = visitStatement(node.next);
+    return node;
+  }
+
+  Statement visitWhileTrue(WhileTrue node) {
+    fallthrough.push(node);
+    node.body = visitStatement(node.body);
+    fallthrough.pop();
+    return node;
+  }
+
   Statement visitWhileCondition(WhileCondition node) {
+    fallthrough.push(node);
     node.condition = makeCondition(node.condition, true, liftNots: false);
     node.body = visitStatement(node.body);
+    fallthrough.pop();
     node.next = visitStatement(node.next);
     return node;
   }
 
+  Statement visitBreak(Break node) {
+    if (isFallthroughBreak(node)) {
+      fallthrough.use();
+    }
+    return node;
+  }
+
+  Statement visitContinue(Continue node) {
+    if (isFallthroughContinue(node)) {
+      fallthrough.use();
+    }
+    return node;
+  }
+
+  Statement visitReturn(Return node) {
+    node.value = visitExpression(node.value);
+    if (isFallthroughReturn(node)) {
+      fallthrough.use();
+    }
+    return node;
+  }
+
   Expression visitNot(Not node) {
     return toBoolean(makeCondition(node.operand, false, liftNots: false));
   }
@@ -391,6 +481,10 @@
     return polarity ? e : new Not(e);
   }
 
+  bool isNull(Expression e) {
+    return e is Constant && e.value.isNull;
+  }
+
   bool isTrue(Expression e) {
     return e is Constant && e.value.isTrue;
   }
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
index 68b8459..bad7690 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -307,7 +307,7 @@
       // Handle constant assignments specially.
       // They are always safe to propagate (though we should avoid duplication).
       // Moreover, they should not prevent other expressions from propagating.
-      if (assign.variable.readCount <= 1) {
+      if (assign.variable.readCount == 1) {
         // A single-use constant should always be propagted to its use site.
         constantEnvironment[assign.variable] = assign.value;
         --assign.variable.writeCount;
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
index 0d663c5..6e39aae 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -320,7 +320,7 @@
     // Introduce labels for continuations that need them.
     int safeForInliningLengthOnEntry = safeForInlining.length;
     for (cps_ir.Continuation continuation in node.continuations) {
-      if (continuation.hasMultipleUses) {
+      if (continuation.hasMultipleUses || continuation.isRecursive) {
         labels[continuation] = new Label();
       } else {
         safeForInlining.add(continuation);
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
index 3c937f1..ab549e2 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -1341,3 +1341,39 @@
     return node;
   }
 }
+
+class FallthroughTarget {
+  final Statement target;
+  int useCount = 0;
+
+  FallthroughTarget(this.target);
+}
+
+/// A stack machine for tracking fallthrough while traversing the Tree IR.
+class FallthroughStack {
+  final List<FallthroughTarget> _stack =
+    <FallthroughTarget>[new FallthroughTarget(null)];
+
+  /// Set a new fallthrough target.
+  void push(Statement newFallthrough) {
+    _stack.add(new FallthroughTarget(newFallthrough));
+  }
+
+  /// Remove the current fallthrough target.
+  void pop() {
+    _stack.removeLast();
+  }
+
+  /// The current fallthrough target, or `null` if control will fall over
+  /// the end of the method.
+  Statement get target => _stack.last.target;
+
+  /// Number of uses of the current fallthrough target.
+  int get useCount => _stack.last.useCount;
+
+  /// Indicate that a statement will fall through to the current fallthrough
+  /// target.
+  void use() {
+    ++_stack.last.useCount;
+  }
+}
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
index ab4b5b0..caffb4a 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
@@ -328,7 +328,7 @@
 
   @override
   visitForeignStatement(ForeignStatement node) {
-    printStatement(null, 'foreign');
+    printStatement(null, 'foreign ${node.codeTemplate.source}');
   }
 }
 
@@ -522,7 +522,7 @@
   @override
   String visitForeignExpression(ForeignExpression node) {
     String arguments = node.arguments.map(visitExpression).join(', ');
-    return 'Foreign "${node.codeTemplate}"($arguments)';
+    return 'Foreign "${node.codeTemplate.source}"($arguments)';
   }
 
   @override
diff --git a/pkg/compiler/lib/src/types/constants.dart b/pkg/compiler/lib/src/types/constants.dart
index 1bcc1be..27b21c8 100644
--- a/pkg/compiler/lib/src/types/constants.dart
+++ b/pkg/compiler/lib/src/types/constants.dart
@@ -1,114 +1,114 @@
-// 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 types.constants;

-

-import '../constants/values.dart';

-import '../dart2jslib.dart';

-import 'types.dart';

-import '../js_backend/js_backend.dart' show SyntheticConstantKind;

-

-/// Computes the [TypeMask] for the constant [value].

-TypeMask computeTypeMask(Compiler compiler, ConstantValue value) {

-  return value.accept(const ConstantValueTypeMasks(), compiler);

-}

-

-class ConstantValueTypeMasks extends ConstantValueVisitor<TypeMask, Compiler> {

-  const ConstantValueTypeMasks();

-

-  @override

-  TypeMask visitConstructed(ConstructedConstantValue constant,

-                            Compiler compiler) {

-    if (compiler.backend.isInterceptorClass(constant.type.element)) {

-      return compiler.typesTask.nonNullType;

-    }

-    return new TypeMask.nonNullExact(constant.type.element, compiler.world);

-  }

-

-  @override

-  TypeMask visitDeferred(DeferredConstantValue constant, Compiler compiler) {

-    return constant.referenced.accept(this, compiler);

-  }

-

-  @override

-  TypeMask visitDouble(DoubleConstantValue constant, Compiler compiler) {

-    // We have to distinguish -0.0 from 0, but for all practical purposes

-    // -0.0 is an integer.

-    // TODO(17235): this kind of special casing should only happen in the

-    // backend.

-    if (constant.isMinusZero &&

-        compiler.backend.constantSystem.isInt(constant)) {

-      return compiler.typesTask.uint31Type;

-    }

-    assert(!compiler.backend.constantSystem.isInt(constant));

-    return compiler.typesTask.doubleType;

-  }

-

-  @override

-  TypeMask visitSynthetic(SyntheticConstantValue constant, Compiler compiler) {

-    switch (constant.kind) {

-      case SyntheticConstantKind.DUMMY_INTERCEPTOR:

-        return constant.payload;

-      case SyntheticConstantKind.EMPTY_VALUE:

-        return constant.payload;

-      case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:

-        return compiler.typesTask.intType;

-      case SyntheticConstantKind.NAME:

-        return compiler.typesTask.stringType;

-      default:

-        compiler.internalError(compiler.currentElement,

-                               "Unexpected DummyConstantKind.");

-        return null;

-    }

-  }

-

-  @override

-  TypeMask visitBool(BoolConstantValue constant, Compiler compiler) {

-    return compiler.typesTask.boolType;

-  }

-

-  @override

-  TypeMask visitFunction(FunctionConstantValue constant, Compiler compiler) {

-    return compiler.typesTask.functionType;

-  }

-

-  @override

-  TypeMask visitInt(IntConstantValue constant, Compiler compiler) {

-    if (constant.isUInt31()) return compiler.typesTask.uint31Type;

-    if (constant.isUInt32()) return compiler.typesTask.uint32Type;

-    if (constant.isPositive()) return compiler.typesTask.positiveIntType;

-    return compiler.typesTask.intType;

-  }

-

-  @override

-  TypeMask visitInterceptor(InterceptorConstantValue constant,

-                            Compiler compiler) {

-    return compiler.typesTask.nonNullType;

-  }

-

-  @override

-  TypeMask visitList(ListConstantValue constant, Compiler compiler) {

-    return compiler.typesTask.constListType;

-  }

-

-  @override

-  TypeMask visitMap(MapConstantValue constant, Compiler compiler) {

-    return compiler.typesTask.constMapType;

-  }

-

-  @override

-  TypeMask visitNull(NullConstantValue constant, Compiler compiler) {

-    return compiler.typesTask.nullType;

-  }

-

-  @override

-  TypeMask visitString(StringConstantValue constant, Compiler compiler) {

-    return compiler.typesTask.stringType;

-  }

-

-  @override

-  TypeMask visitType(TypeConstantValue constant, Compiler compiler) {

-    return compiler.typesTask.typeType;

-  }

-}

+// 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 types.constants;
+
+import '../constants/values.dart';
+import '../dart2jslib.dart';
+import 'types.dart';
+import '../js_backend/js_backend.dart' show SyntheticConstantKind;
+
+/// Computes the [TypeMask] for the constant [value].
+TypeMask computeTypeMask(Compiler compiler, ConstantValue value) {
+  return value.accept(const ConstantValueTypeMasks(), compiler);
+}
+
+class ConstantValueTypeMasks extends ConstantValueVisitor<TypeMask, Compiler> {
+  const ConstantValueTypeMasks();
+
+  @override
+  TypeMask visitConstructed(ConstructedConstantValue constant,
+                            Compiler compiler) {
+    if (compiler.backend.isInterceptorClass(constant.type.element)) {
+      return compiler.typesTask.nonNullType;
+    }
+    return new TypeMask.nonNullExact(constant.type.element, compiler.world);
+  }
+
+  @override
+  TypeMask visitDeferred(DeferredConstantValue constant, Compiler compiler) {
+    return constant.referenced.accept(this, compiler);
+  }
+
+  @override
+  TypeMask visitDouble(DoubleConstantValue constant, Compiler compiler) {
+    // We have to distinguish -0.0 from 0, but for all practical purposes
+    // -0.0 is an integer.
+    // TODO(17235): this kind of special casing should only happen in the
+    // backend.
+    if (constant.isMinusZero &&
+        compiler.backend.constantSystem.isInt(constant)) {
+      return compiler.typesTask.uint31Type;
+    }
+    assert(!compiler.backend.constantSystem.isInt(constant));
+    return compiler.typesTask.doubleType;
+  }
+
+  @override
+  TypeMask visitSynthetic(SyntheticConstantValue constant, Compiler compiler) {
+    switch (constant.kind) {
+      case SyntheticConstantKind.DUMMY_INTERCEPTOR:
+        return constant.payload;
+      case SyntheticConstantKind.EMPTY_VALUE:
+        return constant.payload;
+      case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
+        return compiler.typesTask.intType;
+      case SyntheticConstantKind.NAME:
+        return compiler.typesTask.stringType;
+      default:
+        compiler.internalError(compiler.currentElement,
+                               "Unexpected DummyConstantKind.");
+        return null;
+    }
+  }
+
+  @override
+  TypeMask visitBool(BoolConstantValue constant, Compiler compiler) {
+    return compiler.typesTask.boolType;
+  }
+
+  @override
+  TypeMask visitFunction(FunctionConstantValue constant, Compiler compiler) {
+    return compiler.typesTask.functionType;
+  }
+
+  @override
+  TypeMask visitInt(IntConstantValue constant, Compiler compiler) {
+    if (constant.isUInt31()) return compiler.typesTask.uint31Type;
+    if (constant.isUInt32()) return compiler.typesTask.uint32Type;
+    if (constant.isPositive()) return compiler.typesTask.positiveIntType;
+    return compiler.typesTask.intType;
+  }
+
+  @override
+  TypeMask visitInterceptor(InterceptorConstantValue constant,
+                            Compiler compiler) {
+    return compiler.typesTask.nonNullType;
+  }
+
+  @override
+  TypeMask visitList(ListConstantValue constant, Compiler compiler) {
+    return compiler.typesTask.constListType;
+  }
+
+  @override
+  TypeMask visitMap(MapConstantValue constant, Compiler compiler) {
+    return compiler.typesTask.constMapType;
+  }
+
+  @override
+  TypeMask visitNull(NullConstantValue constant, Compiler compiler) {
+    return compiler.typesTask.nullType;
+  }
+
+  @override
+  TypeMask visitString(StringConstantValue constant, Compiler compiler) {
+    return compiler.typesTask.stringType;
+  }
+
+  @override
+  TypeMask visitType(TypeConstantValue constant, Compiler compiler) {
+    return compiler.typesTask.typeType;
+  }
+}
diff --git a/pkg/compiler/lib/src/universe/universe.dart b/pkg/compiler/lib/src/universe/universe.dart
index 8af7763..28715e6 100644
--- a/pkg/compiler/lib/src/universe/universe.dart
+++ b/pkg/compiler/lib/src/universe/universe.dart
@@ -421,9 +421,7 @@
     return match(other);
   }
 
-  bool signatureApplies(FunctionElement function) {
-    if (Elements.isUnresolved(function)) return false;
-    FunctionSignature parameters = function.functionSignature;
+  bool signatureApplies(FunctionSignature parameters) {
     if (argumentCount > parameters.parameterCount) return false;
     int requiredParameterCount = parameters.requiredParameterCount;
     int optionalParameterCount = parameters.optionalParameterCount;
@@ -529,6 +527,9 @@
       ConstructorElement callee,
       /*T*/ compileArgument(ParameterElement element),
       /*T*/ compileConstant(ParameterElement element)) {
+    assert(invariant(caller, !callee.isErroneous,
+        message: "Cannot compute arguments to erroneous constructor: "
+                 "$caller calling $callee."));
 
     FunctionSignature signature = caller.functionSignature;
     Map<Node, ParameterElement> mapping = <Node, ParameterElement>{};
@@ -572,7 +573,7 @@
     }
     CallStructure callStructure =
         new CallStructure(signature.parameterCount, namedParameters);
-    if (!callStructure.signatureApplies(callee)) {
+    if (!callStructure.signatureApplies(signature)) {
       return false;
     }
     list.addAll(callStructure.makeArgumentsList(
@@ -853,7 +854,8 @@
   }
 
   bool signatureApplies(FunctionElement function) {
-    return callStructure.signatureApplies(function);
+    if (Elements.isUnresolved(function)) return false;
+    return callStructure.signatureApplies(function.functionSignature);
   }
 
   bool sameNameHack(Element element, World world) {
diff --git a/pkg/compiler/lib/src/use_unused_api.dart b/pkg/compiler/lib/src/use_unused_api.dart
index a15b716..215bfa5 100644
--- a/pkg/compiler/lib/src/use_unused_api.dart
+++ b/pkg/compiler/lib/src/use_unused_api.dart
@@ -290,7 +290,9 @@
 }
 
 useSemanticVisitor() {
-  new semantic_visitor.BulkSendVisitor().apply(null, null);
+  new semantic_visitor.BulkSendVisitor()
+      ..apply(null, null)
+      ..visitSuperFieldFieldCompound(null, null, null, null, null, null);
   new semantic_visitor.TraversalVisitor(null).apply(null, null);
   new semantic_visitor.BulkDeclarationVisitor().apply(null, null);
 }
diff --git a/pkg/compiler/lib/src/warnings.dart b/pkg/compiler/lib/src/warnings.dart
index eb32045..f144262 100644
--- a/pkg/compiler/lib/src/warnings.dart
+++ b/pkg/compiler/lib/src/warnings.dart
@@ -640,10 +640,11 @@
       "Not a compile-time constant.");
 
   static const MessageKind DEFERRED_COMPILE_TIME_CONSTANT = const MessageKind(
-      "A Deferred value cannot be used as a compile-time constant.");
+      "A deferred value cannot be used as a compile-time constant.");
 
   static const MessageKind DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION =
-      const MessageKind("A deferred class cannot be used to create a"
+      const MessageKind(
+          "A deferred class cannot be used to create a "
           "compile-time constant.");
 
   static const MessageKind CYCLIC_COMPILE_TIME_CONSTANTS = const MessageKind(
@@ -2203,7 +2204,7 @@
   static const MessageKind PREAMBLE = const MessageKind(
     "When run on the command-line, the compiled output might"
     " require a preamble file located in:\n"
-    "  <sdk>/lib/_internal/compiler/js_lib/preambles.");
+    "  <sdk>/lib/_internal/js_runtime/lib/preambles.");
 
   static const MessageKind INVALID_SYNC_MODIFIER = const MessageKind(
       "Invalid modifier 'sync'.",
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
new file mode 100644
index 0000000..a078492
--- /dev/null
+++ b/pkg/compiler/pubspec.yaml
@@ -0,0 +1,23 @@
+# This pubspec is currently mainly used to make it easier to develop on dart2js
+# by making it a standalone package.
+name: compiler
+#version: do-not-upload
+dependencies:
+  package_config: ^0.0.4
+  js_ast:
+    path: ../js_ast
+  js_runtime:
+    path: ../../sdk/lib/_internal/js_runtime
+  sdk_library_metadata:
+    path: ../../sdk/lib/_internal/sdk_library_metadata
+
+# Uncomment if running gclient, so you can depend directly on the downloaded
+# versions of dart2js's transitive dependencies:
+#
+# dependency_overrides:
+#   package_config:
+#     path: ../../third_party/pkg/package_config
+#   path:
+#     path: ../../third_party/pkg/path
+#   charcode:
+#     path: ../../third_party/pkg/charcode
diff --git a/pkg/compiler/samples/darttags/darttags.dart b/pkg/compiler/samples/darttags/darttags.dart
index d675463..0653a09 100644
--- a/pkg/compiler/samples/darttags/darttags.dart
+++ b/pkg/compiler/samples/darttags/darttags.dart
@@ -32,7 +32,7 @@
 
 import 'dart:mirrors';
 
-import 'package:_internal/libraries.dart'
+import 'package:sdk_library_metadata/libraries.dart'
     show LIBRARIES, LibraryInfo;
 
 import 'package:compiler/src/mirrors/analyze.dart'
diff --git a/pkg/compiler/samples/jsonify/jsonify.dart b/pkg/compiler/samples/jsonify/jsonify.dart
index 54a6e18..0d0c7e6 100644
--- a/pkg/compiler/samples/jsonify/jsonify.dart
+++ b/pkg/compiler/samples/jsonify/jsonify.dart
@@ -7,7 +7,7 @@
 
 import 'dart:mirrors';
 
-import 'package:_internal/libraries.dart'
+import 'package:sdk_library_metadata/libraries.dart'
     show LIBRARIES, LibraryInfo;
 
 import '../../lib/src/mirrors/analyze.dart'
diff --git a/pkg/dart2js_incremental/lib/library_updater.dart b/pkg/dart2js_incremental/lib/library_updater.dart
index 6b08832..924f2f4 100644
--- a/pkg/dart2js_incremental/lib/library_updater.dart
+++ b/pkg/dart2js_incremental/lib/library_updater.dart
@@ -73,7 +73,7 @@
 import 'package:compiler/src/js_emitter/program_builder.dart' show
     ProgramBuilder;
 
-import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
+import 'package:js_runtime/shared/embedded_names.dart'
     as embeddedNames;
 
 import 'package:compiler/src/js_backend/js_backend.dart' show
diff --git a/pkg/docgen/lib/src/exports/libraries.dart b/pkg/docgen/lib/src/exports/libraries.dart
index 00163df..7e48c79 100644
--- a/pkg/docgen/lib/src/exports/libraries.dart
+++ b/pkg/docgen/lib/src/exports/libraries.dart
@@ -4,4 +4,4 @@
 
 library docgen.exports.libraries;
 
-export '../../../../../sdk/lib/_internal/libraries.dart';
+export 'package:sdk_library_metadata/libraries.dart';
diff --git a/pkg/js_ast/test/printer_callback_test.dart b/pkg/js_ast/test/printer_callback_test.dart
index 1a1db35..b4ff074 100644
--- a/pkg/js_ast/test/printer_callback_test.dart
+++ b/pkg/js_ast/test/printer_callback_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// Note: This test relies on LF line endings in the source file.
+
 // Test that JS printer callbacks occur when expected.
 
 library js_ast.printer.callback_test;
diff --git a/pkg/pkg.gyp b/pkg/pkg.gyp
index 4afbb19..771152c 100644
--- a/pkg/pkg.gyp
+++ b/pkg/pkg.gyp
@@ -19,7 +19,8 @@
                 '"../third_party/pkg_tested"])',
             '<!@(["python", "../tools/list_pkg_directories.py", '
                 '"../runtime"])',
-            '../sdk/lib/_internal',
+            '../sdk/lib/_internal/js_runtime/lib',
+            '../sdk/lib/_internal/sdk_library_metadata/lib',
             '../site/try',
           ],
           'outputs': [
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 86cc7f1..5bb70dc 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -150,7 +150,6 @@
 analyzer/test/*: PubGetError
 
 [ $compiler == dart2js && $cps_ir ]
-analysis_server/tool/spec/check_all_test: Crash # Invalid argument(s)
 analyzer/test/cancelable_future_test: Crash # Invalid argument(s)
 analyzer/test/enum_test: Crash # Invalid argument(s)
 analyzer/test/file_system/memory_file_system_test: Crash # Invalid argument(s)
@@ -162,8 +161,7 @@
 analyzer/test/generated/element_test: Crash # Invalid argument(s)
 analyzer/test/generated/incremental_resolver_test: Crash # Invalid argument(s)
 analyzer/test/generated/incremental_scanner_test: Crash # Invalid argument(s)
-analyzer/test/generated/java_core_test: Crash # Invalid argument(s)
-analyzer/test/generated/java_io_test: Crash # Invalid argument(s)
+analyzer/test/generated/java_core_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 analyzer/test/generated/non_error_resolver_test: Crash # Invalid argument(s)
 analyzer/test/generated/parser_test: Crash # Invalid argument(s)
 analyzer/test/generated/resolver_test: Crash # Invalid argument(s)
@@ -190,10 +188,9 @@
 analyzer/test/src/task/model_test: Crash # Invalid argument(s)
 analyzer/test/src/util/asserts_test: Crash # Invalid argument(s)
 analyzer/test/src/util/lru_map_test: Crash # Invalid argument(s)
-fixnum/test/int_32_test: Crash # Invalid argument(s)
-fixnum/test/int_64_test: Crash # Invalid argument(s)
-js_ast/test/printer_callback_test: RuntimeError # Please triage this failure.
-microlytics/test/dart_microlytics_test: RuntimeError # Please triage this failure.
+fixnum/test/int_32_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+fixnum/test/int_64_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 typed_data/test/typed_buffers_test/01: Crash # Invalid argument(s)
-typed_data/test/typed_buffers_test/none: Crash # Invalid argument(s)
-typed_mock/test/typed_mock_test: Crash # Invalid argument(s)
+typed_data/test/typed_buffers_test/none : RuntimeError # TypeError: receiver.get$_nums is not a function
+typed_mock/test/typed_mock_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+analyzer/test/generated/source_factory_test : Crash # Invalid argument(s)
diff --git a/pkg/pkgbuild.status b/pkg/pkgbuild.status
index 7484d4a..a2c33a4 100644
--- a/pkg/pkgbuild.status
+++ b/pkg/pkgbuild.status
@@ -8,16 +8,20 @@
 
 [ $use_repository_packages ]
 pkg/analyzer: PubGetError
+pkg/compiler: PubGetError # Issue 23750
 samples/third_party/angular_todo: Fail # angular needs to be updated
 samples/third_party/todomvc_performance: Skip # dependencies are not in the repo
+third_party/pkg/package_config: PubGetError # Issue 23750
 
 [ $use_public_packages ]
+pkg/compiler: PubGetError # Issue 23750
 samples/third_party/angular_todo: Pass, Slow
 third_party/pkg/async_await: Skip # Uses expect package.
 samples/third_party/todomvc_performance: Pass, Slow
 
 [ $builder_tag == russian ]
 samples/third_party/angular_todo: Fail # Issue 16356
+samples/third_party/dromaeo: Fail # Issue 23750
 
 [ $use_public_packages && $system == windows ]
 samples/third_party/todomvc_performance: Fail # Issue 18086
diff --git a/runtime/lib/bigint.dart b/runtime/lib/bigint.dart
index adfb0db..ce151cf 100644
--- a/runtime/lib/bigint.dart
+++ b/runtime/lib/bigint.dart
@@ -267,7 +267,9 @@
     return r_used;
   }
 
-  // r_digits[0..r_used-1] = x_digits[0..x_used-1] << n.
+  // r_digits[ds..x_used+ds] = x_digits[0..x_used-1] << (n % _DIGIT_BITS)
+  // where ds = ceil(n / _DIGIT_BITS)
+  // Doesn't clear digits below ds.
   static void _lsh(Uint32List x_digits, int x_used, int n,
                    Uint32List r_digits) {
     final ds = n ~/ _DIGIT_BITS;
@@ -292,7 +294,7 @@
       return _dlShift(ds);
     }
     var r_used = _used + ds + 1;
-    var r_digits = new Uint32List(r_used + 2 + (r_used & 1));  // +2 for 64-bit.
+    var r_digits = new Uint32List(r_used + 2 - (r_used & 1));  // for 64-bit.
     _lsh(_digits, _used, n, r_digits);
     return new _Bigint(_neg, r_used, r_digits);
   }
@@ -307,7 +309,7 @@
       return _dlShiftDigits(x_digits, x_used, ds, r_digits);
     }
     var r_used = x_used + ds + 1;
-    assert(r_digits.length >= r_used + 2 + (r_used & 1));  // +2 for 64-bit.
+    assert(r_digits.length >= r_used + 2 - (r_used & 1));  // for 64-bit.
     _lsh(x_digits, x_used, n, r_digits);
     var i = ds;
     while (--i >= 0) {
@@ -1404,7 +1406,7 @@
     if (e == 0) return 1;
     m = m._toBigint();
     final m_used = m._used;
-    final m_used2p4 = 2*m_used + 4;
+    final m_used2p4 = 2 * m_used + 4;
     final e_bitlen = e.bitLength;
     if (e_bitlen <= 0) return 1;
     final bool cannotUseMontgomery = m.isEven || _abs() >= m;
@@ -1562,7 +1564,7 @@
       if (((x_used == 1) && (x_digits[0] == 1)) ||
           ((y_used == 1) && (y_digits[0] == 1))) return 1;
       bool xy_cloned = false;
-      while (x.isEven && y.isEven) {
+      while (((x_digits[0] & 1) == 0) && ((y_digits[0] & 1) == 0)) {
         _rsh(x_digits, x_used, 1, x_digits);
         _rsh(y_digits, y_used, 1, y_digits);
         s++;
@@ -1583,7 +1585,7 @@
       }
     }
     var u_digits = _cloneDigits(x_digits, 0, x_used, m_len);
-    var v_digits = _cloneDigits(y_digits, 0, y_used, m_len);
+    var v_digits = _cloneDigits(y_digits, 0, y_used, m_len + 2);  // +2 for lsh.
     final bool ac = (x_digits[0] & 1) == 0;
 
     // Variables a, b, c, and d require one more digit.
@@ -1747,7 +1749,7 @@
     }
     if (!inv) {
       if (s > 0) {
-        _lsh(v_digits, m_used, s, v_digits);
+        m_used = _lShiftDigits(v_digits, m_used, s, v_digits);
       }
       return new _Bigint(false, m_used, v_digits)._toValidInt();
     }
diff --git a/runtime/lib/core_patch.dart b/runtime/lib/core_patch.dart
index 2a45ae7..0358cc2 100644
--- a/runtime/lib/core_patch.dart
+++ b/runtime/lib/core_patch.dart
@@ -205,3 +205,27 @@
     }
   }
 }
+
+patch class Resource {
+  /* patch */ const factory Resource(String uri) = _Resource;
+}
+
+class _Resource implements Resource {
+  final String _location;
+
+  const _Resource(String uri) : _location = uri;
+
+  Uri get uri => Uri.base.resolve(_location);
+
+  Stream<List<int>> openRead() {
+    throw new UnimplementedError("openRead");
+  }
+
+  Future<List<int>> readAsBytes() {
+    throw new UnimplementedError("readAsBytes");
+  }
+
+  Future<String> readAsString({Encoding encoding}) {
+    throw new UnimplementedError("readAsString");
+  }
+}
diff --git a/runtime/lib/internal_patch.dart b/runtime/lib/internal_patch.dart
index 86c4a5a..ce44229 100644
--- a/runtime/lib/internal_patch.dart
+++ b/runtime/lib/internal_patch.dart
@@ -21,4 +21,4 @@
 
 final bool is64Bit = _inquireIs64Bit();
 
-bool _inquireIs64Bit() native "Internal_inquireIs64Bit";
\ No newline at end of file
+bool _inquireIs64Bit() native "Internal_inquireIs64Bit";
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index e43b658..5a25ea3 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -24,8 +24,10 @@
 export 'package:observatory/src/elements/heap_map.dart';
 export 'package:observatory/src/elements/heap_profile.dart';
 export 'package:observatory/src/elements/heap_snapshot.dart';
+export 'package:observatory/src/elements/icdata_view.dart';
 export 'package:observatory/src/elements/instance_ref.dart';
 export 'package:observatory/src/elements/instance_view.dart';
+export 'package:observatory/src/elements/instructions_view.dart';
 export 'package:observatory/src/elements/io_view.dart';
 export 'package:observatory/src/elements/isolate_reconnect.dart';
 export 'package:observatory/src/elements/isolate_ref.dart';
@@ -38,6 +40,7 @@
 export 'package:observatory/src/elements/nav_bar.dart';
 export 'package:observatory/src/elements/object_common.dart';
 export 'package:observatory/src/elements/object_view.dart';
+export 'package:observatory/src/elements/objectpool_view.dart';
 export 'package:observatory/src/elements/observatory_application.dart';
 export 'package:observatory/src/elements/observatory_element.dart';
 export 'package:observatory/src/elements/ports.dart';
diff --git a/runtime/observatory/lib/elements.html b/runtime/observatory/lib/elements.html
index 0eeabc9..c64656a 100644
--- a/runtime/observatory/lib/elements.html
+++ b/runtime/observatory/lib/elements.html
@@ -20,6 +20,8 @@
 <link rel="import" href="src/elements/instance_ref.html">
 <link rel="import" href="src/elements/instance_view.html">
 <link rel="import" href="src/elements/io_view.html">
+<link rel="import" href="src/elements/icdata_view.html">
+<link rel="import" href="src/elements/instructions_view.html">
 <link rel="import" href="src/elements/isolate_reconnect.html">
 <link rel="import" href="src/elements/isolate_ref.html">
 <link rel="import" href="src/elements/isolate_summary.html">
@@ -31,6 +33,7 @@
 <link rel="import" href="src/elements/nav_bar.html">
 <link rel="import" href="src/elements/object_common.html">
 <link rel="import" href="src/elements/object_view.html">
+<link rel="import" href="src/elements/objectpool_view.html">
 <link rel="import" href="src/elements/observatory_application.html">
 <link rel="import" href="src/elements/observatory_element.html">
 <link rel="import" href="src/elements/ports.html">
diff --git a/runtime/observatory/lib/src/elements/class_view.html b/runtime/observatory/lib/src/elements/class_view.html
index 10f67fc..ad85d16 100644
--- a/runtime/observatory/lib/src/elements/class_view.html
+++ b/runtime/observatory/lib/src/elements/class_view.html
@@ -196,7 +196,7 @@
               </template>
               <template if="{{ mostRetained != null }}">
                 <template repeat="{{ most in mostRetained }}">
-                  {{ most.retainedSize | formatSize }}<instance-ref ref="{{ most }}"></instance-ref><br>
+                  {{ most.retainedSize | formatSize }}<any-service-ref ref="{{ most }}"></any-service-ref><br>
                 </template>
               </template>
             </div>
diff --git a/runtime/observatory/lib/src/elements/code_view.dart b/runtime/observatory/lib/src/elements/code_view.dart
index 4995996..7c6ddef 100644
--- a/runtime/observatory/lib/src/elements/code_view.dart
+++ b/runtime/observatory/lib/src/elements/code_view.dart
@@ -197,9 +197,10 @@
   }
 
   void _fillDisassemblyDOMRow(TableRowElement tr, int rowIndex) {
-    var row = disassemblyTable.rows[rowIndex];
-    for (var i = 0; i < row.values.length; i++) {
-      var cell = tr.children[i];
+    final row = disassemblyTable.rows[rowIndex];
+    final n = row.values.length;
+    for (var i = 0; i < n; i++) {
+      final cell = tr.children[i];
       cell.title = row.values[i].toString();
       cell.text = row.values[i].toString();
     }
@@ -226,11 +227,13 @@
     }
 
     assert(tableBody.children.length == disassemblyTable.sortedRows.length);
+
     // Fill table.
-    for (var i = 0; i < disassemblyTable.sortedRows.length; i++) {
+    var i = 0;
+    for (var tr in tableBody.children) {
       var rowIndex = disassemblyTable.sortedRows[i];
-      var tr = tableBody.children[i];
       _fillDisassemblyDOMRow(tr, rowIndex);
+      i++;
     }
   }
 
diff --git a/runtime/observatory/lib/src/elements/code_view.html b/runtime/observatory/lib/src/elements/code_view.html
index ddb3d98..7b1c057 100644
--- a/runtime/observatory/lib/src/elements/code_view.html
+++ b/runtime/observatory/lib/src/elements/code_view.html
@@ -55,6 +55,10 @@
       <template if="{{ !(code.isDartCode && code.isOptimized) }}">
         <h1>Code for {{ code.name }}</h1>
       </template>
+      <object-common object="{{ code }}"></object-common>
+
+      <br><br>
+
       <div class="memberList">
         <div class="memberItem">
           <div class="memberName">Kind</div>
@@ -107,32 +111,34 @@
         </template>
       </div>
     </div>
-    <hr>
-    <table id="inlineRangeTable" class="table">
-      <thead id="inlineRangeTableHead">
-        <tr>
-          <th class="address" title="Address range">Address Range</th>
-          <th class="tick" title="Inclusive">Inclusive</th>
-          <th class="tick" title="Exclusive">Exclusive</th>
-          <th title="Functions">Functions</th>
-        </tr>
-      </thead>
-      <tbody class="monospace" id="inlineRangeTableBody">
-      </tbody>
-    </table>
-    <hr>
-    <table id="disassemblyTable" class="table">
-      <thead id="disassemblyTableHead">
-      <tr>
-        <th class="address" title="Address">Address</th>
-        <th class="tick" title="Inclusive">Inclusive</th>
-        <th class="tick" title="Exclusive">Exclusive</th>
-        <th class="disassembly" title="Disassembly">Disassembly</th>
-      </tr>
-      </thead>
-      <tbody class="monospace" id="disassemblyTableBody">
-      </tbody>
-    </table>
+    <div class="content-centered-big">
+      <hr>
+      <table id="inlineRangeTable" class="table">
+        <thead id="inlineRangeTableHead">
+          <tr>
+            <th class="address" title="Address range">Address Range</th>
+            <th class="tick" title="Inclusive">Inclusive</th>
+            <th class="tick" title="Exclusive">Exclusive</th>
+            <th title="Functions">Functions</th>
+          </tr>
+        </thead>
+        <tbody class="monospace" id="inlineRangeTableBody">
+        </tbody>
+      </table>
+      <hr>
+      <table id="disassemblyTable" class="table">
+        <thead id="disassemblyTableHead">
+          <tr>
+            <th class="address" title="Address">Address</th>
+            <th class="tick" title="Inclusive">Inclusive</th>
+            <th class="tick" title="Exclusive">Exclusive</th>
+            <th class="disassembly" title="Disassembly">Disassembly</th>
+          </tr>
+        </thead>
+        <tbody class="monospace" id="disassemblyTableBody">
+        </tbody>
+      </table>
+    </div>
     <view-footer></view-footer>
   </template>
 </polymer-element>
diff --git a/runtime/observatory/lib/src/elements/function_ref.dart b/runtime/observatory/lib/src/elements/function_ref.dart
index 53920b9..1f4d06f 100644
--- a/runtime/observatory/lib/src/elements/function_ref.dart
+++ b/runtime/observatory/lib/src/elements/function_ref.dart
@@ -26,24 +26,20 @@
     if (ref == null) {
       return;
     }
-    if (function.isDart) {
-      if (qualified) {
-        if (function.dartOwner is ServiceFunction) {
-          var functionRef = new Element.tag('function-ref');
-          functionRef.ref = function.dartOwner;
-          functionRef.qualified = true;
-          shadowRoot.children.add(functionRef);
-          insertTextSpanIntoShadowRoot('.');
-        } else if (function.dartOwner is Class) {
-          var classRef = new Element.tag('class-ref');
-          classRef.ref = function.dartOwner;
-          shadowRoot.children.add(classRef);
-          insertTextSpanIntoShadowRoot('.');
-        }
+    if (qualified) {
+      if (function.dartOwner is ServiceFunction) {
+        var functionRef = new Element.tag('function-ref');
+        functionRef.ref = function.dartOwner;
+        functionRef.qualified = true;
+        shadowRoot.children.add(functionRef);
+        insertTextSpanIntoShadowRoot('.');
+      } else if (function.dartOwner is Class) {
+        var classRef = new Element.tag('class-ref');
+        classRef.ref = function.dartOwner;
+        shadowRoot.children.add(classRef);
+        insertTextSpanIntoShadowRoot('.');
       }
-      insertLinkIntoShadowRoot(name, url, hoverText);
-    } else {
-      insertTextSpanIntoShadowRoot(name);
     }
+    insertLinkIntoShadowRoot(name, url, hoverText);
   }
 }
diff --git a/runtime/observatory/lib/src/elements/function_view.html b/runtime/observatory/lib/src/elements/function_view.html
index 4b75325..fee4cb4 100644
--- a/runtime/observatory/lib/src/elements/function_view.html
+++ b/runtime/observatory/lib/src/elements/function_view.html
@@ -27,7 +27,6 @@
 
     <div class="content">
       <h1>function {{ function.qualifiedName }}</h1>
-
       <div class="memberList">
         <div class="memberItem">
           <div class="memberName">kind</div>
@@ -74,6 +73,12 @@
            </div>
          </template>
          <div class="memberItem">
+           <div class="memberName">ic data array</div>
+           <div class="memberValue">
+             <instance-ref ref="{{ function.icDataArray }}"></instance-ref>
+           </div>
+         </div>
+         <div class="memberItem">
            <div class="memberName">deoptimizations</div>
            <div class="memberValue">{{ function.deoptimizations }}</div>
          </div>
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart
index 53b8a52..f75726f 100644
--- a/runtime/observatory/lib/src/elements/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart
@@ -65,7 +65,7 @@
     percentNode.text =  Utils.formatPercentNormalized(percentRetained);
     percentNode.style.minWidth = '5em';
     percentNode.style.textAlign = 'right';
-    percentNode.title = "Retaining x of y.";
+    percentNode.title = "Percent of heap being retained";
     percentNode.style.display = 'inline-block';
     firstColumn.children.add(percentNode);
 
diff --git a/runtime/observatory/lib/src/elements/icdata_view.dart b/runtime/observatory/lib/src/elements/icdata_view.dart
new file mode 100644
index 0000000..d69f672
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/icdata_view.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library icdata_view;
+
+import 'dart:async';
+import 'observatory_element.dart';
+import 'package:observatory/service.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('icdata-view')
+class ICDataViewElement extends ObservatoryElement {
+  @published ICData icData;
+
+  ICDataViewElement.created() : super.created();
+
+  Future refresh() {
+    return icData.reload();
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/icdata_view.html b/runtime/observatory/lib/src/elements/icdata_view.html
new file mode 100644
index 0000000..d31f14f
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/icdata_view.html
@@ -0,0 +1,63 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="class_ref.html">
+<link rel="import" href="error_view.html">
+<link rel="import" href="field_ref.html">
+<link rel="import" href="function_ref.html">
+<link rel="import" href="inbound_reference.html">
+<link rel="import" href="instance_ref.html">
+<link rel="import" href="observatory_element.html">
+<link rel="import" href="object_common.html">
+<link rel="import" href="nav_bar.html">
+<link rel="import" href="eval_link.html">
+
+<polymer-element name="icdata-view" extends="observatory-element">
+  <template>
+    <link rel="stylesheet" href="css/shared.css">
+    <nav-bar>
+      <top-nav-menu></top-nav-menu>
+      <vm-nav-menu vm="{{ icData.isolate.vm }}"></vm-nav-menu>
+      <isolate-nav-menu isolate="{{ icData.isolate }}"></isolate-nav-menu>
+      <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
+      <nav-refresh callback="{{ refresh }}"></nav-refresh>
+    </nav-bar>
+
+    <div class="content">
+      <object-common object="{{ icData }}"></object-common>
+
+      <br><br>
+
+      <div class="memberList">
+        <div class="memberItem">
+          <div class="memberName">selector</div>
+          <div class="memberValue"> 
+            {{ icData.selector }}
+          </div>
+        </div>
+        <div class="memberItem">
+          <div class="memberName">owner</div>
+          <div class="memberValue">
+            <any-service-ref ref="{{ icData.dartOwner }}"></any-service-ref>
+          </div>
+        </div>
+        <div class="memberItem">
+          <div class="memberName">argumentsDescriptor</div>
+          <div class="memberValue">
+            <any-service-ref ref="{{ icData.argumentsDescriptor }}"></any-service-ref>
+          </div>
+        </div>
+        <div class="memberItem">
+          <div class="memberName">entries</div>
+          <div class="memberValue">
+            <any-service-ref ref="{{ icData.entries }}"></any-service-ref>
+          </div>
+        </div>
+      </div>
+
+    </div>
+  
+    <hr>
+    <view-footer></view-footer>
+  </template>
+</polymer-element>
+
+<script type="application/dart" src="icdata_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/instance_ref.html b/runtime/observatory/lib/src/elements/instance_ref.html
index 10782d5..d8a1def 100644
--- a/runtime/observatory/lib/src/elements/instance_ref.html
+++ b/runtime/observatory/lib/src/elements/instance_ref.html
@@ -42,6 +42,10 @@
         </a>
       </template>
 
+      <template if="{{ ref.isRegExp }}">
+        <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.clazz.name }}({{ ref.pattern.valueAsString }})</em></a>
+      </template>
+
       <template if="{{ ref.isPlainInstance }}">
         <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.clazz.name }}</em></a>
         <curly-block callback="{{ expander() }}">
diff --git a/runtime/observatory/lib/src/elements/instance_view.html b/runtime/observatory/lib/src/elements/instance_view.html
index 76a8bce..4e718d9 100644
--- a/runtime/observatory/lib/src/elements/instance_view.html
+++ b/runtime/observatory/lib/src/elements/instance_view.html
@@ -60,16 +60,6 @@
             </div>
           </template>
 
-          <template if="{{ instance.isMirrorReference }}">
-            <div class="memberItem">
-              <div class="memberName">referent</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ instance.referent }}">
-                </any-service-ref>
-              </div>
-            </div>
-          </template>
-
           <template if="{{ instance.typeClass != null }}">
             <div class="memberItem">
               <div class="memberName">type class</div>
@@ -113,23 +103,6 @@
             </div>
           </template>
 
-          <template if="{{ instance.isWeakProperty }}">
-            <div class="memberItem">
-              <div class="memberName">key</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ instance.key }}">
-                </any-service-ref>
-              </div>
-            </div>
-            <div class="memberItem">
-              <div class="memberName">value</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ instance.value }}">
-                </any-service-ref>
-              </div>
-            </div>
-          </template>
-
           <div class="memberItem">
             <div class="memberName">toString()</div>
             <div class="memberValue">
@@ -228,6 +201,67 @@
             </div>
           </curly-block><br><br>
         </template>
+
+        <template if="{{ instance.isRegExp }}">
+          <div class="memberList">
+            <div class="memberItem">
+              <div class="memberName">pattern</div>
+              <div class="memberValue">
+                <any-service-ref ref="{{ instance.pattern }}"></any-service-ref>
+              </div>
+            </div>
+            <div class="memberItem">
+              <div class="memberName">oneByteFunction</div>
+              <div class="memberValue">
+                <any-service-ref ref="{{ instance.oneByteFunction }}"></any-service-ref>
+              </div>
+            </div>
+            <div class="memberItem">
+              <div class="memberName">twoByteFunction</div>
+              <div class="memberValue">
+                <any-service-ref ref="{{ instance.twoByteFunction }}"></any-service-ref>
+              </div>
+            </div>
+            <div class="memberItem">
+              <div class="memberName">externalOneByteFunction</div>
+              <div class="memberValue">
+                <any-service-ref ref="{{ instance.externalOneByteFunction }}"></any-service-ref>
+              </div>
+            </div>
+            <div class="memberItem">
+              <div class="memberName">externalTwoByteFunction</div>
+              <div class="memberValue">
+                <any-service-ref ref="{{ instance.externalTwoByteFunction }}"></any-service-ref>
+              </div>
+            </div>
+          </div>
+        </template>
+
+        <template if="{{ instance.isMirrorReference }}">
+          <div class="memberItem">
+            <div class="memberName">referent</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ instance.referent }}">
+              </any-service-ref>
+            </div>
+          </div>
+        </template>
+
+        <template if="{{ instance.isWeakProperty }}">
+          <div class="memberItem">
+            <div class="memberName">key</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ instance.key }}"></any-service-ref>
+            </div>
+          </div>
+          <div class="memberItem">
+            <div class="memberName">value</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ instance.value }}"></any-service-ref>
+            </div>
+          </div>
+        </template>
+
       </div>
 
       <div class="content-centered-big">
diff --git a/runtime/observatory/lib/src/elements/instructions_view.dart b/runtime/observatory/lib/src/elements/instructions_view.dart
new file mode 100644
index 0000000..e5c1fb2
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/instructions_view.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library instructions_view;
+
+import 'dart:async';
+import 'observatory_element.dart';
+import 'package:observatory/service.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('instructions-view')
+class InstructionsViewElement extends ObservatoryElement {
+  @published Instructions instructions;
+
+  InstructionsViewElement.created() : super.created();
+
+  Future refresh() {
+    return instructions.reload();
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/instructions_view.html b/runtime/observatory/lib/src/elements/instructions_view.html
new file mode 100644
index 0000000..feb108c
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/instructions_view.html
@@ -0,0 +1,51 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="class_ref.html">
+<link rel="import" href="error_view.html">
+<link rel="import" href="field_ref.html">
+<link rel="import" href="function_ref.html">
+<link rel="import" href="inbound_reference.html">
+<link rel="import" href="instance_ref.html">
+<link rel="import" href="observatory_element.html">
+<link rel="import" href="object_common.html">
+<link rel="import" href="nav_bar.html">
+<link rel="import" href="eval_link.html">
+
+<polymer-element name="instructions-view" extends="observatory-element">
+  <template>
+    <link rel="stylesheet" href="css/shared.css">
+    <nav-bar>
+      <top-nav-menu></top-nav-menu>
+      <vm-nav-menu vm="{{ instructions.isolate.vm }}"></vm-nav-menu>
+      <isolate-nav-menu isolate="{{ instructions.isolate }}"></isolate-nav-menu>
+      <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
+      <nav-refresh callback="{{ refresh }}"></nav-refresh>
+    </nav-bar>
+
+    <div class="content">
+      <object-common object="{{ instructions }}"></object-common>
+
+      <br><br>
+
+      <div class="memberList">
+        <div class="memberItem">
+          <div class="memberName">code</div>
+          <div class="memberValue">
+            <any-service-ref ref="{{ instructions.code }}"></any-service-ref>
+          </div>
+        </div>
+        <div class="memberItem">
+          <div class="memberName">objectPool</div>
+          <div class="memberValue">
+            <any-service-ref ref="{{ instructions.objectPool }}"></any-service-ref>
+          </div>
+        </div>
+      </div>
+
+    </div>
+  
+    <hr>
+    <view-footer></view-footer>
+  </template>
+</polymer-element>
+
+<script type="application/dart" src="instructions_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/objectpool_view.dart b/runtime/observatory/lib/src/elements/objectpool_view.dart
new file mode 100644
index 0000000..9bc5a4e
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/objectpool_view.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library objectpool_view;
+
+import 'dart:async';
+import 'observatory_element.dart';
+import 'package:observatory/service.dart';
+import 'package:polymer/polymer.dart';
+
+@CustomTag('objectpool-view')
+class ObjectPoolViewElement extends ObservatoryElement {
+  @published ObjectPool pool;
+  @published List annotatedEntries;
+
+  ObjectPoolViewElement.created() : super.created();
+
+  bool isServiceObject(o) => o is ServiceObject;
+
+  void poolChanged(oldValue) {
+    annotateRawEntries();
+  }
+
+  Future annotateRawEntries() {
+    var tasks = pool.entries.map((entry) {
+     if (entry is int) {
+       var addr = entry.toRadixString(16);
+       return pool.isolate.getObjectByAddress(addr).then((result) {
+         return result is ServiceObject ? result : null;
+       });
+     } else {
+       return new Future.value(null);
+     }
+    });
+
+    return Future.wait(tasks).then((results) => annotatedEntries = results);
+  }
+
+  Future refresh() {
+    return pool.reload().then((_) => annotateRawEntries());
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/objectpool_view.html b/runtime/observatory/lib/src/elements/objectpool_view.html
new file mode 100644
index 0000000..a928531
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/objectpool_view.html
@@ -0,0 +1,57 @@
+<link rel="import" href="../../../../packages/polymer/polymer.html">
+<link rel="import" href="class_ref.html">
+<link rel="import" href="error_view.html">
+<link rel="import" href="field_ref.html">
+<link rel="import" href="function_ref.html">
+<link rel="import" href="inbound_reference.html">
+<link rel="import" href="instance_ref.html">
+<link rel="import" href="observatory_element.html">
+<link rel="import" href="object_common.html">
+<link rel="import" href="nav_bar.html">
+<link rel="import" href="eval_link.html">
+
+<polymer-element name="objectpool-view" extends="observatory-element">
+  <template>
+    <link rel="stylesheet" href="css/shared.css">
+    <nav-bar>
+      <top-nav-menu></top-nav-menu>
+      <vm-nav-menu vm="{{ pool.isolate.vm }}"></vm-nav-menu>
+      <isolate-nav-menu isolate="{{ pool.isolate }}"></isolate-nav-menu>
+      <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
+      <nav-refresh callback="{{ refresh }}"></nav-refresh>
+    </nav-bar>
+
+    <div class="content">
+      <object-common object="{{ pool }}"></object-common>
+
+      <br><br>
+
+      entries ({{ pool.entries.length }})
+      <div class="memberList">
+        <template repeat="{{ index in pool.entries.asMap().keys }}">
+          <div class="memberItem">
+            <div class="memberName">[{{ index }}]</div>
+            <div class="memberValue">
+              <template if="{{ isServiceObject(pool.entries[index]) }}">
+                <any-service-ref ref="{{ pool.entries[index] }}">
+                </any-service-ref>
+              </template>
+              <template if="{{ !isServiceObject(pool.entries[index]) }}">
+                0x{{ pool.entries[index].toRadixString(16) }}
+                <template if="{{ annotatedEntries != null && annotatedEntries[index] != null }}">
+                  (<any-service-ref ref="{{ annotatedEntries[index] }}"></any-service-ref>)
+                </template>
+             </template>
+            </div>
+          </div>
+        </template>
+      </div>
+
+    </div>
+  
+    <hr>
+    <view-footer></view-footer>
+  </template>
+</polymer-element>
+
+<script type="application/dart" src="objectpool_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 791534f..66b125c 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -439,8 +439,12 @@
                     ? script.tokenToLine(currentPos)
                     : null);
     _currentCol = (currentPos != null
-                   ? (script.tokenToCol(currentPos) - 1)  // make this 0-based.
+                   ? (script.tokenToCol(currentPos))
                    : null);
+    if (_currentCol != null) {
+      _currentCol--;  // make this 0-based.
+    }
+
     _endLine = (endPos != null
                 ? script.tokenToLine(endPos)
                 : script.lines.length + script.lineOffset);
@@ -564,6 +568,10 @@
     var table = new DivElement();
     table.classes.add("sourceTable");
 
+    if (_startLine == null || _endLine == null) {
+      return table;
+    }
+
     annotationsCursor = 0;
 
     int blankLineCount = 0;
diff --git a/runtime/observatory/lib/src/elements/service_ref.html b/runtime/observatory/lib/src/elements/service_ref.html
index 097e90c..839b4c5 100644
--- a/runtime/observatory/lib/src/elements/service_ref.html
+++ b/runtime/observatory/lib/src/elements/service_ref.html
@@ -9,13 +9,31 @@
 
 <polymer-element name="object-ref" extends="service-ref">
   <template><link rel="stylesheet" href="css/shared.css">
-    <template if="{{ nameIsEmpty }}">
-      <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.vmType }}</em></a>
+
+    <template if="{{ ref.isObjectPool }}">
+      <a on-click="{{ goto }}" _href="{{ url }}">
+        <em>{{ ref.vmType }}</em> ({{ ref.length }})
+      </a>
     </template>
-    <template if="{{ !nameIsEmpty }}">
-      <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ name }}</em></a>
+    <template if="{{ ref.isICData }}">
+      <a on-click="{{ goto }}" _href="{{ url }}">
+        <em>{{ ref.vmType }}</em> ({{ ref.selector }})
+      </a>
+    </template>
+    <template if="{{ ref.isInstructions }}">
+      <a on-click="{{ goto }}" _href="{{ url }}">
+        <em>{{ ref.vmType }}</em> ({{ ref.code.name }})
+      </a>
+    </template>
+    <template if="{{ !(ref.isObjectPool || ref.isICData || ref.isInstructions) }}">
+      <template if="{{ nameIsEmpty }}">
+        <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ ref.vmType }}</em></a>
+      </template>
+      <template if="{{ !nameIsEmpty }}">
+        <a on-click="{{ goto }}" _href="{{ url }}"><em>{{ name }}</em></a>
+      </template>
     </template>
   </template>
 </polymer-element>
 
-<script type="application/dart" src="service_ref.dart"></script>
\ No newline at end of file
+<script type="application/dart" src="service_ref.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/service_view.dart b/runtime/observatory/lib/src/elements/service_view.dart
index afedd62..f0c2062 100644
--- a/runtime/observatory/lib/src/elements/service_view.dart
+++ b/runtime/observatory/lib/src/elements/service_view.dart
@@ -78,9 +78,25 @@
         element.connection = object;
         return element;
       case 'Object':
-        ObjectViewElement element = new Element.tag('object-view');
-        element.object = object;
-        return element;
+        switch (object.vmType) {
+          case 'ICData':
+            ICDataViewElement element = new Element.tag('icdata-view');
+            element.icData = object;
+            return element;
+          case 'Instructions':
+            InstructionsViewElement element =
+                new Element.tag('instructions-view');
+            element.instructions = object;
+            return element;
+          case 'ObjectPool':
+            ObjectPoolViewElement element = new Element.tag('objectpool-view');
+            element.pool = object;
+            return element;
+          default:
+            ObjectViewElement element = new Element.tag('object-view');
+            element.object = object;
+            return element;
+        }
       case 'SocketList':
         IOSocketListViewElement element =
             new Element.tag('io-socket-list-view');
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 4a7ad32..f3ebd19 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -102,6 +102,9 @@
   @reflectable String get vmType => _vmType;
   String _vmType;
 
+  bool get isICData => vmType == 'ICData';
+  bool get isInstructions => vmType == 'Instructions';
+  bool get isObjectPool => vmType == 'ObjectPool';
   bool get isContext => type == 'Context';
   bool get isError => type == 'Error';
   bool get isInstance => type == 'Instance';
@@ -118,6 +121,7 @@
   bool get isList => false;
   bool get isMap => false;
   bool get isTypedData => false;
+  bool get isRegExp => false;
   bool get isMirrorReference => false;
   bool get isWeakProperty => false;
   bool get isClosure => false;
@@ -202,12 +206,21 @@
         break;
       case 'Object':
         switch (vmType) {
-          case 'PcDescriptors':
-            obj = new PcDescriptors._empty(owner);
+          case 'ICData':
+            obj = new ICData._empty(owner);
+            break;
+          case 'Instructions':
+            obj = new Instructions._empty(owner);
             break;
           case 'LocalVarDescriptors':
             obj = new LocalVarDescriptors._empty(owner);
             break;
+          case 'ObjectPool':
+            obj = new ObjectPool._empty(owner);
+            break;
+          case 'PcDescriptors':
+            obj = new PcDescriptors._empty(owner);
+            break;
           case 'TokenStream':
             obj = new TokenStream._empty(owner);
             break;
@@ -335,6 +348,14 @@
   }
 }
 
+abstract class HeapObject extends ServiceObject {
+  @observable Class clazz;
+  @observable int size;
+  @observable int retainedSize;
+
+  HeapObject._empty(ServiceObjectOwner owner) : super._empty(owner);
+}
+
 abstract class Coverage {
   // Following getters and functions will be provided by [ServiceObject].
   String get id;
@@ -1875,6 +1896,7 @@
   @observable Context context;  // If a closure.
   @observable String name;  // If a Type.
   @observable int length; // If a List, Map or TypedData.
+  @observable String pattern;  // If a RegExp.
 
   @observable var typeClass;
   @observable var fields;
@@ -1886,6 +1908,10 @@
   @observable Instance key;  // If a WeakProperty.
   @observable Instance value;  // If a WeakProperty.
   @observable Breakpoint activationBreakpoint;  // If a Closure.
+  @observable Function oneByteFunction;  // If a RegExp.
+  @observable Function twoByteFunction;  // If a RegExp.
+  @observable Function externalOneByteFunction;  // If a RegExp.
+  @observable Function externalTwoByteFunction;  // If a RegExp.
 
   bool get isAbstractType {
     return (kind == 'Type' || kind == 'TypeRef' ||
@@ -1914,6 +1940,7 @@
         || kind == 'Float32x4List'
         || kind == 'Float64x2List';
   }
+  bool get isRegExp => kind == 'RegExp';
   bool get isMirrorReference => kind == 'MirrorReference';
   bool get isWeakProperty => kind == 'WeakProperty';
   bool get isClosure => kind == 'Closure';
@@ -1930,7 +1957,6 @@
 
     kind = map['kind'];
     clazz = map['class'];
-    size = map['size'];
     valueAsString = map['valueAsString'];
     // Coerce absence to false.
     valueAsStringIsTruncated = map['valueAsStringIsTruncated'] == true;
@@ -1938,11 +1964,19 @@
     context = map['closureContext'];
     name = map['name'];
     length = map['length'];
+    pattern = map['pattern'];
 
     if (mapIsRef) {
       return;
     }
 
+    size = map['size'];
+
+    oneByteFunction = map['_oneByteFunction'];
+    twoByteFunction = map['_twoByteFunction'];
+    externalOneByteFunction = map['_externalOneByteFunction'];
+    externalTwoByteFunction = map['_externalTwoByteFunction'];
+
     nativeFields = map['_nativeFields'];
     fields = map['fields'];
     elements = map['elements'];
@@ -2022,7 +2056,6 @@
     // Extract full properties.
     _upgradeCollection(map, isolate);
 
-    size = map['size'];
     length = map['length'];
     parentContext = map['parent'];
 
@@ -2030,6 +2063,7 @@
       return;
     }
 
+    size = map['size'];
     clazz = map['class'];
     variables = map['variables'];
 
@@ -2111,6 +2145,7 @@
   @observable int usageCounter;
   @observable bool isDart;
   @observable ProfileFunction profile;
+  @observable Instance icDataArray;
 
   bool get immutable => false;
 
@@ -2124,7 +2159,7 @@
 
     dartOwner = map['owner'];
     kind = FunctionKind.fromJSON(map['_kind']);
-    isDart = !kind.isSynthetic();
+    isDart = kind.isDart();
 
     if (dartOwner is ServiceFunction) {
       ServiceFunction ownerFunction = dartOwner;
@@ -2155,6 +2190,7 @@
     unoptimizedCode = map['_unoptimizedCode'];
     deoptimizations = map['_deoptimizations'];
     usageCounter = map['_usageCounter'];
+    icDataArray = map['_icDataArray'];
   }
 }
 
@@ -2749,9 +2785,74 @@
   }
 }
 
-class TokenStream extends ServiceObject {
-  @observable Class clazz;
-  @observable int size;
+class ObjectPool extends HeapObject {
+  bool get canCache => false;
+  bool get immutable => false;
+
+  @observable int length;
+  @observable List entries;
+
+  ObjectPool._empty(ServiceObjectOwner owner) : super._empty(owner);
+
+  void _update(ObservableMap m, bool mapIsRef) {
+    _upgradeCollection(m, isolate);
+    clazz = m['class'];
+    length = m['length'];
+    if (mapIsRef) {
+      return;
+    }
+    size = m['size'];
+    entries = m['_entries'];
+  }
+}
+
+class ICData extends HeapObject {
+  @observable ServiceObject dartOwner;
+  @observable String selector;
+  @observable Instance argumentsDescriptor;
+  @observable Instance entries;
+
+  bool get canCache => false;
+  bool get immutable => false;
+
+  ICData._empty(ServiceObjectOwner owner) : super._empty(owner);
+
+  void _update(ObservableMap m, bool mapIsRef) {
+    _upgradeCollection(m, isolate);
+    clazz = m['class'];
+    dartOwner = m['_owner'];
+    selector = m['_selector'];
+    if (mapIsRef) {
+      return;
+    }
+    size = m['size'];
+    argumentsDescriptor = m['_argumentsDescriptor'];
+    entries = m['_entries'];
+  }
+}
+
+class Instructions extends HeapObject {
+  bool get canCache => false;
+  bool get immutable => true;
+
+  @observable Code code;
+  @observable ObjectPool objectPool;
+
+  Instructions._empty(ServiceObjectOwner owner) : super._empty(owner);
+
+  void _update(ObservableMap m, bool mapIsRef) {
+    _upgradeCollection(m, isolate);
+    clazz = m['class'];
+    code = m['_code'];
+    if (mapIsRef) {
+      return;
+    }
+    size = m['size'];
+    objectPool = m['_objectPool'];
+  }
+}
+
+class TokenStream extends HeapObject {
   bool get canCache => false;
   bool get immutable => true;
 
@@ -2807,7 +2908,8 @@
     }
   }
 
-  void _resolveJumpTarget(List<CodeInstruction> instructions) {
+  void _resolveJumpTarget(List<CodeInstruction> instructionsByAddressOffset,
+                          int startAddress) {
     if (!_isJumpInstruction()) {
       return;
     }
@@ -2815,13 +2917,8 @@
     if (address == 0) {
       return;
     }
-    for (var i = 0; i < instructions.length; i++) {
-      var instruction = instructions[i];
-      if (instruction.address == address) {
-        jumpTarget = instruction;
-        return;
-      }
-    }
+
+    jumpTarget = instructionsByAddressOffset[address - startAddress];
   }
 }
 
@@ -2861,7 +2958,7 @@
   CodeInlineInterval(this.start, this.end);
 }
 
-class Code extends ServiceObject {
+class Code extends HeapObject {
   @observable CodeKind kind;
   @observable ServiceObject objectPool;
   @observable ServiceFunction function;
@@ -2870,6 +2967,8 @@
   @reflectable int startAddress = 0;
   @reflectable int endAddress = 0;
   @reflectable final instructions = new ObservableList<CodeInstruction>();
+  List<CodeInstruction> instructionsByAddressOffset;
+
   @observable ProfileCode profile;
   final List<CodeInlineInterval> inlineIntervals =
       new List<CodeInlineInterval>();
@@ -2938,6 +3037,7 @@
       return;
     }
     _loaded = true;
+    size = m['size'];
     startAddress = int.parse(m['_startAddress'], radix:16);
     endAddress = int.parse(m['_endAddress'], radix:16);
     function = isolate.getFromMap(m['function']);
@@ -3008,6 +3108,8 @@
   void _processDisassembly(List<String> disassembly){
     assert(disassembly != null);
     instructions.clear();
+    instructionsByAddressOffset = new List(endAddress - startAddress);
+
     assert((disassembly.length % 3) == 0);
     for (var i = 0; i < disassembly.length; i += 3) {
       var address = 0;  // Assume code comment.
@@ -3021,37 +3123,37 @@
       }
       var instruction = new CodeInstruction(address, pcOffset, machine, human);
       instructions.add(instruction);
+      if (disassembly[i] != '') {
+        // Not a code comment.
+        instructionsByAddressOffset[pcOffset] = instruction;
+      }
     }
     for (var instruction in instructions) {
-      instruction._resolveJumpTarget(instructions);
+      instruction._resolveJumpTarget(instructionsByAddressOffset, startAddress);
     }
   }
 
-  void _processDescriptor(Map d) {
-    var pcOffset = int.parse(d['pcOffset'], radix:16);
-    var address = startAddress + pcOffset;
-    var deoptId = d['deoptId'];
-    var tokenPos = d['tokenPos'];
-    var tryIndex = d['tryIndex'];
-    var kind = d['kind'].trim();
-    for (var instruction in instructions) {
-      if (instruction.address == address) {
+  void _processDescriptors(List<Map> descriptors) {
+    for (Map descriptor in descriptors) {
+      var pcOffset = int.parse(descriptor['pcOffset'], radix:16);
+      var address = startAddress + pcOffset;
+      var deoptId = descriptor['deoptId'];
+      var tokenPos = descriptor['tokenPos'];
+      var tryIndex = descriptor['tryIndex'];
+      var kind = descriptor['kind'].trim();
+
+      var instruction = instructionsByAddressOffset[address - startAddress];
+      if (instruction != null) {
         instruction.descriptors.add(new PcDescriptor(pcOffset,
                                                      deoptId,
                                                      tokenPos,
                                                      tryIndex,
                                                      kind));
-        return;
+      } else {
+        Logger.root.warning(
+          'Could not find instruction with pc descriptor address: $address');
       }
     }
-    Logger.root.warning(
-        'Could not find instruction with pc descriptor address: $address');
-  }
-
-  void _processDescriptors(List<Map> descriptors) {
-    for (Map descriptor in descriptors) {
-      _processDescriptor(descriptor);
-    }
   }
 
   /// Returns true if [address] is contained inside [this].
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index 7b5f63d..9445912 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -77,12 +77,16 @@
     'lib/src/elements/heap_profile.html',
     'lib/src/elements/heap_snapshot.dart',
     'lib/src/elements/heap_snapshot.html',
+    'lib/src/elements/icdata_view.dart',
+    'lib/src/elements/icdata_view.html',
     'lib/src/elements/inbound_reference.dart',
     'lib/src/elements/inbound_reference.html',
     'lib/src/elements/instance_ref.dart',
     'lib/src/elements/instance_ref.html',
     'lib/src/elements/instance_view.dart',
     'lib/src/elements/instance_view.html',
+    'lib/src/elements/instructions_view.dart',
+    'lib/src/elements/instructions_view.html',
     'lib/src/elements/io_view.dart',
     'lib/src/elements/io_view.html',
     'lib/src/elements/isolate_reconnect.dart',
@@ -107,6 +111,8 @@
     'lib/src/elements/object_common.html',
     'lib/src/elements/object_view.dart',
     'lib/src/elements/object_view.html',
+    'lib/src/elements/objectpool_view.dart',
+    'lib/src/elements/objectpool_view.html',
     'lib/src/elements/observatory_application.dart',
     'lib/src/elements/observatory_application.html',
     'lib/src/elements/observatory_element.dart',
diff --git a/runtime/vm/disassembler_x64.cc b/runtime/vm/disassembler_x64.cc
index be31deb..0b87662 100644
--- a/runtime/vm/disassembler_x64.cc
+++ b/runtime/vm/disassembler_x64.cc
@@ -1089,6 +1089,8 @@
       // if (rex_w()) AppendToBuffer("REX.W ");
     } else if ((current & 0xFE) == 0xF2) {  // Group 1 prefix (0xF2 or 0xF3).
       group_1_prefix_ = current;
+    } else if (current == 0xF0) {
+      AppendToBuffer("lock ");
     } else {  // Not a prefix - an opcode.
       break;
     }
@@ -1515,8 +1517,9 @@
     current = data + JumpConditional(data);
 
   } else if (opcode == 0xBE || opcode == 0xBF || opcode == 0xB6 ||
-             opcode == 0xB7 || opcode == 0xAF) {
-    // Size-extending moves, IMUL.
+             opcode == 0xB7 || opcode == 0xAF || opcode == 0xB0 ||
+             opcode == 0xB1) {
+    // Size-extending moves, IMUL, cmpxchg.
     current += PrintOperands(mnemonic, REG_OPER_OP_ORDER, current);
 
   } else if ((opcode & 0xF0) == 0x90) {
@@ -1581,6 +1584,9 @@
       return "shrd";
     case 0xAF:
       return "imul";
+    case 0xB0:
+    case 0xB1:
+      return "cmpxchg";
     case 0xB6:
       return "movzxb";
     case 0xB7:
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 0cc4f2b3..d493fa3 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -83,7 +83,7 @@
     FLAG_deoptimize_alot = false;  // Used in some tests.
     FLAG_deoptimize_every = 0;  // Used in some tests.
     FLAG_collect_code = false;
-    FLAG_guess_other_cid = false;
+    FLAG_guess_other_cid = true;
     Compiler::set_always_optimize(true);
     // TODO(srdjan): Enable CHA deoptimization when eager class finalization is
     // implemented, either with precompilation or as a special pass.
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 6f2f635..abdb548 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -27,9 +27,7 @@
 
 DEFINE_FLAG(int, getter_setter_ratio, 13,
     "Ratio of getter/setter usage used for double field unboxing heuristics");
-// Setting 'guess_other_cid' to true causes issue 23693 crash.
-// TODO(srdjan): Evaluate if that optimization is wrong.
-DEFINE_FLAG(bool, guess_other_cid, false,
+DEFINE_FLAG(bool, guess_other_cid, true,
     "Artificially create type feedback for arithmetic etc. operations"
     " by guessing the other unknown argument cid");
 DEFINE_FLAG(bool, load_cse, true, "Use redundant load elimination.");
@@ -197,8 +195,6 @@
       Token::IsBinaryOperator(op_kind)) {
     // Guess cid: if one of the inputs is a number assume that the other
     // is a number of same type.
-    // Issue 23693. It is potentially wrong to assign types here that may
-    // conflict with other graph analysis.
     if (FLAG_guess_other_cid) {
       const intptr_t cid_0 = class_ids[0];
       const intptr_t cid_1 = class_ids[1];
diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc
index 59d2cd3..5fec37b 100644
--- a/runtime/vm/flow_graph_range_analysis.cc
+++ b/runtime/vm/flow_graph_range_analysis.cc
@@ -621,11 +621,10 @@
 static RangeBoundary NarrowMin(const Range* range,
                                const Range* new_range,
                                RangeBoundary::RangeSize size) {
-#ifdef DEBUG
   const RangeBoundary min = Range::ConstantMin(range, size);
   const RangeBoundary new_min = Range::ConstantMin(new_range, size);
-  ASSERT(min.ConstantValue() <= new_min.ConstantValue());
-#endif
+  if (min.ConstantValue() > new_min.ConstantValue()) return range->min();
+
   // TODO(vegorov): consider using negative infinity to indicate widened bound.
   return range->min().IsMinimumOrBelow(size) ? new_range->min() : range->min();
 }
@@ -640,11 +639,10 @@
 static RangeBoundary NarrowMax(const Range* range,
                                const Range* new_range,
                                RangeBoundary::RangeSize size) {
-#ifdef DEBUG
   const RangeBoundary max = Range::ConstantMax(range, size);
   const RangeBoundary new_max = Range::ConstantMax(new_range, size);
-  ASSERT(max.ConstantValue() >= new_max.ConstantValue());
-#endif
+  if (max.ConstantValue() < new_max.ConstantValue()) return range->max();
+
   // TODO(vegorov): consider using positive infinity to indicate widened bound.
   return range->max().IsMaximumOrAbove(size) ? new_range->max() : range->max();
 }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 4274060..150be3e 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2736,7 +2736,7 @@
   set_state_bits(
       TraceAllocationBit::update(trace_allocation, raw_ptr()->state_bits_));
   if (changed) {
-    // TODO(johnmccutchan): Deoptimize the world?
+    DisableAllocationStub();
   }
 }
 
@@ -3633,6 +3633,14 @@
 
 
 void Class::DisableAllocationStub() const {
+  const Code& existing_stub = Code::Handle(allocation_stub());
+  if (existing_stub.IsNull()) {
+    return;
+  }
+  ASSERT(!CodePatcher::IsEntryPatched(existing_stub));
+  // Patch the stub so that the next caller will regenerate the stub.
+  CodePatcher::PatchEntry(existing_stub);
+  // Disassociate the existing stub from class.
   StorePointer(&raw_ptr()->allocation_stub_, Code::null());
 }
 
@@ -6979,6 +6987,10 @@
   if (!code.IsNull()) {
     jsobj.AddProperty("code", code);
   }
+  Array& ics = Array::Handle(ic_data_array());
+  if (!ics.IsNull()) {
+    jsobj.AddProperty("_icDataArray", ics);
+  }
   jsobj.AddProperty("_optimizable", is_optimizable());
   jsobj.AddProperty("_inlinable", is_inlinable());
   code = unoptimized_code();
@@ -10709,7 +10721,14 @@
 
 
 void Instructions::PrintJSONImpl(JSONStream* stream, bool ref) const {
-  Object::PrintJSONImpl(stream, ref);
+  JSONObject jsobj(stream);
+  AddCommonObjectProperties(&jsobj, "Object", ref);
+  jsobj.AddServiceId(*this);
+  jsobj.AddProperty("_code", Code::Handle(code()));
+  if (ref) {
+    return;
+  }
+  jsobj.AddProperty("_objectPool", ObjectPool::Handle(object_pool()));
 }
 
 
@@ -10800,7 +10819,35 @@
 
 
 void ObjectPool::PrintJSONImpl(JSONStream* stream, bool ref) const {
-  Object::PrintJSONImpl(stream, ref);
+  JSONObject jsobj(stream);
+  AddCommonObjectProperties(&jsobj, "Object", ref);
+  jsobj.AddServiceId(*this);
+  jsobj.AddProperty("length", Length());
+  if (ref) {
+    return;
+  }
+
+  {
+    JSONArray jsarr(&jsobj, "_entries");
+    uword imm;
+    Object& obj = Object::Handle();
+    for (intptr_t i = 0; i < Length(); i++) {
+      switch (InfoAt(i)) {
+      case ObjectPool::kTaggedObject:
+        obj = ObjectAt(i);
+        jsarr.AddValue(obj);
+        break;
+      case ObjectPool::kImmediate:
+        // We might want to distingiush between immediates and addresses
+        // in the future.
+        imm = RawValueAt(i);
+        jsarr.AddValue64(imm);
+        break;
+      default:
+        UNREACHABLE();
+      }
+    }
+  }
 }
 
 
@@ -12212,7 +12259,17 @@
 
 
 void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const {
-  Object::PrintJSONImpl(stream, ref);
+  JSONObject jsobj(stream);
+  AddCommonObjectProperties(&jsobj, "Object", ref);
+  jsobj.AddServiceId(*this);
+  jsobj.AddProperty("_owner", Object::Handle(owner()));
+  jsobj.AddProperty("_selector", String::Handle(target_name()).ToCString());
+  if (ref) {
+    return;
+  }
+  jsobj.AddProperty("_argumentsDescriptor",
+                    Object::Handle(arguments_descriptor()));
+  jsobj.AddProperty("_entries", Object::Handle(ic_data()));
 }
 
 
@@ -12974,7 +13031,7 @@
     // Generate a fake function reference.
     JSONObject func(&jsobj, "function");
     func.AddProperty("type", "@Function");
-    func.AddProperty("kind", "Stub");
+    func.AddProperty("_kind", "Stub");
     func.AddProperty("name", user_name.ToCString());
     AddNameProperties(&func, user_name, vm_name);
   }
@@ -20850,7 +20907,26 @@
 
 
 void JSRegExp::PrintJSONImpl(JSONStream* stream, bool ref) const {
-  Instance::PrintJSONImpl(stream, ref);
+  JSONObject jsobj(stream);
+  PrintSharedInstanceJSON(&jsobj, ref);
+  jsobj.AddProperty("kind", "RegExp");
+  jsobj.AddServiceId(*this);
+
+  jsobj.AddProperty("pattern", String::Handle(pattern()));
+
+  if (ref) {
+    return;
+  }
+
+  Function& func = Function::Handle();
+  func = function(kOneByteStringCid);
+  jsobj.AddProperty("_oneByteFunction", func);
+  func = function(kTwoByteStringCid);
+  jsobj.AddProperty("_twoByteFunction", func);
+  func = function(kExternalOneByteStringCid);
+  jsobj.AddProperty("_externalOneByteFunction", func);
+  func = function(kExternalTwoByteStringCid);
+  jsobj.AddProperty("_externalTwoByteFunction", func);
 }
 
 
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index a8fc76a..6cc8e54 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -9599,14 +9599,17 @@
   bool is_yield_each = false;
   const intptr_t yield_pos = TokenPos();
   ConsumeToken();  // yield reserved word.
-  ASSERT(innermost_function().IsGenerator() ||
-         innermost_function().IsSyncGenClosure() ||
-         innermost_function().IsAsyncGenerator() ||
-         innermost_function().IsAsyncGenClosure());
   if (CurrentToken() == Token::kMUL) {
     is_yield_each = true;
     ConsumeToken();
   }
+  if (!innermost_function().IsGenerator() &&
+      !innermost_function().IsGeneratorClosure()) {
+    ReportError(yield_pos,
+                "yield%s statement only allowed in generator functions",
+                is_yield_each ? "*" : "");
+  }
+
   AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
 
   LetNode* yield = new(Z) LetNode(yield_pos);
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 188d7cd..5e8940a 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -19,12 +19,6 @@
 
 DEFINE_FLAG(bool, trace_profiler, false, "Trace profiler.");
 
-// Forward declarations.
-class CodeRegion;
-class ProfileFunction;
-class ProfileFunctionTable;
-
-
 class DeoptimizedCodeSet : public ZoneAllocated {
  public:
   explicit DeoptimizedCodeSet(Isolate* isolate)
@@ -92,156 +86,361 @@
   const GrowableObjectArray& current_;
 };
 
-class ProfileFunction : public ZoneAllocated {
- public:
-  enum Kind {
-    kDartFunction,    // Dart function.
-    kNativeFunction,  // Synthetic function for Native (C/C++).
-    kTagFunction,     // Synthetic function for a VM or User tag.
-    kStubFunction,    // Synthetic function for stub code.
-    kUnkownFunction,  // A singleton function for unknown objects.
-  };
-  ProfileFunction(Kind kind,
+
+ProfileFunction::ProfileFunction(Kind kind,
                   const char* name,
                   const Function& function,
                   const intptr_t table_index)
-      : kind_(kind),
-        name_(name),
-        function_(Function::ZoneHandle(function.raw())),
-        table_index_(table_index),
-        code_objects_(new ZoneGrowableArray<intptr_t>()),
-        exclusive_ticks_(0),
-        inclusive_ticks_(0),
-        inclusive_tick_serial_(0) {
-    ASSERT((kind_ != kDartFunction) || !function_.IsNull());
-    ASSERT((kind_ != kDartFunction) || (table_index_ >= 0));
-    ASSERT(code_objects_->length() == 0);
-  }
+    : kind_(kind),
+      name_(name),
+      function_(Function::ZoneHandle(function.raw())),
+      table_index_(table_index),
+      profile_codes_(0),
+      exclusive_ticks_(0),
+      inclusive_ticks_(0) {
+  ASSERT((kind_ != kDartFunction) || !function_.IsNull());
+  ASSERT((kind_ != kDartFunction) || (table_index_ >= 0));
+  ASSERT(profile_codes_.length() == 0);
+}
 
-  const char* name() const {
-    ASSERT(name_ != NULL);
+
+const char* ProfileFunction::Name() const {
+  if (name_ != NULL) {
     return name_;
   }
+  ASSERT(!function_.IsNull());
+  const String& func_name =
+      String::Handle(function_.QualifiedUserVisibleName());
+  return func_name.ToCString();
+}
 
-  RawFunction* function() const {
-    return function_.raw();
-  }
-
-  intptr_t index() const {
-    return table_index_;
-  }
-
-  Kind kind() const {
-    return kind_;
-  }
-
-  const char* KindToCString(Kind kind) {
-    switch (kind) {
-      case kDartFunction:
-        return "Dart";
-      case kNativeFunction:
-        return "Native";
-      case kTagFunction:
-        return "Tag";
-      case kStubFunction:
-        return "Stub";
-      case kUnkownFunction:
-        return "Collected";
-      default:
-        UNIMPLEMENTED();
-        return "";
-    }
-  }
-
-  void Dump() {
-    const char* n = (name_ == NULL) ? "<NULL>" : name_;
-    const char* fn = "";
-    if (!function_.IsNull()) {
-      fn = function_.ToQualifiedCString();
-    }
-    OS::Print("%s %s [%s]", KindToCString(kind()), n, fn);
-  }
-
-  void AddCodeObjectIndex(intptr_t index) {
-    for (intptr_t i = 0; i < code_objects_->length(); i++) {
-      if ((*code_objects_)[i] == index) {
-        return;
-      }
-    }
-    code_objects_->Add(index);
-  }
-
-  intptr_t inclusive_ticks() const {
-    return inclusive_ticks_;
-  }
-  void inc_inclusive_ticks() {
-    inclusive_ticks_++;
-  }
-  intptr_t exclusive_ticks() const {
-    return exclusive_ticks_;
-  }
-
-  void Tick(bool exclusive, intptr_t serial) {
-    // Assert that exclusive ticks are never passed a valid serial number.
-    ASSERT((exclusive && (serial == -1)) || (!exclusive && (serial != -1)));
-    if (!exclusive && (inclusive_tick_serial_ == serial)) {
-      // We've already given this object an inclusive tick for this sample.
+void ProfileFunction::Tick(bool exclusive, intptr_t inclusive_serial) {
+  if (exclusive) {
+    exclusive_ticks_++;
+  } else {
+    if (inclusive_serial_ == inclusive_serial) {
+      // Already ticket.
       return;
     }
-    if (exclusive) {
-      exclusive_ticks_++;
-    } else {
-      inclusive_ticks_++;
-      // Mark the last serial we ticked the inclusive count.
-      inclusive_tick_serial_ = serial;
+    inclusive_serial_ = inclusive_serial;
+    inclusive_ticks_++;
+  }
+}
+
+
+const char* ProfileFunction::KindToCString(Kind kind) {
+  switch (kind) {
+    case kDartFunction:
+      return "Dart";
+    case kNativeFunction:
+      return "Native";
+    case kTagFunction:
+      return "Tag";
+    case kStubFunction:
+      return "Stub";
+    case kUnknownFunction:
+      return "Collected";
+    default:
+      UNIMPLEMENTED();
+      return "";
+  }
+}
+
+
+void ProfileFunction::PrintToJSONObject(JSONObject* func) {
+  func->AddProperty("type", "@Function");
+  func->AddProperty("name", name());
+  func->AddProperty("_kind", KindToCString(kind()));
+}
+
+
+void ProfileFunction::PrintToJSONArray(JSONArray* functions) {
+  JSONObject obj(functions);
+  obj.AddProperty("kind", KindToCString(kind()));
+  obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks());
+  obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks());
+  if (kind() == kDartFunction) {
+    ASSERT(!function_.IsNull());
+    obj.AddProperty("function", function_);
+  } else {
+    JSONObject func(&obj, "function");
+    PrintToJSONObject(&func);
+  }
+  {
+    JSONArray codes(&obj, "codes");
+    for (intptr_t i = 0; i < profile_codes_.length(); i++) {
+      intptr_t code_index = profile_codes_[i];
+      codes.AddValue(code_index);
+    }
+  }
+}
+
+
+void ProfileFunction::AddProfileCode(intptr_t code_table_index) {
+  for (intptr_t i = 0; i < profile_codes_.length(); i++) {
+    if (profile_codes_[i] == code_table_index) {
+      return;
+    }
+  }
+  profile_codes_.Add(code_table_index);
+}
+
+
+ProfileCodeAddress::ProfileCodeAddress(uword pc)
+    : pc_(pc),
+      exclusive_ticks_(0),
+      inclusive_ticks_(0) {
+}
+
+
+void ProfileCodeAddress::Tick(bool exclusive) {
+  if (exclusive) {
+    exclusive_ticks_++;
+  } else {
+    inclusive_ticks_++;
+  }
+}
+
+
+ProfileCode::ProfileCode(Kind kind,
+                         uword start,
+                         uword end,
+                         int64_t timestamp,
+                         const Code& code)
+    : kind_(kind),
+      start_(start),
+      end_(end),
+      exclusive_ticks_(0),
+      inclusive_ticks_(0),
+      inclusive_serial_(-1),
+      code_(code),
+      name_(NULL),
+      compile_timestamp_(0),
+      function_(NULL),
+      code_table_index_(-1),
+      address_ticks_(0) {
+}
+
+
+void ProfileCode::AdjustExtent(uword start, uword end) {
+  if (start < start_) {
+    start_ = start;
+  }
+  if (end > end_) {
+    end_ = end;
+  }
+  ASSERT(start_ < end_);
+}
+
+
+bool ProfileCode::Overlaps(const ProfileCode* other) const {
+  ASSERT(other != NULL);
+  return other->Contains(start_)   ||
+         other->Contains(end_ - 1) ||
+         Contains(other->start())  ||
+         Contains(other->end() - 1);
+}
+
+
+bool ProfileCode::IsOptimizedDart() const {
+  return !code_.IsNull() && code_.is_optimized();
+}
+
+
+void ProfileCode::SetName(const char* name) {
+  if (name == NULL) {
+    name_ = NULL;
+  }
+  intptr_t len = strlen(name);
+  name_ = Isolate::Current()->current_zone()->Alloc<const char>(len + 1);
+  strncpy(const_cast<char*>(name_), name, len);
+  const_cast<char*>(name_)[len] = '\0';
+}
+
+
+void ProfileCode::GenerateAndSetSymbolName(const char* prefix) {
+  const intptr_t kBuffSize = 512;
+  char buff[kBuffSize];
+  OS::SNPrint(&buff[0], kBuffSize-1, "%s [%" Px ", %" Px ")",
+              prefix, start(), end());
+  SetName(buff);
+}
+
+
+void ProfileCode::Tick(uword pc, bool exclusive, intptr_t serial) {
+  if (exclusive) {
+    exclusive_ticks_++;
+  } else {
+    if (inclusive_serial_ == serial) {
+      // Already ticked for this sample.
+      return;
+    }
+    inclusive_serial_ = serial;
+    inclusive_ticks_++;
+  }
+  TickAddress(pc, exclusive);
+}
+
+
+void ProfileCode::TickAddress(uword pc, bool exclusive) {
+  const intptr_t length = address_ticks_.length();
+
+  intptr_t i = 0;
+  for (; i < length; i++) {
+    ProfileCodeAddress& entry = address_ticks_[i];
+    if (entry.pc() == pc) {
+      // Tick the address entry.
+      entry.Tick(exclusive);
+      return;
+    }
+    if (entry.pc() > pc) {
+      break;
     }
   }
 
-  void PrintToJSONObject(JSONObject* func) {
-    func->AddProperty("type", "@Function");
-    func->AddProperty("name", name());
-    func->AddProperty("_kind", KindToCString(kind()));
-  }
+  // New address, add entry.
+  ProfileCodeAddress entry(pc);
 
-  void PrintToJSONArray(JSONArray* functions) {
-    JSONObject obj(functions);
-    obj.AddProperty("kind", KindToCString(kind()));
-    obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks());
-    obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks());
-    if (kind() == kDartFunction) {
-      ASSERT(!function_.IsNull());
-      obj.AddProperty("function", function_);
-    } else {
-      JSONObject func(&obj, "function");
-      PrintToJSONObject(&func);
-    }
-    {
-      JSONArray codes(&obj, "codes");
-      for (intptr_t i = 0; i < code_objects_->length(); i++) {
-        intptr_t code_index = (*code_objects_)[i];
-        codes.AddValue(code_index);
-      }
+  entry.Tick(exclusive);
+
+  if (i < length) {
+    // Insert at i.
+    address_ticks_.InsertAt(i, entry);
+  } else {
+    // Add to end.
+    address_ticks_.Add(entry);
+  }
+}
+
+
+void ProfileCode::PrintNativeCode(JSONObject* profile_code_obj) {
+  ASSERT(kind() == kNativeCode);
+  JSONObject obj(profile_code_obj, "code");
+  obj.AddProperty("type", "@Code");
+  obj.AddProperty("kind", "Native");
+  obj.AddProperty("name", name());
+  obj.AddProperty("_optimized", false);
+  obj.AddPropertyF("start", "%" Px "", start());
+  obj.AddPropertyF("end", "%" Px "", end());
+  {
+    // Generate a fake function entry.
+    JSONObject func(&obj, "function");
+    ASSERT(function_ != NULL);
+    function_->PrintToJSONObject(&func);
+  }
+}
+
+
+void ProfileCode::PrintCollectedCode(JSONObject* profile_code_obj) {
+  ASSERT(kind() == kCollectedCode);
+  JSONObject obj(profile_code_obj, "code");
+  obj.AddProperty("type", "@Code");
+  obj.AddProperty("kind", "Collected");
+  obj.AddProperty("name", name());
+  obj.AddProperty("_optimized", false);
+  obj.AddPropertyF("start", "%" Px "", start());
+  obj.AddPropertyF("end", "%" Px "", end());
+  {
+    // Generate a fake function entry.
+    JSONObject func(&obj, "function");
+    ASSERT(function_ != NULL);
+    function_->PrintToJSONObject(&func);
+  }
+}
+
+
+void ProfileCode::PrintOverwrittenCode(JSONObject* profile_code_obj) {
+  ASSERT(kind() == kReusedCode);
+  JSONObject obj(profile_code_obj, "code");
+  obj.AddProperty("type", "@Code");
+  obj.AddProperty("kind", "Collected");
+  obj.AddProperty("name", name());
+  obj.AddProperty("_optimized", false);
+  obj.AddPropertyF("start", "%" Px "", start());
+  obj.AddPropertyF("end", "%" Px "", end());
+  {
+    // Generate a fake function entry.
+    JSONObject func(&obj, "function");
+    ASSERT(function_ != NULL);
+    function_->PrintToJSONObject(&func);
+  }
+}
+
+
+void ProfileCode::PrintTagCode(JSONObject* profile_code_obj) {
+  ASSERT(kind() == kTagCode);
+  JSONObject obj(profile_code_obj, "code");
+  obj.AddProperty("type", "@Code");
+  obj.AddProperty("kind", "Tag");
+  obj.AddProperty("name", name());
+  obj.AddPropertyF("start", "%" Px "", start());
+  obj.AddPropertyF("end", "%" Px "", end());
+  obj.AddProperty("_optimized", false);
+  {
+    // Generate a fake function entry.
+    JSONObject func(&obj, "function");
+    ASSERT(function_ != NULL);
+    function_->PrintToJSONObject(&func);
+  }
+}
+
+
+const char* ProfileCode::KindToCString(Kind kind) {
+  switch (kind) {
+    case kDartCode:
+      return "Dart";
+    case kCollectedCode:
+      return "Collected";
+    case kNativeCode:
+      return "Native";
+    case kReusedCode:
+      return "Overwritten";
+    case kTagCode:
+      return "Tag";
+  }
+  UNREACHABLE();
+  return NULL;
+}
+
+
+void ProfileCode::PrintToJSONArray(JSONArray* codes) {
+  JSONObject obj(codes);
+  obj.AddProperty("kind", ProfileCode::KindToCString(kind()));
+  obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks());
+  obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks());
+  if (kind() == kDartCode) {
+    ASSERT(!code_.IsNull());
+    obj.AddProperty("code", code_);
+  } else if (kind() == kCollectedCode) {
+    PrintCollectedCode(&obj);
+  } else if (kind() == kReusedCode) {
+    PrintOverwrittenCode(&obj);
+  } else if (kind() == kTagCode) {
+    PrintTagCode(&obj);
+  } else {
+    ASSERT(kind() == kNativeCode);
+    PrintNativeCode(&obj);
+  }
+  {
+    JSONArray ticks(&obj, "ticks");
+    for (intptr_t i = 0; i < address_ticks_.length(); i++) {
+      const ProfileCodeAddress& entry = address_ticks_[i];
+      ticks.AddValueF("%" Px "", entry.pc());
+      ticks.AddValueF("%" Pd "", entry.exclusive_ticks());
+      ticks.AddValueF("%" Pd "", entry.inclusive_ticks());
     }
   }
-
- private:
-  const Kind kind_;
-  const char* name_;
-  const Function& function_;
-  const intptr_t table_index_;
-  ZoneGrowableArray<intptr_t>* code_objects_;
-  intptr_t exclusive_ticks_;
-  intptr_t inclusive_ticks_;
-  intptr_t inclusive_tick_serial_;
-};
+}
 
 
-class ProfileFunctionTable : public ValueObject {
+class ProfileFunctionTable : public ZoneAllocated {
  public:
   ProfileFunctionTable()
       : null_function_(Function::ZoneHandle()),
-        table_(new ZoneGrowableArray<ProfileFunction*>()),
+        table_(8),
         unknown_function_(NULL) {
+    unknown_function_ = Add(ProfileFunction::kUnknownFunction,
+                            "<unknown Dart function>");
   }
 
   ProfileFunction* LookupOrAdd(const Function& function) {
@@ -255,8 +454,8 @@
 
   intptr_t LookupIndex(const Function& function) {
     ASSERT(!function.IsNull());
-    for (intptr_t i = 0; i < table_->length(); i++) {
-      ProfileFunction* profile_function = (*table_)[i];
+    for (intptr_t i = 0; i < table_.length(); i++) {
+      ProfileFunction* profile_function = table_[i];
       if (profile_function->function() == function.raw()) {
         return i;
       }
@@ -265,11 +464,6 @@
   }
 
   ProfileFunction* GetUnknown() {
-    if (unknown_function_ == NULL) {
-      // Construct.
-      unknown_function_ = Add(ProfileFunction::kUnkownFunction,
-                              "<unknown Dart function>");
-    }
     ASSERT(unknown_function_ != NULL);
     return unknown_function_;
   }
@@ -292,14 +486,14 @@
     return Add(ProfileFunction::kStubFunction, name);
   }
 
-  intptr_t Length() const {
-    return table_->length();
+  intptr_t length() const {
+    return table_.length();
   }
 
   ProfileFunction* At(intptr_t i) const {
     ASSERT(i >= 0);
-    ASSERT(i < Length());
-    return (*table_)[i];
+    ASSERT(i < length());
+    return table_[i];
   }
 
  private:
@@ -310,8 +504,8 @@
         new ProfileFunction(kind,
                             name,
                             null_function_,
-                            table_->length());
-    table_->Add(profile_function);
+                            table_.length());
+    table_.Add(profile_function);
     return profile_function;
   }
 
@@ -321,8 +515,8 @@
         new ProfileFunction(ProfileFunction::kDartFunction,
                             NULL,
                             function,
-                            table_->length());
-    table_->Add(profile_function);
+                            table_.length());
+    table_.Add(profile_function);
     return profile_function;
   }
 
@@ -332,559 +526,189 @@
     if (index == -1) {
       return NULL;
     }
-    return (*table_)[index];
+    return table_[index];
   }
 
   const Function& null_function_;
-  ZoneGrowableArray<ProfileFunction*>* table_;
-
+  ZoneGrowableArray<ProfileFunction*> table_;
   ProfileFunction* unknown_function_;
 };
 
 
-struct AddressEntry {
-  uword pc;
-  intptr_t exclusive_ticks;
-  intptr_t inclusive_ticks;
+ProfileFunction* ProfileCode::SetFunctionAndName(ProfileFunctionTable* table) {
+  ASSERT(function_ == NULL);
 
-  void tick(bool exclusive) {
-    if (exclusive) {
-      exclusive_ticks++;
+  ProfileFunction* function = NULL;
+  if ((kind() == kReusedCode) || (kind() == kCollectedCode)) {
+    if (name() == NULL) {
+      // Lazily set generated name.
+      GenerateAndSetSymbolName("[Collected]");
+    }
+    // Map these to a canonical unknown function.
+    function = table->GetUnknown();
+  } else if (kind() == kDartCode) {
+    ASSERT(!code_.IsNull());
+    const Object& obj = Object::Handle(code_.owner());
+    if (obj.IsFunction()) {
+      const String& user_name = String::Handle(code_.PrettyName());
+      function = table->LookupOrAdd(Function::Cast(obj));
+      SetName(user_name.ToCString());
     } else {
-      inclusive_ticks++;
+      // A stub.
+      const String& user_name = String::Handle(code_.PrettyName());
+      function = table->AddStub(start(), user_name.ToCString());
+      SetName(user_name.ToCString());
     }
-  }
-};
-
-typedef bool (*RegionCompare)(uword pc, uword region_start, uword region_end);
-
-// A contiguous address region that holds code. Each CodeRegion has a "kind"
-// which describes the type of code contained inside the region. Each
-// region covers the following interval: [start, end).
-class CodeRegion : public ZoneAllocated {
- public:
-  enum Kind {
-    kDartCode,       // Live Dart code.
-    kCollectedCode,  // Dead Dart code.
-    kNativeCode,     // Native code.
-    kReusedCode,     // Dead Dart code that has been reused by new kDartCode.
-    kTagCode,        // A special kind of code representing a tag.
-  };
-
-  CodeRegion(Kind kind,
-             uword start,
-             uword end,
-             int64_t timestamp,
-             const Code& code)
-      : kind_(kind),
-        start_(start),
-        end_(end),
-        inclusive_ticks_(0),
-        exclusive_ticks_(0),
-        inclusive_tick_serial_(0),
-        name_(NULL),
-        compile_timestamp_(timestamp),
-        code_(Code::ZoneHandle(code.raw())),
-        profile_function_(NULL),
-        code_table_index_(-1) {
-    ASSERT(start_ < end_);
-    // Ensure all kDartCode have a valid code_ object.
-    ASSERT((kind != kDartCode) || (!code_.IsNull()));
-  }
-
-  uword start() const { return start_; }
-  void set_start(uword start) {
-    start_ = start;
-  }
-
-  uword end() const { return end_; }
-  void set_end(uword end) {
-    end_ = end;
-  }
-
-  void AdjustExtent(uword start, uword end) {
-    if (start < start_) {
-      start_ = start;
+  } else if (kind() == kNativeCode) {
+    if (name() == NULL) {
+      // Lazily set generated name.
+      GenerateAndSetSymbolName("[Native]");
     }
-    if (end > end_) {
-      end_ = end;
-    }
-    ASSERT(start_ < end_);
-  }
-
-  bool contains(uword pc) const {
-    return (pc >= start_) && (pc < end_);
-  }
-
-  bool overlaps(const CodeRegion* other) const {
-    ASSERT(other != NULL);
-    return other->contains(start_)   ||
-           other->contains(end_ - 1) ||
-           contains(other->start())  ||
-           contains(other->end() - 1);
-  }
-
-  int64_t compile_timestamp() const { return compile_timestamp_; }
-  void set_compile_timestamp(int64_t timestamp) {
-    compile_timestamp_ = timestamp;
-  }
-
-  intptr_t inclusive_ticks() const { return inclusive_ticks_; }
-  void set_inclusive_ticks(intptr_t inclusive_ticks) {
-    inclusive_ticks_ = inclusive_ticks;
-  }
-  void inc_inclusive_ticks() {
-    inclusive_ticks_++;
-  }
-
-  intptr_t exclusive_ticks() const { return exclusive_ticks_; }
-  void set_exclusive_ticks(intptr_t exclusive_ticks) {
-    exclusive_ticks_ = exclusive_ticks;
-  }
-
-  const char* name() const { return name_; }
-  void SetName(const char* name) {
-    if (name == NULL) {
-      name_ = NULL;
-    }
-    intptr_t len = strlen(name);
-    name_ = Isolate::Current()->current_zone()->Alloc<const char>(len + 1);
-    strncpy(const_cast<char*>(name_), name, len);
-    const_cast<char*>(name_)[len] = '\0';
-  }
-
-  bool IsOptimizedDart() const {
-    return !code_.IsNull() && code_.is_optimized();
-  }
-
-  RawCode* code() const {
-    return code_.raw();
-  }
-
-  ProfileFunction* SetFunctionAndName(ProfileFunctionTable* table) {
-    ASSERT(profile_function_ == NULL);
-
-    ProfileFunction* function = NULL;
-    if ((kind() == kReusedCode) || (kind() == kCollectedCode)) {
-      if (name() == NULL) {
-        // Lazily set generated name.
-        GenerateAndSetSymbolName("[Collected]");
-      }
-      // Map these to a canonical unknown function.
-      function = table->GetUnknown();
-    } else if (kind() == kDartCode) {
-      ASSERT(!code_.IsNull());
-      const Object& obj = Object::Handle(code_.owner());
-      if (obj.IsFunction()) {
-        const String& user_name = String::Handle(code_.PrettyName());
-        function = table->LookupOrAdd(Function::Cast(obj));
-        SetName(user_name.ToCString());
+    function = table->AddNative(start(), name());
+  } else if (kind() == kTagCode) {
+    if (name() == NULL) {
+      if (UserTags::IsUserTag(start())) {
+        const char* tag_name = UserTags::TagName(start());
+        ASSERT(tag_name != NULL);
+        SetName(tag_name);
+      } else if (VMTag::IsVMTag(start()) ||
+                 VMTag::IsRuntimeEntryTag(start()) ||
+                 VMTag::IsNativeEntryTag(start())) {
+        const char* tag_name = VMTag::TagName(start());
+        ASSERT(tag_name != NULL);
+        SetName(tag_name);
       } else {
-        // A stub.
-        const String& user_name = String::Handle(code_.PrettyName());
-        function = table->AddStub(start(), user_name.ToCString());
-        SetName(user_name.ToCString());
-      }
-    } else if (kind() == kNativeCode) {
-      if (name() == NULL) {
-        // Lazily set generated name.
-        GenerateAndSetSymbolName("[Native]");
-      }
-      function = table->AddNative(start(), name());
-    } else if (kind() == kTagCode) {
-      if (name() == NULL) {
-        if (UserTags::IsUserTag(start())) {
-          const char* tag_name = UserTags::TagName(start());
-          ASSERT(tag_name != NULL);
-          SetName(tag_name);
-        } else if (VMTag::IsVMTag(start()) ||
-                   VMTag::IsRuntimeEntryTag(start()) ||
-                   VMTag::IsNativeEntryTag(start())) {
-          const char* tag_name = VMTag::TagName(start());
-          ASSERT(tag_name != NULL);
-          SetName(tag_name);
+        if (start() == VMTag::kRootTagId) {
+          SetName("Root");
         } else {
-          if (start() == VMTag::kRootTagId) {
-            SetName("Root");
-          } else {
-            ASSERT(start() == VMTag::kTruncatedTagId);
-            SetName("[Truncated]");
-          }
+          ASSERT(start() == VMTag::kTruncatedTagId);
+          SetName("[Truncated]");
         }
       }
-      function = table->AddTag(start(), name());
-    } else {
-      UNREACHABLE();
     }
-    ASSERT(function != NULL);
-    // Register this CodeRegion with this function.
-    function->AddCodeObjectIndex(code_table_index());
-    profile_function_ = function;
-    return profile_function_;
-  }
-
-  ProfileFunction* function() const {
-    ASSERT(profile_function_ != NULL);
-    return profile_function_;
-  }
-
-  void set_code_table_index(intptr_t code_table_index) {
-    ASSERT(code_table_index_ == -1);
-    ASSERT(code_table_index != -1);
-    code_table_index_ = code_table_index;
-  }
-  intptr_t code_table_index() const {
-    ASSERT(code_table_index_ != -1);
-    return code_table_index_;
-  }
-
-  Kind kind() const { return kind_; }
-
-  static const char* KindToCString(Kind kind) {
-    switch (kind) {
-      case kDartCode:
-        return "Dart";
-      case kCollectedCode:
-        return "Collected";
-      case kNativeCode:
-        return "Native";
-      case kReusedCode:
-        return "Overwritten";
-      case kTagCode:
-        return "Tag";
-    }
+    function = table->AddTag(start(), name());
+  } else {
     UNREACHABLE();
-    return NULL;
   }
+  ASSERT(function != NULL);
 
-  void DebugPrint() const {
-    OS::Print("%s [%" Px ", %" Px ") %" Pd64 "\n",
-              KindToCString(kind_),
-              start(),
-              end(),
-              compile_timestamp_);
-  }
+  function->AddProfileCode(code_table_index());
 
-  void Tick(uword pc, bool exclusive, intptr_t serial) {
-    // Assert that exclusive ticks are never passed a valid serial number.
-    ASSERT((exclusive && (serial == -1)) || (!exclusive && (serial != -1)));
-    if (!exclusive && (inclusive_tick_serial_ == serial)) {
-      // We've already given this code object an inclusive tick for this sample.
-      return;
-    }
-    // Tick the code object.
-    if (exclusive) {
-      exclusive_ticks_++;
-    } else {
-      inclusive_ticks_++;
-      // Mark the last serial we ticked the inclusive count.
-      inclusive_tick_serial_ = serial;
-    }
-    TickAddress(pc, exclusive);
-  }
-
-  void PrintNativeCode(JSONObject* profile_code_obj) {
-    ASSERT(kind() == kNativeCode);
-    JSONObject obj(profile_code_obj, "code");
-    obj.AddProperty("type", "@Code");
-    obj.AddProperty("kind", "Native");
-    obj.AddProperty("name", name());
-    obj.AddProperty("_optimized", false);
-    obj.AddPropertyF("start", "%" Px "", start());
-    obj.AddPropertyF("end", "%" Px "", end());
-    {
-      // Generate a fake function entry.
-      JSONObject func(&obj, "function");
-      profile_function_->PrintToJSONObject(&func);
-    }
-  }
-
-  void PrintCollectedCode(JSONObject* profile_code_obj) {
-    ASSERT(kind() == kCollectedCode);
-    JSONObject obj(profile_code_obj, "code");
-    obj.AddProperty("type", "@Code");
-    obj.AddProperty("kind", "Collected");
-    obj.AddProperty("name", name());
-    obj.AddProperty("_optimized", false);
-    obj.AddPropertyF("start", "%" Px "", start());
-    obj.AddPropertyF("end", "%" Px "", end());
-    {
-      // Generate a fake function entry.
-      JSONObject func(&obj, "function");
-      profile_function_->PrintToJSONObject(&func);
-    }
-  }
-
-  void PrintOverwrittenCode(JSONObject* profile_code_obj) {
-    ASSERT(kind() == kReusedCode);
-    JSONObject obj(profile_code_obj, "code");
-    obj.AddProperty("type", "@Code");
-    obj.AddProperty("kind", "Collected");
-    obj.AddProperty("name", name());
-    obj.AddProperty("_optimized", false);
-    obj.AddPropertyF("start", "%" Px "", start());
-    obj.AddPropertyF("end", "%" Px "", end());
-    {
-      // Generate a fake function entry.
-      JSONObject func(&obj, "function");
-      ASSERT(profile_function_ != NULL);
-      profile_function_->PrintToJSONObject(&func);
-    }
-  }
-
-  void PrintTagCode(JSONObject* profile_code_obj) {
-    ASSERT(kind() == kTagCode);
-    JSONObject obj(profile_code_obj, "code");
-    obj.AddProperty("type", "@Code");
-    obj.AddProperty("kind", "Tag");
-    obj.AddProperty("name", name());
-    obj.AddPropertyF("start", "%" Px "", start());
-    obj.AddPropertyF("end", "%" Px "", end());
-    obj.AddProperty("_optimized", false);
-    {
-      // Generate a fake function entry.
-      JSONObject func(&obj, "function");
-      ASSERT(profile_function_ != NULL);
-      profile_function_->PrintToJSONObject(&func);
-    }
-  }
-
-  void PrintToJSONArray(JSONArray* codes) {
-    JSONObject obj(codes);
-    obj.AddProperty("kind", KindToCString(kind()));
-    obj.AddPropertyF("inclusiveTicks", "%" Pd "", inclusive_ticks());
-    obj.AddPropertyF("exclusiveTicks", "%" Pd "", exclusive_ticks());
-    if (kind() == kDartCode) {
-      ASSERT(!code_.IsNull());
-      obj.AddProperty("code", code_);
-    } else if (kind() == kCollectedCode) {
-      PrintCollectedCode(&obj);
-    } else if (kind() == kReusedCode) {
-      PrintOverwrittenCode(&obj);
-    } else if (kind() == kTagCode) {
-      PrintTagCode(&obj);
-    } else {
-      ASSERT(kind() == kNativeCode);
-      PrintNativeCode(&obj);
-    }
-    {
-      JSONArray ticks(&obj, "ticks");
-      for (intptr_t i = 0; i < address_table_.length(); i++) {
-        const AddressEntry& entry = address_table_[i];
-        ticks.AddValueF("%" Px "", entry.pc);
-        ticks.AddValueF("%" Pd "", entry.exclusive_ticks);
-        ticks.AddValueF("%" Pd "", entry.inclusive_ticks);
-      }
-    }
-  }
-
- private:
-  void TickAddress(uword pc, bool exclusive) {
-    const intptr_t length = address_table_.length();
-    intptr_t i = 0;
-    for (; i < length; i++) {
-      AddressEntry& entry = address_table_[i];
-      if (entry.pc == pc) {
-        // Tick the address entry.
-        entry.tick(exclusive);
-        return;
-      }
-      if (entry.pc > pc) {
-        break;
-      }
-    }
-    // New address, add entry.
-    AddressEntry entry;
-    entry.pc = pc;
-    entry.exclusive_ticks = 0;
-    entry.inclusive_ticks = 0;
-    entry.tick(exclusive);
-    if (i < length) {
-      // Insert at i.
-      address_table_.InsertAt(i, entry);
-    } else {
-      // Add to end.
-      address_table_.Add(entry);
-    }
-  }
-
-  void GenerateAndSetSymbolName(const char* prefix) {
-    const intptr_t kBuffSize = 512;
-    char buff[kBuffSize];
-    OS::SNPrint(&buff[0], kBuffSize-1, "%s [%" Px ", %" Px ")",
-                prefix, start(), end());
-    SetName(buff);
-  }
-
-  // CodeRegion kind.
-  const Kind kind_;
-  // CodeRegion start address.
-  uword start_;
-  // CodeRegion end address.
-  uword end_;
-  // Inclusive ticks.
-  intptr_t inclusive_ticks_;
-  // Exclusive ticks.
-  intptr_t exclusive_ticks_;
-  // Inclusive tick serial number, ensures that each CodeRegion is only given
-  // a single inclusive tick per sample.
-  intptr_t inclusive_tick_serial_;
-  // Name of code region.
-  const char* name_;
-  // The compilation timestamp associated with this code region.
-  int64_t compile_timestamp_;
-  // Dart code object (may be null).
-  const Code& code_;
-  // Pointer to ProfileFunction.
-  ProfileFunction* profile_function_;
-  // Final code table index.
-  intptr_t code_table_index_;
-  ZoneGrowableArray<AddressEntry> address_table_;
-  DISALLOW_COPY_AND_ASSIGN(CodeRegion);
-};
+  function_ = function;
+  return function_;
+}
 
 
-// A sorted table of CodeRegions. Does not allow for overlap.
-class CodeRegionTable : public ValueObject {
+typedef bool (*RangeCompare)(uword pc, uword region_start, uword region_end);
+
+class ProfileCodeTable : public ZoneAllocated {
  public:
-  enum TickResult {
-    kTicked = 0,     // CodeRegion found and ticked.
-    kNotFound = -1,   // No CodeRegion found.
-    kNewerCode = -2,  // CodeRegion found but it was compiled after sample.
-  };
-
-  CodeRegionTable() :
-      code_region_table_(new ZoneGrowableArray<CodeRegion*>(64)) {
+  ProfileCodeTable()
+      : table_(8) {
   }
 
-  // Ticks the CodeRegion containing pc if it is alive at timestamp.
-  TickResult Tick(uword pc,
-                  bool exclusive,
-                  intptr_t serial,
-                  int64_t timestamp) {
-    intptr_t index = FindIndex(pc);
-    if (index < 0) {
-      // Not found.
-      return kNotFound;
-    }
-    ASSERT(index < code_region_table_->length());
-    CodeRegion* region = At(index);
-    if (region->compile_timestamp() > timestamp) {
-      // Compiled after tick.
-      return kNewerCode;
-    }
-    region->Tick(pc, exclusive, serial);
-    return kTicked;
+  intptr_t length() const { return table_.length(); }
+
+  ProfileCode* At(intptr_t index) const {
+    ASSERT(index >= 0);
+    ASSERT(index < length());
+    return table_[index];
   }
 
-  // Table length.
-  intptr_t Length() const { return code_region_table_->length(); }
-
-  // Get the CodeRegion at index.
-  CodeRegion* At(intptr_t index) const {
-    return (*code_region_table_)[index];
-  }
-
-  // Find the table index to the CodeRegion containing pc.
+  // Find the table index to the ProfileCode containing pc.
   // Returns < 0 if not found.
-  intptr_t FindIndex(uword pc) const {
-    intptr_t index = FindRegionIndex(pc, &CompareLowerBound);
-    const CodeRegion* code_region = NULL;
-    if (index == code_region_table_->length()) {
+  intptr_t FindCodeIndexForPC(uword pc) const {
+    intptr_t index = FindCodeIndex(pc, &CompareLowerBound);
+    if (index == length()) {
       // Not present.
       return -1;
     }
-    code_region = At(index);
-    if (code_region->contains(pc)) {
-      // Found at index.
-      return index;
+    const ProfileCode* code = At(index);
+    if (!code->Contains(pc)) {
+      // Not present.
+      return -1;
     }
-    return -2;
+    // Found at index.
+    return index;
   }
 
-  // Insert code_region into the table. Returns the table index where the
-  // CodeRegion was inserted. Will merge with an overlapping CodeRegion if
-  // one is present.
-  intptr_t InsertCodeRegion(CodeRegion* code_region) {
-    const uword start = code_region->start();
-    const uword end = code_region->end();
-    const intptr_t length = code_region_table_->length();
+  ProfileCode* FindCodeForPC(uword pc) const {
+    intptr_t index = FindCodeIndexForPC(pc);
+    if (index < 0) {
+      return NULL;
+    }
+    return At(index);
+  }
+
+  // Insert |new_code| into the table. Returns the table index where |new_code|
+  // was inserted. Will merge with an overlapping ProfileCode if one is present.
+  intptr_t InsertCode(ProfileCode* new_code) {
+    const uword start = new_code->start();
+    const uword end = new_code->end();
+    const intptr_t length = table_.length();
     if (length == 0) {
-      code_region_table_->Add(code_region);
+      table_.Add(new_code);
       return length;
     }
-    // Determine the correct place to insert or merge code_region into table.
-    intptr_t lo = FindRegionIndex(start, &CompareLowerBound);
-    intptr_t hi = FindRegionIndex(end - 1, &CompareUpperBound);
+    // Determine the correct place to insert or merge |new_code| into table.
+    intptr_t lo = FindCodeIndex(start, &CompareLowerBound);
+    intptr_t hi = FindCodeIndex(end - 1, &CompareUpperBound);
     // TODO(johnmccutchan): Simplify below logic.
     if ((lo == length) && (hi == length)) {
       lo = length - 1;
     }
     if (lo == length) {
-      CodeRegion* region = At(hi);
-      if (region->overlaps(code_region)) {
-        HandleOverlap(region, code_region, start, end);
+      ProfileCode* code = At(hi);
+      if (code->Overlaps(new_code)) {
+        HandleOverlap(code, new_code, start, end);
         return hi;
       }
-      code_region_table_->Add(code_region);
+      table_.Add(new_code);
       return length;
     } else if (hi == length) {
-      CodeRegion* region = At(lo);
-      if (region->overlaps(code_region)) {
-        HandleOverlap(region, code_region, start, end);
+      ProfileCode* code = At(lo);
+      if (code->Overlaps(new_code)) {
+        HandleOverlap(code, new_code, start, end);
         return lo;
       }
-      code_region_table_->Add(code_region);
+      table_.Add(new_code);
       return length;
     } else if (lo == hi) {
-      CodeRegion* region = At(lo);
-      if (region->overlaps(code_region)) {
-        HandleOverlap(region, code_region, start, end);
+      ProfileCode* code = At(lo);
+      if (code->Overlaps(new_code)) {
+        HandleOverlap(code, new_code, start, end);
         return lo;
       }
-      code_region_table_->InsertAt(lo, code_region);
+      table_.InsertAt(lo, new_code);
       return lo;
     } else {
-      CodeRegion* region = At(lo);
-      if (region->overlaps(code_region)) {
-        HandleOverlap(region, code_region, start, end);
+      ProfileCode* code = At(lo);
+      if (code->Overlaps(new_code)) {
+        HandleOverlap(code, new_code, start, end);
         return lo;
       }
-      region = At(hi);
-      if (region->overlaps(code_region)) {
-        HandleOverlap(region, code_region, start, end);
+      code = At(hi);
+      if (code->Overlaps(new_code)) {
+        HandleOverlap(code, new_code, start, end);
         return hi;
       }
-      code_region_table_->InsertAt(hi, code_region);
+      table_.InsertAt(hi, new_code);
       return hi;
     }
     UNREACHABLE();
   }
 
-  void Verify() {
-    VerifyOrder();
-    VerifyOverlap();
-  }
-
-  void DebugPrint() {
-    OS::Print("Dumping CodeRegionTable:\n");
-    for (intptr_t i = 0; i < code_region_table_->length(); i++) {
-      CodeRegion* region = At(i);
-      region->DebugPrint();
-    }
-  }
-
  private:
-  intptr_t FindRegionIndex(uword pc, RegionCompare comparator) const {
+  intptr_t FindCodeIndex(uword pc, RangeCompare comparator) const {
     ASSERT(comparator != NULL);
-    intptr_t count = code_region_table_->length();
+    intptr_t count = table_.length();
     intptr_t first = 0;
     while (count > 0) {
       intptr_t it = first;
       intptr_t step = count / 2;
       it += step;
-      const CodeRegion* code_region = At(it);
-      if (comparator(pc, code_region->start(), code_region->end())) {
+      const ProfileCode* code = At(it);
+      if (comparator(pc, code->start(), code->end())) {
         first = ++it;
         count -= (step + 1);
       } else {
@@ -902,375 +726,124 @@
     return end <= pc;
   }
 
-  void HandleOverlap(CodeRegion* region, CodeRegion* code_region,
+  void HandleOverlap(ProfileCode* existing, ProfileCode* code,
                      uword start, uword end) {
     // We should never see overlapping Dart code regions.
-    ASSERT(region->kind() != CodeRegion::kDartCode);
+    ASSERT(existing->kind() != ProfileCode::kDartCode);
     // We should never see overlapping Tag code regions.
-    ASSERT(region->kind() != CodeRegion::kTagCode);
+    ASSERT(existing->kind() != ProfileCode::kTagCode);
     // When code regions overlap, they should be of the same kind.
-    ASSERT(region->kind() == code_region->kind());
-    region->AdjustExtent(start, end);
+    ASSERT(existing->kind() == code->kind());
+    existing->AdjustExtent(start, end);
   }
 
   void VerifyOrder() {
-    const intptr_t length = code_region_table_->length();
+    const intptr_t length = table_.length();
     if (length == 0) {
       return;
     }
-    uword last = (*code_region_table_)[0]->end();
+    uword last = table_[0]->end();
     for (intptr_t i = 1; i < length; i++) {
-      CodeRegion* a = (*code_region_table_)[i];
+      ProfileCode* a = table_[i];
       ASSERT(last <= a->start());
       last = a->end();
     }
   }
 
   void VerifyOverlap() {
-    const intptr_t length = code_region_table_->length();
+    const intptr_t length = table_.length();
     for (intptr_t i = 0; i < length; i++) {
-      CodeRegion* a = (*code_region_table_)[i];
+      ProfileCode* a = table_[i];
       for (intptr_t j = i+1; j < length; j++) {
-        CodeRegion* b = (*code_region_table_)[j];
-        ASSERT(!a->contains(b->start()) &&
-               !a->contains(b->end() - 1) &&
-               !b->contains(a->start()) &&
-               !b->contains(a->end() - 1));
+        ProfileCode* b = table_[j];
+        ASSERT(!a->Contains(b->start()) &&
+               !a->Contains(b->end() - 1) &&
+               !b->Contains(a->start()) &&
+               !b->Contains(a->end() - 1));
       }
     }
   }
 
-  ZoneGrowableArray<CodeRegion*>* code_region_table_;
+  ZoneGrowableArray<ProfileCode*> table_;
 };
 
 
-class CodeRegionTableBuilder {
+ProfileTrieNode::ProfileTrieNode(intptr_t table_index)
+    : table_index_(table_index),
+      count_(0),
+      children_(0) {
+  ASSERT(table_index_ >= 0);
+}
+
+
+ProfileTrieNode::~ProfileTrieNode() {
+}
+
+
+void ProfileTrieNode::SortChildren() {
+  children_.Sort(ProfileTrieNodeCompare);
+  // Recurse.
+  for (intptr_t i = 0; i < children_.length(); i++) {
+    children_[i]->SortChildren();
+  }
+}
+
+
+intptr_t ProfileTrieNode::IndexOf(ProfileTrieNode* node) {
+  for (intptr_t i = 0; i < children_.length(); i++) {
+    if (children_[i] == node) {
+      return i;
+    }
+  }
+  return -1;
+}
+
+
+class ProfileCodeTrieNode : public ProfileTrieNode {
  public:
-  CodeRegionTableBuilder(Isolate* isolate,
-                         CodeRegionTable* live_code_table,
-                         CodeRegionTable* dead_code_table,
-                         CodeRegionTable* tag_code_table,
-                         DeoptimizedCodeSet* deoptimized_code)
-      : live_code_table_(live_code_table),
-        dead_code_table_(dead_code_table),
-        tag_code_table_(tag_code_table),
-        isolate_(isolate),
-        vm_isolate_(Dart::vm_isolate()),
-        null_code_(Code::ZoneHandle()),
-        deoptimized_code_(deoptimized_code) {
-    ASSERT(live_code_table_ != NULL);
-    ASSERT(dead_code_table_ != NULL);
-    ASSERT(tag_code_table_ != NULL);
-    ASSERT(isolate_ != NULL);
-    ASSERT(vm_isolate_ != NULL);
-    ASSERT(null_code_.IsNull());
-    frames_ = 0;
-    min_time_ = kMaxInt64;
-    max_time_ = 0;
+  explicit ProfileCodeTrieNode(intptr_t table_index)
+      : ProfileTrieNode(table_index) {
   }
 
-  void Build(ProcessedSampleBuffer* buffer) {
-    for (intptr_t i = 0; i < buffer->length(); i++) {
-      ProcessedSample* sample = buffer->At(i);
-      VisitSample(i, sample);
+  void PrintToJSONArray(JSONArray* array) const {
+    ASSERT(array != NULL);
+    // Write CodeRegion index.
+    array->AddValue(table_index());
+    // Write count.
+    array->AddValue(count());
+    // Write number of children.
+    intptr_t child_count = NumChildren();
+    array->AddValue(child_count);
+    // Recurse.
+    for (intptr_t i = 0; i < child_count; i++) {
+      children_[i]->PrintToJSONArray(array);
     }
   }
 
-  intptr_t frames() const { return frames_; }
-
-  intptr_t  TimeDeltaMicros() const {
-    return static_cast<intptr_t>(max_time_ - min_time_);
-  }
-  int64_t  max_time() const { return max_time_; }
-
- private:
-  void VisitSample(intptr_t serial, ProcessedSample* sample) {
-    int64_t timestamp = sample->timestamp();
-    if (timestamp > max_time_) {
-      max_time_ = timestamp;
-    }
-    if (timestamp < min_time_) {
-      min_time_ = timestamp;
-    }
-
-    // Make sure VM tag is created.
-    if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
-      CreateTag(VMTag::kNativeTagId);
-    } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
-      CreateTag(VMTag::kRuntimeTagId);
-    }
-    CreateTag(sample->vm_tag());
-
-    // Make sure user tag is created.
-    CreateUserTag(sample->user_tag());
-
-    // Exclusive tick for top frame if the first frame was executing.
-    if (!sample->first_frame_executing()) {
-      Tick(sample->At(0), true, serial, timestamp);
-    }
-
-    // Inclusive tick for all frames.
-    for (intptr_t i = 0; i < sample->length(); i++) {
-      ASSERT(sample->At(i) != 0);
-      frames_++;
-      Tick(sample->At(i), false, serial, timestamp);
-    }
-  }
-
-  void CreateTag(uword tag) {
-    intptr_t index = tag_code_table_->FindIndex(tag);
-    if (index >= 0) {
-      // Already created.
-      return;
-    }
-    CodeRegion* region = new CodeRegion(CodeRegion::kTagCode,
-                                        tag,
-                                        tag + 1,
-                                        0,
-                                        null_code_);
-    index = tag_code_table_->InsertCodeRegion(region);
-    ASSERT(index >= 0);
-  }
-
-  void CreateUserTag(uword tag) {
-    if (tag == 0) {
-      // None set.
-      return;
-    }
-    return CreateTag(tag);
-  }
-
-  void Tick(uword pc, bool exclusive, intptr_t serial, int64_t timestamp) {
-    CodeRegionTable::TickResult r;
-    if (exclusive) {
-      // Exclusive ticks do not have an associated serial.
-      serial = -1;
-    }
-
-    r = live_code_table_->Tick(pc, exclusive, serial, timestamp);
-    if (r == CodeRegionTable::kTicked) {
-      // Live code found and ticked.
-      return;
-    }
-
-    if (r == CodeRegionTable::kNewerCode) {
-      // Code has been overwritten by newer code.
-      // Update shadow table of dead code regions.
-      r = dead_code_table_->Tick(pc, exclusive, serial, timestamp);
-      ASSERT(r != CodeRegionTable::kNewerCode);
-      if (r == CodeRegionTable::kTicked) {
-        // Dead code found and ticked.
-        return;
+  ProfileCodeTrieNode* GetChild(intptr_t child_table_index) {
+    const intptr_t length = NumChildren();
+    intptr_t i = 0;
+    while (i < length) {
+      ProfileCodeTrieNode* child =
+          reinterpret_cast<ProfileCodeTrieNode*>(children_[i]);
+      if (child->table_index() == child_table_index) {
+        return child;
       }
-      ASSERT(r == CodeRegionTable::kNotFound);
-      CreateAndTickDeadCodeRegion(pc, exclusive, serial);
-      return;
-    }
-
-    // Create new live CodeRegion.
-    ASSERT(r == CodeRegionTable::kNotFound);
-    CodeRegion* region = CreateCodeRegion(pc);
-    intptr_t index = live_code_table_->InsertCodeRegion(region);
-    ASSERT(index >= 0);
-    region = live_code_table_->At(index);
-    if (region->compile_timestamp() <= timestamp) {
-      region->Tick(pc, exclusive, serial);
-      return;
-    }
-
-    // We have created a new code region but it's for a CodeRegion
-    // compiled after the sample.
-    ASSERT(region->kind() == CodeRegion::kDartCode);
-    CreateAndTickDeadCodeRegion(pc, exclusive, serial);
-  }
-
-  void CreateAndTickDeadCodeRegion(uword pc, bool exclusive, intptr_t serial) {
-    // Need to create dead code.
-    CodeRegion* region = new CodeRegion(CodeRegion::kReusedCode,
-                                        pc,
-                                        pc + 1,
-                                        0,
-                                        null_code_);
-    intptr_t index = dead_code_table_->InsertCodeRegion(region);
-    ASSERT(index >= 0);
-    dead_code_table_->At(index)->Tick(pc, exclusive, serial);
-  }
-
-  CodeRegion* CreateCodeRegion(uword pc) {
-    const intptr_t kDartCodeAlignment = OS::PreferredCodeAlignment();
-    const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1);
-    Code& code = Code::Handle(isolate_);
-
-    // Check current isolate for pc.
-    if (isolate_->heap()->CodeContains(pc)) {
-      code ^= Code::LookupCode(pc);
-      if (!code.IsNull()) {
-        deoptimized_code_->Add(code);
-        return new CodeRegion(CodeRegion::kDartCode,
-                              code.EntryPoint(),
-                              code.EntryPoint() + code.Size(),
-                              code.compile_timestamp(),
-                              code);
+      if (child->table_index() > child_table_index) {
+        break;
       }
-      return new CodeRegion(CodeRegion::kCollectedCode,
-                            pc,
-                            (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
-                            0,
-                            code);
+      i++;
     }
-
-    // Check VM isolate for pc.
-    if (vm_isolate_->heap()->CodeContains(pc)) {
-      code ^= Code::LookupCodeInVmIsolate(pc);
-      if (!code.IsNull()) {
-        return new CodeRegion(CodeRegion::kDartCode,
-                              code.EntryPoint(),
-                              code.EntryPoint() + code.Size(),
-                              code.compile_timestamp(),
-                              code);
-      }
-      return new CodeRegion(CodeRegion::kCollectedCode,
-                            pc,
-                            (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
-                            0,
-                            code);
+    ProfileCodeTrieNode* child = new ProfileCodeTrieNode(child_table_index);
+    if (i < length) {
+      // Insert at i.
+      children_.InsertAt(i, reinterpret_cast<ProfileTrieNode*>(child));
+    } else {
+      // Add to end.
+      children_.Add(reinterpret_cast<ProfileTrieNode*>(child));
     }
-
-    // Check NativeSymbolResolver for pc.
-    uintptr_t native_start = 0;
-    char* native_name = NativeSymbolResolver::LookupSymbolName(pc,
-                                                               &native_start);
-    if (native_name == NULL) {
-      // No native name found.
-      return new CodeRegion(CodeRegion::kNativeCode,
-                            pc,
-                            pc + 1,
-                            0,
-                            code);
-    }
-    ASSERT(pc >= native_start);
-    CodeRegion* code_region =
-        new CodeRegion(CodeRegion::kNativeCode,
-                       native_start,
-                       pc + 1,
-                       0,
-                       code);
-    code_region->SetName(native_name);
-    free(native_name);
-    return code_region;
+    return child;
   }
-
-  intptr_t frames_;
-  int64_t min_time_;
-  int64_t max_time_;
-  CodeRegionTable* live_code_table_;
-  CodeRegionTable* dead_code_table_;
-  CodeRegionTable* tag_code_table_;
-  Isolate* isolate_;
-  Isolate* vm_isolate_;
-  const Code& null_code_;
-  DeoptimizedCodeSet* deoptimized_code_;
-};
-
-
-class CodeRegionFunctionMapper : public ValueObject {
- public:
-  CodeRegionFunctionMapper(Isolate* isolate,
-                           CodeRegionTable* live_code_table,
-                           CodeRegionTable* dead_code_table,
-                           CodeRegionTable* tag_code_table,
-                           ProfileFunctionTable* function_table)
-      : isolate_(isolate),
-        live_code_table_(live_code_table),
-        dead_code_table_(dead_code_table),
-        tag_code_table_(tag_code_table),
-        function_table_(function_table) {
-    ASSERT(isolate_ != NULL);
-    ASSERT(live_code_table_ != NULL);
-    ASSERT(dead_code_table_ != NULL);
-    ASSERT(tag_code_table_ != NULL);
-    dead_code_table_offset_ = live_code_table_->Length();
-    tag_code_table_offset_ = dead_code_table_offset_ +
-                             dead_code_table_->Length();
-
-    const Code& null_code = Code::ZoneHandle();
-
-    // Create the truncated tag.
-    intptr_t truncated_index =
-        tag_code_table_->FindIndex(VMTag::kTruncatedTagId);
-    ASSERT(truncated_index < 0);
-    CodeRegion* truncated =
-        new CodeRegion(CodeRegion::kTagCode,
-                       VMTag::kTruncatedTagId,
-                       VMTag::kTruncatedTagId + 1,
-                       0,
-                       null_code);
-    truncated_index = tag_code_table_->InsertCodeRegion(truncated);
-    ASSERT(truncated_index >= 0);
-
-    // Create the root tag.
-    intptr_t root_index = tag_code_table_->FindIndex(VMTag::kRootTagId);
-    ASSERT(root_index < 0);
-    CodeRegion* root = new CodeRegion(CodeRegion::kTagCode,
-                                      VMTag::kRootTagId,
-                                      VMTag::kRootTagId + 1,
-                                      0,
-                                      null_code);
-    root_index = tag_code_table_->InsertCodeRegion(root);
-    ASSERT(root_index >= 0);
-  }
-
-  void Map() {
-    // Calculate final indexes in code table for each CodeRegion.
-    for (intptr_t i = 0; i < live_code_table_->Length(); i++) {
-      const intptr_t index = i;
-      CodeRegion* region = live_code_table_->At(i);
-      ASSERT(region != NULL);
-      region->set_code_table_index(index);
-    }
-
-    for (intptr_t i = 0; i < dead_code_table_->Length(); i++) {
-      const intptr_t index = dead_code_table_offset_ + i;
-      CodeRegion* region = dead_code_table_->At(i);
-      ASSERT(region != NULL);
-      region->set_code_table_index(index);
-    }
-
-    for (intptr_t i = 0; i < tag_code_table_->Length(); i++) {
-      const intptr_t index = tag_code_table_offset_ + i;
-      CodeRegion* region = tag_code_table_->At(i);
-      ASSERT(region != NULL);
-      region->set_code_table_index(index);
-    }
-
-    // Associate a ProfileFunction with each CodeRegion.
-    for (intptr_t i = 0; i < live_code_table_->Length(); i++) {
-      CodeRegion* region = live_code_table_->At(i);
-      ASSERT(region != NULL);
-      region->SetFunctionAndName(function_table_);
-    }
-
-    for (intptr_t i = 0; i < dead_code_table_->Length(); i++) {
-      CodeRegion* region = dead_code_table_->At(i);
-      ASSERT(region != NULL);
-      region->SetFunctionAndName(function_table_);
-    }
-
-    for (intptr_t i = 0; i < tag_code_table_->Length(); i++) {
-      CodeRegion* region = tag_code_table_->At(i);
-      ASSERT(region != NULL);
-      region->SetFunctionAndName(function_table_);
-    }
-  }
-
- private:
-  Isolate* isolate_;
-  CodeRegionTable* live_code_table_;
-  CodeRegionTable* dead_code_table_;
-  CodeRegionTable* tag_code_table_;
-  ProfileFunctionTable* function_table_;
-  intptr_t dead_code_table_offset_;
-  intptr_t tag_code_table_offset_;
 };
 
 
@@ -1299,90 +872,26 @@
 };
 
 
-class ProfileFunctionTrieNode : public ZoneAllocated {
+class ProfileFunctionTrieNode : public ProfileTrieNode {
  public:
-  explicit ProfileFunctionTrieNode(intptr_t profile_function_table_index)
-      : profile_function_table_index_(profile_function_table_index),
-        count_(0),
-        code_objects_(new ZoneGrowableArray<ProfileFunctionTrieNodeCode>()) {
-  }
-
-  void Tick() {
-    count_++;
-  }
-
-  intptr_t count() const {
-    return count_;
-  }
-
-  intptr_t profile_function_table_index() const {
-    return profile_function_table_index_;
-  }
-
-
-  ProfileFunctionTrieNode* GetChild(intptr_t child_index) {
-    const intptr_t length = children_.length();
-    intptr_t i = 0;
-    while (i < length) {
-      ProfileFunctionTrieNode* child = children_[i];
-      if (child->profile_function_table_index() == child_index) {
-        return child;
-      }
-      if (child->profile_function_table_index() > child_index) {
-        break;
-      }
-      i++;
-    }
-    // Add new ProfileFunctionTrieNode, sorted by index.
-    ProfileFunctionTrieNode* child =
-        new ProfileFunctionTrieNode(child_index);
-    if (i < length) {
-      // Insert at i.
-      children_.InsertAt(i, child);
-    } else {
-      // Add to end.
-      children_.Add(child);
-    }
-    return child;
-  }
-
-  void AddCodeObjectIndex(intptr_t index) {
-    for (intptr_t i = 0; i < code_objects_->length(); i++) {
-      ProfileFunctionTrieNodeCode& code_object = (*code_objects_)[i];
-      if (code_object.index() == index) {
-        code_object.Tick();
-        return;
-      }
-    }
-    ProfileFunctionTrieNodeCode code_object(index);
-    code_object.Tick();
-    code_objects_->Add(code_object);
-  }
-
-  // This should only be called after the trie is completely built.
-  void SortByCount() {
-    code_objects_->Sort(ProfileFunctionTrieNodeCodeCompare);
-    children_.Sort(ProfileFunctionTrieNodeCompare);
-    intptr_t child_count = children_.length();
-    // Recurse.
-    for (intptr_t i = 0; i < child_count; i++) {
-      children_[i]->SortByCount();
-    }
+  explicit ProfileFunctionTrieNode(intptr_t table_index)
+      : ProfileTrieNode(table_index),
+        code_objects_(1) {
   }
 
   void PrintToJSONArray(JSONArray* array) const {
     ASSERT(array != NULL);
     // Write CodeRegion index.
-    array->AddValue(profile_function_table_index_);
+    array->AddValue(table_index());
     // Write count.
-    array->AddValue(count_);
+    array->AddValue(count());
     // Write number of code objects.
-    intptr_t code_count = code_objects_->length();
+    intptr_t code_count = code_objects_.length();
     array->AddValue(code_count);
     // Write each code object index and ticks.
     for (intptr_t i = 0; i < code_count; i++) {
-      array->AddValue((*code_objects_)[i].index());
-      array->AddValue((*code_objects_)[i].ticks());
+      array->AddValue(code_objects_[i].index());
+      array->AddValue(code_objects_[i].ticks());
     }
     // Write number of children.
     intptr_t child_count = children_.length();
@@ -1393,377 +902,397 @@
     }
   }
 
- private:
-  static int ProfileFunctionTrieNodeCodeCompare(
-      const ProfileFunctionTrieNodeCode* a,
-      const ProfileFunctionTrieNodeCode* b) {
-    ASSERT(a != NULL);
-    ASSERT(b != NULL);
-    return b->ticks() - a->ticks();
-  }
-
-  static int ProfileFunctionTrieNodeCompare(ProfileFunctionTrieNode* const* a,
-                                            ProfileFunctionTrieNode* const* b) {
-    ASSERT(a != NULL);
-    ASSERT(b != NULL);
-    return (*b)->count() - (*a)->count();
-  }
-
-  const intptr_t profile_function_table_index_;
-  intptr_t count_;
-  ZoneGrowableArray<ProfileFunctionTrieNode*> children_;
-  ZoneGrowableArray<ProfileFunctionTrieNodeCode>* code_objects_;
-};
-
-
-class TrieBuilder : public ValueObject {
- public:
-  TrieBuilder(CodeRegionTable* live_code_table,
-              CodeRegionTable* dead_code_table,
-              CodeRegionTable* tag_code_table)
-      : live_code_table_(live_code_table),
-        dead_code_table_(dead_code_table),
-        tag_code_table_(tag_code_table) {
-    ASSERT(live_code_table_ != NULL);
-    ASSERT(dead_code_table_ != NULL);
-    ASSERT(tag_code_table_ != NULL);
-  }
-
-  ProfilerService::TagOrder tag_order() const {
-    return tag_order_;
-  }
-
-  void set_tag_order(ProfilerService::TagOrder tag_order) {
-    tag_order_ = tag_order;
-  }
-
- protected:
-  intptr_t FindTagIndex(uword tag) const {
-    if (tag == 0) {
-      UNREACHABLE();
-      return -1;
-    }
-    intptr_t index = tag_code_table_->FindIndex(tag);
-    if (index < 0) {
-      UNREACHABLE();
-      return -1;
-    }
-    ASSERT(index >= 0);
-    CodeRegion* region = tag_code_table_->At(index);
-    ASSERT(region->contains(tag));
-    return region->code_table_index();
-  }
-
-  intptr_t FindDeadIndex(uword pc, int64_t timestamp) const {
-    intptr_t index = dead_code_table_->FindIndex(pc);
-    if (index < 0) {
-      OS::Print("%" Px " cannot be found\n", pc);
-      return -1;
-    }
-    CodeRegion* region = dead_code_table_->At(index);
-    ASSERT(region->contains(pc));
-    ASSERT(region->compile_timestamp() <= timestamp);
-    return region->code_table_index();
-  }
-
-  intptr_t FindFinalIndex(uword pc, int64_t timestamp) const {
-    intptr_t index = live_code_table_->FindIndex(pc);
-    if (index < 0) {
-      // Try dead code table.
-      return FindDeadIndex(pc, timestamp);
-    }
-    CodeRegion* region = live_code_table_->At(index);
-    ASSERT(region->contains(pc));
-    if (region->compile_timestamp() > timestamp) {
-      // Overwritten code, find in dead code table.
-      return FindDeadIndex(pc, timestamp);
-    }
-    ASSERT(region->compile_timestamp() <= timestamp);
-    return region->code_table_index();
-  }
-
-  bool vm_tags_emitted() const {
-    return (tag_order_ == ProfilerService::kUserVM) ||
-           (tag_order_ == ProfilerService::kVMUser) ||
-           (tag_order_ == ProfilerService::kVM);
-  }
-
-  CodeRegion* FindCodeObject(uword pc, int64_t timestamp) const {
-    intptr_t index = live_code_table_->FindIndex(pc);
-    if (index < 0) {
-      return NULL;
-    }
-    CodeRegion* region = live_code_table_->At(index);
-    ASSERT(region->contains(pc));
-    if (region->compile_timestamp() > timestamp) {
-      // Overwritten code, find in dead code table.
-      index = dead_code_table_->FindIndex(pc);
-      if (index < 0) {
-        return NULL;
+  ProfileFunctionTrieNode* GetChild(intptr_t child_table_index) {
+    const intptr_t length = NumChildren();
+    intptr_t i = 0;
+    while (i < length) {
+      ProfileFunctionTrieNode* child =
+          reinterpret_cast<ProfileFunctionTrieNode*>(children_[i]);
+      if (child->table_index() == child_table_index) {
+        return child;
       }
-      region = dead_code_table_->At(index);
-      ASSERT(region->contains(pc));
-      ASSERT(region->compile_timestamp() <= timestamp);
-      return region;
+      if (child->table_index() > child_table_index) {
+        break;
+      }
+      i++;
     }
-    ASSERT(region->compile_timestamp() <= timestamp);
-    return region;
-  }
-
-  CodeRegionTable* live_code_table_;
-  CodeRegionTable* dead_code_table_;
-  CodeRegionTable* tag_code_table_;
-  ProfilerService::TagOrder tag_order_;
-};
-
-
-class ProfileFunctionTrieBuilder : public TrieBuilder {
- public:
-  ProfileFunctionTrieBuilder(CodeRegionTable* live_code_table,
-                             CodeRegionTable* dead_code_table,
-                             CodeRegionTable* tag_code_table,
-                             ProfileFunctionTable* function_table)
-      : TrieBuilder(live_code_table, dead_code_table, tag_code_table),
-        function_table_(function_table),
-        inclusive_tree_(false) {
-    ASSERT(function_table_ != NULL);
-    set_tag_order(ProfilerService::kUserVM);
-
-    // Verify that the truncated tag exists.
-    ASSERT(tag_code_table_->FindIndex(VMTag::kTruncatedTagId) >= 0);
-
-    // Verify that the root tag exists.
-    intptr_t root_index = tag_code_table_->FindIndex(VMTag::kRootTagId);
-    ASSERT(root_index >= 0);
-
-    // Setup root.
-    CodeRegion* region = tag_code_table_->At(root_index);
-    ASSERT(region != NULL);
-    ProfileFunction* function = region->function();
-    ASSERT(function != NULL);
-
-    exclusive_root_ = new ProfileFunctionTrieNode(function->index());
-    inclusive_root_ = new ProfileFunctionTrieNode(function->index());
-  }
-
-  void VisitSample(intptr_t sample_idx, ProcessedSample* sample) {
-    inclusive_tree_ = false;
-    ProcessSampleExclusive(sample_idx, sample);
-    inclusive_tree_ = true;
-    ProcessSampleInclusive(sample_idx, sample);
-  }
-
-  void Build(ProcessedSampleBuffer* buffer) {
-    for (intptr_t i = 0; i < buffer->length(); i++) {
-      ProcessedSample* sample = buffer->At(i);
-      VisitSample(i, sample);
-    }
-  }
-
-  ProfileFunctionTrieNode* exclusive_root() const {
-    return exclusive_root_;
-  }
-
-  ProfileFunctionTrieNode* inclusive_root() const {
-    return inclusive_root_;
-  }
-
-  ProfilerService::TagOrder tag_order() const {
-    return tag_order_;
-  }
-
-  bool vm_tags_emitted() const {
-    return (tag_order_ == ProfilerService::kUserVM) ||
-           (tag_order_ == ProfilerService::kVMUser) ||
-           (tag_order_ == ProfilerService::kVM);
-  }
-
-  void set_tag_order(ProfilerService::TagOrder tag_order) {
-    tag_order_ = tag_order;
-  }
-
- private:
-  void ProcessSampleInclusive(intptr_t sample_idx, ProcessedSample* sample) {
-    // Give the root a tick.
-    inclusive_root_->Tick();
-    ProfileFunctionTrieNode* current = inclusive_root_;
-    current = AppendTags(sample, current);
-    if (sample->truncated()) {
-      InclusiveTickTruncatedTag();
-      current = AppendTruncatedTag(current);
-    }
-    // Walk the sampled PCs.
-    for (intptr_t i = sample->length() - 1; i >= 0; i--) {
-      ASSERT(sample->At(i) != 0);
-      current = ProcessPC(sample->At(i),
-                          sample->timestamp(),
-                          current,
-                          sample_idx,
-                          (i == 0),
-                          !sample->first_frame_executing() && (i == 0));
-    }
-  }
-
-  void ProcessSampleExclusive(intptr_t sample_idx, ProcessedSample* sample) {
-    // Give the root a tick.
-    exclusive_root_->Tick();
-    ProfileFunctionTrieNode* current = exclusive_root_;
-    current = AppendTags(sample, current);
-    // Walk the sampled PCs.
-    for (intptr_t i = 0; i < sample->length(); i++) {
-      ASSERT(sample->At(i) != 0);
-      current = ProcessPC(sample->At(i),
-                          sample->timestamp(),
-                          current,
-                          sample_idx,
-                          (i == 0),
-                          !sample->first_frame_executing() && (i == 0));
-    }
-    if (sample->truncated()) {
-      current = AppendTruncatedTag(current);
-    }
-  }
-
-  ProfileFunctionTrieNode* AppendUserTag(ProcessedSample* sample,
-                                         ProfileFunctionTrieNode* current) {
-    intptr_t user_tag_index = FindTagFunctionIndex(sample->user_tag());
-    if (user_tag_index >= 0) {
-      current = current->GetChild(user_tag_index);
-      // Give the tag a tick.
-      current->Tick();
-    }
-    return current;
-  }
-
-
-  ProfileFunctionTrieNode* AppendTruncatedTag(
-      ProfileFunctionTrieNode* current) {
-    intptr_t truncated_tag_index = FindTagFunctionIndex(VMTag::kTruncatedTagId);
-    ASSERT(truncated_tag_index >= 0);
-    current = current->GetChild(truncated_tag_index);
-    current->Tick();
-    return current;
-  }
-
-  void InclusiveTickTruncatedTag() {
-    intptr_t index = tag_code_table_->FindIndex(VMTag::kTruncatedTagId);
-    CodeRegion* region = tag_code_table_->At(index);
-    ProfileFunction* function = region->function();
-    function->inc_inclusive_ticks();
-  }
-
-  ProfileFunctionTrieNode* AppendVMTag(ProcessedSample* sample,
-                                       ProfileFunctionTrieNode* current) {
-    if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
-      // Insert a dummy kNativeTagId node.
-      intptr_t tag_index = FindTagFunctionIndex(VMTag::kNativeTagId);
-      current = current->GetChild(tag_index);
-      // Give the tag a tick.
-      current->Tick();
-    } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
-      // Insert a dummy kRuntimeTagId node.
-      intptr_t tag_index = FindTagFunctionIndex(VMTag::kRuntimeTagId);
-      current = current->GetChild(tag_index);
-      // Give the tag a tick.
-      current->Tick();
+    ProfileFunctionTrieNode* child =
+        new ProfileFunctionTrieNode(child_table_index);
+    if (i < length) {
+      // Insert at i.
+      children_.InsertAt(i, reinterpret_cast<ProfileTrieNode*>(child));
     } else {
-      intptr_t tag_index = FindTagFunctionIndex(sample->vm_tag());
-      current = current->GetChild(tag_index);
-      // Give the tag a tick.
-      current->Tick();
+      // Add to end.
+      children_.Add(reinterpret_cast<ProfileTrieNode*>(child));
     }
-    return current;
+    return child;
   }
 
-  ProfileFunctionTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
-      ProcessedSample* sample, ProfileFunctionTrieNode* current) {
-    // Only Native and Runtime entries have a second VM tag.
-    if (!VMTag::IsNativeEntryTag(sample->vm_tag()) &&
-        !VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
-      return current;
-    }
-    intptr_t tag_index = FindTagFunctionIndex(sample->vm_tag());
-    current = current->GetChild(tag_index);
-    // Give the tag a tick.
-    current->Tick();
-    return current;
-  }
-
-  ProfileFunctionTrieNode* AppendVMTags(ProcessedSample* sample,
-                                        ProfileFunctionTrieNode* current) {
-    current = AppendVMTag(sample, current);
-    current = AppendSpecificNativeRuntimeEntryVMTag(sample, current);
-    return current;
-  }
-
-  ProfileFunctionTrieNode* AppendTags(ProcessedSample* sample,
-                                      ProfileFunctionTrieNode* current) {
-    // None.
-    if (tag_order() == ProfilerService::kNoTags) {
-      return current;
-    }
-    // User first.
-    if ((tag_order() == ProfilerService::kUserVM) ||
-        (tag_order() == ProfilerService::kUser)) {
-      current = AppendUserTag(sample, current);
-      // Only user.
-      if (tag_order() == ProfilerService::kUser) {
-        return current;
+  void AddCodeObjectIndex(intptr_t index) {
+    for (intptr_t i = 0; i < code_objects_.length(); i++) {
+      ProfileFunctionTrieNodeCode& code_object = code_objects_[i];
+      if (code_object.index() == index) {
+        code_object.Tick();
+        return;
       }
-      return AppendVMTags(sample, current);
     }
-    // VM first.
-    ASSERT((tag_order() == ProfilerService::kVMUser) ||
-           (tag_order() == ProfilerService::kVM));
-    current = AppendVMTags(sample, current);
-    // Only VM.
-    if (tag_order() == ProfilerService::kVM) {
-      return current;
-    }
-    return AppendUserTag(sample, current);
+    ProfileFunctionTrieNodeCode code_object(index);
+    code_object.Tick();
+    code_objects_.Add(code_object);
   }
 
-  intptr_t FindTagFunctionIndex(uword tag) const {
-    if (tag == 0) {
-      UNREACHABLE();
-      return -1;
-    }
-    intptr_t index = tag_code_table_->FindIndex(tag);
-    if (index < 0) {
-      UNREACHABLE();
-      return -1;
-    }
-    ASSERT(index >= 0);
-    CodeRegion* region = tag_code_table_->At(index);
-    ASSERT(region->contains(tag));
-    ProfileFunction* function = region->function();
-    ASSERT(function != NULL);
-    return function->index();
+ private:
+  ZoneGrowableArray<ProfileFunctionTrieNodeCode> code_objects_;
+};
+
+
+class ProfileBuilder : public ValueObject {
+ public:
+  ProfileBuilder(Isolate* isolate,
+                 SampleFilter* filter,
+                 Profile::TagOrder tag_order,
+                 Profile* profile)
+      : isolate_(isolate),
+        vm_isolate_(Dart::vm_isolate()),
+        filter_(filter),
+        tag_order_(tag_order),
+        profile_(profile),
+        deoptimized_code_(new DeoptimizedCodeSet(isolate)),
+        null_code_(Code::ZoneHandle()),
+        null_function_(Function::ZoneHandle()),
+        tick_functions_(false),
+        samples_(NULL) {
+    ASSERT(profile_ != NULL);
   }
 
-  void Dump(ProfileFunctionTrieNode* current) {
-    int current_index = current->profile_function_table_index();
-    ProfileFunction* function = function_table_->At(current_index);
-    function->Dump();
-    OS::Print("\n");
+  void Build() {
+    ScopeTimer sw("ProfileBuilder::Build", FLAG_trace_profiler);
+    FilterSamples();
+
+    Setup();
+    BuildCodeTable();
+    FinalizeCodeIndexes();
+    BuildFunctionTable();
+
+    BuildCodeTrie(Profile::kExclusiveCode);
+    BuildCodeTrie(Profile::kInclusiveCode);
+
+    BuildFunctionTrie(Profile::kExclusiveFunction);
+    BuildFunctionTrie(Profile::kInclusiveFunction);
   }
 
-  ProfileFunctionTrieNode* ProcessPC(uword pc,
-                                     int64_t timestamp,
-                                     ProfileFunctionTrieNode* current,
-                                     intptr_t inclusive_serial,
-                                     bool top_frame,
-                                     bool exit_frame) {
-    CodeRegion* region = FindCodeObject(pc, timestamp);
-    if (region == NULL) {
-      return current;
+ private:
+  static bool IsInclusiveTrie(Profile::TrieKind kind) {
+    return (kind == Profile::kInclusiveFunction) ||
+           (kind == Profile::kInclusiveCode);
+  }
+
+  void Setup() {
+    profile_->live_code_ = new ProfileCodeTable();
+    profile_->dead_code_ = new ProfileCodeTable();
+    profile_->tag_code_ = new ProfileCodeTable();
+    profile_->functions_ = new ProfileFunctionTable();
+    // Register some synthetic tags.
+    RegisterProfileCodeTag(VMTag::kRootTagId);
+    RegisterProfileCodeTag(VMTag::kTruncatedTagId);
+  }
+
+  void FilterSamples() {
+    ScopeTimer sw("ProfileBuilder::FilterSamples", FLAG_trace_profiler);
+    MutexLocker profiler_data_lock(isolate_->profiler_data_mutex());
+    IsolateProfilerData* profiler_data = isolate_->profiler_data();
+    if (profiler_data == NULL) {
+      return;
     }
-    const char* region_name = region->name();
-    if (region_name == NULL) {
-      region_name = "";
+    SampleBuffer* sample_buffer = profiler_data->sample_buffer();
+    if (sample_buffer == NULL) {
+      return;
     }
-    intptr_t code_index = region->code_table_index();
-    const Code& code = Code::ZoneHandle(region->code());
+    samples_ = sample_buffer->BuildProcessedSampleBuffer(filter_);
+    profile_->sample_count_ = samples_->length();
+  }
+
+  void UpdateMinMaxTimes(int64_t timestamp) {
+    profile_->min_time_ =
+        timestamp < profile_->min_time_ ? timestamp : profile_->min_time_;
+    profile_->max_time_ =
+        timestamp > profile_->max_time_ ? timestamp : profile_->max_time_;
+  }
+
+  void BuildCodeTable() {
+    ScopeTimer sw("ProfileBuilder::BuildCodeTable", FLAG_trace_profiler);
+    for (intptr_t i = 0; i < samples_->length(); i++) {
+      ProcessedSample* sample = samples_->At(i);
+      const int64_t timestamp = sample->timestamp();
+
+      // This is our first pass over the sample buffer, use this as an
+      // opportunity to determine the min and max time ranges of this profile.
+      UpdateMinMaxTimes(timestamp);
+
+      // Make sure VM tag exists.
+      if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
+        RegisterProfileCodeTag(VMTag::kNativeTagId);
+      } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
+        RegisterProfileCodeTag(VMTag::kRuntimeTagId);
+      }
+      RegisterProfileCodeTag(sample->vm_tag());
+      // Make sure user tag exists.
+      RegisterProfileCodeTag(sample->user_tag());
+
+      // Make sure that a ProfileCode objects exist for all pcs in the sample
+      // and tick each one.
+      for (intptr_t i = 0; i < sample->length(); i++) {
+        const uword pc = sample->At(i);
+        ASSERT(pc != 0);
+        ProfileCode* code = RegisterProfileCode(pc, timestamp);
+        ASSERT(code != NULL);
+        code->Tick(pc, (i == 0), i);
+      }
+    }
+  }
+
+  void FinalizeCodeIndexes() {
+    ScopeTimer sw("ProfileBuilder::FinalizeCodeIndexes", FLAG_trace_profiler);
+    ProfileCodeTable* live_table = profile_->live_code_;
+    ProfileCodeTable* dead_table = profile_->dead_code_;
+    ProfileCodeTable* tag_table = profile_->tag_code_;
+    const intptr_t dead_code_index_offset = live_table->length();
+    const intptr_t tag_code_index_offset =
+        dead_table->length() + dead_code_index_offset;
+
+    profile_->dead_code_index_offset_ = dead_code_index_offset;
+    profile_->tag_code_index_offset_ = tag_code_index_offset;
+
+    for (intptr_t i = 0; i < live_table->length(); i++) {
+      const intptr_t index = i;
+      ProfileCode* code = live_table->At(i);
+      ASSERT(code != NULL);
+      code->set_code_table_index(index);
+    }
+
+    for (intptr_t i = 0; i < dead_table->length(); i++) {
+      const intptr_t index = dead_code_index_offset + i;
+      ProfileCode* code = dead_table->At(i);
+      ASSERT(code != NULL);
+      code->set_code_table_index(index);
+    }
+
+    for (intptr_t i = 0; i < tag_table->length(); i++) {
+      const intptr_t index = tag_code_index_offset + i;
+      ProfileCode* code = tag_table->At(i);
+      ASSERT(code != NULL);
+      code->set_code_table_index(index);
+    }
+  }
+
+  void BuildFunctionTable() {
+    ScopeTimer sw("ProfileBuilder::BuildFunctionTable", FLAG_trace_profiler);
+    ProfileCodeTable* live_table = profile_->live_code_;
+    ProfileCodeTable* dead_table = profile_->dead_code_;
+    ProfileCodeTable* tag_table = profile_->tag_code_;
+    ProfileFunctionTable* function_table = profile_->functions_;
+    for (intptr_t i = 0; i < live_table->length(); i++) {
+      ProfileCode* code = live_table->At(i);
+      ASSERT(code != NULL);
+      code->SetFunctionAndName(function_table);
+    }
+
+    for (intptr_t i = 0; i < dead_table->length(); i++) {
+      ProfileCode* code = dead_table->At(i);
+      ASSERT(code != NULL);
+      code->SetFunctionAndName(function_table);
+    }
+
+    for (intptr_t i = 0; i < tag_table->length(); i++) {
+      ProfileCode* code = tag_table->At(i);
+      ASSERT(code != NULL);
+      code->SetFunctionAndName(function_table);
+    }
+  }
+
+  void BuildCodeTrie(Profile::TrieKind kind) {
+    ProfileCodeTrieNode* root =
+        new ProfileCodeTrieNode(GetProfileCodeTagIndex(VMTag::kRootTagId));
+    if (IsInclusiveTrie(kind)) {
+      BuildInclusiveCodeTrie(root);
+    } else {
+      BuildExclusiveCodeTrie(root);
+    }
+    root->SortChildren();
+    profile_->roots_[static_cast<intptr_t>(kind)] = root;
+  }
+
+  void BuildInclusiveCodeTrie(ProfileCodeTrieNode* root) {
+    ScopeTimer sw("ProfileBuilder::BuildInclusiveCodeTrie",
+                  FLAG_trace_profiler);
+    for (intptr_t i = 0; i < samples_->length(); i++) {
+      ProcessedSample* sample = samples_->At(i);
+
+      // Tick the root.
+      ProfileCodeTrieNode* current = root;
+      current->Tick();
+
+      // VM & User tags.
+      current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+
+      // Truncated tag.
+      if (sample->truncated()) {
+        current = AppendTruncatedTag(current);
+      }
+
+      // Walk the sampled PCs.
+      for (intptr_t j = sample->length() - 1; j >= 0; j--) {
+        ASSERT(sample->At(j) != 0);
+        intptr_t index =
+            GetProfileCodeIndex(sample->At(j), sample->timestamp());
+        ASSERT(index >= 0);
+        current = current->GetChild(index);
+        current->Tick();
+      }
+    }
+  }
+
+  void BuildExclusiveCodeTrie(ProfileCodeTrieNode* root) {
+    ScopeTimer sw("ProfileBuilder::BuildExclusiveCodeTrie",
+                  FLAG_trace_profiler);
+    for (intptr_t i = 0; i < samples_->length(); i++) {
+      ProcessedSample* sample = samples_->At(i);
+
+      // Tick the root.
+      ProfileCodeTrieNode* current = root;
+      current->Tick();
+
+      // VM & User tags.
+      current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+
+      // Walk the sampled PCs.
+      for (intptr_t j = 0; j < sample->length(); j++) {
+        ASSERT(sample->At(j) != 0);
+        intptr_t index =
+            GetProfileCodeIndex(sample->At(j), sample->timestamp());
+        ASSERT(index >= 0);
+        current = current->GetChild(index);
+
+        if (j == 0) {
+          // Executing PC.
+          if (!sample->first_frame_executing() || vm_tags_emitted()) {
+            // Only tick if this isn't an exit frame or VM tags are emitted.
+            current->Tick();
+          }
+        } else {
+          // Caller PCs.
+          current->Tick();
+        }
+
+        current->Tick();
+      }
+
+      // Truncated tag.
+      if (sample->truncated()) {
+        current = AppendTruncatedTag(current);
+      }
+    }
+  }
+
+  void BuildFunctionTrie(Profile::TrieKind kind) {
+    ProfileFunctionTrieNode* root =
+        new ProfileFunctionTrieNode(
+            GetProfileFunctionTagIndex(VMTag::kRootTagId));
+    // We tick the functions while building the trie, but, we don't want to do
+    // it for both tries, just one.
+    tick_functions_ = IsInclusiveTrie(kind);
+    if (IsInclusiveTrie(kind)) {
+      BuildInclusiveFunctionTrie(root);
+    } else {
+      BuildExclusiveFunctionTrie(root);
+    }
+    root->SortChildren();
+    profile_->roots_[static_cast<intptr_t>(kind)] = root;
+  }
+
+  void BuildInclusiveFunctionTrie(ProfileFunctionTrieNode* root) {
+    ScopeTimer sw("ProfileBuilder::BuildInclusiveFunctionTrie",
+                  FLAG_trace_profiler);
+    for (intptr_t i = 0; i < samples_->length(); i++) {
+      ProcessedSample* sample = samples_->At(i);
+
+      // Tick the root.
+      ProfileFunctionTrieNode* current = root;
+      current->Tick();
+
+      // VM & User tags.
+      current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+
+      // Truncated tag.
+      if (sample->truncated()) {
+        current = AppendTruncatedTag(current);
+        InclusiveTickTruncatedTag();
+      }
+
+      // Walk the sampled PCs.
+      for (intptr_t j = sample->length() - 1; j >= 0; j--) {
+        ASSERT(sample->At(j) != 0);
+        current = ProcessFunctionPC(
+            sample->At(j),
+            sample->timestamp(),
+            current,
+            i,
+            (j == 0),
+            sample->first_frame_executing(),
+            true);
+      }
+    }
+  }
+
+  void BuildExclusiveFunctionTrie(ProfileFunctionTrieNode* root) {
+    ScopeTimer sw("ProfileBuilder::BuildExclusiveFunctionTrie",
+                  FLAG_trace_profiler);
+    for (intptr_t i = 0; i < samples_->length(); i++) {
+      ProcessedSample* sample = samples_->At(i);
+
+      // Tick the root.
+      ProfileFunctionTrieNode* current = root;
+      current->Tick();
+
+      // VM & User tags.
+      current = AppendTags(sample->vm_tag(), sample->user_tag(), current);
+
+      // Walk the sampled PCs.
+      for (intptr_t j = 0; j < sample->length(); j++) {
+        ASSERT(sample->At(j) != 0);
+        current = ProcessFunctionPC(
+            sample->At(j),
+            sample->timestamp(),
+            current,
+            i,
+            (j == 0),
+            sample->first_frame_executing(),
+            false);
+      }
+
+      // Truncated tag.
+      if (sample->truncated()) {
+        current = AppendTruncatedTag(current);
+      }
+    }
+  }
+
+  ProfileFunctionTrieNode* ProcessFunctionPC(
+      uword pc,
+      int64_t timestamp,
+      ProfileFunctionTrieNode* current,
+      intptr_t inclusive_serial,
+      bool top_frame,
+      bool top_frame_executing,
+      bool inclusive_tree) {
+    ProfileCode* profile_code = GetProfileCode(pc, timestamp);
+    ASSERT(profile_code != NULL);
+    const char* code_name = profile_code->name();
+    if (code_name == NULL) {
+      code_name = "";
+    }
+    intptr_t code_index = profile_code->code_table_index();
+    const Code& code = Code::ZoneHandle(profile_code->code());
     GrowableArray<Function*> inlined_functions;
     if (!code.IsNull()) {
       intptr_t offset = pc - code.EntryPoint();
@@ -1771,18 +1300,18 @@
     }
     if (code.IsNull() || (inlined_functions.length() == 0)) {
       // No inlined functions.
-      ProfileFunction* function = region->function();
+      ProfileFunction* function = profile_code->function();
       ASSERT(function != NULL);
       current = ProcessFunction(function,
                                 current,
                                 inclusive_serial,
                                 top_frame,
-                                exit_frame,
+                                top_frame_executing,
                                 code_index);
       return current;
     }
 
-    if (inclusive_tree_) {
+    if (inclusive_tree) {
       for (intptr_t i = inlined_functions.length() - 1; i >= 0; i--) {
         Function* inlined_function = inlined_functions[i];
         ASSERT(inlined_function != NULL);
@@ -1791,7 +1320,7 @@
                                          current,
                                          inclusive_serial,
                                          top_frame,
-                                         exit_frame,
+                                         top_frame_executing,
                                          code_index);
         top_frame = false;
       }
@@ -1804,7 +1333,7 @@
                                          current,
                                          inclusive_serial,
                                          top_frame,
-                                         exit_frame,
+                                         top_frame_executing,
                                          code_index);
         top_frame = false;
       }
@@ -1818,16 +1347,16 @@
       ProfileFunctionTrieNode* current,
       intptr_t inclusive_serial,
       bool top_frame,
-      bool exit_frame,
+      bool top_frame_executing,
       intptr_t code_index) {
-    ProfileFunction* function =
-        function_table_->LookupOrAdd(*inlined_function);
+    ProfileFunctionTable* function_table = profile_->functions_;
+    ProfileFunction* function = function_table->LookupOrAdd(*inlined_function);
     ASSERT(function != NULL);
     return ProcessFunction(function,
                            current,
                            inclusive_serial,
                            top_frame,
-                           exit_frame,
+                           top_frame_executing,
                            code_index);
   }
 
@@ -1835,20 +1364,18 @@
                                            ProfileFunctionTrieNode* current,
                                            intptr_t inclusive_serial,
                                            bool top_frame,
-                                           bool exit_frame,
+                                           bool top_frame_executing,
                                            intptr_t code_index) {
-    const bool exclusive = top_frame && !exit_frame;
-    if (!inclusive_tree_) {
-      // We process functions for the inclusive and exclusive trees.
-      // Only tick the function for the exclusive tree.
+    const bool exclusive = top_frame && top_frame_executing;
+    if (tick_functions_) {
       function->Tick(exclusive, exclusive ? -1 : inclusive_serial);
     }
-    function->AddCodeObjectIndex(code_index);
-    current = current->GetChild(function->index());
+    function->AddProfileCode(code_index);
+    current = current->GetChild(function->table_index());
     current->AddCodeObjectIndex(code_index);
     if (top_frame) {
-      if (!exit_frame || vm_tags_emitted()) {
-        // Only tick if this isn't an exit frame or VM tags are emitted.
+      if (top_frame_executing || vm_tags_emitted()) {
+        // Only tick if this function is using CPU time or VM tags are emitted.
         current->Tick();
       }
     } else {
@@ -1857,232 +1384,58 @@
     return current;
   }
 
-  ProfileFunctionTrieNode* exclusive_root_;
-  ProfileFunctionTrieNode* inclusive_root_;
-  ProfileFunctionTable* function_table_;
-  bool inclusive_tree_;
-};
-
-
-class CodeRegionTrieNode : public ZoneAllocated {
- public:
-  explicit CodeRegionTrieNode(intptr_t code_region_index)
-      : code_region_index_(code_region_index),
-        count_(0),
-        children_(new ZoneGrowableArray<CodeRegionTrieNode*>()) {
+  // Tick the truncated tag's inclusive tick count.
+  void InclusiveTickTruncatedTag() {
+    ProfileCodeTable* tag_table = profile_->tag_code_;
+    intptr_t index = tag_table->FindCodeIndexForPC(VMTag::kTruncatedTagId);
+    ASSERT(index >= 0);
+    ProfileCode* code = tag_table->At(index);
+    code->IncInclusiveTicks();
+    ASSERT(code != NULL);
+    ProfileFunction* function = code->function();
+    function->IncInclusiveTicks();
   }
 
-  void Tick() {
-    ASSERT(code_region_index_ >= 0);
-    count_++;
-  }
 
-  intptr_t count() const {
-    ASSERT(code_region_index_ >= 0);
-    return count_;
-  }
+  // Tag append functions are overloaded for |ProfileCodeTrieNode| and
+  // |ProfileFunctionTrieNode| types.
 
-  intptr_t code_region_index() const {
-    return code_region_index_;
-  }
-
-  ZoneGrowableArray<CodeRegionTrieNode*>& children() const {
-    return *children_;
-  }
-
-  CodeRegionTrieNode* GetChild(intptr_t child_code_region_index) {
-    const intptr_t length = children_->length();
-    intptr_t i = 0;
-    while (i < length) {
-      CodeRegionTrieNode* child = (*children_)[i];
-      if (child->code_region_index() == child_code_region_index) {
-        return child;
-      }
-      if (child->code_region_index() > child_code_region_index) {
-        break;
-      }
-      i++;
-    }
-    // Add new CodeRegion, sorted by CodeRegionTable index.
-    CodeRegionTrieNode* child = new CodeRegionTrieNode(child_code_region_index);
-    if (i < length) {
-      // Insert at i.
-      children_->InsertAt(i, child);
-    } else {
-      // Add to end.
-      children_->Add(child);
-    }
-    return child;
-  }
-
-  // This should only be called after the trie is completely built.
-  void SortByCount() {
-    children_->Sort(CodeRegionTrieNodeCompare);
-    ZoneGrowableArray<CodeRegionTrieNode*>& kids = children();
-    intptr_t child_count = kids.length();
-    // Recurse.
-    for (intptr_t i = 0; i < child_count; i++) {
-      kids[i]->SortByCount();
-    }
-  }
-
-  void PrintToJSONArray(JSONArray* array) const {
-    ASSERT(array != NULL);
-    // Write CodeRegion index.
-    array->AddValue(code_region_index_);
-    // Write count.
-    array->AddValue(count_);
-    // Write number of children.
-    ZoneGrowableArray<CodeRegionTrieNode*>& kids = children();
-    intptr_t child_count = kids.length();
-    array->AddValue(child_count);
-    // Recurse.
-    for (intptr_t i = 0; i < child_count; i++) {
-      kids[i]->PrintToJSONArray(array);
-    }
-  }
-
- private:
-  static int CodeRegionTrieNodeCompare(CodeRegionTrieNode* const* a,
-                                       CodeRegionTrieNode* const* b) {
-    ASSERT(a != NULL);
-    ASSERT(b != NULL);
-    return (*b)->count() - (*a)->count();
-  }
-
-  const intptr_t code_region_index_;
-  intptr_t count_;
-  ZoneGrowableArray<CodeRegionTrieNode*>* children_;
-};
-
-
-class CodeRegionTrieBuilder : public TrieBuilder {
- public:
-  CodeRegionTrieBuilder(Isolate* isolate,
-                        CodeRegionTable* live_code_table,
-                        CodeRegionTable* dead_code_table,
-                        CodeRegionTable* tag_code_table)
-      : TrieBuilder(live_code_table, dead_code_table, tag_code_table) {
-    set_tag_order(ProfilerService::kUserVM);
-
-    // Verify that the truncated tag exists.
-    ASSERT(tag_code_table_->FindIndex(VMTag::kTruncatedTagId) >= 0);
-
-    // Verify that the root tag exists.
-    intptr_t root_index = tag_code_table_->FindIndex(VMTag::kRootTagId);
-    ASSERT(root_index >= 0);
-    CodeRegion* region = tag_code_table_->At(root_index);
-    ASSERT(region != NULL);
-
-    exclusive_root_ = new CodeRegionTrieNode(region->code_table_index());
-    inclusive_root_ = new CodeRegionTrieNode(region->code_table_index());
-  }
-
-  void Build(ProcessedSampleBuffer* buffer) {
-    for (intptr_t i = 0; i < buffer->length(); i++) {
-      ProcessedSample* sample = buffer->At(i);
-      VisitSample(sample);
-    }
-  }
-
-  CodeRegionTrieNode* inclusive_root() const {
-    return inclusive_root_;
-  }
-
-  CodeRegionTrieNode* exclusive_root() const {
-    return exclusive_root_;
-  }
-
- private:
-  void VisitSample(ProcessedSample* sample) {
-    ProcessSampleExclusive(sample);
-    ProcessSampleInclusive(sample);
-  }
-
-  void ProcessSampleInclusive(ProcessedSample* sample) {
-    // Give the root a tick.
-    inclusive_root_->Tick();
-    CodeRegionTrieNode* current = inclusive_root_;
-    current = AppendTags(sample, current);
-    if (sample->truncated()) {
-      current = AppendTruncatedTag(current);
-    }
-    // Walk the sampled PCs.
-    for (intptr_t i = sample->length() - 1; i >= 0; i--) {
-      ASSERT(sample->At(i) != 0);
-      intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp());
-      if (index < 0) {
-        continue;
-      }
-      current = current->GetChild(index);
-      current->Tick();
-    }
-  }
-
-  void ProcessSampleExclusive(ProcessedSample* sample) {
-    // Give the root a tick.
-    exclusive_root_->Tick();
-    CodeRegionTrieNode* current = exclusive_root_;
-    current = AppendTags(sample, current);
-    // Walk the sampled PCs.
-    for (intptr_t i = 0; i < sample->length(); i++) {
-      ASSERT(sample->At(i) != 0);
-      intptr_t index = FindFinalIndex(sample->At(i), sample->timestamp());
-      if (index < 0) {
-        continue;
-      }
-      current = current->GetChild(index);
-      if (i == 0) {
-        // Executing PC.
-        if (!sample->first_frame_executing() || vm_tags_emitted()) {
-          // Only tick if this isn't an exit frame or VM tags are emitted.
-          current->Tick();
-        }
-      } else {
-        // Caller PCs.
-        current->Tick();
-      }
-    }
-    if (sample->truncated()) {
-      current = AppendTruncatedTag(current);
-    }
-  }
-
-  CodeRegionTrieNode* AppendUserTag(ProcessedSample* sample,
-                                    CodeRegionTrieNode* current) {
-    intptr_t user_tag_index = FindTagIndex(sample->user_tag());
+  // ProfileCodeTrieNode
+  ProfileCodeTrieNode* AppendUserTag(uword user_tag,
+                                     ProfileCodeTrieNode* current) {
+    intptr_t user_tag_index = GetProfileCodeTagIndex(user_tag);
     if (user_tag_index >= 0) {
       current = current->GetChild(user_tag_index);
-      // Give the tag a tick.
       current->Tick();
     }
     return current;
   }
 
-  CodeRegionTrieNode* AppendTruncatedTag(CodeRegionTrieNode* current) {
-    intptr_t truncated_tag_index = FindTagIndex(VMTag::kTruncatedTagId);
+  ProfileCodeTrieNode* AppendTruncatedTag(ProfileCodeTrieNode* current) {
+    intptr_t truncated_tag_index =
+        GetProfileCodeTagIndex(VMTag::kTruncatedTagId);
     ASSERT(truncated_tag_index >= 0);
     current = current->GetChild(truncated_tag_index);
     current->Tick();
     return current;
   }
 
-  CodeRegionTrieNode* AppendVMTag(ProcessedSample* sample,
-                                  CodeRegionTrieNode* current) {
-    if (VMTag::IsNativeEntryTag(sample->vm_tag())) {
+  ProfileCodeTrieNode* AppendVMTag(uword vm_tag,
+                                   ProfileCodeTrieNode* current) {
+    if (VMTag::IsNativeEntryTag(vm_tag)) {
       // Insert a dummy kNativeTagId node.
-      intptr_t tag_index = FindTagIndex(VMTag::kNativeTagId);
+      intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kNativeTagId);
       current = current->GetChild(tag_index);
       // Give the tag a tick.
       current->Tick();
-    } else if (VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
+    } else if (VMTag::IsRuntimeEntryTag(vm_tag)) {
       // Insert a dummy kRuntimeTagId node.
-      intptr_t tag_index = FindTagIndex(VMTag::kRuntimeTagId);
+      intptr_t tag_index = GetProfileCodeTagIndex(VMTag::kRuntimeTagId);
       current = current->GetChild(tag_index);
       // Give the tag a tick.
       current->Tick();
     } else {
-      intptr_t tag_index = FindTagIndex(sample->vm_tag());
+      intptr_t tag_index = GetProfileCodeTagIndex(vm_tag);
       current = current->GetChild(tag_index);
       // Give the tag a tick.
       current->Tick();
@@ -2090,59 +1443,527 @@
     return current;
   }
 
-  CodeRegionTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
-      ProcessedSample* sample, CodeRegionTrieNode* current) {
+  ProfileCodeTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
+      uword vm_tag, ProfileCodeTrieNode* current) {
     // Only Native and Runtime entries have a second VM tag.
-    if (!VMTag::IsNativeEntryTag(sample->vm_tag()) &&
-        !VMTag::IsRuntimeEntryTag(sample->vm_tag())) {
+    if (!VMTag::IsNativeEntryTag(vm_tag) &&
+        !VMTag::IsRuntimeEntryTag(vm_tag)) {
       return current;
     }
-    intptr_t tag_index = FindTagIndex(sample->vm_tag());
+    intptr_t tag_index = GetProfileCodeTagIndex(vm_tag);
     current = current->GetChild(tag_index);
     // Give the tag a tick.
     current->Tick();
     return current;
   }
 
-  CodeRegionTrieNode* AppendVMTags(ProcessedSample* sample,
-                                   CodeRegionTrieNode* current) {
-    current = AppendVMTag(sample, current);
-    current = AppendSpecificNativeRuntimeEntryVMTag(sample, current);
+  ProfileCodeTrieNode* AppendVMTags(uword vm_tag,
+                                    ProfileCodeTrieNode* current) {
+    current = AppendVMTag(vm_tag, current);
+    current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current);
     return current;
   }
 
-  CodeRegionTrieNode* AppendTags(ProcessedSample* sample,
-                                 CodeRegionTrieNode* current) {
+  ProfileCodeTrieNode* AppendTags(uword vm_tag,
+                                  uword user_tag,
+                                  ProfileCodeTrieNode* current) {
     // None.
-    if (tag_order() == ProfilerService::kNoTags) {
+    if (tag_order() == Profile::kNoTags) {
       return current;
     }
     // User first.
-    if ((tag_order() == ProfilerService::kUserVM) ||
-        (tag_order() == ProfilerService::kUser)) {
-      current = AppendUserTag(sample, current);
+    if ((tag_order() == Profile::kUserVM) ||
+        (tag_order() == Profile::kUser)) {
+      current = AppendUserTag(user_tag, current);
       // Only user.
-      if (tag_order() == ProfilerService::kUser) {
+      if (tag_order() == Profile::kUser) {
         return current;
       }
-      return AppendVMTags(sample, current);
+      return AppendVMTags(vm_tag, current);
     }
     // VM first.
-    ASSERT((tag_order() == ProfilerService::kVMUser) ||
-           (tag_order() == ProfilerService::kVM));
-    current = AppendVMTags(sample, current);
+    ASSERT((tag_order() == Profile::kVMUser) ||
+           (tag_order() == Profile::kVM));
+    current = AppendVMTags(vm_tag, current);
     // Only VM.
-    if (tag_order() == ProfilerService::kVM) {
+    if (tag_order() == Profile::kVM) {
       return current;
     }
-    return AppendUserTag(sample, current);
+    return AppendUserTag(user_tag, current);
   }
 
-  CodeRegionTrieNode* exclusive_root_;
-  CodeRegionTrieNode* inclusive_root_;
+  // ProfileFunctionTrieNode
+  ProfileFunctionTrieNode* AppendUserTag(uword user_tag,
+                                         ProfileFunctionTrieNode* current) {
+    intptr_t user_tag_index = GetProfileFunctionTagIndex(user_tag);
+    if (user_tag_index >= 0) {
+      current = current->GetChild(user_tag_index);
+      current->Tick();
+    }
+    return current;
+  }
+
+  ProfileFunctionTrieNode* AppendTruncatedTag(
+      ProfileFunctionTrieNode* current) {
+    intptr_t truncated_tag_index =
+        GetProfileFunctionTagIndex(VMTag::kTruncatedTagId);
+    ASSERT(truncated_tag_index >= 0);
+    current = current->GetChild(truncated_tag_index);
+    current->Tick();
+    return current;
+  }
+
+  ProfileFunctionTrieNode* AppendVMTag(uword vm_tag,
+                                   ProfileFunctionTrieNode* current) {
+    if (VMTag::IsNativeEntryTag(vm_tag)) {
+      // Insert a dummy kNativeTagId node.
+      intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kNativeTagId);
+      current = current->GetChild(tag_index);
+      // Give the tag a tick.
+      current->Tick();
+    } else if (VMTag::IsRuntimeEntryTag(vm_tag)) {
+      // Insert a dummy kRuntimeTagId node.
+      intptr_t tag_index = GetProfileFunctionTagIndex(VMTag::kRuntimeTagId);
+      current = current->GetChild(tag_index);
+      // Give the tag a tick.
+      current->Tick();
+    } else {
+      intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag);
+      current = current->GetChild(tag_index);
+      // Give the tag a tick.
+      current->Tick();
+    }
+    return current;
+  }
+
+  ProfileFunctionTrieNode* AppendSpecificNativeRuntimeEntryVMTag(
+      uword vm_tag, ProfileFunctionTrieNode* current) {
+    // Only Native and Runtime entries have a second VM tag.
+    if (!VMTag::IsNativeEntryTag(vm_tag) &&
+        !VMTag::IsRuntimeEntryTag(vm_tag)) {
+      return current;
+    }
+    intptr_t tag_index = GetProfileFunctionTagIndex(vm_tag);
+    current = current->GetChild(tag_index);
+    // Give the tag a tick.
+    current->Tick();
+    return current;
+  }
+
+  ProfileFunctionTrieNode* AppendVMTags(uword vm_tag,
+                                    ProfileFunctionTrieNode* current) {
+    current = AppendVMTag(vm_tag, current);
+    current = AppendSpecificNativeRuntimeEntryVMTag(vm_tag, current);
+    return current;
+  }
+
+  ProfileFunctionTrieNode* AppendTags(uword vm_tag,
+                                      uword user_tag,
+                                      ProfileFunctionTrieNode* current) {
+    // None.
+    if (tag_order() == Profile::kNoTags) {
+      return current;
+    }
+    // User first.
+    if ((tag_order() == Profile::kUserVM) ||
+        (tag_order() == Profile::kUser)) {
+      current = AppendUserTag(user_tag, current);
+      // Only user.
+      if (tag_order() == Profile::kUser) {
+        return current;
+      }
+      return AppendVMTags(vm_tag, current);
+    }
+    // VM first.
+    ASSERT((tag_order() == Profile::kVMUser) ||
+           (tag_order() == Profile::kVM));
+    current = AppendVMTags(vm_tag, current);
+    // Only VM.
+    if (tag_order() == Profile::kVM) {
+      return current;
+    }
+    return AppendUserTag(user_tag, current);
+  }
+
+  intptr_t GetProfileCodeTagIndex(uword tag) {
+    ProfileCodeTable* tag_table = profile_->tag_code_;
+    intptr_t index = tag_table->FindCodeIndexForPC(tag);
+    ASSERT(index >= 0);
+    ProfileCode* code = tag_table->At(index);
+    ASSERT(code != NULL);
+    return code->code_table_index();
+  }
+
+  intptr_t GetProfileFunctionTagIndex(uword tag) {
+    ProfileCodeTable* tag_table = profile_->tag_code_;
+    intptr_t index = tag_table->FindCodeIndexForPC(tag);
+    ASSERT(index >= 0);
+    ProfileCode* code = tag_table->At(index);
+    ASSERT(code != NULL);
+    ProfileFunction* function = code->function();
+    ASSERT(function != NULL);
+    return function->table_index();
+  }
+
+  intptr_t GetProfileCodeIndex(uword pc, int64_t timestamp) {
+    return GetProfileCode(pc, timestamp)->code_table_index();
+  }
+
+  ProfileCode* GetProfileCode(uword pc, int64_t timestamp) {
+    ProfileCodeTable* live_table = profile_->live_code_;
+    ProfileCodeTable* dead_table = profile_->dead_code_;
+
+    intptr_t index = live_table->FindCodeIndexForPC(pc);
+    ProfileCode* code = NULL;
+    if (index < 0) {
+      index = dead_table->FindCodeIndexForPC(pc);
+      ASSERT(index >= 0);
+      code = dead_table->At(index);
+    } else {
+      code = live_table->At(index);
+      ASSERT(code != NULL);
+      if (code->compile_timestamp() > timestamp) {
+        // Code is newer than sample. Fall back to dead code table.
+        index = dead_table->FindCodeIndexForPC(pc);
+        ASSERT(index >= 0);
+        code = dead_table->At(index);
+      }
+    }
+
+    ASSERT(code != NULL);
+    ASSERT(code->Contains(pc));
+    ASSERT(code->compile_timestamp() <= timestamp);
+    return code;
+  }
+
+  void RegisterProfileCodeTag(uword tag) {
+    if (tag == 0) {
+      // No tag.
+      return;
+    }
+    ProfileCodeTable* tag_table = profile_->tag_code_;
+    intptr_t index = tag_table->FindCodeIndexForPC(tag);
+    if (index >= 0) {
+      // Already created.
+      return;
+    }
+    ProfileCode* code = new ProfileCode(ProfileCode::kTagCode,
+                                        tag,
+                                        tag + 1,
+                                        0,
+                                        null_code_);
+    index = tag_table->InsertCode(code);
+    ASSERT(index >= 0);
+  }
+
+  ProfileCode* CreateProfileCodeReused(uword pc) {
+    ProfileCode* code = new ProfileCode(ProfileCode::kReusedCode,
+                                        pc,
+                                        pc + 1,
+                                        0,
+                                        null_code_);
+    return code;
+  }
+
+  ProfileCode* CreateProfileCode(uword pc) {
+    const intptr_t kDartCodeAlignment = OS::PreferredCodeAlignment();
+    const intptr_t kDartCodeAlignmentMask = ~(kDartCodeAlignment - 1);
+    Code& code = Code::Handle(isolate_);
+
+    // Check current isolate for pc.
+    if (isolate_->heap()->CodeContains(pc)) {
+      code ^= Code::LookupCode(pc);
+      if (!code.IsNull()) {
+        deoptimized_code_->Add(code);
+        return new ProfileCode(ProfileCode::kDartCode,
+                              code.EntryPoint(),
+                              code.EntryPoint() + code.Size(),
+                              code.compile_timestamp(),
+                              code);
+      }
+      return new ProfileCode(ProfileCode::kCollectedCode,
+                            pc,
+                            (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
+                            0,
+                            code);
+    }
+
+    // Check VM isolate for pc.
+    if (vm_isolate_->heap()->CodeContains(pc)) {
+      code ^= Code::LookupCodeInVmIsolate(pc);
+      if (!code.IsNull()) {
+        return new ProfileCode(ProfileCode::kDartCode,
+                              code.EntryPoint(),
+                              code.EntryPoint() + code.Size(),
+                              code.compile_timestamp(),
+                              code);
+      }
+      return new ProfileCode(ProfileCode::kCollectedCode,
+                            pc,
+                            (pc & kDartCodeAlignmentMask) + kDartCodeAlignment,
+                            0,
+                            code);
+    }
+
+    // Check NativeSymbolResolver for pc.
+    uintptr_t native_start = 0;
+    char* native_name = NativeSymbolResolver::LookupSymbolName(pc,
+                                                               &native_start);
+    if (native_name == NULL) {
+      // No native name found.
+      return new ProfileCode(ProfileCode::kNativeCode,
+                            pc,
+                            pc + 1,
+                            0,
+                            code);
+    }
+    ASSERT(pc >= native_start);
+    ProfileCode* profile_code =
+        new ProfileCode(ProfileCode::kNativeCode,
+                       native_start,
+                       pc + 1,
+                       0,
+                       code);
+    profile_code->SetName(native_name);
+    free(native_name);
+    return profile_code;
+  }
+
+  ProfileCode* RegisterProfileCode(uword pc, int64_t timestamp) {
+    ProfileCodeTable* live_table = profile_->live_code_;
+    ProfileCodeTable* dead_table = profile_->dead_code_;
+
+    ProfileCode* code = live_table->FindCodeForPC(pc);
+    if (code == NULL) {
+      // Code not found.
+      intptr_t index = live_table->InsertCode(CreateProfileCode(pc));
+      ASSERT(index >= 0);
+      code = live_table->At(index);
+      if (code->compile_timestamp() <= timestamp) {
+        // Code was compiled before sample was taken.
+        return code;
+      }
+      // Code was compiled after the sample was taken. Insert code object into
+      // the dead code table.
+      index = dead_table->InsertCode(CreateProfileCodeReused(pc));
+      ASSERT(index >= 0);
+      return dead_table->At(index);
+    }
+    // Existing code found.
+    if (code->compile_timestamp() <= timestamp) {
+      // Code was compiled before sample was taken.
+      return code;
+    }
+    // Code was compiled after the sample was taken. Check if we have an entry
+    // in the dead code table.
+    code = dead_table->FindCodeForPC(pc);
+    if (code != NULL) {
+      return code;
+    }
+    // Create a new dead code entry.
+    intptr_t index = dead_table->InsertCode(CreateProfileCodeReused(pc));
+    ASSERT(index >= 0);
+    return dead_table->At(index);
+  }
+
+  Profile::TagOrder tag_order() const {
+    return tag_order_;
+  }
+
+  bool vm_tags_emitted() const {
+    return (tag_order_ == Profile::kUserVM) ||
+           (tag_order_ == Profile::kVMUser) ||
+           (tag_order_ == Profile::kVM);
+  }
+
+  Isolate* isolate_;
+  Isolate* vm_isolate_;
+  SampleFilter* filter_;
+  Profile::TagOrder tag_order_;
+  Profile* profile_;
+  DeoptimizedCodeSet* deoptimized_code_;
+  const Code& null_code_;
+  const Function& null_function_;
+  bool tick_functions_;
+
+  ProcessedSampleBuffer* samples_;
 };
 
 
+Profile::Profile(Isolate* isolate)
+    : isolate_(isolate),
+      live_code_(NULL),
+      dead_code_(NULL),
+      tag_code_(NULL),
+      functions_(NULL),
+      dead_code_index_offset_(-1),
+      tag_code_index_offset_(-1),
+      min_time_(kMaxInt64),
+      max_time_(0) {
+  ASSERT(isolate_ != NULL);
+  for (intptr_t i = 0; i < kNumTrieKinds; i++) {
+    roots_[i] = NULL;
+  }
+}
+
+
+void Profile::Build(SampleFilter* filter, TagOrder tag_order) {
+  ProfileBuilder builder(isolate_, filter, tag_order, this);
+  builder.Build();
+}
+
+
+ProfileFunction* Profile::GetFunction(intptr_t index) {
+  ASSERT(functions_ != NULL);
+  return functions_->At(index);
+}
+
+
+ProfileCode* Profile::GetCode(intptr_t index) {
+  ASSERT(live_code_ != NULL);
+  ASSERT(dead_code_ != NULL);
+  ASSERT(tag_code_ != NULL);
+  ASSERT(dead_code_index_offset_ >= 0);
+  ASSERT(tag_code_index_offset_ >= 0);
+
+  // Code indexes span three arrays.
+  //           0 ... |live_code|
+  // |live_code| ... |dead_code|
+  // |dead_code| ... |tag_code|
+
+  if (index < dead_code_index_offset_) {
+    return live_code_->At(index);
+  }
+
+  if (index < tag_code_index_offset_) {
+    index -= dead_code_index_offset_;
+    return dead_code_->At(index);
+  }
+
+  index -= tag_code_index_offset_;
+  return tag_code_->At(index);
+}
+
+
+ProfileTrieNode* Profile::GetTrieRoot(TrieKind trie_kind) {
+  return roots_[static_cast<intptr_t>(trie_kind)];
+}
+
+
+void Profile::PrintJSON(JSONStream* stream) {
+  ScopeTimer sw("Profile::PrintJSON", FLAG_trace_profiler);
+  JSONObject obj(stream);
+  obj.AddProperty("type", "_CpuProfile");
+  obj.AddProperty("samplePeriod",
+                  static_cast<intptr_t>(FLAG_profile_period));
+  obj.AddProperty("stackDepth",
+                  static_cast<intptr_t>(FLAG_profile_depth));
+  obj.AddProperty("sampleCount", sample_count());
+  obj.AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan()));
+  {
+    JSONArray codes(&obj, "codes");
+    for (intptr_t i = 0; i < live_code_->length(); i++) {
+      ProfileCode* code = live_code_->At(i);
+      ASSERT(code != NULL);
+      code->PrintToJSONArray(&codes);
+    }
+    for (intptr_t i = 0; i < dead_code_->length(); i++) {
+      ProfileCode* code = dead_code_->At(i);
+      ASSERT(code != NULL);
+      code->PrintToJSONArray(&codes);
+    }
+    for (intptr_t i = 0; i < tag_code_->length(); i++) {
+      ProfileCode* code = tag_code_->At(i);
+      ASSERT(code != NULL);
+      code->PrintToJSONArray(&codes);
+    }
+  }
+
+  {
+    JSONArray functions(&obj, "functions");
+    for (intptr_t i = 0; i < functions_->length(); i++) {
+      ProfileFunction* function = functions_->At(i);
+      ASSERT(function != NULL);
+      function->PrintToJSONArray(&functions);
+    }
+  }
+  {
+    JSONArray code_trie(&obj, "exclusiveCodeTrie");
+    ProfileTrieNode* root = roots_[static_cast<intptr_t>(kExclusiveCode)];
+    ASSERT(root != NULL);
+    root->PrintToJSONArray(&code_trie);
+  }
+  {
+    JSONArray code_trie(&obj, "inclusiveCodeTrie");
+    ProfileTrieNode* root = roots_[static_cast<intptr_t>(kInclusiveCode)];
+    ASSERT(root != NULL);
+    root->PrintToJSONArray(&code_trie);
+  }
+  {
+    JSONArray function_trie(&obj, "exclusiveFunctionTrie");
+    ProfileTrieNode* root = roots_[static_cast<intptr_t>(kExclusiveFunction)];
+    ASSERT(root != NULL);
+    root->PrintToJSONArray(&function_trie);
+  }
+  {
+    JSONArray function_trie(&obj, "inclusiveFunctionTrie");
+    ProfileTrieNode* root = roots_[static_cast<intptr_t>(kInclusiveFunction)];
+    ASSERT(root != NULL);
+    root->PrintToJSONArray(&function_trie);
+  }
+}
+
+
+void ProfileTrieWalker::Reset(Profile::TrieKind trie_kind) {
+  code_trie_ = Profile::IsCodeTrie(trie_kind);
+  parent_ = NULL;
+  current_ = profile_->GetTrieRoot(trie_kind);
+  ASSERT(current_ != NULL);
+}
+
+
+const char* ProfileTrieWalker::CurrentName() {
+  if (current_ == NULL) {
+    return NULL;
+  }
+  if (code_trie_) {
+    ProfileCode* code = profile_->GetCode(current_->table_index());
+    return code->name();
+  } else {
+    ProfileFunction* func = profile_->GetFunction(current_->table_index());
+    return func->Name();
+  }
+  UNREACHABLE();
+}
+
+
+bool ProfileTrieWalker::Down() {
+  if ((current_ == NULL) || (current_->NumChildren() == 0)) {
+    return false;
+  }
+  parent_ = current_;
+  current_ = current_->At(0);
+  return true;
+}
+
+
+bool ProfileTrieWalker::NextSibling() {
+  if (parent_ == NULL) {
+    return false;
+  }
+  intptr_t current_index = parent_->IndexOf(current_);
+  if (current_index < 0) {
+    return false;
+  }
+  current_index++;
+  if (current_index >= parent_->NumChildren()) {
+    return false;
+  }
+  current_ = parent_->At(current_index);
+  return true;
+}
+
+
 class NoAllocationSampleFilter : public SampleFilter {
  public:
   explicit NoAllocationSampleFilter(Isolate* isolate)
@@ -2155,189 +1976,30 @@
 };
 
 
-void ProfilerService::PrintJSON(JSONStream* stream, TagOrder tag_order) {
+void ProfilerService::PrintJSON(JSONStream* stream,
+                                Profile::TagOrder tag_order) {
   Isolate* isolate = Isolate::Current();
   // Disable profile interrupts while processing the buffer.
   Profiler::EndExecution(isolate);
-  MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
-  IsolateProfilerData* profiler_data = isolate->profiler_data();
-  if (profiler_data == NULL) {
-    stream->PrintError(kFeatureDisabled, NULL);
-    return;
+
+  {
+    MutexLocker profiler_data_lock(isolate->profiler_data_mutex());
+    IsolateProfilerData* profiler_data = isolate->profiler_data();
+    if (profiler_data == NULL) {
+      stream->PrintError(kFeatureDisabled, NULL);
+      return;
+    }
   }
-  SampleBuffer* sample_buffer = profiler_data->sample_buffer();
-  ASSERT(sample_buffer != NULL);
-  ScopeTimer sw("ProfilerService::PrintJSON", FLAG_trace_profiler);
+
   {
     StackZone zone(isolate);
     HANDLESCOPE(isolate);
-
-    ProcessedSampleBuffer* processed_samples = NULL;
-    {
-      ScopeTimer sw("BuildProcessedSampleBuffer", FLAG_trace_profiler);
-      NoAllocationSampleFilter filter(isolate);
-      processed_samples = sample_buffer->BuildProcessedSampleBuffer(&filter);
-    }
-
-    {
-      // Live code holds Dart, Native, and Collected CodeRegions.
-      CodeRegionTable live_code_table;
-      // Dead code holds Overwritten CodeRegions.
-      CodeRegionTable dead_code_table;
-      // Tag code holds Tag CodeRegions.
-      CodeRegionTable tag_code_table;
-      // Table holding all ProfileFunctions.
-      ProfileFunctionTable function_table;
-      // Set of deoptimized code still referenced by the profiler.
-      DeoptimizedCodeSet* deoptimized_code = new DeoptimizedCodeSet(isolate);
-
-      // Build CodeRegion tables.
-      CodeRegionTableBuilder builder(isolate,
-                                     &live_code_table,
-                                     &dead_code_table,
-                                     &tag_code_table,
-                                     deoptimized_code);
-      {
-        ScopeTimer sw("CodeRegionTableBuilder::Build", FLAG_trace_profiler);
-        builder.Build(processed_samples);
-      }
-      intptr_t samples = processed_samples->length();
-      intptr_t frames = builder.frames();
-      if (FLAG_trace_profiler) {
-        intptr_t total_live_code_objects = live_code_table.Length();
-        intptr_t total_dead_code_objects = dead_code_table.Length();
-        intptr_t total_tag_code_objects = tag_code_table.Length();
-        OS::Print(
-            "Processed %" Pd " samples with %" Pd " frames\n", samples, frames);
-        OS::Print("CodeTables: live=%" Pd " dead=%" Pd " tag=%" Pd "\n",
-                  total_live_code_objects,
-                  total_dead_code_objects,
-                  total_tag_code_objects);
-      }
-
-      if (FLAG_trace_profiler) {
-        ScopeTimer sw("CodeRegionTableVerify", FLAG_trace_profiler);
-        live_code_table.Verify();
-        dead_code_table.Verify();
-        tag_code_table.Verify();
-      }
-
-      {
-        ScopeTimer st("CodeRegionFunctionMapping", FLAG_trace_profiler);
-        CodeRegionFunctionMapper mapper(isolate, &live_code_table,
-                                                 &dead_code_table,
-                                                 &tag_code_table,
-                                                 &function_table);
-        mapper.Map();
-      }
-      if (FLAG_trace_profiler) {
-        intptr_t total_functions = function_table.Length();
-        OS::Print("FunctionTable: size=%" Pd "\n", total_functions);
-      }
-      CodeRegionTrieBuilder code_trie_builder(isolate,
-                                              &live_code_table,
-                                              &dead_code_table,
-                                              &tag_code_table);
-      code_trie_builder.set_tag_order(tag_order);
-      {
-        // Build CodeRegion trie.
-        ScopeTimer sw("CodeRegionTrieBuilder::Build", FLAG_trace_profiler);
-        code_trie_builder.Build(processed_samples);
-        code_trie_builder.exclusive_root()->SortByCount();
-        code_trie_builder.inclusive_root()->SortByCount();
-      }
-      if (FLAG_trace_profiler) {
-        OS::Print("Code Trie Root Count: E: %" Pd " I: %" Pd "\n",
-                  code_trie_builder.exclusive_root()->count(),
-                  code_trie_builder.inclusive_root()->count());
-      }
-      ProfileFunctionTrieBuilder function_trie_builder(&live_code_table,
-                                                       &dead_code_table,
-                                                       &tag_code_table,
-                                                       &function_table);
-      function_trie_builder.set_tag_order(tag_order);
-      {
-        // Build ProfileFunction trie.
-        ScopeTimer sw("ProfileFunctionTrieBuilder::Build",
-                      FLAG_trace_profiler);
-        function_trie_builder.Build(processed_samples);
-        function_trie_builder.exclusive_root()->SortByCount();
-        function_trie_builder.inclusive_root()->SortByCount();
-      }
-      if (FLAG_trace_profiler) {
-        OS::Print("Function Trie Root Count: E: %" Pd " I: %" Pd "\n",
-                  function_trie_builder.exclusive_root()->count(),
-                  function_trie_builder.inclusive_root()->count());
-      }
-      {
-        ScopeTimer sw("CpuProfileJSONStream", FLAG_trace_profiler);
-        // Serialize to JSON.
-        JSONObject obj(stream);
-        obj.AddProperty("type", "_CpuProfile");
-        obj.AddProperty("sampleCount", samples);
-        obj.AddProperty("samplePeriod",
-                        static_cast<intptr_t>(FLAG_profile_period));
-        obj.AddProperty("stackDepth",
-                        static_cast<intptr_t>(FLAG_profile_depth));
-        obj.AddProperty("timeSpan",
-                        MicrosecondsToSeconds(builder.TimeDeltaMicros()));
-        {
-          JSONArray code_trie(&obj, "exclusiveCodeTrie");
-          CodeRegionTrieNode* root = code_trie_builder.exclusive_root();
-          ASSERT(root != NULL);
-          root->PrintToJSONArray(&code_trie);
-        }
-        {
-          JSONArray code_trie(&obj, "inclusiveCodeTrie");
-          CodeRegionTrieNode* root = code_trie_builder.inclusive_root();
-          ASSERT(root != NULL);
-          root->PrintToJSONArray(&code_trie);
-        }
-        {
-          JSONArray function_trie(&obj, "exclusiveFunctionTrie");
-          ProfileFunctionTrieNode* root =
-              function_trie_builder.exclusive_root();
-          ASSERT(root != NULL);
-          root->PrintToJSONArray(&function_trie);
-        }
-        {
-          JSONArray function_trie(&obj, "inclusiveFunctionTrie");
-          ProfileFunctionTrieNode* root =
-              function_trie_builder.inclusive_root();
-          ASSERT(root != NULL);
-          root->PrintToJSONArray(&function_trie);
-        }
-        {
-          JSONArray codes(&obj, "codes");
-          for (intptr_t i = 0; i < live_code_table.Length(); i++) {
-            CodeRegion* region = live_code_table.At(i);
-            ASSERT(region != NULL);
-            region->PrintToJSONArray(&codes);
-          }
-          for (intptr_t i = 0; i < dead_code_table.Length(); i++) {
-            CodeRegion* region = dead_code_table.At(i);
-            ASSERT(region != NULL);
-            region->PrintToJSONArray(&codes);
-          }
-          for (intptr_t i = 0; i < tag_code_table.Length(); i++) {
-            CodeRegion* region = tag_code_table.At(i);
-            ASSERT(region != NULL);
-            region->PrintToJSONArray(&codes);
-          }
-        }
-        {
-          JSONArray functions(&obj, "functions");
-          for (intptr_t i = 0; i < function_table.Length(); i++) {
-            ProfileFunction* function = function_table.At(i);
-            ASSERT(function != NULL);
-            function->PrintToJSONArray(&functions);
-          }
-        }
-      }
-      // Update the isolates set of dead code.
-      deoptimized_code->UpdateIsolate(isolate);
-    }
+    Profile profile(isolate);
+    NoAllocationSampleFilter filter(isolate);
+    profile.Build(&filter, tag_order);
+    profile.PrintJSON(stream);
   }
+
   // Enable profile interrupts.
   Profiler::BeginExecution(isolate);
 }
diff --git a/runtime/vm/profiler_service.h b/runtime/vm/profiler_service.h
index 19f01b6..d281a84 100644
--- a/runtime/vm/profiler_service.h
+++ b/runtime/vm/profiler_service.h
@@ -8,20 +8,270 @@
 #include "vm/allocation.h"
 #include "vm/code_observers.h"
 #include "vm/globals.h"
+#include "vm/growable_array.h"
+#include "vm/object.h"
 #include "vm/tags.h"
 #include "vm/thread_interrupter.h"
 
-// Profile VM Service.
+// CPU Profile model and service protocol bits.
 // NOTE: For sampling and stack walking related code, see profiler.h.
 
 namespace dart {
 
 // Forward declarations.
+class Code;
+class Function;
 class JSONArray;
 class JSONStream;
-class ProfilerCodeRegionTable;
+class ProfileFunctionTable;
+class ProfileCodeTable;
+class RawCode;
+class RawFunction;
+class SampleFilter;
 
-class ProfilerService : public AllStatic {
+// Profile data related to a |Function|.
+class ProfileFunction : public ZoneAllocated {
+ public:
+  enum Kind {
+    kDartFunction,    // Dart function.
+    kNativeFunction,  // Synthetic function for Native (C/C++).
+    kTagFunction,     // Synthetic function for a VM or User tag.
+    kStubFunction,    // Synthetic function for stub code.
+    kUnknownFunction,  // A singleton function for unknown objects.
+  };
+
+  ProfileFunction(Kind kind,
+                  const char* name,
+                  const Function& function,
+                  const intptr_t table_index);
+
+  const char* name() const {
+    ASSERT(name_ != NULL);
+    return name_;
+  }
+
+  const char* Name() const;
+
+  RawFunction* function() const {
+    return function_.raw();
+  }
+
+  intptr_t table_index() const {
+    return table_index_;
+  }
+
+  Kind kind() const {
+    return kind_;
+  }
+
+  intptr_t exclusive_ticks() const { return exclusive_ticks_; }
+  intptr_t inclusive_ticks() const { return inclusive_ticks_; }
+
+  void IncInclusiveTicks() {
+    inclusive_ticks_++;
+  }
+
+  void Tick(bool exclusive, intptr_t inclusive_serial);
+
+  static const char* KindToCString(Kind kind);
+
+  void PrintToJSONArray(JSONArray* functions);
+
+ private:
+  const Kind kind_;
+  const char* name_;
+  const Function& function_;
+  const intptr_t table_index_;
+  ZoneGrowableArray<intptr_t> profile_codes_;
+
+  intptr_t exclusive_ticks_;
+  intptr_t inclusive_ticks_;
+  intptr_t inclusive_serial_;
+
+  void PrintToJSONObject(JSONObject* func);
+  // A |ProfileCode| that contains this function.
+  void AddProfileCode(intptr_t code_table_index);
+
+  friend class ProfileCode;
+  friend class ProfileBuilder;
+};
+
+
+class ProfileCodeAddress {
+ public:
+  explicit ProfileCodeAddress(uword pc);
+
+  void Tick(bool exclusive);
+
+  uword pc() const { return pc_; }
+  intptr_t exclusive_ticks() const { return exclusive_ticks_; }
+  intptr_t inclusive_ticks() const { return inclusive_ticks_; }
+
+ private:
+  uword pc_;
+  intptr_t exclusive_ticks_;
+  intptr_t inclusive_ticks_;
+};
+
+
+// Profile data related to a |Code|.
+class ProfileCode : public ZoneAllocated {
+ public:
+  enum Kind {
+    kDartCode,       // Live Dart code.
+    kCollectedCode,  // Dead Dart code.
+    kNativeCode,     // Native code.
+    kReusedCode,     // Dead Dart code that has been reused by new kDartCode.
+    kTagCode,        // A special kind of code representing a tag.
+  };
+
+  ProfileCode(Kind kind,
+              uword start,
+              uword end,
+              int64_t timestamp,
+              const Code& code);
+
+  Kind kind() const { return kind_; }
+
+  uword start() const { return start_; }
+  void set_start(uword start) { start_ = start; }
+
+  uword end() const { return end_; }
+  void set_end(uword end) { end_ = end; }
+
+  void AdjustExtent(uword start, uword end);
+
+  bool Contains(uword pc) const {
+    return (pc >= start_) && (pc < end_);
+  }
+
+  bool Overlaps(const ProfileCode* other) const;
+
+  int64_t compile_timestamp() const { return compile_timestamp_; }
+  void set_compile_timestamp(int64_t timestamp) {
+    compile_timestamp_ = timestamp;
+  }
+
+  intptr_t exclusive_ticks() const { return exclusive_ticks_; }
+  void set_exclusive_ticks(intptr_t exclusive_ticks) {
+    exclusive_ticks_ = exclusive_ticks;
+  }
+  void IncExclusiveTicks() {
+    exclusive_ticks_++;
+  }
+
+  intptr_t inclusive_ticks() const { return inclusive_ticks_; }
+  void set_inclusive_ticks(intptr_t inclusive_ticks) {
+    inclusive_ticks_ = inclusive_ticks;
+  }
+  void IncInclusiveTicks() {
+    inclusive_ticks_++;
+  }
+
+  bool IsOptimizedDart() const;
+  RawCode* code() const {
+    return code_.raw();
+  }
+
+  const char* name() const { return name_; }
+  void SetName(const char* name);
+  void GenerateAndSetSymbolName(const char* prefix);
+
+  static const char* KindToCString(Kind kind);
+
+  void PrintToJSONArray(JSONArray* codes);
+
+ private:
+  void Tick(uword pc, bool exclusive, intptr_t serial);
+  void TickAddress(uword pc, bool exclusive);
+
+  ProfileFunction* SetFunctionAndName(ProfileFunctionTable* table);
+
+  ProfileFunction* function() const {
+    return function_;
+  }
+
+  void PrintNativeCode(JSONObject* profile_code_obj);
+  void PrintCollectedCode(JSONObject* profile_code_obj);
+  void PrintOverwrittenCode(JSONObject* profile_code_obj);
+  void PrintTagCode(JSONObject* profile_code_obj);
+
+  void set_code_table_index(intptr_t index) { code_table_index_ = index; }
+  intptr_t code_table_index() const { return code_table_index_; }
+
+  const Kind kind_;
+  uword start_;
+  uword end_;
+  intptr_t exclusive_ticks_;
+  intptr_t inclusive_ticks_;
+  intptr_t inclusive_serial_;
+
+  const Code& code_;
+  const char* name_;
+  int64_t compile_timestamp_;
+  ProfileFunction* function_;
+  intptr_t code_table_index_;
+  ZoneGrowableArray<ProfileCodeAddress> address_ticks_;
+
+  friend class ProfileBuilder;
+};
+
+
+// Stack traces are organized in a trie. This holds information about one node
+// in the trie. A node in a tree represents a stack frame and a path in the tree
+// represents a stack trace. Each unique stack trace appears in the tree once
+// and each node has a count indicating how many times this has been observed.
+// The index can be used to look up a |ProfileFunction| or |ProfileCode|.
+// A node can have zero or more children. Depending on the kind of trie the
+// children are callers or callees of the current node.
+class ProfileTrieNode : public ZoneAllocated {
+ public:
+  explicit ProfileTrieNode(intptr_t index);
+  virtual ~ProfileTrieNode();
+
+  virtual void PrintToJSONArray(JSONArray* array) const = 0;
+
+  // Index into function or code tables.
+  intptr_t table_index() const { return table_index_; }
+
+  intptr_t count() const { return count_; }
+
+  void Tick() {
+    count_++;
+  }
+
+  intptr_t NumChildren() const {
+    return children_.length();
+  }
+
+  ProfileTrieNode* At(intptr_t i) {
+    return children_.At(i);
+  }
+
+  intptr_t IndexOf(ProfileTrieNode* node);
+
+ protected:
+  void SortChildren();
+
+  static int ProfileTrieNodeCompare(ProfileTrieNode* const* a,
+                                    ProfileTrieNode* const* b) {
+    ASSERT(a != NULL);
+    ASSERT(b != NULL);
+    return (*b)->count() - (*a)->count();
+  }
+
+
+  intptr_t table_index_;
+  intptr_t count_;
+  ZoneGrowableArray<ProfileTrieNode*> children_;
+
+  friend class ProfileBuilder;
+};
+
+
+// The model for a profile. Most of the model is zone allocated, therefore
+// a zone must be created that lives longer than this object.
+class Profile : public ValueObject {
  public:
   enum TagOrder {
     kNoTags,
@@ -31,8 +281,90 @@
     kVMUser
   };
 
+  enum TrieKind {
+    kExclusiveCode,
+    kExclusiveFunction,
+    kInclusiveCode,
+    kInclusiveFunction,
+    kNumTrieKinds,
+  };
+
+  static bool IsCodeTrie(TrieKind kind) {
+    return (kind == kExclusiveCode) || (kind == kInclusiveCode);
+  }
+
+  static bool IsFunctionTrie(TrieKind kind) {
+    return !IsCodeTrie(kind);
+  }
+
+  explicit Profile(Isolate* isolate);
+
+  // Build a filtered model using |filter| with the specified |tag_order|.
+  void Build(SampleFilter* filter, TagOrder tag_order);
+
+  // After building:
+  int64_t min_time() const { return min_time_; }
+  int64_t max_time() const { return max_time_; }
+  int64_t GetTimeSpan() const {
+    return max_time() - min_time();
+  }
+  intptr_t sample_count() const { return sample_count_; }
+
+  ProfileFunction* GetFunction(intptr_t index);
+  ProfileCode* GetCode(intptr_t index);
+  ProfileTrieNode* GetTrieRoot(TrieKind trie_kind);
+
+  void PrintJSON(JSONStream* stream);
+
+ private:
+  Isolate* isolate_;
+  ProfileCodeTable* live_code_;
+  ProfileCodeTable* dead_code_;
+  ProfileCodeTable* tag_code_;
+  ProfileFunctionTable* functions_;
+  intptr_t dead_code_index_offset_;
+  intptr_t tag_code_index_offset_;
+
+  ProfileTrieNode* roots_[kNumTrieKinds];
+
+  int64_t min_time_;
+  int64_t max_time_;
+
+  intptr_t sample_count_;
+
+  friend class ProfileBuilder;
+};
+
+
+class ProfileTrieWalker : public ValueObject {
+ public:
+  explicit ProfileTrieWalker(Profile* profile)
+      : profile_(profile),
+        parent_(NULL),
+        current_(NULL),
+        code_trie_(false) {
+    ASSERT(profile_ != NULL);
+  }
+
+  void Reset(Profile::TrieKind trie_kind);
+
+  const char* CurrentName();
+
+  bool Down();
+  bool NextSibling();
+
+ private:
+  Profile* profile_;
+  ProfileTrieNode* parent_;
+  ProfileTrieNode* current_;
+  bool code_trie_;
+};
+
+
+class ProfilerService : public AllStatic {
+ public:
   static void PrintJSON(JSONStream* stream,
-                        TagOrder tag_order);
+                        Profile::TagOrder tag_order);
 
   static void ClearSamples();
 };
diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc
index 561bb69..4f1ea87 100644
--- a/runtime/vm/profiler_test.cc
+++ b/runtime/vm/profiler_test.cc
@@ -8,6 +8,7 @@
 #include "vm/dart_api_state.h"
 #include "vm/globals.h"
 #include "vm/profiler.h"
+#include "vm/profiler_service.h"
 #include "vm/unit_test.h"
 
 namespace dart {
@@ -108,15 +109,35 @@
 }
 
 
+class AllocationFilter : public SampleFilter {
+ public:
+  explicit AllocationFilter(Isolate* isolate, intptr_t cid)
+      : SampleFilter(isolate),
+        cid_(cid) {
+  }
+
+  bool FilterSample(Sample* sample) {
+    return sample->is_allocation_sample() && (sample->allocation_cid() == cid_);
+  }
+
+ private:
+  intptr_t cid_;
+};
+
+
 TEST_CASE(Profiler_TrivialRecordAllocation) {
   const char* kScript =
       "class A {\n"
       "  var a;\n"
       "  var b;\n"
       "}\n"
+      "class B {\n"
+      "  static boo() {\n"
+      "    return new A();\n"
+      "  }\n"
+      "}\n"
       "main() {\n"
-      "  var z = new A();\n"
-      "  return z;\n"
+      "  return B.boo();\n"
       "}\n";
 
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
@@ -130,6 +151,166 @@
 
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
   EXPECT_VALID(result);
+
+
+  {
+    Isolate* isolate = Isolate::Current();
+    StackZone zone(isolate);
+    HANDLESCOPE(isolate);
+    Profile profile(isolate);
+    AllocationFilter filter(isolate, class_a.id());
+    profile.Build(&filter, Profile::kNoTags);
+    // We should have 1 allocation sample.
+    EXPECT_EQ(1, profile.sample_count());
+    ProfileTrieWalker walker(&profile);
+
+    // Exclusive code: B.boo -> main.
+    walker.Reset(Profile::kExclusiveCode);
+    // Move down from the root.
+    EXPECT(walker.Down());
+    EXPECT_STREQ("B.boo", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("main", walker.CurrentName());
+    EXPECT(!walker.Down());
+
+    // Inclusive code: main -> B.boo.
+    walker.Reset(Profile::kInclusiveCode);
+    // Move down from the root.
+    EXPECT(walker.Down());
+    EXPECT_STREQ("main", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("B.boo", walker.CurrentName());
+    EXPECT(!walker.Down());
+
+    // Exclusive function: B.boo -> main.
+    walker.Reset(Profile::kExclusiveFunction);
+    // Move down from the root.
+    EXPECT(walker.Down());
+    EXPECT_STREQ("B.boo", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("main", walker.CurrentName());
+    EXPECT(!walker.Down());
+
+    // Inclusive function: main -> B.boo.
+    walker.Reset(Profile::kInclusiveFunction);
+    // Move down from the root.
+    EXPECT(walker.Down());
+    EXPECT_STREQ("main", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("B.boo", walker.CurrentName());
+    EXPECT(!walker.Down());
+  }
+}
+
+
+TEST_CASE(Profiler_ToggleRecordAllocation) {
+  const char* kScript =
+      "class A {\n"
+      "  var a;\n"
+      "  var b;\n"
+      "}\n"
+      "class B {\n"
+      "  static boo() {\n"
+      "    return new A();\n"
+      "  }\n"
+      "}\n"
+      "main() {\n"
+      "  return B.boo();\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+  Library& root_library = Library::Handle();
+  root_library ^= Api::UnwrapHandle(lib);
+
+  const Class& class_a = Class::Handle(GetClass(root_library, "A"));
+  EXPECT(!class_a.IsNull());
+
+  Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+  EXPECT_VALID(result);
+
+
+  {
+    Isolate* isolate = Isolate::Current();
+    StackZone zone(isolate);
+    HANDLESCOPE(isolate);
+    Profile profile(isolate);
+    AllocationFilter filter(isolate, class_a.id());
+    profile.Build(&filter, Profile::kNoTags);
+    // We should have no allocation samples.
+    EXPECT_EQ(0, profile.sample_count());
+  }
+
+  // Turn on allocation tracing for A.
+  class_a.SetTraceAllocation(true);
+
+  result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+  EXPECT_VALID(result);
+
+  {
+    Isolate* isolate = Isolate::Current();
+    StackZone zone(isolate);
+    HANDLESCOPE(isolate);
+    Profile profile(isolate);
+    AllocationFilter filter(isolate, class_a.id());
+    profile.Build(&filter, Profile::kNoTags);
+    // We should have one allocation sample.
+    EXPECT_EQ(1, profile.sample_count());
+    ProfileTrieWalker walker(&profile);
+
+    // Exclusive code: B.boo -> main.
+    walker.Reset(Profile::kExclusiveCode);
+    // Move down from the root.
+    EXPECT(walker.Down());
+    EXPECT_STREQ("B.boo", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("main", walker.CurrentName());
+    EXPECT(!walker.Down());
+
+    // Inclusive code: main -> B.boo.
+    walker.Reset(Profile::kInclusiveCode);
+    // Move down from the root.
+    EXPECT(walker.Down());
+    EXPECT_STREQ("main", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("B.boo", walker.CurrentName());
+    EXPECT(!walker.Down());
+
+    // Exclusive function: boo -> main.
+    walker.Reset(Profile::kExclusiveFunction);
+    // Move down from the root.
+    EXPECT(walker.Down());
+    EXPECT_STREQ("B.boo", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("main", walker.CurrentName());
+    EXPECT(!walker.Down());
+
+    // Inclusive function: main -> boo.
+    walker.Reset(Profile::kInclusiveFunction);
+    // Move down from the root.
+    EXPECT(walker.Down());
+    EXPECT_STREQ("main", walker.CurrentName());
+    EXPECT(walker.Down());
+    EXPECT_STREQ("B.boo", walker.CurrentName());
+    EXPECT(!walker.Down());
+  }
+
+  // Turn off allocation tracing for A.
+  class_a.SetTraceAllocation(false);
+
+  result = Dart_Invoke(lib, NewString("main"), 0, NULL);
+  EXPECT_VALID(result);
+
+  {
+    Isolate* isolate = Isolate::Current();
+    StackZone zone(isolate);
+    HANDLESCOPE(isolate);
+    Profile profile(isolate);
+    AllocationFilter filter(isolate, class_a.id());
+    profile.Build(&filter, Profile::kNoTags);
+    // We should still only have one allocation sample.
+    EXPECT_EQ(1, profile.sample_count());
+  }
 }
 
 }  // namespace dart
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 25de978..c40f71e 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -1521,6 +1521,8 @@
     }
     return true;
   }
+  // TODO(rmacnak): There is no way to get the size retained by a class object.
+  // SizeRetainedByClass should be a separate RPC.
   if (obj.IsClass()) {
     const Class& cls = Class::Cast(obj);
     ObjectGraph graph(isolate);
@@ -1529,18 +1531,11 @@
     result.PrintJSON(js, true);
     return true;
   }
-  if (obj.IsInstance() || obj.IsNull()) {
-    // We don't use Instance::Cast here because it doesn't allow null.
-    ObjectGraph graph(isolate);
-    intptr_t retained_size = graph.SizeRetainedByInstance(obj);
-    const Object& result = Object::Handle(Integer::New(retained_size));
-    result.PrintJSON(js, true);
-    return true;
-  }
-  js->PrintError(kInvalidParams,
-                 "%s: invalid 'targetId' parameter: "
-                 "id '%s' does not correspond to a "
-                 "library, class, or instance", js->method(), target_id);
+
+  ObjectGraph graph(isolate);
+  intptr_t retained_size = graph.SizeRetainedByInstance(obj);
+  const Object& result = Object::Handle(Integer::New(retained_size));
+  result.PrintJSON(js, true);
   return true;
 }
 
@@ -2224,13 +2219,13 @@
 };
 
 
-static ProfilerService::TagOrder tags_enum_values[] = {
-  ProfilerService::kNoTags,
-  ProfilerService::kUserVM,
-  ProfilerService::kUser,
-  ProfilerService::kVMUser,
-  ProfilerService::kVM,
-  ProfilerService::kNoTags,  // Default value.
+static Profile::TagOrder tags_enum_values[] = {
+  Profile::kNoTags,
+  Profile::kUserVM,
+  Profile::kUser,
+  Profile::kVMUser,
+  Profile::kVM,
+  Profile::kNoTags,  // Default value.
 };
 
 
@@ -2242,7 +2237,7 @@
 
 
 static bool GetCpuProfile(Isolate* isolate, JSONStream* js) {
-  ProfilerService::TagOrder tag_order =
+  Profile::TagOrder tag_order =
       EnumMapper(js->LookupParam("tags"), tags_enum_names, tags_enum_values);
   ProfilerService::PrintJSON(js, tag_order);
   return true;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index d764864..f0bbf8f 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -796,7 +796,9 @@
   @Class super [optional];
 
   // A list of interface types for this class.
-  @Type[] interfaces;
+  //
+  // The value will be of the kind: Type.
+  @Instance[] interfaces;
 
   // A list of fields in this class. Does not include fields from
   // superclasses.
@@ -836,7 +838,7 @@
 _@Code_ is a reference to a _Code_ object.
 
 ```
-class @Code extends @Object {
+class Code extends @Object {
   // A name for this code object.
   string name;
 
@@ -1061,7 +1063,10 @@
   @Object owner;
 
   // The declared type of this field.
-  @Type declaredType;
+  //
+  // The value will always be of one of the kinds:
+  // Type, TypeRef, TypeParameter, BoundedType.
+  @Instance declaredType;
 
   // Is this field const?
   bool const;
@@ -1086,7 +1091,10 @@
   @Object owner;
 
   // The declared type of this field.
-  @Type declaredType;
+  //
+  // The value will always be of one of the kinds:
+  // Type, TypeRef, TypeParameter, BoundedType.
+  @Instance declaredType;
 
   // Is this field const?
   bool const;
@@ -1136,10 +1144,10 @@
 ```
 class FlagList extends Response {
   // A list of all flags which are set to default values.
-  unmodifiedFlags []Flag
+  Flag[] unmodifiedFlags;
 
   // A list of all flags which have been modified by the user.
-  modifiedFlags []Flag
+  Flag[] modifiedFlags;
 }
 ```
 
@@ -1170,11 +1178,10 @@
   @Library|@Class|@Function owner;
 
   // Is this function static?
-  bool static
+  bool static;
 
   // Is this function const?
   bool const;
-
 }
 ```
 
@@ -1182,7 +1189,6 @@
 
 
 ```
-// A Dart language function.
 class Function extends Object {
   // The name of this function.
   string name;
@@ -1263,6 +1269,13 @@
   // Provided for instance kinds:
   //   TypeParameter
   @Class parameterizedClass [optional];
+
+
+  // The pattern of a RegExp instance.
+  //
+  // Provided for instance kinds:
+  //   RegExp
+  String pattern [optional];
 }
 ```
 
@@ -1379,13 +1392,19 @@
   // Provided for instance kinds:
   //   MirrorReference
   @Instance mirrorReferent [optional];
-  
+
+  // The pattern of a RegExp instance.
+  //
+  // Provided for instance kinds:
+  //   RegExp
+  String pattern [optional];
+
   // The key for a WeakProperty instance.
   //
   // Provided for instance kinds:
   //   WeakProperty
   @Instance propertyKey [optional];
-  
+
   // The key for a WeakProperty instance.
   //
   // Provided for instance kinds:
@@ -1408,7 +1427,7 @@
   // - or -
   // the referent of a TypeRef instance.
   //
-  // The value will always be one of:
+  // The value will always be of one of the kinds:
   // Type, TypeRef, TypeParameter, BoundedType.
   //
   // Provided for instance kinds:
@@ -1418,7 +1437,7 @@
 
   // The bound of a TypeParameter or BoundedType.
   //
-  // The value will always be one of:
+  // The value will always be of one of the kinds:
   // Type, TypeRef, TypeParameter, BoundedType.
   //
   // Provided for instance kinds:
@@ -1433,7 +1452,7 @@
 ### InstanceKind
 
 ```
-enum {
+enum InstanceKind {
   // A general instance of the Dart class Object.
   PlainInstance,
 
@@ -1484,6 +1503,9 @@
   // An instance of the Dart class MirrorReference.
   MirrorReference,
 
+  // An instance of the Dart class RegExp.
+  RegExp,
+
   // An instance of the Dart class WeakProperty.
   WeakProperty,
 
@@ -1682,7 +1704,7 @@
 class @Object extends Response {
   // A unique identifier for an Object. Passed to the
   // getObject RPC to load this Object.
-  string id
+  string id;
 }
 ```
 
@@ -1816,7 +1838,7 @@
 
 ```
 class SourceLocation extends Response {
-  // The script contaiinging the source location.
+  // The script containing the source location.
   @Script script;
 
   // The first token of the location.
@@ -1833,7 +1855,7 @@
 ### Stack
 
 ```
-class Stack {
+class Stack extends Response {
   Frame[] frames;
   Message[] messages;
 }
@@ -1877,7 +1899,10 @@
   string name;
 
   // A list of types.
-  @Type[] types;
+  //
+  // The value will always be one of the kinds:
+  // Type, TypeRef, TypeParameter, BoundedType.
+  @Instance[] types;
 }
 ```
 
@@ -1937,10 +1962,10 @@
   // The time that the VM started in milliseconds since the epoch.
   //
   // Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
-  int startTime
+  int startTime;
 
   // A list of isolates running in the VM.
-  @Isolate[] isolates
+  @Isolate[] isolates;
 }
 ```
 
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index d657120..0d876d3 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1083,7 +1083,8 @@
   const int kInlineInstanceSize = 12;
   const intptr_t instance_size = cls.instance_size();
   ASSERT(instance_size > 0);
-  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
+      !cls.trace_allocation()) {
     Label slow_case;
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 5d07451..10e2411 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -1128,7 +1128,8 @@
     __ ldr(R1, Address(SP));
     // R1: instantiated type arguments.
   }
-  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
+      !cls.trace_allocation()) {
     Label slow_case;
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index e6f8818..95ba111 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1055,7 +1055,8 @@
     __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset));
     // EDX: instantiated type arguments.
   }
-  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
+      !cls.trace_allocation()) {
     Label slow_case;
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index a65cb5b..eb53d7f 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -1178,7 +1178,8 @@
     __ lw(T1, Address(SP, 0 * kWordSize));
     // T1: type arguments.
   }
-  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
+      !cls.trace_allocation()) {
     Label slow_case;
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 2a15822..c844e1f 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1089,7 +1089,8 @@
     __ movq(RDX, Address(RSP, kObjectTypeArgumentsOffset));
     // RDX: instantiated type arguments.
   }
-  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) {
+  if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size) &&
+      !cls.trace_allocation()) {
     Label slow_case;
     // Allocate the object and update top to point to
     // next object start and initialize the allocated object.
diff --git a/samples/samples.status b/samples/samples.status
index 92b4837..224e573 100644
--- a/samples/samples.status
+++ b/samples/samples.status
@@ -25,4 +25,3 @@
 *: Skip
 
 [ $compiler == dart2js && $cps_ir ]
-sample_extension/test/sample_extension_test: Crash # Invalid argument(s)
diff --git a/sdk/lib/_internal/compiler/js_lib/annotations.dart b/sdk/lib/_internal/js_runtime/lib/annotations.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/annotations.dart
rename to sdk/lib/_internal/js_runtime/lib/annotations.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/async_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/async_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/collection_patch.dart b/sdk/lib/_internal/js_runtime/lib/collection_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/collection_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/collection_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/constant_map.dart b/sdk/lib/_internal/js_runtime/lib/constant_map.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/constant_map.dart
rename to sdk/lib/_internal/js_runtime/lib/constant_map.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/convert_patch.dart b/sdk/lib/_internal/js_runtime/lib/convert_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/convert_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/convert_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
similarity index 87%
rename from sdk/lib/_internal/compiler/js_lib/core_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 7045e05..4e2e714 100644
--- a/sdk/lib/_internal/compiler/js_lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -510,3 +510,71 @@
     throw new UnsupportedError("'Uri.base' is not supported");
   }
 }
+
+@patch
+class Resource {
+  @patch
+  const factory Resource(String uri) = _Resource;
+}
+
+Uri _resolvePackageUri(Uri packageUri) {
+  assert(packageUri.scheme == "package");
+  if (packageUri.hasAuthority) {
+    throw new ArgumentError("Package-URI must not have a host: $packageUri");
+  }
+  var resolved = Uri.base.resolve("packages/${packageUri.path}");
+  return resolved;
+}
+
+class _Resource implements Resource {
+  final String _location;
+
+  const _Resource(String uri) : _location = uri;
+
+  Uri get uri => Uri.base.resolve(_location);
+
+  Stream<List<int>> openRead() {
+    Uri uri = this.uri;
+    if (uri.scheme == "package") {
+      uri = _resolvePackageUri(uri);
+    }
+    if (uri.scheme == "http" || uri.scheme == "https") {
+      return _readAsStream(uri);
+    }
+    throw new StateError("Unable to find resource, unknown scheme: $_location");
+  }
+
+  Future<List<int>> readAsBytes() {
+    Uri uri = this.uri;
+    if (uri.scheme == "package") {
+      uri = _resolvePackageUri(uri);
+    }
+    if (uri.scheme == "http" || uri.scheme == "https") {
+      return _readAsBytes(uri);
+    }
+    throw new StateError("Unable to find resource, unknown scheme: $_location");
+  }
+
+  Future<String> readAsString({Encoding encoding: UTF8}) {
+    Uri uri = this.uri;
+    if (uri.scheme == "package") {
+      uri = _resolvePackageUri(uri);
+    }
+    if (uri.scheme == "http" || uri.scheme == "https") {
+      return _readAsString(uri);
+    }
+    throw new StateError("Unable to find resource, unknown scheme: $_location");
+  }
+
+  Stream<List<int>> _readAsStream(Uri uri) {
+    throw new UnimplementedError("Streaming bytes via HTTP");
+  }
+
+  Future<List<int>> _readAsBytes(Uri uri) {
+    throw new UnimplementedError("Reading bytes via HTTP");
+  }
+
+  Future<String> _readAsString(Uri uri) {
+    throw new UnimplementedError("Reading string via HTTP");
+  }
+}
diff --git a/sdk/lib/_internal/compiler/js_lib/developer_patch.dart b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/developer_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/developer_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/foreign_helper.dart b/sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/foreign_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/foreign_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/interceptors.dart b/sdk/lib/_internal/js_runtime/lib/interceptors.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/interceptors.dart
rename to sdk/lib/_internal/js_runtime/lib/interceptors.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/internal_patch.dart b/sdk/lib/_internal/js_runtime/lib/internal_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/internal_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/internal_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/io_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/io_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/isolate_helper.dart b/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/isolate_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/isolate_patch.dart b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/isolate_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/isolate_serialization.dart b/sdk/lib/_internal/js_runtime/lib/isolate_serialization.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/isolate_serialization.dart
rename to sdk/lib/_internal/js_runtime/lib/isolate_serialization.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_array.dart b/sdk/lib/_internal/js_runtime/lib/js_array.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_array.dart
rename to sdk/lib/_internal/js_runtime/lib/js_array.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/js_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_mirrors.dart b/sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_mirrors.dart
rename to sdk/lib/_internal/js_runtime/lib/js_mirrors.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_names.dart b/sdk/lib/_internal/js_runtime/lib/js_names.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_names.dart
rename to sdk/lib/_internal/js_runtime/lib/js_names.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_number.dart b/sdk/lib/_internal/js_runtime/lib/js_number.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_number.dart
rename to sdk/lib/_internal/js_runtime/lib/js_number.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_primitives.dart b/sdk/lib/_internal/js_runtime/lib/js_primitives.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_primitives.dart
rename to sdk/lib/_internal/js_runtime/lib/js_primitives.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_rti.dart
rename to sdk/lib/_internal/js_runtime/lib/js_rti.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/js_string.dart b/sdk/lib/_internal/js_runtime/lib/js_string.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/js_string.dart
rename to sdk/lib/_internal/js_runtime/lib/js_string.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/linked_hash_map.dart b/sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/linked_hash_map.dart
rename to sdk/lib/_internal/js_runtime/lib/linked_hash_map.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/math_patch.dart b/sdk/lib/_internal/js_runtime/lib/math_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/math_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/math_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/mirror_helper.dart b/sdk/lib/_internal/js_runtime/lib/mirror_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/mirror_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/mirror_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/mirrors_patch.dart b/sdk/lib/_internal/js_runtime/lib/mirrors_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/mirrors_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/mirrors_patch.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/native_helper.dart b/sdk/lib/_internal/js_runtime/lib/native_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/native_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/native_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/native_typed_data.dart b/sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/native_typed_data.dart
rename to sdk/lib/_internal/js_runtime/lib/native_typed_data.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/preambles/README b/sdk/lib/_internal/js_runtime/lib/preambles/README
similarity index 75%
rename from sdk/lib/_internal/compiler/js_lib/preambles/README
rename to sdk/lib/_internal/js_runtime/lib/preambles/README
index 7eb614e..4465012 100644
--- a/sdk/lib/_internal/compiler/js_lib/preambles/README
+++ b/sdk/lib/_internal/js_runtime/lib/preambles/README
@@ -4,10 +4,10 @@
 
 =Usage=
 - d8:
-    d8 <sdk>/lib/_internal/compiler/js_lib/preambles/d8.js <output>.js
+    d8 <sdk>/lib/_internal/js_runtime/lib/preambles/d8.js <output>.js
 
 - jsshell:
-    jsshell -f <sdk>/lib/_internal/compiler/js_lib/preambles/d8.js -f <output>.js
+    jsshell -f <sdk>/lib/_internal/js_runtime/lib/preambles/d8.js -f <output>.js
 
 - node.js:
   The d8 preamble file works for most programs.
diff --git a/sdk/lib/_internal/compiler/js_lib/preambles/d8.js b/sdk/lib/_internal/js_runtime/lib/preambles/d8.js
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/preambles/d8.js
rename to sdk/lib/_internal/js_runtime/lib/preambles/d8.js
diff --git a/sdk/lib/_internal/compiler/js_lib/preambles/jsshell.js b/sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/preambles/jsshell.js
rename to sdk/lib/_internal/js_runtime/lib/preambles/jsshell.js
diff --git a/sdk/lib/_internal/compiler/js_lib/regexp_helper.dart b/sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/regexp_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/regexp_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/shared/async_await_error_codes.dart b/sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/shared/async_await_error_codes.dart
rename to sdk/lib/_internal/js_runtime/lib/shared/async_await_error_codes.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart
rename to sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/string_helper.dart b/sdk/lib/_internal/js_runtime/lib/string_helper.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/string_helper.dart
rename to sdk/lib/_internal/js_runtime/lib/string_helper.dart
diff --git a/sdk/lib/_internal/compiler/js_lib/typed_data_patch.dart b/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart
similarity index 100%
rename from sdk/lib/_internal/compiler/js_lib/typed_data_patch.dart
rename to sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart
diff --git a/sdk/lib/_internal/js_runtime/pubspec.yaml b/sdk/lib/_internal/js_runtime/pubspec.yaml
new file mode 100644
index 0000000..058f035
--- /dev/null
+++ b/sdk/lib/_internal/js_runtime/pubspec.yaml
@@ -0,0 +1,4 @@
+# Note: This package is not meant to be uploaded to pub. This file is used to
+# make it easer to develop on dart2js.
+name: js_runtime
+# version: do-not-upload
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index 7cd70c2..daeea77 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -2,339 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+/// This file moved under `sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart`.
+@deprecated
 library libraries;
 
-/**
- * A bit flag used by [LibraryInfo] indicating that a library is used by dart2js
- */
-const int DART2JS_PLATFORM = 1;
-
-/**
- * A bit flag used by [LibraryInfo] indicating that a library is used by the VM
- */
-const int VM_PLATFORM = 2;
-
-/**
- * Mapping of "dart:" library name (e.g. "core") to information about that library.
- * This information is structured such that Dart Editor can parse this file
- * and extract the necessary information without executing it
- * while other tools can access via execution.
- */
-const Map<String, LibraryInfo> LIBRARIES = const {
-
-  "async": const LibraryInfo(
-      "async/async.dart",
-      maturity: Maturity.STABLE,
-      dart2jsPatchPath: "_internal/compiler/js_lib/async_patch.dart"),
-
-  "_blink": const LibraryInfo(
-      "_blink/dartium/_blink_dartium.dart",
-      category: "Client",
-      implementation: true,
-      documented: false,
-      platforms: VM_PLATFORM),
-
-  "_chrome": const LibraryInfo(
-      "_chrome/dart2js/chrome_dart2js.dart",
-      documented: false,
-      category: "Client"),
-
-  "collection": const LibraryInfo(
-      "collection/collection.dart",
-      maturity: Maturity.STABLE,
-      dart2jsPatchPath: "_internal/compiler/js_lib/collection_patch.dart"),
-
-  "convert": const LibraryInfo(
-      "convert/convert.dart",
-      maturity: Maturity.STABLE,
-      dart2jsPatchPath: "_internal/compiler/js_lib/convert_patch.dart"),
-
-  "core": const LibraryInfo(
-      "core/core.dart",
-      maturity: Maturity.STABLE,
-      dart2jsPatchPath: "_internal/compiler/js_lib/core_patch.dart"),
-
-  "developer": const LibraryInfo(
-      "developer/developer.dart",
-      maturity: Maturity.UNSTABLE,
-      dart2jsPatchPath: "_internal/compiler/js_lib/developer_patch.dart"),
-
-  "html": const LibraryInfo(
-      "html/dartium/html_dartium.dart",
-      category: "Client",
-      maturity: Maturity.WEB_STABLE,
-      dart2jsPath: "html/dart2js/html_dart2js.dart"),
-
-  "html_common": const LibraryInfo(
-      "html/html_common/html_common.dart",
-      category: "Client",
-      maturity: Maturity.WEB_STABLE,
-      dart2jsPath: "html/html_common/html_common_dart2js.dart",
-      documented: false,
-      implementation: true),
-
-  "indexed_db": const LibraryInfo(
-      "indexed_db/dartium/indexed_db_dartium.dart",
-      category: "Client",
-      maturity: Maturity.WEB_STABLE,
-      dart2jsPath: "indexed_db/dart2js/indexed_db_dart2js.dart"),
-
-  "io": const LibraryInfo(
-      "io/io.dart",
-      category: "Server",
-      maturity: Maturity.STABLE,
-      dart2jsPatchPath: "_internal/compiler/js_lib/io_patch.dart"),
-
-  "isolate": const LibraryInfo(
-      "isolate/isolate.dart",
-      maturity: Maturity.STABLE,
-      dart2jsPatchPath: "_internal/compiler/js_lib/isolate_patch.dart"),
-
-  "js": const LibraryInfo(
-      "js/dartium/js_dartium.dart",
-      category: "Client",
-      maturity: Maturity.STABLE,
-      dart2jsPath: "js/dart2js/js_dart2js.dart"),
-
-  "math": const LibraryInfo(
-      "math/math.dart",
-      maturity: Maturity.STABLE,
-      dart2jsPatchPath: "_internal/compiler/js_lib/math_patch.dart"),
-
-  "mirrors": const LibraryInfo(
-      "mirrors/mirrors.dart",
-      maturity: Maturity.UNSTABLE,
-      dart2jsPatchPath: "_internal/compiler/js_lib/mirrors_patch.dart"),
-
-  "profiler": const LibraryInfo(
-      "profiler/profiler.dart",
-      maturity: Maturity.UNSTABLE),
-
-  "nativewrappers": const LibraryInfo(
-      "html/dartium/nativewrappers.dart",
-      category: "Client",
-      implementation: true,
-      documented: false,
-      platforms: VM_PLATFORM),
-
-  "typed_data": const LibraryInfo(
-      "typed_data/typed_data.dart",
-      maturity: Maturity.STABLE,
-      dart2jsPatchPath: "_internal/compiler/js_lib/typed_data_patch.dart"),
-
-  "_native_typed_data": const LibraryInfo(
-      "_internal/compiler/js_lib/native_typed_data.dart",
-      category: "Internal",
-      implementation: true,
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
-  "svg": const LibraryInfo(
-      "svg/dartium/svg_dartium.dart",
-      category: "Client",
-      maturity: Maturity.WEB_STABLE,
-      dart2jsPath: "svg/dart2js/svg_dart2js.dart"),
-
-  "web_audio": const LibraryInfo(
-      "web_audio/dartium/web_audio_dartium.dart",
-      category: "Client",
-      maturity: Maturity.WEB_STABLE,
-      dart2jsPath: "web_audio/dart2js/web_audio_dart2js.dart"),
-
-  "web_gl": const LibraryInfo(
-      "web_gl/dartium/web_gl_dartium.dart",
-      category: "Client",
-      maturity: Maturity.WEB_STABLE,
-      dart2jsPath: "web_gl/dart2js/web_gl_dart2js.dart"),
-
-  "web_sql": const LibraryInfo(
-      "web_sql/dartium/web_sql_dartium.dart",
-      category: "Client",
-      maturity: Maturity.WEB_STABLE,
-      dart2jsPath: "web_sql/dart2js/web_sql_dart2js.dart"),
-
-  "_internal": const LibraryInfo(
-      "internal/internal.dart",
-      category: "Internal",
-      documented: false,
-      dart2jsPatchPath:
-          "_internal/compiler/js_lib/internal_patch.dart"),
-
-  "_js_helper": const LibraryInfo(
-      "_internal/compiler/js_lib/js_helper.dart",
-      category: "Internal",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
-  "_interceptors": const LibraryInfo(
-      "_internal/compiler/js_lib/interceptors.dart",
-      category: "Internal",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
-  "_foreign_helper": const LibraryInfo(
-      "_internal/compiler/js_lib/foreign_helper.dart",
-      category: "Internal",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
-  "_isolate_helper": const LibraryInfo(
-      "_internal/compiler/js_lib/isolate_helper.dart",
-      category: "Internal",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
-  "_js_mirrors": const LibraryInfo(
-      "_internal/compiler/js_lib/js_mirrors.dart",
-      category: "Internal",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
-  "_js_names": const LibraryInfo(
-      "_internal/compiler/js_lib/js_names.dart",
-      category: "Internal",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
-  "_js_primitives": const LibraryInfo(
-      "_internal/compiler/js_lib/js_primitives.dart",
-      category: "Internal",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
-  // TODO(ahe): This library is only for dart2dart, perhaps it should use a
-  // different platform.
-  "_mirror_helper": const LibraryInfo(
-      "_internal/compiler/js_lib/mirror_helper.dart",
-      category: "Internal",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
-  "_js_embedded_names": const LibraryInfo(
-      "_internal/compiler/js_lib/shared/embedded_names.dart",
-      category: "Internal",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
-  "_async_await_error_codes": const LibraryInfo(
-      "_internal/compiler/js_lib/shared/async_await_error_codes.dart",
-      category: "Internal",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-
-  "_metadata": const LibraryInfo(
-      "html/html_common/metadata.dart",
-      category: "Internal",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
-};
-
-/**
- * Information about a "dart:" library.
- */
-class LibraryInfo {
-
-  /**
-   * Path to the library's *.dart file relative to this file.
-   */
-  final String path;
-
-  /**
-   * The category in which the library should appear in the editor
-   * (e.g. "Shared", "Client", "Server", ...).
-   * If a category is not specified it defaults to "Shared".
-   */
-  final String category;
-
-  /**
-   * Path to the dart2js library's *.dart file relative to this file
-   * or null if dart2js uses the common library path defined above.
-   * Access using the [#getDart2JsPath()] method.
-   */
-  final String dart2jsPath;
-
-  /**
-   * Path to the dart2js library's patch file relative to this file
-   * or null if no dart2js patch file associated with this library.
-   * Access using the [#getDart2JsPatchPath()] method.
-   */
-  final String dart2jsPatchPath;
-
-  /**
-   * True if this library is documented and should be shown to the user.
-   */
-  final bool documented;
-
-  /**
-   * Bit flags indicating which platforms consume this library.
-   * See [DART2JS_LIBRARY] and [VM_LIBRARY].
-   */
-  final int platforms;
-
-  /**
-   * True if the library contains implementation details for another library.
-   * The implication is that these libraries are less commonly used
-   * and that tools like Dart Editor should not show these libraries
-   * in a list of all libraries unless the user specifically asks the tool to
-   * do so.
-   */
-  final bool implementation;
-
-  /**
-   * States the current maturity of this library.
-   */
-  final Maturity maturity;
-
-  const LibraryInfo(this.path, {
-                    this.category: "Shared",
-                    this.dart2jsPath,
-                    this.dart2jsPatchPath,
-                    this.implementation: false,
-                    this.documented: true,
-                    this.maturity: Maturity.UNSPECIFIED,
-                    this.platforms: DART2JS_PLATFORM | VM_PLATFORM});
-
-  bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0;
-  bool get isVmLibrary => (platforms & VM_PLATFORM) != 0;
-}
-
-
-
-/**
- * Abstraction to capture the maturity of a library.
- */
-class Maturity {
-  final int level;
-  final String name;
-  final String description;
-
-  const Maturity(this.level, this.name, this.description);
-
-  String toString() => "$name: $level\n$description\n";
-
-  static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
-    "This library will be remove before next major release.");
-
-  static const Maturity EXPERIMENTAL = const Maturity(1, "Experimental",
-    "This library is experimental and will likely change or be removed\n"
-    "in future versions.");
-
-  static const Maturity UNSTABLE = const Maturity(2, "Unstable",
-    "This library is in still changing and have not yet endured\n"
-    "sufficient real-world testing.\n"
-    "Backwards-compatibility is NOT guaranteed.");
-
-  static const Maturity WEB_STABLE = const Maturity(3, "Web Stable",
-    "This library is tracking the DOM evolution as defined by WC3.\n"
-    "Backwards-compatibility is NOT guaranteed.");
-
-  static const Maturity STABLE = const Maturity(4, "Stable",
-    "The library is stable. API backwards-compatibility is guaranteed.\n"
-    "However implementation details might change.");
-
-  static const Maturity LOCKED = const Maturity(5, "Locked",
-    "This library will not change except when serious bugs are encountered.");
-
-  static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
-    "The maturity for this library has not been specified.");
-}
+export 'sdk_library_metadata/lib/libraries.dart';
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
new file mode 100644
index 0000000..1a2e3eb
--- /dev/null
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -0,0 +1,340 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library libraries;
+
+/**
+ * A bit flag used by [LibraryInfo] indicating that a library is used by dart2js
+ */
+const int DART2JS_PLATFORM = 1;
+
+/**
+ * A bit flag used by [LibraryInfo] indicating that a library is used by the VM
+ */
+const int VM_PLATFORM = 2;
+
+/**
+ * Mapping of "dart:" library name (e.g. "core") to information about that library.
+ * This information is structured such that Dart Editor can parse this file
+ * and extract the necessary information without executing it
+ * while other tools can access via execution.
+ */
+const Map<String, LibraryInfo> LIBRARIES = const {
+
+  "async": const LibraryInfo(
+      "async/async.dart",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/async_patch.dart"),
+
+  "_blink": const LibraryInfo(
+      "_blink/dartium/_blink_dartium.dart",
+      category: "Client",
+      implementation: true,
+      documented: false,
+      platforms: VM_PLATFORM),
+
+  "_chrome": const LibraryInfo(
+      "_chrome/dart2js/chrome_dart2js.dart",
+      documented: false,
+      category: "Client"),
+
+  "collection": const LibraryInfo(
+      "collection/collection.dart",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/collection_patch.dart"),
+
+  "convert": const LibraryInfo(
+      "convert/convert.dart",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/convert_patch.dart"),
+
+  "core": const LibraryInfo(
+      "core/core.dart",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/core_patch.dart"),
+
+  "developer": const LibraryInfo(
+      "developer/developer.dart",
+      maturity: Maturity.UNSTABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/developer_patch.dart"),
+
+  "html": const LibraryInfo(
+      "html/dartium/html_dartium.dart",
+      category: "Client",
+      maturity: Maturity.WEB_STABLE,
+      dart2jsPath: "html/dart2js/html_dart2js.dart"),
+
+  "html_common": const LibraryInfo(
+      "html/html_common/html_common.dart",
+      category: "Client",
+      maturity: Maturity.WEB_STABLE,
+      dart2jsPath: "html/html_common/html_common_dart2js.dart",
+      documented: false,
+      implementation: true),
+
+  "indexed_db": const LibraryInfo(
+      "indexed_db/dartium/indexed_db_dartium.dart",
+      category: "Client",
+      maturity: Maturity.WEB_STABLE,
+      dart2jsPath: "indexed_db/dart2js/indexed_db_dart2js.dart"),
+
+  "io": const LibraryInfo(
+      "io/io.dart",
+      category: "Server",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/io_patch.dart"),
+
+  "isolate": const LibraryInfo(
+      "isolate/isolate.dart",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/isolate_patch.dart"),
+
+  "js": const LibraryInfo(
+      "js/dartium/js_dartium.dart",
+      category: "Client",
+      maturity: Maturity.STABLE,
+      dart2jsPath: "js/dart2js/js_dart2js.dart"),
+
+  "math": const LibraryInfo(
+      "math/math.dart",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/math_patch.dart"),
+
+  "mirrors": const LibraryInfo(
+      "mirrors/mirrors.dart",
+      maturity: Maturity.UNSTABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/mirrors_patch.dart"),
+
+  "profiler": const LibraryInfo(
+      "profiler/profiler.dart",
+      maturity: Maturity.UNSTABLE),
+
+  "nativewrappers": const LibraryInfo(
+      "html/dartium/nativewrappers.dart",
+      category: "Client",
+      implementation: true,
+      documented: false,
+      platforms: VM_PLATFORM),
+
+  "typed_data": const LibraryInfo(
+      "typed_data/typed_data.dart",
+      maturity: Maturity.STABLE,
+      dart2jsPatchPath: "_internal/js_runtime/lib/typed_data_patch.dart"),
+
+  "_native_typed_data": const LibraryInfo(
+      "_internal/js_runtime/lib/native_typed_data.dart",
+      category: "Internal",
+      implementation: true,
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  "svg": const LibraryInfo(
+      "svg/dartium/svg_dartium.dart",
+      category: "Client",
+      maturity: Maturity.WEB_STABLE,
+      dart2jsPath: "svg/dart2js/svg_dart2js.dart"),
+
+  "web_audio": const LibraryInfo(
+      "web_audio/dartium/web_audio_dartium.dart",
+      category: "Client",
+      maturity: Maturity.WEB_STABLE,
+      dart2jsPath: "web_audio/dart2js/web_audio_dart2js.dart"),
+
+  "web_gl": const LibraryInfo(
+      "web_gl/dartium/web_gl_dartium.dart",
+      category: "Client",
+      maturity: Maturity.WEB_STABLE,
+      dart2jsPath: "web_gl/dart2js/web_gl_dart2js.dart"),
+
+  "web_sql": const LibraryInfo(
+      "web_sql/dartium/web_sql_dartium.dart",
+      category: "Client",
+      maturity: Maturity.WEB_STABLE,
+      dart2jsPath: "web_sql/dart2js/web_sql_dart2js.dart"),
+
+  "_internal": const LibraryInfo(
+      "internal/internal.dart",
+      category: "Internal",
+      documented: false,
+      dart2jsPatchPath:
+          "_internal/js_runtime/lib/internal_patch.dart"),
+
+  "_js_helper": const LibraryInfo(
+      "_internal/js_runtime/lib/js_helper.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  "_interceptors": const LibraryInfo(
+      "_internal/js_runtime/lib/interceptors.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  "_foreign_helper": const LibraryInfo(
+      "_internal/js_runtime/lib/foreign_helper.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  "_isolate_helper": const LibraryInfo(
+      "_internal/js_runtime/lib/isolate_helper.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  "_js_mirrors": const LibraryInfo(
+      "_internal/js_runtime/lib/js_mirrors.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  "_js_names": const LibraryInfo(
+      "_internal/js_runtime/lib/js_names.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  "_js_primitives": const LibraryInfo(
+      "_internal/js_runtime/lib/js_primitives.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  // TODO(ahe): This library is only for dart2dart, perhaps it should use a
+  // different platform.
+  "_mirror_helper": const LibraryInfo(
+      "_internal/js_runtime/lib/mirror_helper.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  "_js_embedded_names": const LibraryInfo(
+      "_internal/js_runtime/lib/shared/embedded_names.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  "_async_await_error_codes": const LibraryInfo(
+      "_internal/js_runtime/lib/shared/async_await_error_codes.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  "_metadata": const LibraryInfo(
+      "html/html_common/metadata.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+};
+
+/**
+ * Information about a "dart:" library.
+ */
+class LibraryInfo {
+
+  /**
+   * Path to the library's *.dart file relative to this file.
+   */
+  final String path;
+
+  /**
+   * The category in which the library should appear in the editor
+   * (e.g. "Shared", "Client", "Server", ...).
+   * If a category is not specified it defaults to "Shared".
+   */
+  final String category;
+
+  /**
+   * Path to the dart2js library's *.dart file relative to this file
+   * or null if dart2js uses the common library path defined above.
+   * Access using the [#getDart2JsPath()] method.
+   */
+  final String dart2jsPath;
+
+  /**
+   * Path to the dart2js library's patch file relative to this file
+   * or null if no dart2js patch file associated with this library.
+   * Access using the [#getDart2JsPatchPath()] method.
+   */
+  final String dart2jsPatchPath;
+
+  /**
+   * True if this library is documented and should be shown to the user.
+   */
+  final bool documented;
+
+  /**
+   * Bit flags indicating which platforms consume this library.
+   * See [DART2JS_LIBRARY] and [VM_LIBRARY].
+   */
+  final int platforms;
+
+  /**
+   * True if the library contains implementation details for another library.
+   * The implication is that these libraries are less commonly used
+   * and that tools like Dart Editor should not show these libraries
+   * in a list of all libraries unless the user specifically asks the tool to
+   * do so.
+   */
+  final bool implementation;
+
+  /**
+   * States the current maturity of this library.
+   */
+  final Maturity maturity;
+
+  const LibraryInfo(this.path, {
+                    this.category: "Shared",
+                    this.dart2jsPath,
+                    this.dart2jsPatchPath,
+                    this.implementation: false,
+                    this.documented: true,
+                    this.maturity: Maturity.UNSPECIFIED,
+                    this.platforms: DART2JS_PLATFORM | VM_PLATFORM});
+
+  bool get isDart2jsLibrary => (platforms & DART2JS_PLATFORM) != 0;
+  bool get isVmLibrary => (platforms & VM_PLATFORM) != 0;
+}
+
+
+
+/**
+ * Abstraction to capture the maturity of a library.
+ */
+class Maturity {
+  final int level;
+  final String name;
+  final String description;
+
+  const Maturity(this.level, this.name, this.description);
+
+  String toString() => "$name: $level\n$description\n";
+
+  static const Maturity DEPRECATED = const Maturity(0, "Deprecated",
+    "This library will be remove before next major release.");
+
+  static const Maturity EXPERIMENTAL = const Maturity(1, "Experimental",
+    "This library is experimental and will likely change or be removed\n"
+    "in future versions.");
+
+  static const Maturity UNSTABLE = const Maturity(2, "Unstable",
+    "This library is in still changing and have not yet endured\n"
+    "sufficient real-world testing.\n"
+    "Backwards-compatibility is NOT guaranteed.");
+
+  static const Maturity WEB_STABLE = const Maturity(3, "Web Stable",
+    "This library is tracking the DOM evolution as defined by WC3.\n"
+    "Backwards-compatibility is NOT guaranteed.");
+
+  static const Maturity STABLE = const Maturity(4, "Stable",
+    "The library is stable. API backwards-compatibility is guaranteed.\n"
+    "However implementation details might change.");
+
+  static const Maturity LOCKED = const Maturity(5, "Locked",
+    "This library will not change except when serious bugs are encountered.");
+
+  static const Maturity UNSPECIFIED = const Maturity(-1, "Unspecified",
+    "The maturity for this library has not been specified.");
+}
diff --git a/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml b/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml
new file mode 100644
index 0000000..4d09374
--- /dev/null
+++ b/sdk/lib/_internal/sdk_library_metadata/pubspec.yaml
@@ -0,0 +1,4 @@
+# Note: This package is not meant to be uploaded to pub. This file is used to
+# make it easer to depend on libraries.dart from sdk packages like dart2js.
+name: sdk_library_metadata
+# version: do-not-upload
diff --git a/sdk/lib/core/core.dart b/sdk/lib/core/core.dart
index 4b11edc..a33c8fa 100644
--- a/sdk/lib/core/core.dart
+++ b/sdk/lib/core/core.dart
@@ -157,6 +157,7 @@
 import "dart:_internal" as internal show Symbol;
 import "dart:convert" show UTF8, LATIN1, Encoding;
 import "dart:math" show Random;  // Used by List.shuffle.
+import "dart:async" show Stream, Future;  // Used by Resource.
 
 part "annotations.dart";
 part "bool.dart";
@@ -181,6 +182,7 @@
 part "pattern.dart";
 part "print.dart";
 part "regexp.dart";
+part "resource.dart";
 part "set.dart";
 part "sink.dart";
 part "stacktrace.dart";
diff --git a/sdk/lib/core/core_sources.gypi b/sdk/lib/core/core_sources.gypi
index 2c12762..6cd311f 100644
--- a/sdk/lib/core/core_sources.gypi
+++ b/sdk/lib/core/core_sources.gypi
@@ -29,6 +29,7 @@
     'pattern.dart',
     'print.dart',
     'regexp.dart',
+    'resource.dart',
     'set.dart',
     'sink.dart',
     'stacktrace.dart',
diff --git a/sdk/lib/core/resource.dart b/sdk/lib/core/resource.dart
new file mode 100644
index 0000000..9bb88d1
--- /dev/null
+++ b/sdk/lib/core/resource.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart.core;
+
+/**
+ * A resource that can be read into the program.
+ *
+ * A resource is data that can be located using a URI and read into
+ * the program at runtime.
+ * The URI may use the `package` scheme to read resources provided
+ * along with package sources.
+ */
+abstract class Resource {
+  /**
+   * Creates a resource object with the given [uri] as location.
+   *
+   * The `uri` is a string containing a valid URI.
+   * If the string is not a valid URI, using any of the functions on
+   * the resource object will fail.
+   *
+   * The URI may be relative, in which case it will be resolved
+   * against [Uri.base] before being used.
+   *
+   * The URI may use the `package` scheme, which is always supported.
+   * Other schemes may also be supported where possible.
+   */
+  external const factory Resource(String uri);
+
+  /**
+   * The location `uri` of this resource.
+   *
+   * This is a [Uri] of the `uri` parameter given to the constructor.
+   * If the parameter was not a valid URI, reading `uri` may fail.
+   */
+  Uri get uri;
+
+  /** Read the resource content as a stream of bytes. */
+  Stream<List<int>> openRead();
+
+  /** Read the resource content. */
+  Future<List<int>> readAsBytes();
+
+  /**
+   * Read the resource content as a string.
+   *
+   * The content is decoded into a string using an [Encoding].
+   * If no other encoding is provided, it defaults to UTF-8.
+   */
+  Future<String> readAsString({Encoding encoding});
+}
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 1de3e1c..9e07f31 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -120,9 +120,9 @@
   '_DOMWindowCrossFrame': () => _DOMWindowCrossFrame,
   // FIXME: Move these to better locations.
   'DateTime': () => DateTime,
-  'JsObject': () => js.JsObject,
-  'JsFunction': () => js.JsFunction,
-  'JsArray': () => js.JsArray,
+  'JsObject': () => js.JsObjectImpl,
+  'JsFunction': () => js.JsFunctionImpl,
+  'JsArray': () => js.JsArrayImpl,
   'AbstractWorker': () => AbstractWorker,
   'Animation': () => Animation,
   'AnimationEffect': () => AnimationEffect,
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index e7f3004..0bb53c3 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -89,11 +89,388 @@
 
 import 'dart:collection' show ListMixin;
 import 'dart:nativewrappers';
+import 'dart:math' as math;
+import 'dart:mirrors' as mirrors;
+
+// Pretend we are always in checked mode as we aren't interested in users
+// running Dartium code outside of checked mode.
+final bool CHECK_JS_INVOCATIONS = true;
+
+final _allowedMethods = new Map<Symbol, _DeclarationSet>();
+final _allowedGetters = new Map<Symbol, _DeclarationSet>();
+final _allowedSetters = new Map<Symbol, _DeclarationSet>();
+
+final _jsInterfaceTypes = new Set<Type>();
+Iterable<Type> get jsInterfaceTypes => _jsInterfaceTypes;
+
+/// A collection of methods where all methods have the same name.
+/// This class is intended to optimize whether a specific invocation is
+/// appropritate for at least some of the methods in the collection.
+class _DeclarationSet {
+  _DeclarationSet() : _members = <mirrors.DeclarationMirror>[];
+
+  static bool _checkType(obj, mirrors.TypeMirror type) {
+    if (obj == null) return true;
+    return mirrors.reflectType(obj.runtimeType).isSubtypeOf(type);
+  }
+
+  /// Returns whether the return [value] has a type is consistent with the
+  /// return type from at least one of the members matching the DeclarationSet.
+  bool _checkReturnType(value) {
+    if (value == null) return true;
+    var valueMirror = mirrors.reflectType(value.runtimeType);
+    for (var member in _members) {
+      if (member is mirrors.VariableMirror || member.isGetter) {
+        // TODO(jacobr): actually check return types for getters that return
+        // function types.
+        return true;
+      } else {
+        if (valueMirror.isSubtypeOf(member.returnType)) return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Check whether the [invocation] is consistent with the [member] mirror.
+   */
+  bool _checkDeclaration(
+      Invocation invocation, mirrors.DeclarationMirror member) {
+    if (member is mirrors.VariableMirror || (member as dynamic).isGetter) {
+      // TODO(jacobr): actually check method types against the function type
+      // returned by the getter or field.
+      return true;
+    }
+    var parameters = (member as dynamic).parameters;
+    var positionalArguments = invocation.positionalArguments;
+    // Too many arguments
+    if (parameters.length < positionalArguments.length) return false;
+    // Too few required arguments.
+    if (parameters.length > positionalArguments.length &&
+        !parameters[positionalArguments.length].isOptional) return false;
+    for (var i = 0; i < positionalArguments.length; i++) {
+      if (parameters[i].isNamed) {
+        // Not enough positional arguments.
+        return false;
+      }
+      if (!_checkType(
+          invocation.positionalArguments[i], parameters[i].type)) return false;
+    }
+    if (invocation.namedArguments.isNotEmpty) {
+      var startNamed;
+      for (startNamed = parameters.length - 1; startNamed >= 0; startNamed--) {
+        if (!parameters[startNamed].isNamed) break;
+      }
+      startNamed++;
+
+      // TODO(jacobr): we are unneccessarily using an O(n^2) algorithm here.
+      // If we have JS APIs with a lange number of named parameters we should
+      // optimize this. Either use a HashSet or invert this, walking over
+      // parameters, querying invocation, and making sure we match
+      //invocation.namedArguments.size keys.
+      for (var name in invocation.namedArguments.keys) {
+        bool match = false;
+        for (var j = startNamed; j < parameters.length; j++) {
+          var p = parameters[j];
+          if (p.simpleName == name) {
+            if (!_checkType(invocation.namedArguments[name],
+                parameters[j].type)) return false;
+            match = true;
+            break;
+          }
+        }
+        if (match == false) return false;
+      }
+    }
+    return true;
+  }
+
+  bool checkInvocation(Invocation invocation) {
+    for (var member in _members) {
+      if (_checkDeclaration(invocation, member)) return true;
+    }
+    return false;
+  }
+
+  void add(mirrors.DeclarationMirror mirror) {
+    _members.add(mirror);
+  }
+
+  final List<mirrors.DeclarationMirror> _members;
+}
+
+/**
+ * Temporary method that we hope to remove at some point. This method should
+ * generally only be called by machine generated code.
+ */
+void registerJsInterfaces(List<Type> classes) {
+  if (_finalized == true) {
+    throw 'JSInterop class registration already finalized';
+  }
+  for (Type type in classes) {
+    if (!_jsInterfaceTypes.add(type)) continue; // Already registered.
+    mirrors.ClassMirror typeMirror = mirrors.reflectType(type);
+    typeMirror.declarations.forEach((symbol, declaration) {
+      if (declaration is mirrors.MethodMirror ||
+          declaration is mirrors.VariableMirror && !declaration.isStatic) {
+        bool treatAsGetter = false;
+        bool treatAsSetter = false;
+        if (declaration is mirrors.VariableMirror) {
+          treatAsGetter = true;
+          if (!declaration.isConst && !declaration.isFinal) {
+            treatAsSetter = true;
+          }
+        } else {
+          if (declaration.isGetter) {
+            treatAsGetter = true;
+          } else if (declaration.isSetter) {
+            treatAsSetter = true;
+          } else if (!declaration.isConstructor) {
+            _allowedMethods
+                .putIfAbsent(symbol, () => new _DeclarationSet())
+                .add(declaration);
+          }
+        }
+        if (treatAsGetter) {
+          _allowedGetters
+              .putIfAbsent(symbol, () => new _DeclarationSet())
+              .add(declaration);
+          _allowedMethods
+              .putIfAbsent(symbol, () => new _DeclarationSet())
+              .add(declaration);
+        }
+        if (treatAsSetter) {
+          _allowedSetters
+              .putIfAbsent(symbol, () => new _DeclarationSet())
+              .add(declaration);
+        }
+      }
+    });
+  }
+}
+
+_finalizeJsInterfaces() native "Js_finalizeJsInterfaces";
+
+/**
+ * Generates a part file defining source code for JsObjectImpl and related
+ * classes. This calass is needed so that type checks for all registered JavaScript
+ * interop classes pass.
+ */
+String _generateJsObjectImplPart() {
+  Iterable<Type> types = jsInterfaceTypes;
+  var libraryPrefixes = new Map<mirrors.LibraryMirror, String>();
+  var prefixNames = new Set<String>();
+  var sb = new StringBuffer();
+
+  var implements = <String>[];
+  for (var type in types) {
+    mirrors.ClassMirror typeMirror = mirrors.reflectType(type);
+    mirrors.LibraryMirror libraryMirror = typeMirror.owner;
+    var prefixName;
+    if (libraryPrefixes.containsKey(libraryMirror)) {
+      prefixName = libraryPrefixes[libraryMirror];
+    } else {
+      var basePrefixName =
+          mirrors.MirrorSystem.getName(libraryMirror.simpleName);
+      basePrefixName = basePrefixName.replaceAll('.', '_');
+      if (basePrefixName.isEmpty) basePrefixName = "lib";
+      prefixName = basePrefixName;
+      var i = 1;
+      while (prefixNames.contains(prefixName)) {
+        prefixName = '$basePrefixName$i';
+        i++;
+      }
+      prefixNames.add(prefixName);
+      libraryPrefixes[libraryMirror] = prefixName;
+    }
+    implements.add(
+        '${prefixName}.${mirrors.MirrorSystem.getName(typeMirror.simpleName)}');
+  }
+  libraryPrefixes.forEach((libraryMirror, prefix) {
+    sb.writeln('import "${libraryMirror.uri}" as $prefix;');
+  });
+  var implementsClause =
+      implements.isEmpty ? "" : "implements ${implements.join(', ')}";
+  // TODO(jacobr): only certain classes need to be implemented by
+  // Function and Array.
+  sb.write('''
+class JsObjectImpl extends JsObject $implementsClause {
+  JsObjectImpl.internal() : super.internal();
+}
+
+class JsFunctionImpl extends JsFunction $implementsClause {
+  JsFunctionImpl.internal() : super.internal();
+}
+
+class JsArrayImpl<E> extends JsArray<E> $implementsClause {
+  JsArrayImpl.internal() : super.internal();
+}
+''');
+  return sb.toString();
+}
+
+// Start of block of helper methods facilitating emulating JavaScript Array
+// methods on Dart List objects passed to JavaScript via JS interop.
+// TODO(jacobr): match JS more closely.
+String _toStringJs(obj) => '$obj';
+
+// TODO(jacobr): this might not exactly match JS semantics but should be
+// adequate for now.
+int _toIntJs(obj) {
+  if (obj is int) return obj;
+  if (obj is num) return obj.toInt();
+  return num.parse('$obj'.trim(), (_) => 0).toInt();
+}
+
+// TODO(jacobr): this might not exactly match JS semantics but should be
+// adequate for now.
+num _toNumJs(obj) {
+  return obj is num ? obj : num.parse('$obj'.trim(), (_) => 0);
+}
+
+/// Match the behavior of setting List length in JavaScript with the exception
+/// that Dart does not distinguish undefined and null.
+_setListLength(List list, rawlen) {
+  num len = _toNumJs(rawlen);
+  if (len is! int || len < 0) {
+    throw new RangeError("Invalid array length");
+  }
+  if (len > list.length) {
+    _arrayExtend(list, len);
+  } else if (len < list.length) {
+    list.removeRange(len, list.length);
+  }
+  return rawlen;
+}
+
+// TODO(jacobr): should we really bother with this method instead of just
+// shallow copying to a JS array and calling the JavaScript join method?
+String _arrayJoin(List list, sep) {
+  if (sep == null) {
+    sep = ",";
+  }
+  return list.map((e) => e == null ? "" : e.toString()).join(sep.toString());
+}
+
+// TODO(jacobr): should we really bother with this method instead of just
+// shallow copying to a JS array and using the toString method?
+String _arrayToString(List list) => _arrayJoin(list, ",");
+
+int _arrayPush(List list, List args) {
+  for(var e in args) {
+    list.add(e);
+  }
+  return list.length;
+}
+
+_arrayPop(List list) {
+  if (list.length > 0) return list.removeLast();
+}
+
+// TODO(jacobr): would it be better to just copy input to a JS List
+// and call Array.concat?
+List _arrayConcat(List input, List args) {
+  var ret = new List.from(input);
+  for (var e in args) {
+    // TODO(jacobr): technically in ES6 we should use
+    // Symbol.isConcatSpreadable to determine whether call addAll. Once v8
+    // supports it, we can make all Dart classes implementing Iterable
+    // specify isConcatSpreadable and tweak this behavior to allow Iterable.
+    if (e is List) {
+      ret.addAll(e);
+    } else {
+      ret.add(e);
+    }
+  }
+  return ret;
+}
+
+List _arraySplice(List input, List args) {
+  int start = 0;
+  if (args.length > 0) {
+    var rawStart = _toIntJs(args[0]);
+    if (rawStart < 0) {
+      start = math.max(0, input.length - rawStart);
+    } else {
+      start = math.min(input.length, rawStart);
+    }
+  }
+  var end = start;
+  if (args.length > 1) {
+    var rawDeleteCount = _toIntJs(args[1]);
+    if (rawDeleteCount < 0) rawDeleteCount = 0;
+    end = math.min(input.length, start + rawDeleteCount);
+  }
+  var replacement = [];
+  var removedElements = input.getRange(start, end).toList();
+  if (args.length > 2) {
+    replacement = args.getRange(2, args.length);
+  }
+  input.replaceRange(start, end, replacement);
+  return removedElements;
+}
+
+List _arrayReverse(List l) {
+  for (var i = 0, j = l.length - 1; i < j; i++, j--) {
+    var tmp = l[i];
+    l[i] = l[j];
+    l[j] = tmp;
+  }
+  return l;
+}
+
+_arrayShift(List l) {
+  if (l.isEmpty) return null; // Technically we should return undefined.
+  return l.removeAt(0);
+}
+
+int _arrayUnshift(List l, List args) {
+  l.insertAll(0, args);
+  return l.length;
+}
+
+_arrayExtend(List l, int newLength) {
+  for (var i = l.length; i < newLength; i++) {
+    // TODO(jacobr): we'd really like to add undefined to better match
+    // JavaScript semantics.
+    l.add(null);
+  }
+}
+
+List _arraySort(List l, rawCompare) {
+  // TODO(jacobr): alternately we could just copy the Array to JavaScript,
+  // invoke the JS sort method and then copy the result back to Dart.
+  Comparator compare;
+  if (rawCompare == null) {
+    compare = (a, b) => _toStringJs(a).compareTo(_toStringJs(b));
+  } else if (rawCompare is JsFunction) {
+    compare = (a, b) => rawCompare.apply([a, b]);
+  } else {
+    compare = rawCompare;
+  }
+  l.sort(compare);
+  return l;
+}
+// End of block of helper methods to emulate JavaScript Array methods on Dart List.
+
+/**
+ * Can be called to provide a predictable point where no more JS interfaces can
+ * be added. Creating an instance of JsObject will also automatically trigger
+ * all JsObjects to be finalized.
+ */
+void finalizeJsInterfaces() {
+  if (_finalized == true) {
+    throw 'JSInterop class registration already finalized';
+  }
+  _finalizeJsInterfaces();
+}
 
 JsObject _cachedContext;
 
 JsObject get _context native "Js_context_Callback";
 
+bool get _finalized native "Js_interfacesFinalized_Callback";
+
 JsObject get context {
   if (_cachedContext == null) {
     _cachedContext = _context;
@@ -114,9 +491,24 @@
    * Constructs a new JavaScript object from [constructor] and returns a proxy
    * to it.
    */
-  factory JsObject(JsFunction constructor, [List arguments]) => _create(constructor, arguments);
+  factory JsObject(JsFunction constructor, [List arguments]) =>
+      _create(constructor, arguments);
 
-  static JsObject _create(JsFunction constructor, arguments) native "JsObject_constructorCallback";
+  static JsObject _create(
+      JsFunction constructor, arguments) native "JsObject_constructorCallback";
+
+  _buildArgs(Invocation invocation) {
+    if (invocation.namedArguments.isEmpty) {
+      return invocation.positionalArguments;
+    } else {
+      var varArgs = new Map<String, Object>();
+      invocation.namedArguments.forEach((symbol, val) {
+        varArgs[mirrors.MirrorSystem.getName(symbol)] = val;
+      });
+      return invocation.positionalArguments.toList()
+        ..add(new JsObject.jsify(varArgs));
+    }
+  }
 
   /**
    * Constructs a [JsObject] that proxies a native Dart object; _for expert use
@@ -131,8 +523,7 @@
    */
   factory JsObject.fromBrowserObject(object) {
     if (object is num || object is String || object is bool || object == null) {
-      throw new ArgumentError(
-        "object cannot be a num, string, bool, or null");
+      throw new ArgumentError("object cannot be a num, string, bool, or null");
     }
     return _fromBrowserObject(object);
   }
@@ -155,7 +546,8 @@
 
   static JsObject _jsify(object) native "JsObject_jsify";
 
-  static JsObject _fromBrowserObject(object) native "JsObject_fromBrowserObject";
+  static JsObject _fromBrowserObject(
+      object) native "JsObject_fromBrowserObject";
 
   /**
    * Returns the value associated with [property] from the proxied JavaScript
@@ -163,7 +555,7 @@
    *
    * The type of [property] must be either [String] or [num].
    */
-  operator[](property) native "JsObject_[]";
+  operator [](property) native "JsObject_[]";
 
   /**
    * Sets the value associated with [property] on the proxied JavaScript
@@ -171,13 +563,14 @@
    *
    * The type of [property] must be either [String] or [num].
    */
-  operator[]=(property, value) native "JsObject_[]=";
+  operator []=(property, value) native "JsObject_[]=";
 
   int get hashCode native "JsObject_hashCode";
 
-  operator==(other) => other is JsObject && _identityEquality(this, other);
+  operator ==(other) => other is JsObject && _identityEquality(this, other);
 
-  static bool _identityEquality(JsObject a, JsObject b) native "JsObject_identityEquality";
+  static bool _identityEquality(
+      JsObject a, JsObject b) native "JsObject_identityEquality";
 
   /**
    * Returns `true` if the JavaScript object contains the specified property
@@ -207,7 +600,7 @@
   String toString() {
     try {
       return _toString();
-    } catch(e) {
+    } catch (e) {
       return super.toString();
     }
   }
@@ -223,7 +616,7 @@
   callMethod(String method, [List args]) {
     try {
       return _callMethod(method, args);
-    } catch(e) {
+    } catch (e) {
       if (hasProperty(method)) {
         rethrow;
       } else {
@@ -232,13 +625,63 @@
     }
   }
 
+  noSuchMethod(Invocation invocation) {
+    throwError() {
+      throw new NoSuchMethodError(this, invocation.memberName,
+          invocation.positionalArguments, invocation.namedArguments);
+    }
+
+    String name = mirrors.MirrorSystem.getName(invocation.memberName);
+    if (invocation.isGetter) {
+      if (CHECK_JS_INVOCATIONS) {
+        var matches = _allowedGetters[invocation.memberName];
+        if (matches == null &&
+            !_allowedMethods.containsKey(invocation.memberName)) {
+          throwError();
+        }
+        var ret = this[name];
+        if (matches != null && matches._checkReturnType(ret)) return ret;
+        if (ret is Function ||
+            (ret is JsFunction /* shouldn't be needed in the future*/) &&
+                _allowedMethods.containsKey(
+                    invocation.memberName)) return ret; // Warning: we have not bound "this"... we could type check on the Function but that is of little value in Dart.
+        throwError();
+      } else {
+        // TODO(jacobr): should we throw if the JavaScript object doesn't have the property?
+        return this[name];
+      }
+    } else if (invocation.isSetter) {
+      if (CHECK_JS_INVOCATIONS) {
+        var matches = _allowedSetters[invocation.memberName];
+        if (matches == null ||
+            !matches.checkInvocation(invocation)) throwError();
+      }
+      assert(name.endsWith("="));
+      name = name.substring(0, name.length - 1);
+      return this[name] = invocation.positionalArguments.first;
+    } else {
+      // TODO(jacobr): also allow calling getters that look like functions.
+      var matches;
+      if (CHECK_JS_INVOCATIONS) {
+        matches = _allowedMethods[invocation.memberName];
+        if (matches == null ||
+            !matches.checkInvocation(invocation)) throwError();
+      }
+      var ret = this.callMethod(name, _buildArgs(invocation));
+      if (CHECK_JS_INVOCATIONS) {
+        if (!matches._checkReturnType(ret)) throwError();
+      }
+      return ret;
+    }
+  }
+
   _callMethod(String name, List args) native "JsObject_callMethod";
 }
 
 /**
  * Proxies a JavaScript Function object.
  */
-class JsFunction extends JsObject {
+class JsFunction extends JsObject implements Function {
   JsFunction.internal() : super.internal();
 
   /**
@@ -253,13 +696,21 @@
    */
   dynamic apply(List args, {thisArg}) native "JsFunction_apply";
 
+  noSuchMethod(Invocation invocation) {
+    if (invocation.isMethod && invocation.memberName == #call) {
+      return apply(_buildArgs(invocation));
+    }
+    return super.noSuchMethod(invocation);
+  }
+
   /**
    * Internal only version of apply which uses debugger proxies of Dart objects
    * rather than opaque handles. This method is private because it cannot be
    * efficiently implemented in Dart2Js so should only be used by internal
    * tools.
    */
-  _applyDebuggerOnly(List args, {thisArg}) native "JsFunction_applyDebuggerOnly";
+  _applyDebuggerOnly(List args,
+      {thisArg}) native "JsFunction_applyDebuggerOnly";
 
   static JsFunction _withThis(Function f) native "JsFunction_withThis";
 }
@@ -268,14 +719,17 @@
  * A [List] proxying a JavaScript Array.
  */
 class JsArray<E> extends JsObject with ListMixin<E> {
+  JsArray.internal() : super.internal();
 
   factory JsArray() => _newJsArray();
 
   static JsArray _newJsArray() native "JsArray_newJsArray";
 
-  factory JsArray.from(Iterable<E> other) => _newJsArrayFromSafeList(new List.from(other));
+  factory JsArray.from(Iterable<E> other) =>
+      _newJsArrayFromSafeList(new List.from(other));
 
-  static JsArray _newJsArrayFromSafeList(List list) native "JsArray_newJsArrayFromSafeList";
+  static JsArray _newJsArrayFromSafeList(
+      List list) native "JsArray_newJsArrayFromSafeList";
 
   _checkIndex(int index, {bool insert: false}) {
     int length = insert ? this.length + 1 : this.length;
@@ -304,7 +758,7 @@
   }
 
   void operator []=(index, E value) {
-    if(index is int) {
+    if (index is int) {
       _checkIndex(index);
     }
     super[index] = value;
@@ -312,7 +766,9 @@
 
   int get length native "JsArray_length";
 
-  void set length(int length) { super['length'] = length; }
+  void set length(int length) {
+    super['length'] = length;
+  }
 
   // Methods overriden for better performance
 
@@ -326,7 +782,7 @@
   }
 
   void insert(int index, E element) {
-    _checkIndex(index, insert:true);
+    _checkIndex(index, insert: true);
     callMethod('splice', [index, 0, element]);
   }
 
@@ -365,7 +821,7 @@
  */
 const _UNDEFINED = const Object();
 
-// FIXME(jacobr): this method is a hack to work around the lack of proper dart
+// TODO(jacobr): this method is a hack to work around the lack of proper dart
 // support for varargs methods.
 List _stripUndefinedArgs(List args) =>
     args.takeWhile((i) => i != _UNDEFINED).toList();
@@ -375,8 +831,7 @@
  * than 11) of arguments without violating Dart type checks.
  */
 Function _wrapAsDebuggerVarArgsFunction(JsFunction jsFunction) =>
-  ([a1=_UNDEFINED, a2=_UNDEFINED, a3=_UNDEFINED, a4=_UNDEFINED,
-    a5=_UNDEFINED, a6=_UNDEFINED, a7=_UNDEFINED, a8=_UNDEFINED,
-    a9=_UNDEFINED, a10=_UNDEFINED]) =>
-    jsFunction._applyDebuggerOnly(_stripUndefinedArgs(
-        [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10]));
+    ([a1 = _UNDEFINED, a2 = _UNDEFINED, a3 = _UNDEFINED, a4 = _UNDEFINED,
+        a5 = _UNDEFINED, a6 = _UNDEFINED, a7 = _UNDEFINED, a8 = _UNDEFINED,
+        a9 = _UNDEFINED, a10 = _UNDEFINED]) => jsFunction._applyDebuggerOnly(
+            _stripUndefinedArgs([a1, a2, a3, a4, a5, a6, a7, a8, a9, a10]));
diff --git a/tests/benchmark_smoke/benchmark_smoke.status b/tests/benchmark_smoke/benchmark_smoke.status
index 7eef00b..fea516e0 100644
--- a/tests/benchmark_smoke/benchmark_smoke.status
+++ b/tests/benchmark_smoke/benchmark_smoke.status
@@ -9,4 +9,3 @@
 *: Fail, Pass # TODO(ahe): Triage these tests.
 
 [ $compiler == dart2js && $cps_ir ]
-benchmark_smoke_test: Crash # Invalid argument(s)
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 4a74533..de69117 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -9602,13 +9602,9 @@
 WebPlatformTest/webstorage/storage_session_setitem_t01: RuntimeError # Please triage this failure
 
 [ $compiler == dart2js && $cps_ir ]
-Language/07_Classes/6_Constructors/1_Generative_Constructors_A02_t01: RuntimeError # Please triage this failure.
 Language/12_Expressions/05_Strings/1_String_Interpolation_A01_t12: RuntimeError # Cannot read property 'prototype' of undefined
 Language/12_Expressions/05_Strings/1_String_Interpolation_A02_t02: RuntimeError # Cannot read property 'prototype' of undefined
 Language/12_Expressions/12_Instance_Creation/1_New_A06_t12: RuntimeError # Please triage this failure.
-Language/12_Expressions/12_Instance_Creation/1_New_A08_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/12_Instance_Creation/1_New_A08_t02: RuntimeError # Please triage this failure.
-Language/12_Expressions/12_Instance_Creation/1_New_A08_t03: RuntimeError # Please triage this failure.
 Language/12_Expressions/13_Property_Extraction_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
 Language/12_Expressions/13_Property_Extraction_A01_t02: RuntimeError # Cannot read property 'prototype' of undefined
 Language/12_Expressions/13_Property_Extraction_A01_t03: RuntimeError # Cannot read property 'prototype' of undefined
@@ -9616,43 +9612,19 @@
 Language/12_Expressions/13_Property_Extraction_A03_t02: RuntimeError # Cannot read property 'call' of undefined
 Language/12_Expressions/13_Property_Extraction_A03_t03: RuntimeError # Cannot read property 'call' of undefined
 Language/12_Expressions/13_Spawning_an_Isolate_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
-Language/12_Expressions/14_Function_Invocation/4_Function_Expression_Invocation_A01_t02: RuntimeError # Please triage this failure.
 Language/12_Expressions/15_Method_Invocation/1_Ordinary_Invocation_A05_t04: RuntimeError # Cannot read property 'prototype' of undefined
 Language/12_Expressions/15_Method_Invocation/3_Static_Invocation_A04_t05: RuntimeError # Cannot read property 'prototype' of undefined
 Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A01_t01: RuntimeError # Cannot read property 'call' of undefined
 Language/12_Expressions/15_Method_Invocation/4_Super_Invocation_A03_t04: RuntimeError # Cannot read property 'prototype' of undefined
-Language/12_Expressions/18_Assignment_A05_t02: RuntimeError # Please triage this failure.
-Language/12_Expressions/18_Assignment_A05_t05: RuntimeError # Please triage this failure.
-Language/12_Expressions/26_Multiplicative_Expressions_A02_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/26_Multiplicative_Expressions_A03_t01: RuntimeError # Please triage this failure.
-Language/12_Expressions/28_Postfix_Expressions_A05_t02: RuntimeError # Please triage this failure.
-Language/12_Expressions/28_Postfix_Expressions_A09_t02: RuntimeError # Please triage this failure.
 Language/12_Expressions/29_Assignable_Expressions_A01_t08: RuntimeError # receiver.get$_first is not a function
 Language/12_Expressions/30_Identifier_Reference_A09_t03: Crash # (i=0): For-loop variable captured in loop header
-Language/12_Expressions/30_Identifier_Reference_A09_t04: RuntimeError # Please triage this failure.
 Language/12_Expressions/30_Identifier_Reference_A10_t01: RuntimeError # Cannot read property 'prototype' of undefined
 Language/12_Expressions/30_Identifier_Reference_A10_t02: RuntimeError # Cannot read property 'prototype' of undefined
 Language/13_Statements/02_Expression_Statements_A01_t06: RuntimeError # Cannot read property 'prototype' of undefined
-Language/13_Statements/06_For/1_For_Loop_A01_t09: RuntimeError # Please triage this failure.
 Language/13_Statements/06_For_A01_t07: Crash # unsupported operation on erroneous element
 Language/13_Statements/12_Labels_A03_t04: Crash # (switch (i){L:case 0:flag=true;break;case 2:continue L;}): continue to a labeled switch case
-Language/13_Statements/13_Break_A03_t01: RuntimeError # Issue 23708.
-Language/13_Statements/13_Break_A03_t03: RuntimeError # Issue 23708.
-Language/13_Statements/13_Break_A03_t04: RuntimeError # Please triage this failure.
-Language/13_Statements/13_Break_A03_t06: RuntimeError # Issue 23708.
-Language/13_Statements/13_Break_A03_t07: RuntimeError # Please triage this failure.
-Language/13_Statements/13_Break_A03_t08: RuntimeError # Please triage this failure.
-Language/13_Statements/13_Break_A03_t09: RuntimeError # Issue 23708.
 Language/13_Statements/14_Continue_A02_t12: Crash # (switch (2){L:case 1:flag=true;break;case 2:continue L;}): continue to a labeled switch case
 Language/13_Statements/14_Continue_A02_t13: Crash # (switch (2){case 2:continue L;L:case 1:flag=true;}): continue to a labeled switch case
-Language/13_Statements/14_Continue_A03_t01: RuntimeError # Issue 23708.
-Language/13_Statements/14_Continue_A03_t02: RuntimeError # Please triage this failure.
-Language/13_Statements/14_Continue_A03_t03: RuntimeError # Please triage this failure.
-Language/13_Statements/14_Continue_A03_t04: RuntimeError # Issue 23708.
-Language/13_Statements/14_Continue_A03_t05: RuntimeError # Please triage this failure.
-Language/13_Statements/14_Continue_A03_t06: RuntimeError # Issue 23708.
-Language/13_Statements/14_Continue_A03_t07: RuntimeError # Issue 23708.
-Language/14_Libraries_and_Scripts/1_Imports_A02_t06: RuntimeError # Please triage this failure.
 Language/14_Libraries_and_Scripts/4_Scripts_A03_t03: RuntimeError # receiver.get$_collection$_nums is not a function
 Language/15_Types/3_Type_Declarations/1_Typedef_A02_t01: RuntimeError # Cannot read property 'prototype' of undefined
 Language/15_Types/3_Type_Declarations/1_Typedef_A02_t02: RuntimeError # Cannot read property 'prototype' of undefined
@@ -9689,12 +9661,6 @@
 Language/15_Types/5_Function_Types_A05_t02: RuntimeError # Cannot read property 'prototype' of undefined
 Language/15_Types/5_Function_Types_A05_t05: RuntimeError # Cannot read property 'prototype' of undefined
 Language/15_Types/5_Function_Types_A06_t01: RuntimeError # Cannot read property 'prototype' of undefined
-Language/16_Reference/1_Lexical_Rules/2_Comments_A02_t10: RuntimeError # Please triage this failure.
-LayoutTests/fast/canvas/webgl/compressed-tex-image_t01: Crash # Invalid argument(s)
-LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: Crash # Invalid argument(s)
-LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Crash # Internal Error: No default constructor available.
-LayoutTests/fast/forms/date/date-interactive-validation-required_t01: Crash # Invalid argument(s)
-LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Crash # Invalid argument(s)
 LibTest/async/Completer/Completer.sync_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/async/Completer/completeError_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/async/Completer/completeError_A01_t02: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -9777,7 +9743,7 @@
 LibTest/async/Stream/Stream.fromIterable_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/async/Stream/Stream.fromIterable_A01_t02: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/async/Stream/Stream.fromIterable_A02_t01: RuntimeError # receiver.get$_collection$_nums is not a function
-LibTest/async/Stream/Stream.periodic_A01_t01: Crash # Invalid argument(s)
+LibTest/async/Stream/Stream.periodic_A01_t01 : RuntimeError # TypeError: receiver.get$_nums is not a function
 LibTest/async/Stream/Stream.periodic_A02_t01: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/async/Stream/Stream.periodic_A03_t01: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/async/Stream/Stream_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -9800,7 +9766,7 @@
 LibTest/async/Stream/distinct_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/async/Stream/distinct_A01_t02: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/async/Stream/drain_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
-LibTest/async/Stream/drain_A02_t01: Crash # Invalid argument(s)
+LibTest/async/Stream/drain_A02_t01 : RuntimeError # TypeError: receiver.get$_nums is not a function
 LibTest/async/Stream/drain_A02_t02: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/async/Stream/elementAt_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/async/Stream/elementAt_A01_t02: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -9977,94 +9943,29 @@
 LibTest/async/Zone/run_A01_t01: RuntimeError # receiver.get$_nums is not a function
 LibTest/async/Zone/scheduleMicrotask_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/async/Zone/scheduleMicrotask_A01_t02: RuntimeError # receiver.get$_nums is not a function
-LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/every_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/expand_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/forEachEntry_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/forEach_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/iterator_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/join_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/map_A03_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/remove_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/skipWhile_A03_t01: RuntimeError # Please triage this failure.
-LibTest/collection/DoubleLinkedQueue/toList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/HashMap/allTests_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/HashSet/HashSet.from_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/HashSet/HashSet_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/IterableBase/IterableBase_class_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedHashMap/LinkedHashMap_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/addAll_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/expand_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/expand_A02_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/forEach_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/map_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/map_A02_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/map_A03_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/single_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/skipWhile_A03_t01: RuntimeError # Please triage this failure.
-LibTest/collection/LinkedList/toList_A01_t02: RuntimeError # Please triage this failure.
 LibTest/collection/ListBase/ListBase_class_A01_t02: Crash # Stack Overflow
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Crash # Stack Overflow
-LibTest/collection/ListQueue/ListQueue.from_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/ListQueue/ListQueue.from_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/ListQueue/ListQueue_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/Maps/forEach_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/Maps/mapToString_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/Queue/Queue.from_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/Queue/Queue.from_A01_t02: RuntimeError # Please triage this failure.
-LibTest/collection/Queue/Queue_class_A01_t01: RuntimeError # Please triage this failure.
-LibTest/collection/SplayTreeMap/allTests_A01_t01: RuntimeError # Please triage this failure.
-LibTest/convert/JsonCodec/JsonCodec.withReviver_A01_t01: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonCodec/JsonCodec_A01_t01: Crash # Internal Error: No default constructor available.
 LibTest/convert/JsonCodec/encode_A01_t01: Crash # Internal Error: No default constructor available.
 LibTest/convert/JsonCodec/encode_A01_t02: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonCodec/encode_A02_t01: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonCodec/encode_A02_t02: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonCodec/encode_A02_t03: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonCodec/encode_A03_t01: Crash # Internal Error: No default constructor available.
 LibTest/convert/JsonDecoder/fuse_A01_t01: Crash # Internal Error: No default constructor available.
 LibTest/convert/JsonEncoder/convert_A01_t01: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonEncoder/convert_A02_t01: Crash # Internal Error: No default constructor available.
-LibTest/convert/JsonEncoder/fuse_A01_t01: Crash # Internal Error: No default constructor available.
 LibTest/core/DateTime/parse_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
 LibTest/core/DateTime/parse_A01_t02: RuntimeError # Cannot read property 'prototype' of undefined
 LibTest/core/DateTime/parse_A03_t01: Pass # Please triage this failure.
 LibTest/core/DateTime/timeZoneName_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
-LibTest/core/Function/apply_A01_t01: RuntimeError # Please triage this failure.
 LibTest/core/Invocation/isAccessor_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
-LibTest/core/Invocation/isGetter_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Invocation/isGetter_A01_t02: RuntimeError # Please triage this failure.
+LibTest/core/Invocation/isGetter_A01_t01 : RuntimeError # 
+LibTest/core/Invocation/isGetter_A01_t02 : RuntimeError # 
 LibTest/core/Invocation/isMethod_A01_t02: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
 LibTest/core/Invocation/isSetter_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
-LibTest/core/Invocation/isSetter_A01_t02: RuntimeError # Please triage this failure.
+LibTest/core/Invocation/isSetter_A01_t02 : RuntimeError # 
 LibTest/core/Invocation/memberName_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
-LibTest/core/Invocation/positionalArguments_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/List/List.from_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/List/List.from_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/List/List.generate_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/List/List.generate_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/List/List.generate_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/List/List_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/List/List_A01_t02: RuntimeError # Please triage this failure.
-LibTest/core/List/List_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/List/List_A03_t01: RuntimeError # Please triage this failure.
+LibTest/core/Invocation/positionalArguments_A01_t01 : RuntimeError # 
 LibTest/core/List/List_class_A01_t02: Crash # Stack Overflow
-LibTest/core/Map/allTests_A01_t01: RuntimeError # Please triage this failure.
 LibTest/core/Match/end_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
 LibTest/core/Match/groupCount_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
-LibTest/core/Match/groups_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Match/groups_A02_t01: RuntimeError # Please triage this failure.
 LibTest/core/NoSuchMethodError/toString_A01_t01: RuntimeError # receiver.get$_first is not a function
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A03_t02: RuntimeError # Please triage this failure.
 LibTest/core/RegExp/stringMatch_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
-LibTest/core/Runes/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/core/Set/IterableBase_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Set/Set.from_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Set/forEach_A01_t01: RuntimeError # Please triage this failure.
 LibTest/core/Stopwatch/Stopwatch_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
 LibTest/core/Stopwatch/elapsedInMs_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/core/Stopwatch/elapsedInUs_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -10081,44 +9982,6 @@
 LibTest/core/Stopwatch/stop_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Please triage this failure.
 LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Please triage this failure.
-LibTest/core/Uri/Uri.http_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/Uri.https_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/Uri_A03_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/authority_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/decodeComponent_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/decodeFull_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/decodeQueryComponent_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/decodeQueryComponent_A02_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/hasAuthority_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/host_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/isAbsolute_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/operator_eq_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/origin_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/parse_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/parse_A02_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/parse_A03_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/pathSegments_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/pathSegments_A01_t02: Crash # Invalid argument(s)
-LibTest/core/Uri/pathSegments_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/Uri/pathSegments_A02_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/path_A02_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/port_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/queryParameters_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/queryParameters_A01_t02: Crash # Invalid argument(s)
-LibTest/core/Uri/queryParameters_A01_t03: Crash # Invalid argument(s)
-LibTest/core/Uri/query_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/query_A01_t02: Crash # Invalid argument(s)
-LibTest/core/Uri/resolveUri_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/resolve_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/scheme_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/splitQueryString_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Uri/toFilePath_A01_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/toFilePath_A01_t02: Crash # Invalid argument(s)
-LibTest/core/Uri/toFilePath_A01_t03: Crash # Invalid argument(s)
-LibTest/core/Uri/toFilePath_A02_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/toFilePath_A03_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/toFilePath_A04_t01: Crash # Invalid argument(s)
-LibTest/core/Uri/userInfo_A01_t01: Crash # Invalid argument(s)
 LibTest/core/double/INFINITY_A01_t04: Pass # Please triage this failure.
 LibTest/core/double/NEGATIVE_INFINITY_A01_t04: Pass # Please triage this failure.
 LibTest/core/int/parse_A01_t01: RuntimeError # Cannot read property 'prototype' of undefined
@@ -10156,7 +10019,7 @@
 LibTest/isolate/ReceivePort/contains_A01_t01: RuntimeError # receiver.get$_nums is not a function
 LibTest/isolate/ReceivePort/distinct_A01_t01: RuntimeError # receiver.get$_nums is not a function
 LibTest/isolate/ReceivePort/distinct_A01_t02: RuntimeError # receiver.get$_nums is not a function
-LibTest/isolate/ReceivePort/drain_A02_t01: Crash # Invalid argument(s)
+LibTest/isolate/ReceivePort/drain_A02_t01 : RuntimeError # TypeError: receiver.get$_nums is not a function
 LibTest/isolate/ReceivePort/drain_A02_t02: RuntimeError # receiver.get$_nums is not a function
 LibTest/isolate/ReceivePort/elementAt_A01_t01: RuntimeError # receiver.get$_nums is not a function
 LibTest/isolate/ReceivePort/elementAt_A03_t01: RuntimeError # receiver.get$_nums is not a function
@@ -10208,130 +10071,31 @@
 LibTest/isolate/SendPort/operator_equality_A01_t01: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/isolate/SendPort/send_A01_t04: RuntimeError # receiver.get$_collection$_nums is not a function
 LibTest/isolate/SendPort/send_A02_t01: RuntimeError # receiver.get$_collection$_nums is not a function
-LibTest/math/atan2_A01_t01: RuntimeError # Please triage this failure.
-LibTest/math/exp_A01_t01: RuntimeError # Please triage this failure.
-LibTest/math/log_A01_t01: RuntimeError # Please triage this failure.
-LibTest/math/pow_A01_t01: RuntimeError # Please triage this failure.
-LibTest/math/sin_A01_t01: RuntimeError # Please triage this failure.
-LibTest/math/sqrt_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/reversed_A01_t02: RuntimeError # Please triage this failure.
 LibTest/typed_data/Float32List/setAll_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Float32List/setRange_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Float32List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Float32List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/reversed_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float32x4List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/reversed_A01_t02: RuntimeError # Please triage this failure.
 LibTest/typed_data/Float64List/setAll_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Float64List/setRange_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Float64List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Float64List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Float64List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/reversed_A01_t02: RuntimeError # Please triage this failure.
 LibTest/typed_data/Int16List/setAll_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Int16List/setRange_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Int16List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Int16List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int16List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/Int32List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/reversed_A01_t02: RuntimeError # Please triage this failure.
 LibTest/typed_data/Int32List/setAll_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Int32List/setRange_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Int32List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Int32List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int32List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/Int8List.fromList_A01_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/reversed_A01_t02: RuntimeError # Please triage this failure.
 LibTest/typed_data/Int8List/setAll_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Int8List/setRange_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Int8List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Int8List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Int8List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/reversed_A01_t02: RuntimeError # Please triage this failure.
 LibTest/typed_data/Uint16List/setAll_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Uint16List/setRange_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Uint16List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Uint16List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint16List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/reversed_A01_t02: RuntimeError # Please triage this failure.
 LibTest/typed_data/Uint32List/setAll_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Uint32List/setRange_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Uint32List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Uint32List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint32List/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/reversed_A01_t02: RuntimeError # Please triage this failure.
 LibTest/typed_data/Uint8ClampedList/setAll_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Uint8ClampedList/setRange_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Uint8ClampedList/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Uint8ClampedList/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8ClampedList/toList_A02_t02: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/iterator_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/iterator_current_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/operator_subscript_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/operator_subscript_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/reversed_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/reversed_A01_t02: RuntimeError # Please triage this failure.
 LibTest/typed_data/Uint8List/setAll_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Uint8List/setRange_A01_t01: RuntimeError # this.get$length is not a function
 LibTest/typed_data/Uint8List/setRange_A02_t01: RuntimeError # this.get$length is not a function
-LibTest/typed_data/Uint8List/toList_A01_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/toList_A02_t01: RuntimeError # Please triage this failure.
-LibTest/typed_data/Uint8List/toList_A02_t02: RuntimeError # Please triage this failure.
-Utils/tests/Expect/setEquals_A01_t01: RuntimeError # Please triage this failure.
-Utils/tests/Expect/setEquals_A01_t02: RuntimeError # Please triage this failure.
+LibTest/core/Invocation/namedArguments_A01_t01 : RuntimeError # 
diff --git a/tests/compiler/dart2js/analyze_api_test.dart b/tests/compiler/dart2js/analyze_api_test.dart
index de48a2e..faeebaa 100644
--- a/tests/compiler/dart2js/analyze_api_test.dart
+++ b/tests/compiler/dart2js/analyze_api_test.dart
@@ -4,7 +4,7 @@
 
 library analyze_api;
 
-import '../../../sdk/lib/_internal/libraries.dart';
+import 'package:sdk_library_metadata/libraries.dart';
 import 'analyze_helper.dart';
 import "package:async_helper/async_helper.dart";
 
diff --git a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
index e5c9deb..07f049c 100644
--- a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
+++ b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
@@ -26,7 +26,7 @@
 
   // Uncalled methods in SemanticSendVisitor and subclasses.
   "lib/src/resolution/semantic_visitor.dart": const [
-      "The method 'error", "The method 'visit"],
+      "The method 'error"],
   "lib/src/resolution/semantic_visitor_mixins.dart": const [
       "The class 'Base", "The method 'error", "The method 'visit"],
 
diff --git a/tests/compiler/dart2js/async_await_syntax_test.dart b/tests/compiler/dart2js/async_await_syntax_test.dart
index 336a7cd..fd21a0d 100644
--- a/tests/compiler/dart2js/async_await_syntax_test.dart
+++ b/tests/compiler/dart2js/async_await_syntax_test.dart
@@ -1,22 +1,22 @@
-// 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.

-

-// Test that dart2js produces the expected static type warnings and

-// compile-time errors for these tests.

-

-import 'frontend_checker.dart';

-

-/// Map of test files to run together with their associated whitelist.

-///

-/// For instance

-///     'language/async_await_syntax_test.dart': const ['a03b', 'a04b']

-/// includes the multitest in 'language/async_await_syntax_test.dart' but

-/// expects the subtests 'a03b' and 'a04c' to fail.

-const Map<String, List<String>> TESTS = const <String, List<String>>{

-  'language/async_await_syntax_test.dart': const [],

-};

-

-void main(List<String> arguments) {

-  check(TESTS, arguments: arguments, options: ['--enable-async']);

-}

+// 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.
+
+// Test that dart2js produces the expected static type warnings and
+// compile-time errors for these tests.
+
+import 'frontend_checker.dart';
+
+/// Map of test files to run together with their associated whitelist.
+///
+/// For instance
+///     'language/async_await_syntax_test.dart': const ['a03b', 'a04b']
+/// includes the multitest in 'language/async_await_syntax_test.dart' but
+/// expects the subtests 'a03b' and 'a04c' to fail.
+const Map<String, List<String>> TESTS = const <String, List<String>>{
+  'language/async_await_syntax_test.dart': const ['a05h', 'c11a', 'c11b'],
+};
+
+void main(List<String> arguments) {
+  check(TESTS, arguments: arguments, options: ['--enable-async']);
+}
diff --git a/tests/compiler/dart2js/backend_dart/end2end_test.dart b/tests/compiler/dart2js/backend_dart/end2end_test.dart
index a2a2520..3a7f902 100644
--- a/tests/compiler/dart2js/backend_dart/end2end_test.dart
+++ b/tests/compiler/dart2js/backend_dart/end2end_test.dart
@@ -1,37 +1,37 @@
-// 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.

-

-/// End-to-end test of the dart2dart compiler.

-library dart_backend.end2end_test;

-

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

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

-import 'package:compiler/src/dart_backend/dart_backend.dart';

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

-

-import '../../../../pkg/analyzer2dart/test/test_helper.dart' hide TestSpec;

-import '../../../../pkg/analyzer2dart/test/end2end_data.dart';

-

-import 'test_helper.dart';

-import '../output_collector.dart';

-

-main(List<String> args) {

-  performTests(TEST_DATA, asyncTester, runTest, args);

-}

-

-runTest(TestSpec result) {

-  OutputCollector outputCollector = new OutputCollector();

-  asyncTest(() => compilerFor(result.input, outputProvider: outputCollector)

-      .then((Compiler compiler) {

-    String expectedOutput = result.output.trim();

-    compiler.phase = Compiler.PHASE_COMPILING;

-    DartBackend backend = compiler.backend;

-    backend.assembleProgram();

-    String output = outputCollector.getOutput('', 'dart').trim();

-    Expect.equals(expectedOutput, output,

-        '\nInput:\n${result.input}\n'

-        'Expected:\n$expectedOutput\n'

-        'Actual:\n$output\n');

-  }));

+// 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.
+
+/// End-to-end test of the dart2dart compiler.
+library dart_backend.end2end_test;
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/dart2jslib.dart';
+import 'package:compiler/src/dart_backend/dart_backend.dart';
+import 'package:expect/expect.dart';
+
+import '../../../../pkg/analyzer2dart/test/test_helper.dart' hide TestSpec;
+import '../../../../pkg/analyzer2dart/test/end2end_data.dart';
+
+import 'test_helper.dart';
+import '../output_collector.dart';
+
+main(List<String> args) {
+  performTests(TEST_DATA, asyncTester, runTest, args);
+}
+
+runTest(TestSpec result) {
+  OutputCollector outputCollector = new OutputCollector();
+  asyncTest(() => compilerFor(result.input, outputProvider: outputCollector)
+      .then((Compiler compiler) {
+    String expectedOutput = result.output.trim();
+    compiler.phase = Compiler.PHASE_COMPILING;
+    DartBackend backend = compiler.backend;
+    backend.assembleProgram();
+    String output = outputCollector.getOutput('', 'dart').trim();
+    Expect.equals(expectedOutput, output,
+        '\nInput:\n${result.input}\n'
+        'Expected:\n$expectedOutput\n'
+        'Actual:\n$output\n');
+  }));
 }
\ No newline at end of file
diff --git a/tests/compiler/dart2js/backend_dart/sexpr2_test.dart b/tests/compiler/dart2js/backend_dart/sexpr2_test.dart
index 35c3185..71d294b 100644
--- a/tests/compiler/dart2js/backend_dart/sexpr2_test.dart
+++ b/tests/compiler/dart2js/backend_dart/sexpr2_test.dart
@@ -1,62 +1,62 @@
-// 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.

-

-/// Unittest test of the CPS ir generated by the dart2dart compiler.

-library dart_backend.sexpr2_test;

-

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

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

-import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart';

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

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

-

-import '../../../../pkg/analyzer2dart/test/test_helper.dart';

-import '../../../../pkg/analyzer2dart/test/sexpr_data.dart';

-

-import 'test_helper.dart';

-

-main(List<String> args) {

-  performTests(TEST_DATA, asyncTester, runTest, args);

-}

-

-runTest(TestSpec result) {

-  return compilerFor(result.input).then((Compiler compiler) {

-    void checkOutput(String elementName,

-                     Element element,

-                     String expectedOutput) {

-      FunctionDefinition ir = compiler.irBuilder.getIr(element);

-      if (expectedOutput == null) {

-        Expect.isNull(ir, "\nInput:\n${result.input}\n"

-                          "No CPS IR expected for $element");

-      } else {

-        Expect.isNotNull(ir, "\nInput:\n${result.input}\n"

-                             "No CPS IR for $element");

-        expectedOutput = expectedOutput.trim();

-        String output = ir.accept(new SExpressionStringifier()).trim();

-        Expect.equals(expectedOutput, output,

-            "\nInput:\n${result.input}\n"

-            "Expected for '$elementName':\n$expectedOutput\n"

-            "Actual for '$elementName':\n$output\n");

-      }

-    }

-

-    if (result.output is String) {

-      checkOutput('main', compiler.mainFunction, result.output);

-    } else {

-      assert(result.output is Map<String, String>);

-      result.output.forEach((String elementName, String output) {

-        Element element;

-        if (elementName.contains('.')) {

-          ClassElement cls = compiler.mainApp.localLookup(

-              elementName.substring(0, elementName.indexOf('.')));

-          element = cls.localLookup(

-              elementName.substring(elementName.indexOf('.') + 1));

-        } else {

-          element = compiler.mainApp.localLookup(elementName);

-        }

-        checkOutput(elementName, element, output);

-      });

-    }

-  });

+// 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.
+
+/// Unittest test of the CPS ir generated by the dart2dart compiler.
+library dart_backend.sexpr2_test;
+
+import 'package:compiler/src/dart2jslib.dart';
+import 'package:compiler/src/cps_ir/cps_ir_nodes.dart';
+import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:expect/expect.dart';
+
+import '../../../../pkg/analyzer2dart/test/test_helper.dart';
+import '../../../../pkg/analyzer2dart/test/sexpr_data.dart';
+
+import 'test_helper.dart';
+
+main(List<String> args) {
+  performTests(TEST_DATA, asyncTester, runTest, args);
+}
+
+runTest(TestSpec result) {
+  return compilerFor(result.input).then((Compiler compiler) {
+    void checkOutput(String elementName,
+                     Element element,
+                     String expectedOutput) {
+      FunctionDefinition ir = compiler.irBuilder.getIr(element);
+      if (expectedOutput == null) {
+        Expect.isNull(ir, "\nInput:\n${result.input}\n"
+                          "No CPS IR expected for $element");
+      } else {
+        Expect.isNotNull(ir, "\nInput:\n${result.input}\n"
+                             "No CPS IR for $element");
+        expectedOutput = expectedOutput.trim();
+        String output = ir.accept(new SExpressionStringifier()).trim();
+        Expect.equals(expectedOutput, output,
+            "\nInput:\n${result.input}\n"
+            "Expected for '$elementName':\n$expectedOutput\n"
+            "Actual for '$elementName':\n$output\n");
+      }
+    }
+
+    if (result.output is String) {
+      checkOutput('main', compiler.mainFunction, result.output);
+    } else {
+      assert(result.output is Map<String, String>);
+      result.output.forEach((String elementName, String output) {
+        Element element;
+        if (elementName.contains('.')) {
+          ClassElement cls = compiler.mainApp.localLookup(
+              elementName.substring(0, elementName.indexOf('.')));
+          element = cls.localLookup(
+              elementName.substring(elementName.indexOf('.') + 1));
+        } else {
+          element = compiler.mainApp.localLookup(elementName);
+        }
+        checkOutput(elementName, element, output);
+      });
+    }
+  });
 }
\ No newline at end of file
diff --git a/tests/compiler/dart2js/backend_dart/test_helper.dart b/tests/compiler/dart2js/backend_dart/test_helper.dart
index 3e43cd9..a355d7e 100644
--- a/tests/compiler/dart2js/backend_dart/test_helper.dart
+++ b/tests/compiler/dart2js/backend_dart/test_helper.dart
@@ -1,46 +1,46 @@
-// 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 dart_backend.test_helper;

-

-import 'dart:async';

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

-import 'package:compiler/compiler.dart' as api;

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

-import '../../../../pkg/analyzer2dart/test/test_helper.dart';

-import '../compiler_helper.dart';

-

-/// Compiles the given dart code (which must include a 'main' function) and

-/// returns the compiler.

-Future<Compiler> compilerFor(String code,

-                             {api.CompilerOutputProvider outputProvider}) {

-  MockCompiler compiler = new MockCompiler.internal(

-      emitJavaScript: false,

-      enableMinification: false,

-      outputProvider: outputProvider);

-  compiler.diagnosticHandler = createHandler(compiler, code);

-  return compiler.init().then((_) {

-    compiler.parseScript(code);

-

-    Element element = compiler.mainApp.find('main');

-    if (element == null) return null;

-

-    compiler.mainFunction = element;

-    compiler.phase = Compiler.PHASE_RESOLVING;

-    compiler.backend.enqueueHelpers(compiler.enqueuer.resolution,

-                                    compiler.globalDependencies);

-    compiler.processQueue(compiler.enqueuer.resolution, element);

-    compiler.world.populate();

-    compiler.backend.onResolutionComplete();

-

-    compiler.irBuilder.buildNodes();

-

-    return compiler;

-  });

-}

-

-/// Test group using async_helper.

-asyncTester(Group group, RunTest runTest) {

-  asyncTest(() => Future.forEach(group.results, runTest));

-}

+// 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 dart_backend.test_helper;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/compiler.dart' as api;
+import 'package:compiler/src/dart2jslib.dart';
+import '../../../../pkg/analyzer2dart/test/test_helper.dart';
+import '../compiler_helper.dart';
+
+/// Compiles the given dart code (which must include a 'main' function) and
+/// returns the compiler.
+Future<Compiler> compilerFor(String code,
+                             {api.CompilerOutputProvider outputProvider}) {
+  MockCompiler compiler = new MockCompiler.internal(
+      emitJavaScript: false,
+      enableMinification: false,
+      outputProvider: outputProvider);
+  compiler.diagnosticHandler = createHandler(compiler, code);
+  return compiler.init().then((_) {
+    compiler.parseScript(code);
+
+    Element element = compiler.mainApp.find('main');
+    if (element == null) return null;
+
+    compiler.mainFunction = element;
+    compiler.phase = Compiler.PHASE_RESOLVING;
+    compiler.backend.enqueueHelpers(compiler.enqueuer.resolution,
+                                    compiler.globalDependencies);
+    compiler.processQueue(compiler.enqueuer.resolution, element);
+    compiler.world.populate();
+    compiler.backend.onResolutionComplete();
+
+    compiler.irBuilder.buildNodes();
+
+    return compiler;
+  });
+}
+
+/// Test group using async_helper.
+asyncTester(Group group, RunTest runTest) {
+  asyncTest(() => Future.forEach(group.results, runTest));
+}
diff --git a/tests/compiler/dart2js/check_members_test.dart b/tests/compiler/dart2js/check_members_test.dart
index 023e849..fff8a93 100644
--- a/tests/compiler/dart2js/check_members_test.dart
+++ b/tests/compiler/dart2js/check_members_test.dart
@@ -1,53 +1,53 @@
-// 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.

-

-// Test that dart2js produces the expected static type warnings for least upper

-// bound language tests. This ensures that the analyzer and dart2js agrees

-// on these tests.

-

-import 'warnings_checker.dart';

-

-/// Map from test files to a map of their expected status. If the status map is

-/// `null` no warnings must be missing or unexpected, otherwise the status map

-/// can contain a list of line numbers for keys 'missing' and 'unexpected' for

-/// the warnings of each category.

-const Map<String, dynamic> TESTS = const {

-  // Instance methods.

-    'co19/src/Language/07_Classes/1_Instance_Methods_A01_t01.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A01_t02.dart': null,

-

-    'language/check_method_override_test.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A06_t01.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A06_t02.dart': null,

-

-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t01.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t02.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t03.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t04.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t05.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t06.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t01.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t02.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t03.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t04.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t05.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t06.dart': null,

-

-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t01.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t02.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t04.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t05.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t06.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t07.dart': null,

-    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t08.dart': null,

-  // Getters.

-    'co19/src/Language/07_Classes/2_Getters_A05_t01.dart': null,

-    'co19/src/Language/07_Classes/2_Getters_A05_t02.dart': null,

-    'co19/src/Language/07_Classes/2_Getters_A05_t03.dart': null,

-    'co19/src/Language/07_Classes/2_Getters_A05_t04.dart': null,

-};

-

-void main() {

-  checkWarnings(TESTS);

-}

+// 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.
+
+// Test that dart2js produces the expected static type warnings for least upper
+// bound language tests. This ensures that the analyzer and dart2js agrees
+// on these tests.
+
+import 'warnings_checker.dart';
+
+/// Map from test files to a map of their expected status. If the status map is
+/// `null` no warnings must be missing or unexpected, otherwise the status map
+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
+/// the warnings of each category.
+const Map<String, dynamic> TESTS = const {
+  // Instance methods.
+    'co19/src/Language/07_Classes/1_Instance_Methods_A01_t01.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A01_t02.dart': null,
+
+    'language/check_method_override_test.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A06_t01.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A06_t02.dart': null,
+
+    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t01.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t02.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t03.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t04.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t05.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A02_t06.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t01.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t02.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t03.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t04.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t05.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A03_t06.dart': null,
+
+    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t01.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t02.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t04.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t05.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t06.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t07.dart': null,
+    'co19/src/Language/07_Classes/1_Instance_Methods_A05_t08.dart': null,
+  // Getters.
+    'co19/src/Language/07_Classes/2_Getters_A05_t01.dart': null,
+    'co19/src/Language/07_Classes/2_Getters_A05_t02.dart': null,
+    'co19/src/Language/07_Classes/2_Getters_A05_t03.dart': null,
+    'co19/src/Language/07_Classes/2_Getters_A05_t04.dart': null,
+};
+
+void main() {
+  checkWarnings(TESTS);
+}
diff --git a/tests/compiler/dart2js/constant_expression_evaluate_test.dart b/tests/compiler/dart2js/constant_expression_evaluate_test.dart
index 2e82412..94a0213e 100644
--- a/tests/compiler/dart2js/constant_expression_evaluate_test.dart
+++ b/tests/compiler/dart2js/constant_expression_evaluate_test.dart
@@ -1,237 +1,237 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file

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

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

-

-library dart2js.constants.expressions.evaluate_test;

-

-import 'dart:async';

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

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

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

-import 'package:compiler/src/constants/values.dart';

-import 'package:compiler/src/constant_system_dart.dart';

-import 'package:compiler/src/core_types.dart';

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

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

-import 'memory_compiler.dart';

-

-class TestData {

-  /// Declarations needed for the [constants].

-  final String declarations;

-  /// Tested constants.

-  final List constants;

-

-  const TestData(this.declarations, this.constants);

-}

-

-class ConstantData {

-  /// Source code for the constant expression.

-  final String code;

-  /// Map from environment to expected constant value as structured text.

-  final Map<Map<String, String>, String> expectedValues;

-

-  const ConstantData(this.code,

-                     this.expectedValues);

-}

-

-class MemoryEnvironment implements Environment {

-  final Compiler compiler;

-  final Map<String, String> env;

-

-  MemoryEnvironment(this.compiler,

-                    [this.env = const <String, String>{}]);

-

-  @override

-  String readFromEnvironment(String name) => env[name];

-}

-

-const List<TestData> DATA = const [

-  const TestData('', const [

-    const ConstantData('null', const { const {} : 'NullConstant' }),

-    const ConstantData('false', const { const {} : 'BoolConstant(false)' }),

-    const ConstantData('true', const { const {} : 'BoolConstant(true)' }),

-    const ConstantData('0', const { const {} : 'IntConstant(0)' }),

-    const ConstantData('0.0', const { const {} : 'DoubleConstant(0.0)' }),

-    const ConstantData('"foo"', const { const {} : 'StringConstant("foo")' }),

-    const ConstantData('1 + 2', const { const {} : 'IntConstant(3)' }),

-    const ConstantData('-(1)', const { const {} : 'IntConstant(-1)' }),

-    const ConstantData('"foo".length', const { const {} : 'IntConstant(3)' }),

-    const ConstantData('identical(0, 1)',

-                       const { const {} : 'BoolConstant(false)' }),

-    const ConstantData('"a" "b"', const { const {} : 'StringConstant("ab")' }),

-    const ConstantData('identical',

-        const { const {} : 'FunctionConstant(identical)' }),

-    const ConstantData('true ? 0 : 1', const { const {} : 'IntConstant(0)' }),

-    const ConstantData('proxy',

-        const { const {} : 'ConstructedConstant(_Proxy())' }),

-    const ConstantData('Object', const { const {} : 'TypeConstant(Object)' }),

-    const ConstantData('const [0, 1]',

-        const { const {} : 'ListConstant([IntConstant(0), IntConstant(1)])' }),

-    const ConstantData('const <int>[0, 1]', const {

-        const {} : 'ListConstant(<int>[IntConstant(0), IntConstant(1)])' }),

-    const ConstantData('const {0: 1, 2: 3}',

-        const { const {} :

-          'MapConstant({IntConstant(0): IntConstant(1), '

-                       'IntConstant(2): IntConstant(3)})' }),

-    const ConstantData('const <int, int>{0: 1, 2: 3}',

-        const { const {} :

-          'MapConstant(<int, int>{IntConstant(0): IntConstant(1), '

-                                 'IntConstant(2): IntConstant(3)})' }),

-    const ConstantData(

-        'const bool.fromEnvironment("foo", defaultValue: false)',

-        const { const {} : 'BoolConstant(false)',

-                const {'foo': 'true'} : 'BoolConstant(true)'}),

-    const ConstantData(

-        'const int.fromEnvironment("foo", defaultValue: 42)',

-        const { const {} : 'IntConstant(42)',

-                const {'foo': '87'} : 'IntConstant(87)'}),

-    const ConstantData(

-        'const String.fromEnvironment("foo", defaultValue: "bar")',

-        const { const {} : 'StringConstant("bar")',

-                const {'foo': 'foo'} : 'StringConstant("foo")'}),

-  ]),

-  const TestData('''

-const a = const bool.fromEnvironment("foo", defaultValue: true);

-const b = const int.fromEnvironment("bar", defaultValue: 42);

-

-class A {

-  const A();

-}

-class B {

-  final field1;

-  const B(this.field1);

-}

-class C extends B {

-  final field2;

-  const C({field1: 42, this.field2: false}) : super(field1);

-  const C.named([field = false]) : this(field1: field, field2: field);

-}

-''', const [

-    const ConstantData('const Object()',

-        const { const {} : 'ConstructedConstant(Object())' }),

-    const ConstantData('const A()',

-        const { const {} : 'ConstructedConstant(A())' }),

-    const ConstantData('const B(0)',

-        const { const {} : 'ConstructedConstant(B(field1=IntConstant(0)))' }),

-    const ConstantData('const B(const A())',

-        const { const {} :

-          'ConstructedConstant(B(field1=ConstructedConstant(A())))' }),

-    const ConstantData('const C()', const { const {} :

-        'ConstructedConstant(C(field1=IntConstant(42),'

-                              'field2=BoolConstant(false)))' }),

-    const ConstantData('const C(field1: 87)', const { const {} :

-        'ConstructedConstant(C(field1=IntConstant(87),'

-                              'field2=BoolConstant(false)))' }),

-    const ConstantData('const C(field2: true)', const { const {} :

-        'ConstructedConstant(C(field1=IntConstant(42),'

-                              'field2=BoolConstant(true)))' }),

-    const ConstantData('const C.named()', const { const {} :

-        'ConstructedConstant(C(field1=BoolConstant(false),'

-                              'field2=BoolConstant(false)))' }),

-    const ConstantData('const C.named(87)', const { const {} :

-        'ConstructedConstant(C(field1=IntConstant(87),'

-                              'field2=IntConstant(87)))' }),

-    const ConstantData('const C(field1: a, field2: b)', const {

-        const {} :

-          'ConstructedConstant(C(field1=BoolConstant(true),'

-                                'field2=IntConstant(42)))',

-        const {'foo': 'false', 'bar': '87'} :

-          'ConstructedConstant(C(field1=BoolConstant(false),'

-                                'field2=IntConstant(87)))', }),

-  ]),

-  const TestData('''

-class A<T> implements B {

-  final field1;

-  const A({this.field1:42});

-}

-class B<S> implements C {

-  const factory B({field1}) = A<B<S>>;

-  const factory B.named() = A<S>;

-}

-class C<U> {

-  const factory C({field1}) = A<B<double>>;

-}

-''', const [

-    const ConstantData('const A()',

-        const { const {} :

-          'ConstructedConstant(A<dynamic>(field1=IntConstant(42)))' }),

-    const ConstantData('const A<int>(field1: 87)',

-        const { const {} :

-          'ConstructedConstant(A<int>(field1=IntConstant(87)))' }),

-    const ConstantData('const B()',

-        const { const {} :

-          'ConstructedConstant(A<B<dynamic>>(field1=IntConstant(42)))' }),

-    const ConstantData('const B<int>()',

-        const { const {} :

-          'ConstructedConstant(A<B<int>>(field1=IntConstant(42)))' }),

-    const ConstantData('const B<int>(field1: 87)',

-        const { const {} :

-          'ConstructedConstant(A<B<int>>(field1=IntConstant(87)))' }),

-    const ConstantData('const C<int>(field1: 87)',

-        const { const {} :

-          'ConstructedConstant(A<B<double>>(field1=IntConstant(87)))' }),

-    const ConstantData('const B<int>.named()',

-        const { const {} :

-          'ConstructedConstant(A<int>(field1=IntConstant(42)))' }),

-  ]),

-  const TestData('''

-const c = const int.fromEnvironment("foo", defaultValue: 5);

-const d = const int.fromEnvironment("bar", defaultValue: 10);

-

-class A {

-  final field;

-  const A(a, b) : field = a + b;

-}

-

-class B extends A {

-  const B(a) : super(a, a * 2);

-}

-''', const [

-    const ConstantData('const A(c, d)', const {

-        const {} :

-          'ConstructedConstant(A(field=IntConstant(15)))',

-        const {'foo': '7', 'bar': '11'} :

-          'ConstructedConstant(A(field=IntConstant(18)))', }),

-    const ConstantData('const B(d)', const {

-        const {} :

-          'ConstructedConstant(B(field=IntConstant(30)))',

-        const {'bar': '42'} :

-          'ConstructedConstant(B(field=IntConstant(126)))', }),

-  ]),

-];

-

-main() {

-  asyncTest(() => Future.forEach(DATA, testData));

-}

-

-Future testData(TestData data) {

-  StringBuffer sb = new StringBuffer();

-  sb.write('${data.declarations}\n');

-  Map constants = {};

-  data.constants.forEach((ConstantData constantData) {

-    String name = 'c${constants.length}';

-    sb.write('const $name = ${constantData.code};\n');

-    constants[name] = constantData;

-  });

-  sb.write('main() {}\n');

-  String source = sb.toString();

-  Compiler compiler = compilerFor(

-      {'main.dart': source}, options: ['--analyze-all']);

-  return compiler.runCompiler(Uri.parse('memory:main.dart')).then((_) {

-    var library = compiler.mainApp;

-    constants.forEach((String name, ConstantData data) {

-      FieldElement field = library.localLookup(name);

-      ConstantExpression constant = field.constant;

-      data.expectedValues.forEach(

-          (Map<String, String> env, String expectedText) {

-        Environment environment = new MemoryEnvironment(compiler, env);

-        ConstantValue value =

-            constant.evaluate(environment, DART_CONSTANT_SYSTEM);

-        String valueText = value.toStructuredString();

-        Expect.equals(expectedText, valueText,

-            "Unexpected value '${valueText}' for contant "

-            "`${constant.getText()}`, expected '${expectedText}'.");

-      });

-    });

-  });

-}

+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.constants.expressions.evaluate_test;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/constants/expressions.dart';
+import 'package:compiler/src/constants/values.dart';
+import 'package:compiler/src/constant_system_dart.dart';
+import 'package:compiler/src/core_types.dart';
+import 'package:compiler/src/dart2jslib.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'memory_compiler.dart';
+
+class TestData {
+  /// Declarations needed for the [constants].
+  final String declarations;
+  /// Tested constants.
+  final List constants;
+
+  const TestData(this.declarations, this.constants);
+}
+
+class ConstantData {
+  /// Source code for the constant expression.
+  final String code;
+  /// Map from environment to expected constant value as structured text.
+  final Map<Map<String, String>, String> expectedValues;
+
+  const ConstantData(this.code,
+                     this.expectedValues);
+}
+
+class MemoryEnvironment implements Environment {
+  final Compiler compiler;
+  final Map<String, String> env;
+
+  MemoryEnvironment(this.compiler,
+                    [this.env = const <String, String>{}]);
+
+  @override
+  String readFromEnvironment(String name) => env[name];
+}
+
+const List<TestData> DATA = const [
+  const TestData('', const [
+    const ConstantData('null', const { const {} : 'NullConstant' }),
+    const ConstantData('false', const { const {} : 'BoolConstant(false)' }),
+    const ConstantData('true', const { const {} : 'BoolConstant(true)' }),
+    const ConstantData('0', const { const {} : 'IntConstant(0)' }),
+    const ConstantData('0.0', const { const {} : 'DoubleConstant(0.0)' }),
+    const ConstantData('"foo"', const { const {} : 'StringConstant("foo")' }),
+    const ConstantData('1 + 2', const { const {} : 'IntConstant(3)' }),
+    const ConstantData('-(1)', const { const {} : 'IntConstant(-1)' }),
+    const ConstantData('"foo".length', const { const {} : 'IntConstant(3)' }),
+    const ConstantData('identical(0, 1)',
+                       const { const {} : 'BoolConstant(false)' }),
+    const ConstantData('"a" "b"', const { const {} : 'StringConstant("ab")' }),
+    const ConstantData('identical',
+        const { const {} : 'FunctionConstant(identical)' }),
+    const ConstantData('true ? 0 : 1', const { const {} : 'IntConstant(0)' }),
+    const ConstantData('proxy',
+        const { const {} : 'ConstructedConstant(_Proxy())' }),
+    const ConstantData('Object', const { const {} : 'TypeConstant(Object)' }),
+    const ConstantData('const [0, 1]',
+        const { const {} : 'ListConstant([IntConstant(0), IntConstant(1)])' }),
+    const ConstantData('const <int>[0, 1]', const {
+        const {} : 'ListConstant(<int>[IntConstant(0), IntConstant(1)])' }),
+    const ConstantData('const {0: 1, 2: 3}',
+        const { const {} :
+          'MapConstant({IntConstant(0): IntConstant(1), '
+                       'IntConstant(2): IntConstant(3)})' }),
+    const ConstantData('const <int, int>{0: 1, 2: 3}',
+        const { const {} :
+          'MapConstant(<int, int>{IntConstant(0): IntConstant(1), '
+                                 'IntConstant(2): IntConstant(3)})' }),
+    const ConstantData(
+        'const bool.fromEnvironment("foo", defaultValue: false)',
+        const { const {} : 'BoolConstant(false)',
+                const {'foo': 'true'} : 'BoolConstant(true)'}),
+    const ConstantData(
+        'const int.fromEnvironment("foo", defaultValue: 42)',
+        const { const {} : 'IntConstant(42)',
+                const {'foo': '87'} : 'IntConstant(87)'}),
+    const ConstantData(
+        'const String.fromEnvironment("foo", defaultValue: "bar")',
+        const { const {} : 'StringConstant("bar")',
+                const {'foo': 'foo'} : 'StringConstant("foo")'}),
+  ]),
+  const TestData('''
+const a = const bool.fromEnvironment("foo", defaultValue: true);
+const b = const int.fromEnvironment("bar", defaultValue: 42);
+
+class A {
+  const A();
+}
+class B {
+  final field1;
+  const B(this.field1);
+}
+class C extends B {
+  final field2;
+  const C({field1: 42, this.field2: false}) : super(field1);
+  const C.named([field = false]) : this(field1: field, field2: field);
+}
+''', const [
+    const ConstantData('const Object()',
+        const { const {} : 'ConstructedConstant(Object())' }),
+    const ConstantData('const A()',
+        const { const {} : 'ConstructedConstant(A())' }),
+    const ConstantData('const B(0)',
+        const { const {} : 'ConstructedConstant(B(field1=IntConstant(0)))' }),
+    const ConstantData('const B(const A())',
+        const { const {} :
+          'ConstructedConstant(B(field1=ConstructedConstant(A())))' }),
+    const ConstantData('const C()', const { const {} :
+        'ConstructedConstant(C(field1=IntConstant(42),'
+                              'field2=BoolConstant(false)))' }),
+    const ConstantData('const C(field1: 87)', const { const {} :
+        'ConstructedConstant(C(field1=IntConstant(87),'
+                              'field2=BoolConstant(false)))' }),
+    const ConstantData('const C(field2: true)', const { const {} :
+        'ConstructedConstant(C(field1=IntConstant(42),'
+                              'field2=BoolConstant(true)))' }),
+    const ConstantData('const C.named()', const { const {} :
+        'ConstructedConstant(C(field1=BoolConstant(false),'
+                              'field2=BoolConstant(false)))' }),
+    const ConstantData('const C.named(87)', const { const {} :
+        'ConstructedConstant(C(field1=IntConstant(87),'
+                              'field2=IntConstant(87)))' }),
+    const ConstantData('const C(field1: a, field2: b)', const {
+        const {} :
+          'ConstructedConstant(C(field1=BoolConstant(true),'
+                                'field2=IntConstant(42)))',
+        const {'foo': 'false', 'bar': '87'} :
+          'ConstructedConstant(C(field1=BoolConstant(false),'
+                                'field2=IntConstant(87)))', }),
+  ]),
+  const TestData('''
+class A<T> implements B {
+  final field1;
+  const A({this.field1:42});
+}
+class B<S> implements C {
+  const factory B({field1}) = A<B<S>>;
+  const factory B.named() = A<S>;
+}
+class C<U> {
+  const factory C({field1}) = A<B<double>>;
+}
+''', const [
+    const ConstantData('const A()',
+        const { const {} :
+          'ConstructedConstant(A<dynamic>(field1=IntConstant(42)))' }),
+    const ConstantData('const A<int>(field1: 87)',
+        const { const {} :
+          'ConstructedConstant(A<int>(field1=IntConstant(87)))' }),
+    const ConstantData('const B()',
+        const { const {} :
+          'ConstructedConstant(A<B<dynamic>>(field1=IntConstant(42)))' }),
+    const ConstantData('const B<int>()',
+        const { const {} :
+          'ConstructedConstant(A<B<int>>(field1=IntConstant(42)))' }),
+    const ConstantData('const B<int>(field1: 87)',
+        const { const {} :
+          'ConstructedConstant(A<B<int>>(field1=IntConstant(87)))' }),
+    const ConstantData('const C<int>(field1: 87)',
+        const { const {} :
+          'ConstructedConstant(A<B<double>>(field1=IntConstant(87)))' }),
+    const ConstantData('const B<int>.named()',
+        const { const {} :
+          'ConstructedConstant(A<int>(field1=IntConstant(42)))' }),
+  ]),
+  const TestData('''
+const c = const int.fromEnvironment("foo", defaultValue: 5);
+const d = const int.fromEnvironment("bar", defaultValue: 10);
+
+class A {
+  final field;
+  const A(a, b) : field = a + b;
+}
+
+class B extends A {
+  const B(a) : super(a, a * 2);
+}
+''', const [
+    const ConstantData('const A(c, d)', const {
+        const {} :
+          'ConstructedConstant(A(field=IntConstant(15)))',
+        const {'foo': '7', 'bar': '11'} :
+          'ConstructedConstant(A(field=IntConstant(18)))', }),
+    const ConstantData('const B(d)', const {
+        const {} :
+          'ConstructedConstant(B(field=IntConstant(30)))',
+        const {'bar': '42'} :
+          'ConstructedConstant(B(field=IntConstant(126)))', }),
+  ]),
+];
+
+main() {
+  asyncTest(() => Future.forEach(DATA, testData));
+}
+
+Future testData(TestData data) {
+  StringBuffer sb = new StringBuffer();
+  sb.write('${data.declarations}\n');
+  Map constants = {};
+  data.constants.forEach((ConstantData constantData) {
+    String name = 'c${constants.length}';
+    sb.write('const $name = ${constantData.code};\n');
+    constants[name] = constantData;
+  });
+  sb.write('main() {}\n');
+  String source = sb.toString();
+  Compiler compiler = compilerFor(
+      {'main.dart': source}, options: ['--analyze-all']);
+  return compiler.runCompiler(Uri.parse('memory:main.dart')).then((_) {
+    var library = compiler.mainApp;
+    constants.forEach((String name, ConstantData data) {
+      FieldElement field = library.localLookup(name);
+      ConstantExpression constant = field.constant;
+      data.expectedValues.forEach(
+          (Map<String, String> env, String expectedText) {
+        Environment environment = new MemoryEnvironment(compiler, env);
+        ConstantValue value =
+            constant.evaluate(environment, DART_CONSTANT_SYSTEM);
+        String valueText = value.toStructuredString();
+        Expect.equals(expectedText, valueText,
+            "Unexpected value '${valueText}' for contant "
+            "`${constant.getText()}`, expected '${expectedText}'.");
+      });
+    });
+  });
+}
diff --git a/tests/compiler/dart2js/exit_code_helper.dart b/tests/compiler/dart2js/exit_code_helper.dart
index d3c6121..52794b1 100644
--- a/tests/compiler/dart2js/exit_code_helper.dart
+++ b/tests/compiler/dart2js/exit_code_helper.dart
@@ -1,3 +1,3 @@
-void main() {

-

+void main() {
+
 }
\ No newline at end of file
diff --git a/tests/compiler/dart2js/frontend_checker.dart b/tests/compiler/dart2js/frontend_checker.dart
index b4bd3a0..91fb719 100644
--- a/tests/compiler/dart2js/frontend_checker.dart
+++ b/tests/compiler/dart2js/frontend_checker.dart
@@ -1,110 +1,110 @@
-// 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.

-

-// Checks that dart2js produces the expected static type warnings and

-// compile-time errors for the provided multitests.

-

-import 'dart:async';

-import 'dart:io';

-

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

-import 'package:compiler/src/util/uri_extras.dart'

-    show relativize;

-import 'memory_compiler.dart';

-

-import '../../../tools/testing/dart/multitest.dart'

-    show ExtractTestsFromMultitest;

-import '../../../tools/testing/dart/path.dart'

-    show Path;

-

-

-/// Check the analysis of the multitests in [testFiles] to result in the

-/// expected static warnings and compile-time errors.

-///

-/// [testFiles] is a map of the test files to be checked together with their

-/// associated white listing.

-///

-/// For instance if [testFiles] contain the mapping

-///     'language/async_await_syntax_test.dart': const ['a03b', 'a04b']

-/// the multitests in 'language/async_await_syntax_test.dart' are checked but

-/// the subtests 'a03b' and 'a04c' are expected to fail.

-void check(Map<String, List<String>> testFiles,

-           {List<String> arguments: const <String>[],

-            List<String> options: const <String>[]}) {

-  bool outcomeMismatch = false;

-  bool verbose = arguments.contains('-v');

-  var cachedCompiler;

-  asyncTest(() => Future.forEach(testFiles.keys, (String testFile) {

-    Map<String, String> testSources = {};

-    Map<String, Set<String>> testOutcomes = {};

-    String fileName = 'tests/$testFile';

-    ExtractTestsFromMultitest(new Path(fileName), testSources, testOutcomes);

-    return Future.forEach(testSources.keys, (String testName) {

-      String testFileName = '$fileName/$testName';

-      Set<String> expectedOutcome = testOutcomes[testName];

-      bool expectFailure = testFiles[testFile].contains(testName);

-      DiagnosticCollector collector = new DiagnosticCollector();

-      var compiler = compilerFor(

-           {testFileName: testSources[testName]},

-           diagnosticHandler: collector,

-           options: ['--analyze-only']..addAll(options),

-           showDiagnostics: verbose,

-           cachedCompiler: cachedCompiler);

-      return compiler.run(Uri.parse('memory:$testFileName')).then((_) {

-        bool unexpectedResult = false;

-        if (expectedOutcome.contains('compile-time error')) {

-          if (collector.errors.isEmpty) {

-            print('$testFileName: Missing compile-time error.');

-            unexpectedResult = true;

-          }

-        } else if (expectedOutcome.contains('static type warning')) {

-          if (collector.warnings.isEmpty) {

-            print('$testFileName: Missing static type warning.');

-            unexpectedResult = true;

-          }

-        } else {

-          // Expect ok.

-          if (!collector.errors.isEmpty ||

-              !collector.warnings.isEmpty) {

-            collector.errors.forEach((message) {

-              print('$testFileName: Unexpected error: ${message.message}');

-            });

-            collector.warnings.forEach((message) {

-              print('$testFileName: Unexpected warning: ${message.message}');

-            });

-            unexpectedResult = true;

-          }

-        }

-        if (expectFailure) {

-          if (unexpectedResult) {

-            unexpectedResult = false;

-          } else {

-            print('$testFileName: The test is white-listed '

-                  'and therefore expected to fail.');

-            unexpectedResult = true;

-          }

-        }

-        if (unexpectedResult) {

-          outcomeMismatch = true;

-        }

-        cachedCompiler = compiler;

-      });

-    });

-  }).then((_) {

-    if (outcomeMismatch) {

-      String testFileName =

-            relativize(Uri.base, Platform.script, Platform.isWindows);

-      print('''

-

-===

-=== ERROR: Unexpected result of analysis.

-===

-=== Please update the white-listing in $testFileName

-===

-

-''');

-      exit(1);

-    }

-  }));

-}

+// 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.
+
+// Checks that dart2js produces the expected static type warnings and
+// compile-time errors for the provided multitests.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/util/uri_extras.dart'
+    show relativize;
+import 'memory_compiler.dart';
+
+import '../../../tools/testing/dart/multitest.dart'
+    show ExtractTestsFromMultitest;
+import '../../../tools/testing/dart/path.dart'
+    show Path;
+
+
+/// Check the analysis of the multitests in [testFiles] to result in the
+/// expected static warnings and compile-time errors.
+///
+/// [testFiles] is a map of the test files to be checked together with their
+/// associated white listing.
+///
+/// For instance if [testFiles] contain the mapping
+///     'language/async_await_syntax_test.dart': const ['a03b', 'a04b']
+/// the multitests in 'language/async_await_syntax_test.dart' are checked but
+/// the subtests 'a03b' and 'a04c' are expected to fail.
+void check(Map<String, List<String>> testFiles,
+           {List<String> arguments: const <String>[],
+            List<String> options: const <String>[]}) {
+  bool outcomeMismatch = false;
+  bool verbose = arguments.contains('-v');
+  var cachedCompiler;
+  asyncTest(() => Future.forEach(testFiles.keys, (String testFile) {
+    Map<String, String> testSources = {};
+    Map<String, Set<String>> testOutcomes = {};
+    String fileName = 'tests/$testFile';
+    ExtractTestsFromMultitest(new Path(fileName), testSources, testOutcomes);
+    return Future.forEach(testSources.keys, (String testName) {
+      String testFileName = '$fileName/$testName';
+      Set<String> expectedOutcome = testOutcomes[testName];
+      bool expectFailure = testFiles[testFile].contains(testName);
+      DiagnosticCollector collector = new DiagnosticCollector();
+      var compiler = compilerFor(
+           {testFileName: testSources[testName]},
+           diagnosticHandler: collector,
+           options: ['--analyze-only']..addAll(options),
+           showDiagnostics: verbose,
+           cachedCompiler: cachedCompiler);
+      return compiler.run(Uri.parse('memory:$testFileName')).then((_) {
+        bool unexpectedResult = false;
+        if (expectedOutcome.contains('compile-time error')) {
+          if (collector.errors.isEmpty) {
+            print('$testFileName: Missing compile-time error.');
+            unexpectedResult = true;
+          }
+        } else if (expectedOutcome.contains('static type warning')) {
+          if (collector.warnings.isEmpty) {
+            print('$testFileName: Missing static type warning.');
+            unexpectedResult = true;
+          }
+        } else {
+          // Expect ok.
+          if (!collector.errors.isEmpty ||
+              !collector.warnings.isEmpty) {
+            collector.errors.forEach((message) {
+              print('$testFileName: Unexpected error: ${message.message}');
+            });
+            collector.warnings.forEach((message) {
+              print('$testFileName: Unexpected warning: ${message.message}');
+            });
+            unexpectedResult = true;
+          }
+        }
+        if (expectFailure) {
+          if (unexpectedResult) {
+            unexpectedResult = false;
+          } else {
+            print('$testFileName: The test is white-listed '
+                  'and therefore expected to fail.');
+            unexpectedResult = true;
+          }
+        }
+        if (unexpectedResult) {
+          outcomeMismatch = true;
+        }
+        cachedCompiler = compiler;
+      });
+    });
+  }).then((_) {
+    if (outcomeMismatch) {
+      String testFileName =
+            relativize(Uri.base, Platform.script, Platform.isWindows);
+      print('''
+
+===
+=== ERROR: Unexpected result of analysis.
+===
+=== Please update the white-listing in $testFileName
+===
+
+''');
+      exit(1);
+    }
+  }));
+}
diff --git a/tests/compiler/dart2js/import_mirrors_test.dart b/tests/compiler/dart2js/import_mirrors_test.dart
index f5f799b..1b16f76 100644
--- a/tests/compiler/dart2js/import_mirrors_test.dart
+++ b/tests/compiler/dart2js/import_mirrors_test.dart
@@ -1,413 +1,413 @@
-// 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.

-

-// Test that the compiler emits a warning on import of 'dart:mirrors' unless

-// the flag --enable-experimental-mirrors is used.

-

-library dart2js.test.import;

-

-import 'dart:async';

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

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

-import 'package:compiler/src/dart2jslib.dart' show MessageKind;

-import 'memory_compiler.dart';

-

-const DIRECT_IMPORT = const {

-  '/main.dart': '''

-import 'dart:mirrors';

-

-main() {}

-''',

-

-  'paths':

-      "main.dart => dart:mirrors",

-};

-

-const INDIRECT_IMPORT1 = const {

-  '/main.dart': '''

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'dart:mirrors';

-''',

-

-  'paths':

-      "first.dart => dart:mirrors",

-  'verbosePaths':

-      "main.dart => first.dart => dart:mirrors",

-};

-

-const INDIRECT_IMPORT2 = const {

-  '/main.dart': '''

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'second.dart';

-''',

-  '/second.dart': '''

-import 'dart:mirrors';

-''',

-

-  'paths':

-      "second.dart => dart:mirrors",

-  'verbosePaths':

-      "main.dart => first.dart => second.dart => dart:mirrors",

-};

-

-const INDIRECT_PACKAGE_IMPORT1 = const {

-  '/main.dart': '''

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'package:second/second.dart';

-''',

-  '/pkg/second/second.dart': '''

-import 'dart:mirrors';

-''',

-

-  'paths':

-      "first.dart => package:second => dart:mirrors",

-  'verbosePaths':

-      "main.dart => first.dart => package:second/second.dart => dart:mirrors",

-};

-

-const INDIRECT_PACKAGE_IMPORT2 = const {

-  '/main.dart': '''

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'package:packagename/second.dart';

-''',

-  '/pkg/packagename/second.dart': '''

-import 'dart:mirrors';

-''',

-

-  'paths':

-      "first.dart => package:packagename => dart:mirrors",

-  'verbosePaths':

-      "main.dart => first.dart => package:packagename/second.dart "

-      "=> dart:mirrors",

-};

-

-const INDIRECT_PACKAGE_IMPORT3 = const {

-  '/main.dart': '''

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'package:package1/second.dart';

-''',

-  '/pkg/package1/second.dart': '''

-import 'package:package2/third.dart';

-''',

-  '/pkg/package2/third.dart': '''

-import 'dart:mirrors';

-''',

-

-  'paths':

-      "first.dart => package:package1 => package:package2 => dart:mirrors",

-  'verbosePaths':

-      "main.dart => first.dart => package:package1/second.dart "

-      "=> package:package2/third.dart => dart:mirrors",

-};

-

-const INDIRECT_PACKAGE_IMPORT4 = const {

-  '/main.dart': '''

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'package:package1/second.dart';

-''',

-  '/pkg/package1/second.dart': '''

-import 'sub/third.dart';

-''',

-  '/pkg/package1/sub/third.dart': '''

-import 'package:package2/fourth.dart';

-''',

-  '/pkg/package2/fourth.dart': '''

-import 'lib/src/fifth.dart';

-''',

-  '/pkg/package2/lib/src/fifth.dart': '''

-import 'dart:mirrors';

-''',

-

-  'paths':

-      "first.dart => package:package1 => package:package2 => dart:mirrors",

-  'verbosePaths':

-      "main.dart => first.dart => package:package1/second.dart "

-      "=> package:package1/sub/third.dart => package:package2/fourth.dart "

-      "=> package:package2/lib/src/fifth.dart => dart:mirrors",

-};

-

-const DUAL_DIRECT_IMPORT = const {

-  '/main.dart': '''

-import 'dart:mirrors';

-import 'dart:mirrors';

-

-main() {}

-''',

-

-  'paths':

-      "main.dart => dart:mirrors",

-};

-

-const DUAL_INDIRECT_IMPORT1 = const {

-  '/main.dart': '''

-import 'dart:mirrors';

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'dart:mirrors';

-''',

-

-  'paths': const

-      ["main.dart => dart:mirrors",

-       "first.dart => dart:mirrors"],

-  'verbosePaths': const

-      ["main.dart => dart:mirrors",

-       "main.dart => first.dart => dart:mirrors"],

-};

-

-const DUAL_INDIRECT_IMPORT2 = const {

-  '/main.dart': '''

-import 'first.dart';

-import 'second.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'dart:mirrors';

-''',

-  '/second.dart': '''

-import 'dart:mirrors';

-''',

-

-  'paths': const

-      ["first.dart => dart:mirrors",

-       "second.dart => dart:mirrors"],

-  'verbosePaths': const

-      ["main.dart => first.dart => dart:mirrors",

-       "main.dart => second.dart => dart:mirrors"],

-};

-

-const DUAL_INDIRECT_IMPORT3 = const {

-  '/main.dart': '''

-import 'first.dart';

-import 'second.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'third.dart';

-''',

-  '/second.dart': '''

-import 'third.dart';

-''',

-  '/third.dart': '''

-import 'dart:mirrors';

-''',

-

-  'paths':

-      "third.dart => dart:mirrors",

-  'verbosePaths': const

-      ["main.dart => first.dart => third.dart => dart:mirrors",

-       "main.dart => second.dart => third.dart => dart:mirrors"],

-};

-

-const DUAL_INDIRECT_PACKAGE_IMPORT1 = const {

-  '/main.dart': '''

-import 'package:package1/second.dart';

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'package:package2/third.dart';

-''',

-  '/pkg/package1/second.dart': '''

-import 'dart:mirrors';

-''',

-  '/pkg/package2/third.dart': '''

-import 'dart:mirrors';

-''',

-

-  'paths': const

-      ["main.dart => package:package1 => dart:mirrors",

-       "first.dart => package:package2 => dart:mirrors"],

-  'verbosePaths': const

-      ["main.dart => package:package1/second.dart => dart:mirrors",

-       "main.dart => first.dart => package:package2/third.dart => dart:mirrors"]

-};

-

-const DIRECT_EXPORT = const {

-  '/main.dart': '''

-export 'dart:mirrors';

-

-main() {}

-''',

-

-  'paths':

-      "main.dart => dart:mirrors",

-};

-

-const INDIRECT_EXPORT1 = const {

-  '/main.dart': '''

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-export 'dart:mirrors';

-''',

-

-  'paths':

-      "first.dart => dart:mirrors",

-  'verbosePaths':

-      "main.dart => first.dart => dart:mirrors",

-};

-

-const INDIRECT_EXPORT2 = const {

-  '/main.dart': '''

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'second.dart';

-''',

-  '/second.dart': '''

-export 'dart:mirrors';

-''',

-

-  'paths':

-      "second.dart => dart:mirrors",

-  'verbosePaths':

-      "main.dart => first.dart => second.dart => dart:mirrors",

-};

-

-const INDIRECT_PACKAGE_EXPORT1 = const {

-  '/main.dart': '''

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-import 'package:packagename/second.dart';

-''',

-  '/pkg/packagename/second.dart': '''

-export 'dart:mirrors';

-''',

-

-  'paths':

-      "first.dart => package:packagename => dart:mirrors",

-  'verbosePaths':

-      "main.dart => first.dart => package:packagename/second.dart "

-      "=> dart:mirrors",

-};

-

-const INDIRECT_PACKAGE_EXPORT2 = const {

-  '/main.dart': '''

-import 'first.dart';

-

-main() {}

-''',

-  '/first.dart': '''

-export 'package:packagename/second.dart';

-''',

-  '/pkg/packagename/second.dart': '''

-import 'dart:mirrors';

-''',

-

-  'paths':

-      "first.dart => package:packagename => dart:mirrors",

-  'verbosePaths':

-      "main.dart => first.dart => package:packagename/second.dart "

-      "=> dart:mirrors",

-};

-

-Future test(Map sourceFiles,

-            {expectedPaths,

-             bool verbose: false,

-             bool enableExperimentalMirrors: false}) {

-  if (expectedPaths is! List) {

-    expectedPaths = [expectedPaths];

-  }

-  var collector = new DiagnosticCollector();

-  var options = [];

-  if (verbose) {

-    options.add('--verbose');

-  }

-  if (enableExperimentalMirrors) {

-    options.add('--enable-experimental-mirrors');

-  }

-  var compiler = compilerFor(sourceFiles, diagnosticHandler: collector,

-                             packageRoot: Uri.parse('memory:/pkg/'),

-                             options: options);

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

-    Expect.equals(0, collector.errors.length, 'Errors: ${collector.errors}');

-    if (enableExperimentalMirrors) {

-      Expect.equals(0, collector.warnings.length,

-                    'Warnings: ${collector.errors}');

-    } else {

-      Expect.equals(1, collector.warnings.length,

-                    'Warnings: ${collector.errors}');

-      Expect.equals(

-          MessageKind.IMPORT_EXPERIMENTAL_MIRRORS.message(

-              {'importChain': expectedPaths.join(

-                  MessageKind.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)}).toString(),

-          collector.warnings.first.message);

-    }

-  });

-}

-

-Future checkPaths(Map sourceData) {

-  Map sourceFiles = sourceData;

-  var expectedPaths = sourceData['paths'];

-  var expectedVerbosePaths = sourceData['verbosePaths'];

-  if (expectedVerbosePaths == null) {

-    expectedVerbosePaths = expectedPaths;

-  }

-  return test(sourceFiles, expectedPaths: expectedPaths).then((_) {

-    return test(

-        sourceFiles, expectedPaths: expectedVerbosePaths, verbose: true);

-  }).then((_) {

-    return test(sourceFiles, enableExperimentalMirrors: true);

-  });

-}

-

-void main() {

-  asyncTest(() => Future.forEach([

-      DIRECT_IMPORT,

-      INDIRECT_IMPORT1,

-      INDIRECT_IMPORT2,

-      INDIRECT_PACKAGE_IMPORT1,

-      INDIRECT_PACKAGE_IMPORT2,

-      INDIRECT_PACKAGE_IMPORT3,

-      INDIRECT_PACKAGE_IMPORT4,

-      DUAL_DIRECT_IMPORT,

-      DUAL_INDIRECT_IMPORT1,

-      DUAL_INDIRECT_IMPORT2,

-      DUAL_INDIRECT_IMPORT3,

-      DUAL_INDIRECT_PACKAGE_IMPORT1,

-      DIRECT_EXPORT,

-      INDIRECT_EXPORT1,

-      INDIRECT_EXPORT2,

-      INDIRECT_PACKAGE_EXPORT1,

-      INDIRECT_PACKAGE_EXPORT2],

-      (map) => checkPaths(map)

-  ));

-}

+// 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.
+
+// Test that the compiler emits a warning on import of 'dart:mirrors' unless
+// the flag --enable-experimental-mirrors is used.
+
+library dart2js.test.import;
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/dart2jslib.dart' show MessageKind;
+import 'memory_compiler.dart';
+
+const DIRECT_IMPORT = const {
+  '/main.dart': '''
+import 'dart:mirrors';
+
+main() {}
+''',
+
+  'paths':
+      "main.dart => dart:mirrors",
+};
+
+const INDIRECT_IMPORT1 = const {
+  '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'dart:mirrors';
+''',
+
+  'paths':
+      "first.dart => dart:mirrors",
+  'verbosePaths':
+      "main.dart => first.dart => dart:mirrors",
+};
+
+const INDIRECT_IMPORT2 = const {
+  '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'second.dart';
+''',
+  '/second.dart': '''
+import 'dart:mirrors';
+''',
+
+  'paths':
+      "second.dart => dart:mirrors",
+  'verbosePaths':
+      "main.dart => first.dart => second.dart => dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_IMPORT1 = const {
+  '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'package:second/second.dart';
+''',
+  '/pkg/second/second.dart': '''
+import 'dart:mirrors';
+''',
+
+  'paths':
+      "first.dart => package:second => dart:mirrors",
+  'verbosePaths':
+      "main.dart => first.dart => package:second/second.dart => dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_IMPORT2 = const {
+  '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'package:packagename/second.dart';
+''',
+  '/pkg/packagename/second.dart': '''
+import 'dart:mirrors';
+''',
+
+  'paths':
+      "first.dart => package:packagename => dart:mirrors",
+  'verbosePaths':
+      "main.dart => first.dart => package:packagename/second.dart "
+      "=> dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_IMPORT3 = const {
+  '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'package:package1/second.dart';
+''',
+  '/pkg/package1/second.dart': '''
+import 'package:package2/third.dart';
+''',
+  '/pkg/package2/third.dart': '''
+import 'dart:mirrors';
+''',
+
+  'paths':
+      "first.dart => package:package1 => package:package2 => dart:mirrors",
+  'verbosePaths':
+      "main.dart => first.dart => package:package1/second.dart "
+      "=> package:package2/third.dart => dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_IMPORT4 = const {
+  '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'package:package1/second.dart';
+''',
+  '/pkg/package1/second.dart': '''
+import 'sub/third.dart';
+''',
+  '/pkg/package1/sub/third.dart': '''
+import 'package:package2/fourth.dart';
+''',
+  '/pkg/package2/fourth.dart': '''
+import 'lib/src/fifth.dart';
+''',
+  '/pkg/package2/lib/src/fifth.dart': '''
+import 'dart:mirrors';
+''',
+
+  'paths':
+      "first.dart => package:package1 => package:package2 => dart:mirrors",
+  'verbosePaths':
+      "main.dart => first.dart => package:package1/second.dart "
+      "=> package:package1/sub/third.dart => package:package2/fourth.dart "
+      "=> package:package2/lib/src/fifth.dart => dart:mirrors",
+};
+
+const DUAL_DIRECT_IMPORT = const {
+  '/main.dart': '''
+import 'dart:mirrors';
+import 'dart:mirrors';
+
+main() {}
+''',
+
+  'paths':
+      "main.dart => dart:mirrors",
+};
+
+const DUAL_INDIRECT_IMPORT1 = const {
+  '/main.dart': '''
+import 'dart:mirrors';
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'dart:mirrors';
+''',
+
+  'paths': const
+      ["main.dart => dart:mirrors",
+       "first.dart => dart:mirrors"],
+  'verbosePaths': const
+      ["main.dart => dart:mirrors",
+       "main.dart => first.dart => dart:mirrors"],
+};
+
+const DUAL_INDIRECT_IMPORT2 = const {
+  '/main.dart': '''
+import 'first.dart';
+import 'second.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'dart:mirrors';
+''',
+  '/second.dart': '''
+import 'dart:mirrors';
+''',
+
+  'paths': const
+      ["first.dart => dart:mirrors",
+       "second.dart => dart:mirrors"],
+  'verbosePaths': const
+      ["main.dart => first.dart => dart:mirrors",
+       "main.dart => second.dart => dart:mirrors"],
+};
+
+const DUAL_INDIRECT_IMPORT3 = const {
+  '/main.dart': '''
+import 'first.dart';
+import 'second.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'third.dart';
+''',
+  '/second.dart': '''
+import 'third.dart';
+''',
+  '/third.dart': '''
+import 'dart:mirrors';
+''',
+
+  'paths':
+      "third.dart => dart:mirrors",
+  'verbosePaths': const
+      ["main.dart => first.dart => third.dart => dart:mirrors",
+       "main.dart => second.dart => third.dart => dart:mirrors"],
+};
+
+const DUAL_INDIRECT_PACKAGE_IMPORT1 = const {
+  '/main.dart': '''
+import 'package:package1/second.dart';
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'package:package2/third.dart';
+''',
+  '/pkg/package1/second.dart': '''
+import 'dart:mirrors';
+''',
+  '/pkg/package2/third.dart': '''
+import 'dart:mirrors';
+''',
+
+  'paths': const
+      ["main.dart => package:package1 => dart:mirrors",
+       "first.dart => package:package2 => dart:mirrors"],
+  'verbosePaths': const
+      ["main.dart => package:package1/second.dart => dart:mirrors",
+       "main.dart => first.dart => package:package2/third.dart => dart:mirrors"]
+};
+
+const DIRECT_EXPORT = const {
+  '/main.dart': '''
+export 'dart:mirrors';
+
+main() {}
+''',
+
+  'paths':
+      "main.dart => dart:mirrors",
+};
+
+const INDIRECT_EXPORT1 = const {
+  '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+export 'dart:mirrors';
+''',
+
+  'paths':
+      "first.dart => dart:mirrors",
+  'verbosePaths':
+      "main.dart => first.dart => dart:mirrors",
+};
+
+const INDIRECT_EXPORT2 = const {
+  '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'second.dart';
+''',
+  '/second.dart': '''
+export 'dart:mirrors';
+''',
+
+  'paths':
+      "second.dart => dart:mirrors",
+  'verbosePaths':
+      "main.dart => first.dart => second.dart => dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_EXPORT1 = const {
+  '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+import 'package:packagename/second.dart';
+''',
+  '/pkg/packagename/second.dart': '''
+export 'dart:mirrors';
+''',
+
+  'paths':
+      "first.dart => package:packagename => dart:mirrors",
+  'verbosePaths':
+      "main.dart => first.dart => package:packagename/second.dart "
+      "=> dart:mirrors",
+};
+
+const INDIRECT_PACKAGE_EXPORT2 = const {
+  '/main.dart': '''
+import 'first.dart';
+
+main() {}
+''',
+  '/first.dart': '''
+export 'package:packagename/second.dart';
+''',
+  '/pkg/packagename/second.dart': '''
+import 'dart:mirrors';
+''',
+
+  'paths':
+      "first.dart => package:packagename => dart:mirrors",
+  'verbosePaths':
+      "main.dart => first.dart => package:packagename/second.dart "
+      "=> dart:mirrors",
+};
+
+Future test(Map sourceFiles,
+            {expectedPaths,
+             bool verbose: false,
+             bool enableExperimentalMirrors: false}) {
+  if (expectedPaths is! List) {
+    expectedPaths = [expectedPaths];
+  }
+  var collector = new DiagnosticCollector();
+  var options = [];
+  if (verbose) {
+    options.add('--verbose');
+  }
+  if (enableExperimentalMirrors) {
+    options.add('--enable-experimental-mirrors');
+  }
+  var compiler = compilerFor(sourceFiles, diagnosticHandler: collector,
+                             packageRoot: Uri.parse('memory:/pkg/'),
+                             options: options);
+  return compiler.run(Uri.parse('memory:/main.dart')).then((_) {
+    Expect.equals(0, collector.errors.length, 'Errors: ${collector.errors}');
+    if (enableExperimentalMirrors) {
+      Expect.equals(0, collector.warnings.length,
+                    'Warnings: ${collector.errors}');
+    } else {
+      Expect.equals(1, collector.warnings.length,
+                    'Warnings: ${collector.errors}');
+      Expect.equals(
+          MessageKind.IMPORT_EXPERIMENTAL_MIRRORS.message(
+              {'importChain': expectedPaths.join(
+                  MessageKind.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)}).toString(),
+          collector.warnings.first.message);
+    }
+  });
+}
+
+Future checkPaths(Map sourceData) {
+  Map sourceFiles = sourceData;
+  var expectedPaths = sourceData['paths'];
+  var expectedVerbosePaths = sourceData['verbosePaths'];
+  if (expectedVerbosePaths == null) {
+    expectedVerbosePaths = expectedPaths;
+  }
+  return test(sourceFiles, expectedPaths: expectedPaths).then((_) {
+    return test(
+        sourceFiles, expectedPaths: expectedVerbosePaths, verbose: true);
+  }).then((_) {
+    return test(sourceFiles, enableExperimentalMirrors: true);
+  });
+}
+
+void main() {
+  asyncTest(() => Future.forEach([
+      DIRECT_IMPORT,
+      INDIRECT_IMPORT1,
+      INDIRECT_IMPORT2,
+      INDIRECT_PACKAGE_IMPORT1,
+      INDIRECT_PACKAGE_IMPORT2,
+      INDIRECT_PACKAGE_IMPORT3,
+      INDIRECT_PACKAGE_IMPORT4,
+      DUAL_DIRECT_IMPORT,
+      DUAL_INDIRECT_IMPORT1,
+      DUAL_INDIRECT_IMPORT2,
+      DUAL_INDIRECT_IMPORT3,
+      DUAL_INDIRECT_PACKAGE_IMPORT1,
+      DIRECT_EXPORT,
+      INDIRECT_EXPORT1,
+      INDIRECT_EXPORT2,
+      INDIRECT_PACKAGE_EXPORT1,
+      INDIRECT_PACKAGE_EXPORT2],
+      (map) => checkPaths(map)
+  ));
+}
diff --git a/tests/compiler/dart2js/instantiated_classes_test.dart b/tests/compiler/dart2js/instantiated_classes_test.dart
index d125ff9..ea90156 100644
--- a/tests/compiler/dart2js/instantiated_classes_test.dart
+++ b/tests/compiler/dart2js/instantiated_classes_test.dart
@@ -1,85 +1,85 @@
-// 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 instantiated_classes_test;

-

-import 'dart:async';

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

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

-import 'package:compiler/src/elements/elements.dart'

-    show ClassElement;

-import 'type_test_helper.dart';

-

-void main() {

-  asyncTest(() => Future.forEach([

-    () => test("class Class {}", ["Class"]),

-    () => test("""abstract class A {}

-                  class Class extends A {}""",

-               ["Class"]),

-    () => test("""class A {}

-                  class Class extends A {}""",

-               ["Class"]),

-    () => test("""class A {}

-                  class B {}

-                  class Class extends A {}""",

-               ["Class"]),

-    () => test("""class A {}

-                  class Class implements A {}""",

-               ["Class"]),

-    () => test("""class A {}

-                  class Class extends Object with A {}""",

-               ["Class"]),

-    () => test("""class A {}

-                  class B {}

-                  class Class extends Object with B implements A {}""",

-               ["Class"]),

-

-    () => test("""class A {}

-                  class Class {}""",

-               ["Class", "A"], ["Class", "A"]),

-    () => test("""class A {}

-                  class Class extends A {}""",

-               ["Class", "A"], ["Class", "A"]),

-    () => test("""class A {}

-                  class Class implements A {}""",

-               ["Class", "A"], ["Class", "A"]),

-    () => test("""class A {}

-                  class B extends A {}

-                  class Class extends B {}""",

-               ["Class", "A"], ["Class", "A"]),

-    () => test("""class A {}

-                  class B {}

-                  class Class extends B with A {}""",

-               ["Class", "A"], ["Class", "A"]),

-

-    // TODO(johnniwinther): Avoid registration of `Class` as instantiated.

-    () => test("""class A {}

-                  class Class implements A {

-                    factory Class() = A;

-                  }""",

-               ["Class", "A"], ["Class"]),

-  ], (f) => f()));

-}

-

-Future test(String source, List<String> directlyInstantiatedClasses,

-            [List<String> newClasses = const <String>["Class"]]) {

-  StringBuffer mainSource = new StringBuffer();

-  mainSource.write('main() {\n');

-  for (String newClass in newClasses) {

-    mainSource.write('  new $newClass();\n');

-  }

-  mainSource.write('}');

-  return TypeEnvironment.create(source,

-        mainSource: mainSource.toString(),

-        useMockCompiler: true).then((env) {

-    Iterable<ClassElement> expectedClasses =

-        directlyInstantiatedClasses.map(env.getElement);

-    Iterable<ClassElement> actualClasses =

-        env.compiler.resolverWorld.directlyInstantiatedClasses.where(

-            (c) => c.library == env.compiler.mainApp);

-    Expect.setEquals(expectedClasses, actualClasses);

-  });

-}

-

-

+// 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 instantiated_classes_test;
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/elements/elements.dart'
+    show ClassElement;
+import 'type_test_helper.dart';
+
+void main() {
+  asyncTest(() => Future.forEach([
+    () => test("class Class {}", ["Class"]),
+    () => test("""abstract class A {}
+                  class Class extends A {}""",
+               ["Class"]),
+    () => test("""class A {}
+                  class Class extends A {}""",
+               ["Class"]),
+    () => test("""class A {}
+                  class B {}
+                  class Class extends A {}""",
+               ["Class"]),
+    () => test("""class A {}
+                  class Class implements A {}""",
+               ["Class"]),
+    () => test("""class A {}
+                  class Class extends Object with A {}""",
+               ["Class"]),
+    () => test("""class A {}
+                  class B {}
+                  class Class extends Object with B implements A {}""",
+               ["Class"]),
+
+    () => test("""class A {}
+                  class Class {}""",
+               ["Class", "A"], ["Class", "A"]),
+    () => test("""class A {}
+                  class Class extends A {}""",
+               ["Class", "A"], ["Class", "A"]),
+    () => test("""class A {}
+                  class Class implements A {}""",
+               ["Class", "A"], ["Class", "A"]),
+    () => test("""class A {}
+                  class B extends A {}
+                  class Class extends B {}""",
+               ["Class", "A"], ["Class", "A"]),
+    () => test("""class A {}
+                  class B {}
+                  class Class extends B with A {}""",
+               ["Class", "A"], ["Class", "A"]),
+
+    // TODO(johnniwinther): Avoid registration of `Class` as instantiated.
+    () => test("""class A {}
+                  class Class implements A {
+                    factory Class() = A;
+                  }""",
+               ["Class", "A"], ["Class"]),
+  ], (f) => f()));
+}
+
+Future test(String source, List<String> directlyInstantiatedClasses,
+            [List<String> newClasses = const <String>["Class"]]) {
+  StringBuffer mainSource = new StringBuffer();
+  mainSource.write('main() {\n');
+  for (String newClass in newClasses) {
+    mainSource.write('  new $newClass();\n');
+  }
+  mainSource.write('}');
+  return TypeEnvironment.create(source,
+        mainSource: mainSource.toString(),
+        useMockCompiler: true).then((env) {
+    Iterable<ClassElement> expectedClasses =
+        directlyInstantiatedClasses.map(env.getElement);
+    Iterable<ClassElement> actualClasses =
+        env.compiler.resolverWorld.directlyInstantiatedClasses.where(
+            (c) => c.library == env.compiler.mainApp);
+    Expect.setEquals(expectedClasses, actualClasses);
+  });
+}
+
+
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
index 264dc65..8ba0f45 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_basic_test.dart
@@ -34,7 +34,6 @@
   P.print("(1)");
   P.print("(" + H.S(l) + ")");
   P.print("(" + H.S(m) + ")");
-  return null;
 }"""),
   const TestEntry("""
 foo(a, [b = "b"]) => b;
@@ -56,7 +55,6 @@
   V.bar(4, 5, "c");
   V.bar(6, "b", 7);
   V.bar(8, 9, 10);
-  return null;
 }"""),
   const TestEntry(
   """
@@ -83,7 +81,6 @@
   P.print(a);
   P.print(a);
   P.print(V.foo(b));
-  return null;
 }"""),
   const TestEntry(
   """
@@ -97,7 +94,6 @@
   const TestEntry("main() { return 42; }"),
   const TestEntry("main() { return; }", """
 function() {
-  return null;
 }"""),
   // Constructor invocation
   const TestEntry("""
@@ -108,7 +104,6 @@
 function() {
   P.print(P.LinkedHashSet_LinkedHashSet(null, null, null, null));
   P.print(P.LinkedHashSet_LinkedHashSet$from([1, 2, 3], null));
-  return null;
 }"""),
   // Call synthetic constructor.
   const TestEntry("""
@@ -123,7 +118,6 @@
 }""", r"""
 function() {
   P.print(P.DateTime$now().isBefore$1(P.DateTime$now()));
-  return null;
 }"""),
   // Static calls
   const TestEntry("""
@@ -132,7 +126,6 @@
 """, r"""
 function() {
   V.foo();
-  return null;
 }"""),
   // Static getters
   const TestEntry("""
@@ -141,7 +134,6 @@
 """, r"""
 function() {
   P.print($.foo);
-  return null;
 }"""),
   const TestEntry("""
 get foo { print(42); }
@@ -149,7 +141,6 @@
 """, r"""
 function() {
   V.foo();
-  return null;
 }"""),
   // Static setters
   const TestEntry("""
@@ -160,7 +151,6 @@
   var v0 = 42;
   $.foo = v0;
   P.print(v0);
-  return null;
 }"""),
   const TestEntry("""
 set foo(x) { print(x); }
@@ -168,7 +158,6 @@
 """, r"""
 function() {
   V.foo(42);
-  return null;
 }"""),
   // Assert
   const TestEntry("""
@@ -181,7 +170,6 @@
 }""", r"""
 function() {
   P.print("Done");
-  return null;
 }""")
 ];
 
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
index e58e474..97b53e7 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_closures_test.dart
@@ -24,7 +24,6 @@
   _box_0._captured_x_0 = x;
   _box_0._captured_x_0 = J.getInterceptor$ns(x = _box_0._captured_x_0).$add(x, "1");
   P.print(a.call$0());
-  return null;
 }"""),
 
   const TestEntry("""
@@ -38,7 +37,6 @@
 r"""
 function(x) {
   P.print(new V.main_a(x).call$0());
-  return null;
 }"""),
 
   const TestEntry("""
@@ -55,7 +53,6 @@
   _box_0._captured_x_0 = 122;
   _box_0._captured_x_0 = _box_0._captured_x_0 + 1;
   P.print(a.call$0());
-  return null;
 }"""),
 
   const TestEntry("""
@@ -75,7 +72,6 @@
   _box_0._captured_x_0 = 122;
   _box_0._captured_x_0 = _box_0._captured_x_0 + 1;
   P.print(a.call$0().call$0());
-  return null;
 }"""),
 
   const TestEntry("""
@@ -95,7 +91,6 @@
     i = i + 1;
   }
   P.print(a.call$0());
-  return null;
 }"""),
 
   const TestEntry.forMethod('function(A#b)', """
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
index ff798ac..b724218 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_constructor_test.dart
@@ -43,7 +43,6 @@
 r"""
 function(x, y) {
   P.print(x);
-  return null;
 }"""),
 
   const TestEntry.forMethod('generative_constructor(Sub#)', """
@@ -163,7 +162,6 @@
 }""", r"""
 function() {
   P.print(V.C$(P.$int).foo$0());
-  return null;
 }"""),
   const TestEntry(r"""
 class C<T> {
@@ -174,7 +172,6 @@
 }""", r"""
 function() {
   P.print(V.C$().foo$0());
-  return null;
 }"""),
   const TestEntry.forMethod('generative_constructor(C#)', r"""
 class C<T> {
@@ -246,7 +243,6 @@
 }""", r"""
 function() {
   P.print(V.Foo$create(5));
-  return null;
 }"""),
 const TestEntry(r"""
 class A {
@@ -264,7 +260,6 @@
 }""", r"""
 function() {
   V.B$(5, P.$int).get$typevar();
-  return null;
 }"""),
 ];
 
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
index 0e5808a..b6fc9ad 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_control_flow_test.dart
@@ -60,13 +60,11 @@
   L1:
     while (P.identical(V.foo(true), true)) {
       P.print(1);
-      if (!P.identical(V.foo(false), true))
-        i = V.foo(i);
-      else
+      if (P.identical(V.foo(false), true))
         break L1;
+      i = V.foo(i);
     }
   P.print(2);
-  return null;
 }"""),
 const TestEntry("""
 foo(a) => a;
@@ -82,7 +80,6 @@
 function() {
   V.foo(true) ? P.print(1) : P.print(2);
   P.print(3);
-  return null;
 }"""),
 const TestEntry("""
 foo(a) => a;
@@ -106,7 +103,6 @@
     P.print(2);
   }
   P.print(3);
-  return null;
 }"""),
 const TestEntry("""
 main() {
@@ -118,7 +114,6 @@
 }""","""
 function() {
   P.print("good");
-  return null;
 }"""),
   const TestEntry("""
 foo() => 2;
@@ -132,7 +127,6 @@
 function() {
   V.foo();
   P.print("good");
-  return null;
 }"""),
 ];
 
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
index 41073af..60f9717 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_interceptors_test.dart
@@ -19,7 +19,6 @@
 r"""
 function() {
   P.print(4);
-  return null;
 }"""),
   const TestEntry("""
 main() {
@@ -45,7 +44,6 @@
     }
     i = i + 1;
   }
-  return null;
 }"""),
 ];
 
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart
index 5664553..ad9d2e7 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_literals_test.dart
@@ -29,7 +29,6 @@
   P.print(P.LinkedHashMap_LinkedHashMap$_empty());
   P.print(P.LinkedHashMap_LinkedHashMap$_literal([1, 2]));
   P.print(P.LinkedHashMap_LinkedHashMap$_literal([[1, 2], [3, 4]]));
-  return null;
 }"""),
 ];
 
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart
index 486bcc7..577dca0 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_operators_test.dart
@@ -18,7 +18,6 @@
 """function() {
   V.foo();
   P.print("bad bad");
-  return null;
 }"""),
   const TestEntry("""
 foo() => null;
@@ -28,7 +27,6 @@
 """function() {
   V.foo();
   P.print("bad bad");
-  return null;
 }"""),
   const TestEntry("""
 get foo => foo;
@@ -38,7 +36,6 @@
 """function() {
   V.foo();
   P.print("bad bad");
-  return null;
 }"""),
   const TestEntry("""
 get foo => foo;
@@ -46,7 +43,6 @@
 """function() {
   V.foo();
   P.print(false);
-  return null;
 }"""),
   const TestEntry("""
 get foo => foo;
@@ -55,7 +51,6 @@
   V.foo();
   V.foo();
   P.print(false);
-  return null;
 }"""),
 
 // Needs interceptor calling convention
@@ -84,7 +79,6 @@
   var list = [1, 2, 3];
   J.getInterceptor$a(list).$indexSet(list, 1, 6);
   P.print(list);
-  return null;
 }"""),
 ];
 
diff --git a/tests/compiler/dart2js/least_upper_bound_language_test.dart b/tests/compiler/dart2js/least_upper_bound_language_test.dart
index f75c32c..ad01ad0 100644
--- a/tests/compiler/dart2js/least_upper_bound_language_test.dart
+++ b/tests/compiler/dart2js/least_upper_bound_language_test.dart
@@ -1,22 +1,22 @@
-// 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.

-

-// Test that dart2js produces the expected static type warnings for least upper

-// bound language tests. This ensures that the analyzer and dart2js agrees

-// on these tests.

-

-import 'warnings_checker.dart';

-

-/// Map from test files to a map of their expected status. If the status map is

-/// `null` no warnings must be missing or unexpected, otherwise the status map

-/// can contain a list of line numbers for keys 'missing' and 'unexpected' for

-/// the warnings of each category.

-const Map<String, dynamic> TESTS = const {

-    'language/least_upper_bound_test.dart': null,

-    'language/least_upper_bound_expansive_test.dart': null,

-};

-

-void main() {

-  checkWarnings(TESTS);

-}

+// 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.
+
+// Test that dart2js produces the expected static type warnings for least upper
+// bound language tests. This ensures that the analyzer and dart2js agrees
+// on these tests.
+
+import 'warnings_checker.dart';
+
+/// Map from test files to a map of their expected status. If the status map is
+/// `null` no warnings must be missing or unexpected, otherwise the status map
+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
+/// the warnings of each category.
+const Map<String, dynamic> TESTS = const {
+    'language/least_upper_bound_test.dart': null,
+    'language/least_upper_bound_expansive_test.dart': null,
+};
+
+void main() {
+  checkWarnings(TESTS);
+}
diff --git a/tests/compiler/dart2js/least_upper_bound_test.dart b/tests/compiler/dart2js/least_upper_bound_test.dart
index 804b803..23aa02b 100644
--- a/tests/compiler/dart2js/least_upper_bound_test.dart
+++ b/tests/compiler/dart2js/least_upper_bound_test.dart
@@ -1,852 +1,852 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file

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

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

-

-library subtype_test;

-

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

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

-import 'type_test_helper.dart';

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

-import "package:compiler/src/elements/elements.dart"

-       show Element, ClassElement;

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

-

-void main() {

-  testInterface1();

-  testInterface2();

-  testGeneric();

-  testMixin();

-  testFunction();

-  testTypeVariable();

-}

-

-void testInterface1() {

-  asyncTest(() => TypeEnvironment.create(r"""

-      class A {} // A and B have equal depth.

-      class B {}

-      class I implements A, B {}

-      class J implements A, B {}

-      """).then((env) {

-

-    DartType Object_ = env['Object'];

-    DartType A = env['A'];

-    DartType B = env['B'];

-    DartType I = env['I'];

-    DartType J = env['J'];

-

-    checkLub(DartType a, DartType b, DartType expect) {

-      DartType lub = env.computeLeastUpperBound(a, b);

-      Expect.equals(expect, lub,

-          'Unexpected lub($a,$b) = $lub, expected $expect.');

-    }

-

-    checkLub(Object_, Object_, Object_);

-    checkLub(Object_, A, Object_);

-    checkLub(Object_, B, Object_);

-    checkLub(Object_, I, Object_);

-    checkLub(Object_, J, Object_);

-

-    checkLub(A, Object_, Object_);

-    checkLub(A, A, A);

-    checkLub(A, B, Object_);

-    checkLub(A, I, A);

-    checkLub(A, J, A);

-

-    checkLub(B, Object_, Object_);

-    checkLub(B, A, Object_);

-    checkLub(B, B, B);

-    checkLub(B, I, B);

-    checkLub(B, J, B);

-

-    checkLub(I, Object_, Object_);

-    checkLub(I, A, A);

-    checkLub(I, B, B);

-    checkLub(I, I, I);

-    checkLub(I, J, Object_);

-

-    checkLub(J, Object_, Object_);

-    checkLub(J, A, A);

-    checkLub(J, B, B);

-    checkLub(J, I, Object_);

-    checkLub(J, J, J);

-  }));

-}

-

-void testInterface2() {

-  asyncTest(() => TypeEnvironment.create(r"""

-      class A {}

-      class B {}

-      class C extends B {} // This makes C have higher depth than A.

-      class I implements A, C {}

-      class J implements A, C {}

-      """).then((env) {

-

-    DartType Object_ = env['Object'];

-    DartType A = env['A'];

-    DartType B = env['B'];

-    DartType C = env['C'];

-    DartType I = env['I'];

-    DartType J = env['J'];

-

-    checkLub(DartType a, DartType b, DartType expectedLub) {

-      DartType lub = env.computeLeastUpperBound(a, b);

-      Expect.equals(expectedLub, lub,

-          'Unexpected lub($a,$b) = $lub, expected $expectedLub');

-    }

-

-    checkLub(Object_, Object_, Object_);

-    checkLub(Object_, A, Object_);

-    checkLub(Object_, B, Object_);

-    checkLub(Object_, C, Object_);

-    checkLub(Object_, I, Object_);

-    checkLub(Object_, J, Object_);

-

-    checkLub(A, Object_, Object_);

-    checkLub(A, A, A);

-    checkLub(A, B, Object_);

-    checkLub(A, C, Object_);

-    checkLub(A, I, A);

-    checkLub(A, J, A);

-

-    checkLub(B, Object_, Object_);

-    checkLub(B, A, Object_);

-    checkLub(B, B, B);

-    checkLub(B, C, B);

-    checkLub(B, I, B);

-    checkLub(B, J, B);

-

-    checkLub(C, Object_, Object_);

-    checkLub(C, A, Object_);

-    checkLub(C, B, B);

-    checkLub(C, C, C);

-    checkLub(C, I, C);

-    checkLub(C, J, C);

-

-    checkLub(I, Object_, Object_);

-    checkLub(I, A, A);

-    checkLub(I, B, B);

-    checkLub(I, C, C);

-    checkLub(I, I, I);

-    checkLub(I, J, C);

-

-    checkLub(J, Object_, Object_);

-    checkLub(J, A, A);

-    checkLub(J, B, B);

-    checkLub(J, C, C);

-    checkLub(J, I, C);

-    checkLub(J, J, J);

-  }));

-}

-

-void testGeneric() {

-  asyncTest(() => TypeEnvironment.create(r"""

-      class A {}

-      class B {}

-      class C extends B {}

-      class I<T> {}

-      """).then((env) {

-

-    DartType Object_ = env['Object'];

-    DartType A = env['A'];

-    DartType B = env['B'];

-    DartType C = env['C'];

-    ClassElement I = env.getElement('I');

-    DartType I_A = instantiate(I, [A]);

-    DartType I_B = instantiate(I, [B]);

-    DartType I_C = instantiate(I, [C]);

-

-    checkLub(DartType a, DartType b, DartType expectedLub) {

-      DartType lub = env.computeLeastUpperBound(a, b);

-      Expect.equals(expectedLub, lub,

-          'Unexpected lub($a,$b) = $lub, expected $expectedLub');

-    }

-

-    checkLub(Object_, Object_, Object_);

-    checkLub(Object_, A, Object_);

-    checkLub(Object_, B, Object_);

-    checkLub(Object_, C, Object_);

-    checkLub(Object_, I_A, Object_);

-    checkLub(Object_, I_B, Object_);

-    checkLub(Object_, I_C, Object_);

-

-    checkLub(A, Object_, Object_);

-    checkLub(A, A, A);

-    checkLub(A, B, Object_);

-    checkLub(A, C, Object_);

-    checkLub(A, I_A, Object_);

-    checkLub(A, I_B, Object_);

-    checkLub(A, I_C, Object_);

-

-    checkLub(B, Object_, Object_);

-    checkLub(B, A, Object_);

-    checkLub(B, B, B);

-    checkLub(B, C, B);

-    checkLub(B, I_A, Object_);

-    checkLub(B, I_B, Object_);

-    checkLub(B, I_C, Object_);

-

-    checkLub(C, Object_, Object_);

-    checkLub(C, A, Object_);

-    checkLub(C, B, B);

-    checkLub(C, C, C);

-    checkLub(C, I_A, Object_);

-    checkLub(C, I_B, Object_);

-    checkLub(C, I_C, Object_);

-

-    checkLub(I_A, Object_, Object_);

-    checkLub(I_A, A, Object_);

-    checkLub(I_A, B, Object_);

-    checkLub(I_A, C, Object_);

-    checkLub(I_A, I_A, I_A);

-    checkLub(I_A, I_B, Object_);

-    checkLub(I_A, I_C, Object_);

-

-    checkLub(I_B, Object_, Object_);

-    checkLub(I_B, A, Object_);

-    checkLub(I_B, B, Object_);

-    checkLub(I_B, C, Object_);

-    checkLub(I_B, I_A, Object_);

-    checkLub(I_B, I_B, I_B);

-    checkLub(I_B, I_C, Object_);

-

-    checkLub(I_C, Object_, Object_);

-    checkLub(I_C, A, Object_);

-    checkLub(I_C, B, Object_);

-    checkLub(I_C, C, Object_);

-    checkLub(I_C, I_A, Object_);

-    checkLub(I_C, I_B, Object_);

-    checkLub(I_C, I_C, I_C);

-  }));

-}

-

-void testMixin() {

-  asyncTest(() => TypeEnvironment.create(r"""

-      class A {}

-      class B {}

-      class C extends B {}

-      class D extends C {} // This makes D have higher depth than Object+A.

-      class I extends Object with A, B implements A, D {}

-      class I2 extends Object with A, B implements A, D {}

-      class J extends Object with B, A implements A, D {}

-      """).then((env) {

-

-    DartType Object_ = env['Object'];

-    DartType A = env['A'];

-    DartType B = env['B'];

-    DartType C = env['C'];

-    DartType D = env['D'];

-    DartType I = env['I'];

-    DartType I2 = env['I2'];

-    DartType J = env['J'];

-

-    checkLub(DartType a, DartType b, DartType expectedLub) {

-      DartType lub = env.computeLeastUpperBound(a, b);

-      Expect.equals(expectedLub, lub,

-          'Unexpected lub($a,$b) = $lub, expected $expectedLub');

-    }

-

-    checkLub(Object_, Object_, Object_);

-    checkLub(Object_, A, Object_);

-    checkLub(Object_, B, Object_);

-    checkLub(Object_, C, Object_);

-    checkLub(Object_, D, Object_);

-    checkLub(Object_, I, Object_);

-    checkLub(Object_, I2, Object_);

-    checkLub(Object_, J, Object_);

-

-    checkLub(A, Object_, Object_);

-    checkLub(A, A, A);

-    checkLub(A, B, Object_);

-    checkLub(A, C, Object_);

-    checkLub(A, D, Object_);

-    checkLub(A, I, A);

-    checkLub(A, I2, A);

-    checkLub(A, J, A);

-

-    checkLub(B, Object_, Object_);

-    checkLub(B, A, Object_);

-    checkLub(B, B, B);

-    checkLub(B, C, B);

-    checkLub(B, D, B);

-    checkLub(B, I, B);

-    checkLub(B, I2, B);

-    checkLub(B, J, B);

-

-    checkLub(C, Object_, Object_);

-    checkLub(C, A, Object_);

-    checkLub(C, B, B);

-    checkLub(C, C, C);

-    checkLub(C, D, C);

-    checkLub(C, I, C);

-    checkLub(C, I2, C);

-    checkLub(C, J, C);

-

-    checkLub(D, Object_, Object_);

-    checkLub(D, A, Object_);

-    checkLub(D, B, B);

-    checkLub(D, C, C);

-    checkLub(D, D, D);

-    checkLub(D, I, D);

-    checkLub(D, I2, D);

-    checkLub(D, J, D);

-

-    checkLub(I, Object_, Object_);

-    checkLub(I, A, A);

-    checkLub(I, B, B);

-    checkLub(I, C, C);

-    checkLub(I, D, D);

-    checkLub(I, I, I);

-    checkLub(I, I2, D);

-    checkLub(I, J, D);

-

-    checkLub(I2, Object_, Object_);

-    checkLub(I2, A, A);

-    checkLub(I2, B, B);

-    checkLub(I2, C, C);

-    checkLub(I2, D, D);

-    checkLub(I2, I, D);

-    checkLub(I2, I2, I2);

-    checkLub(I2, J, D);

-

-    checkLub(J, Object_, Object_);

-    checkLub(J, A, A);

-    checkLub(J, B, B);

-    checkLub(J, C, C);

-    checkLub(J, D, D);

-    checkLub(J, I, D);

-    checkLub(J, I2, D);

-    checkLub(J, J, J);

-  }));

-}

-

-void testFunction() {

-  asyncTest(() => TypeEnvironment.create(r"""

-      class A {}

-      class B {}

-      class C extends B {}

-

-      typedef dynamic__();

-      typedef void void__();

-      typedef A A__();

-      typedef B B__();

-      typedef C C__();

-

-      typedef void void__A_B(A a, B b);

-      typedef void void__A_C(A a, C b);

-      typedef void void__B_A(B a, A b);

-      typedef void void__B_C(B a, C b);

-

-      typedef void void___B([B a]);

-      typedef void void___B_C([B a, C b]);

-      typedef void void___C_C([C a, C b]);

-

-      typedef void void____B({B a});

-      typedef void void____B_C({B a, C b});

-      typedef void void____C_C({C a, C b});

-      """).then((env) {

-

-    DartType Object_ = env['Object'];

-    DartType Function_ = env['Function'];

-    DartType dynamic__ = env['dynamic__'];

-    DartType void__ = env['void__'];

-    DartType A__ = env['A__'];

-    DartType B__ = env['B__'];

-    DartType C__ = env['C__'];

-    DartType void__A_B = env['void__A_B'];

-    DartType void__A_C = env['void__A_C'];

-    DartType void__B_A = env['void__B_A'];

-    DartType void__B_C = env['void__B_C'];

-    DartType void___B = env['void___B'];

-    DartType void___B_C = env['void___B_C'];

-    DartType void___C_C = env['void___C_C'];

-    DartType void____B = env['void____B'];

-    DartType void____B_C = env['void____B_C'];

-    DartType void____C_C = env['void____C_C'];

-

-    // Types used only for checking results.

-    DartType void_ = env['void'];

-    DartType B = env['B'];

-    DartType C = env['C'];

-    FunctionType Object__ = env.functionType(Object_, []);

-    FunctionType void__Object_Object =

-        env.functionType(void_, [Object_, Object_]);

-    FunctionType void__Object_B =

-        env.functionType(void_, [Object_, B]);

-    FunctionType void__Object_C =

-        env.functionType(void_, [Object_, C]);

-    FunctionType void__B_Object =

-        env.functionType(void_, [B, Object_]);

-

-    checkLub(DartType a, DartType b, DartType expectedLub) {

-      DartType lub = env.computeLeastUpperBound(a, b);

-      if (a != b) {

-        expectedLub = expectedLub.unalias(env.compiler);

-        lub = lub.unalias(env.compiler);

-      }

-      Expect.equals(expectedLub, lub,

-          'Unexpected lub(${a.unalias(env.compiler)},'

-                         '${b.unalias(env.compiler)}) = '

-                         '${lub}, expected ${expectedLub}');

-    }

-

-    checkLub(Object_, Object_, Object_);

-    checkLub(Object_, Function_, Object_);

-    checkLub(Object_, dynamic__, Object_);

-    checkLub(Object_, void__, Object_);

-    checkLub(Object_, A__, Object_);

-    checkLub(Object_, B__, Object_);

-    checkLub(Object_, C__, Object_);

-    checkLub(Object_, void__A_B, Object_);

-    checkLub(Object_, void__A_C, Object_);

-    checkLub(Object_, void__B_A, Object_);

-    checkLub(Object_, void__B_C, Object_);

-    checkLub(Object_, void___B, Object_);

-    checkLub(Object_, void___B_C, Object_);

-    checkLub(Object_, void___C_C, Object_);

-    checkLub(Object_, void____B, Object_);

-    checkLub(Object_, void____B_C, Object_);

-    checkLub(Object_, void____C_C, Object_);

-

-    checkLub(Function_, Object_, Object_);

-    checkLub(Function_, Function_, Function_);

-    checkLub(Function_, dynamic__, Function_);

-    checkLub(Function_, void__, Function_);

-    checkLub(Function_, A__, Function_);

-    checkLub(Function_, B__, Function_);

-    checkLub(Function_, C__, Function_);

-    checkLub(Function_, void__A_B, Function_);

-    checkLub(Function_, void__A_C, Function_);

-    checkLub(Function_, void__B_A, Function_);

-    checkLub(Function_, void__B_C, Function_);

-    checkLub(Function_, void___B, Function_);

-    checkLub(Function_, void___B_C, Function_);

-    checkLub(Function_, void___C_C, Function_);

-    checkLub(Function_, void____B, Function_);

-    checkLub(Function_, void____B_C, Function_);

-    checkLub(Function_, void____C_C, Function_);

-

-    checkLub(dynamic__, Object_, Object_);

-    checkLub(dynamic__, Function_, Function_);

-    checkLub(dynamic__, dynamic__, dynamic__);

-    checkLub(dynamic__, void__, dynamic__);

-    checkLub(dynamic__, A__, dynamic__);

-    checkLub(dynamic__, B__, dynamic__);

-    checkLub(dynamic__, C__, dynamic__);

-    checkLub(dynamic__, void__A_B, Function_);

-    checkLub(dynamic__, void__A_C, Function_);

-    checkLub(dynamic__, void__B_A, Function_);

-    checkLub(dynamic__, void__B_C, Function_);

-    checkLub(dynamic__, void___B, dynamic__);

-    checkLub(dynamic__, void___B_C, dynamic__);

-    checkLub(dynamic__, void___C_C, dynamic__);

-    checkLub(dynamic__, void____B, dynamic__);

-    checkLub(dynamic__, void____B_C, dynamic__);

-    checkLub(dynamic__, void____C_C, dynamic__);

-

-    checkLub(void__, Object_, Object_);

-    checkLub(void__, Function_, Function_);

-    checkLub(void__, dynamic__, dynamic__);

-    checkLub(void__, void__, void__);

-    checkLub(void__, A__, void__);

-    checkLub(void__, B__, void__);

-    checkLub(void__, C__, void__);

-    checkLub(void__, void__A_B, Function_);

-    checkLub(void__, void__A_C, Function_);

-    checkLub(void__, void__B_A, Function_);

-    checkLub(void__, void__B_C, Function_);

-    checkLub(void__, void___B, void__);

-    checkLub(void__, void___B_C, void__);

-    checkLub(void__, void___C_C, void__);

-    checkLub(void__, void____B, void__);

-    checkLub(void__, void____B_C, void__);

-    checkLub(void__, void____C_C, void__);

-

-    checkLub(A__, Object_, Object_);

-    checkLub(A__, Function_, Function_);

-    checkLub(A__, dynamic__, dynamic__);

-    checkLub(A__, void__, void__);

-    checkLub(A__, A__, A__);

-    checkLub(A__, B__, Object__);

-    checkLub(A__, C__, Object__);

-    checkLub(A__, void__A_B, Function_);

-    checkLub(A__, void__A_C, Function_);

-    checkLub(A__, void__B_A, Function_);

-    checkLub(A__, void__B_C, Function_);

-    checkLub(A__, void___B, void__);

-    checkLub(A__, void___B_C, void__);

-    checkLub(A__, void___C_C, void__);

-    checkLub(A__, void____B, void__);

-    checkLub(A__, void____B_C, void__);

-    checkLub(A__, void____C_C, void__);

-

-    checkLub(B__, Object_, Object_);

-    checkLub(B__, Function_, Function_);

-    checkLub(B__, dynamic__, dynamic__);

-    checkLub(B__, void__, void__);

-    checkLub(B__, A__, Object__);

-    checkLub(B__, B__, B__);

-    checkLub(B__, C__, B__);

-    checkLub(B__, void__A_B, Function_);

-    checkLub(B__, void__A_C, Function_);

-    checkLub(B__, void__B_A, Function_);

-    checkLub(B__, void__B_C, Function_);

-    checkLub(B__, void___B, void__);

-    checkLub(B__, void___B_C, void__);

-    checkLub(B__, void___C_C, void__);

-    checkLub(B__, void____B, void__);

-    checkLub(B__, void____B_C, void__);

-    checkLub(B__, void____C_C, void__);

-

-    checkLub(C__, Object_, Object_);

-    checkLub(C__, Function_, Function_);

-    checkLub(C__, dynamic__, dynamic__);

-    checkLub(C__, void__, void__);

-    checkLub(C__, A__, Object__);

-    checkLub(C__, B__, B__);

-    checkLub(C__, C__, C__);

-    checkLub(C__, void__A_B, Function_);

-    checkLub(C__, void__A_C, Function_);

-    checkLub(C__, void__B_A, Function_);

-    checkLub(C__, void__B_C, Function_);

-    checkLub(C__, void___B, void__);

-    checkLub(C__, void___B_C, void__);

-    checkLub(C__, void___C_C, void__);

-    checkLub(C__, void____B, void__);

-    checkLub(C__, void____B_C, void__);

-    checkLub(C__, void____C_C, void__);

-

-    checkLub(void__A_B, Object_, Object_);

-    checkLub(void__A_B, Function_, Function_);

-    checkLub(void__A_B, dynamic__, Function_);

-    checkLub(void__A_B, void__, Function_);

-    checkLub(void__A_B, A__, Function_);

-    checkLub(void__A_B, B__, Function_);

-    checkLub(void__A_B, C__, Function_);

-    checkLub(void__A_B, void__A_B, void__A_B);

-    checkLub(void__A_B, void__A_C, void__A_B);

-    checkLub(void__A_B, void__B_A, void__Object_Object);

-    checkLub(void__A_B, void__B_C, void__Object_B);

-    checkLub(void__A_B, void___B, Function_);

-    checkLub(void__A_B, void___B_C, Function_);

-    checkLub(void__A_B, void___C_C, Function_);

-    checkLub(void__A_B, void____B, Function_);

-    checkLub(void__A_B, void____B_C, Function_);

-    checkLub(void__A_B, void____C_C, Function_);

-

-    checkLub(void__A_C, Object_, Object_);

-    checkLub(void__A_C, Function_, Function_);

-    checkLub(void__A_C, dynamic__, Function_);

-    checkLub(void__A_C, void__, Function_);

-    checkLub(void__A_C, A__, Function_);

-    checkLub(void__A_C, B__, Function_);

-    checkLub(void__A_C, C__, Function_);

-    checkLub(void__A_C, void__A_B, void__A_B);

-    checkLub(void__A_C, void__A_C, void__A_C);

-    checkLub(void__A_C, void__B_A, void__Object_Object);

-    checkLub(void__A_C, void__B_C, void__Object_C);

-    checkLub(void__A_C, void___B, Function_);

-    checkLub(void__A_C, void___B_C, Function_);

-    checkLub(void__A_C, void___C_C, Function_);

-    checkLub(void__A_C, void____B, Function_);

-    checkLub(void__A_C, void____B_C, Function_);

-    checkLub(void__A_C, void____C_C, Function_);

-

-    checkLub(void__B_A, Object_, Object_);

-    checkLub(void__B_A, Function_, Function_);

-    checkLub(void__B_A, dynamic__, Function_);

-    checkLub(void__B_A, void__, Function_);

-    checkLub(void__B_A, A__, Function_);

-    checkLub(void__B_A, B__, Function_);

-    checkLub(void__B_A, C__, Function_);

-    checkLub(void__B_A, void__A_B, void__Object_Object);

-    checkLub(void__B_A, void__A_C, void__Object_Object);

-    checkLub(void__B_A, void__B_A, void__B_A);

-    checkLub(void__B_A, void__B_C, void__B_Object);

-    checkLub(void__B_A, void___B, Function_);

-    checkLub(void__B_A, void___B_C, Function_);

-    checkLub(void__B_A, void___C_C, Function_);

-    checkLub(void__B_A, void____B, Function_);

-    checkLub(void__B_A, void____B_C, Function_);

-    checkLub(void__B_A, void____C_C, Function_);

-

-    checkLub(void__B_C, Object_, Object_);

-    checkLub(void__B_C, Function_, Function_);

-    checkLub(void__B_C, dynamic__, Function_);

-    checkLub(void__B_C, void__, Function_);

-    checkLub(void__B_C, A__, Function_);

-    checkLub(void__B_C, B__, Function_);

-    checkLub(void__B_C, C__, Function_);

-    checkLub(void__B_C, void__A_B, void__Object_B);

-    checkLub(void__B_C, void__A_C, void__Object_C);

-    checkLub(void__B_C, void__B_A, void__B_Object);

-    checkLub(void__B_C, void__B_C, void__B_C);

-    checkLub(void__B_C, void___B, Function_);

-    checkLub(void__B_C, void___B_C, Function_);

-    checkLub(void__B_C, void___C_C, Function_);

-    checkLub(void__B_C, void____B, Function_);

-    checkLub(void__B_C, void____B_C, Function_);

-    checkLub(void__B_C, void____C_C, Function_);

-

-    checkLub(void___B, Object_, Object_);

-    checkLub(void___B, Function_, Function_);

-    checkLub(void___B, dynamic__, dynamic__);

-    checkLub(void___B, void__, void__);

-    checkLub(void___B, A__, void__);

-    checkLub(void___B, B__, void__);

-    checkLub(void___B, C__, void__);

-    checkLub(void___B, void__A_B, Function_);

-    checkLub(void___B, void__A_C, Function_);

-    checkLub(void___B, void__B_A, Function_);

-    checkLub(void___B, void__B_C, Function_);

-    checkLub(void___B, void___B, void___B);

-    checkLub(void___B, void___B_C, void___B);

-    checkLub(void___B, void___C_C, void___B);

-    checkLub(void___B, void____B, void__);

-    checkLub(void___B, void____B_C, void__);

-    checkLub(void___B, void____C_C, void__);

-

-    checkLub(void___B_C, Object_, Object_);

-    checkLub(void___B_C, Function_, Function_);

-    checkLub(void___B_C, dynamic__, dynamic__);

-    checkLub(void___B_C, void__, void__);

-    checkLub(void___B_C, A__, void__);

-    checkLub(void___B_C, B__, void__);

-    checkLub(void___B_C, C__, void__);

-    checkLub(void___B_C, void__A_B, Function_);

-    checkLub(void___B_C, void__A_C, Function_);

-    checkLub(void___B_C, void__B_A, Function_);

-    checkLub(void___B_C, void__B_C, Function_);

-    checkLub(void___B_C, void___B, void___B);

-    checkLub(void___B_C, void___B_C, void___B_C);

-    checkLub(void___B_C, void___C_C, void___B_C);

-    checkLub(void___B_C, void____B, void__);

-    checkLub(void___B_C, void____B_C, void__);

-    checkLub(void___B_C, void____C_C, void__);

-

-    checkLub(void___C_C, Object_, Object_);

-    checkLub(void___C_C, Function_, Function_);

-    checkLub(void___C_C, dynamic__, dynamic__);

-    checkLub(void___C_C, void__, void__);

-    checkLub(void___C_C, A__, void__);

-    checkLub(void___C_C, B__, void__);

-    checkLub(void___C_C, C__, void__);

-    checkLub(void___C_C, void__A_B, Function_);

-    checkLub(void___C_C, void__A_C, Function_);

-    checkLub(void___C_C, void__B_A, Function_);

-    checkLub(void___C_C, void__B_C, Function_);

-    checkLub(void___C_C, void___B, void___B);

-    checkLub(void___C_C, void___B_C, void___B_C);

-    checkLub(void___C_C, void___C_C, void___C_C);

-    checkLub(void___C_C, void____B, void__);

-    checkLub(void___C_C, void____B_C, void__);

-    checkLub(void___C_C, void____C_C, void__);

-

-    checkLub(void____B, Object_, Object_);

-    checkLub(void____B, Function_, Function_);

-    checkLub(void____B, dynamic__, dynamic__);

-    checkLub(void____B, void__, void__);

-    checkLub(void____B, A__, void__);

-    checkLub(void____B, B__, void__);

-    checkLub(void____B, C__, void__);

-    checkLub(void____B, void__A_B, Function_);

-    checkLub(void____B, void__A_C, Function_);

-    checkLub(void____B, void__B_A, Function_);

-    checkLub(void____B, void__B_C, Function_);

-    checkLub(void____B, void___B, void__);

-    checkLub(void____B, void___B_C, void__);

-    checkLub(void____B, void___C_C, void__);

-    checkLub(void____B, void____B, void____B);

-    checkLub(void____B, void____B_C, void____B);

-    checkLub(void____B, void____C_C, void____B);

-

-    checkLub(void____B_C, Object_, Object_);

-    checkLub(void____B_C, Function_, Function_);

-    checkLub(void____B_C, dynamic__, dynamic__);

-    checkLub(void____B_C, void__, void__);

-    checkLub(void____B_C, A__, void__);

-    checkLub(void____B_C, B__, void__);

-    checkLub(void____B_C, C__, void__);

-    checkLub(void____B_C, void__A_B, Function_);

-    checkLub(void____B_C, void__A_C, Function_);

-    checkLub(void____B_C, void__B_A, Function_);

-    checkLub(void____B_C, void__B_C, Function_);

-    checkLub(void____B_C, void___B, void__);

-    checkLub(void____B_C, void___B_C, void__);

-    checkLub(void____B_C, void___C_C, void__);

-    checkLub(void____B_C, void____B, void____B);

-    checkLub(void____B_C, void____B_C, void____B_C);

-    checkLub(void____B_C, void____C_C, void____B_C);

-

-    checkLub(void____C_C, Object_, Object_);

-    checkLub(void____C_C, Function_, Function_);

-    checkLub(void____C_C, dynamic__, dynamic__);

-    checkLub(void____C_C, void__, void__);

-    checkLub(void____C_C, A__, void__);

-    checkLub(void____C_C, B__, void__);

-    checkLub(void____C_C, C__, void__);

-    checkLub(void____C_C, void__A_B, Function_);

-    checkLub(void____C_C, void__A_C, Function_);

-    checkLub(void____C_C, void__B_A, Function_);

-    checkLub(void____C_C, void__B_C, Function_);

-    checkLub(void____C_C, void___B, void__);

-    checkLub(void____C_C, void___B_C, void__);

-    checkLub(void____C_C, void___C_C, void__);

-    checkLub(void____C_C, void____B, void____B);

-    checkLub(void____C_C, void____B_C, void____B_C);

-    checkLub(void____C_C, void____C_C, void____C_C);

-  }));

-}

-

-void testTypeVariable() {

-  asyncTest(() => TypeEnvironment.create(r"""

-      class A {}

-      class B {}

-      class C extends B {}

-      class I<S extends A,

-              T extends B,

-              U extends C,

-              V extends T,

-              W extends V,

-              X extends T> {}

-      """).then((env) {

-

-    //  A     B

-    //  |    / \

-    //  S   T   C

-    //     / \   \

-    //    V   X   U

-    //   /

-    //  W

-

-    DartType Object_ = env['Object'];

-    DartType A = env['A'];

-    DartType B = env['B'];

-    DartType C = env['C'];

-    ClassElement I = env.getElement('I');

-    DartType S = I.typeVariables[0];

-    DartType T = I.typeVariables[1];

-    DartType U = I.typeVariables[2];

-    DartType V = I.typeVariables[3];

-    DartType W = I.typeVariables[4];

-    DartType X = I.typeVariables[5];

-

-    checkLub(DartType a, DartType b, DartType expectedLub) {

-      DartType lub = env.computeLeastUpperBound(a, b);

-      Expect.equals(expectedLub, lub,

-          'Unexpected lub($a,$b) = $lub, expected $expectedLub');

-    }

-

-    checkLub(Object_, Object_, Object_);

-    checkLub(Object_, A, Object_);

-    checkLub(Object_, B, Object_);

-    checkLub(Object_, C, Object_);

-    checkLub(Object_, S, Object_);

-    checkLub(Object_, T, Object_);

-    checkLub(Object_, U, Object_);

-    checkLub(Object_, V, Object_);

-    checkLub(Object_, W, Object_);

-    checkLub(Object_, X, Object_);

-

-    checkLub(A, Object_, Object_);

-    checkLub(A, A, A);

-    checkLub(A, B, Object_);

-    checkLub(A, C, Object_);

-    checkLub(A, S, A);

-    checkLub(A, T, Object_);

-    checkLub(A, U, Object_);

-    checkLub(A, V, Object_);

-    checkLub(A, W, Object_);

-    checkLub(A, X, Object_);

-

-    checkLub(B, Object_, Object_);

-    checkLub(B, A, Object_);

-    checkLub(B, B, B);

-    checkLub(B, C, B);

-    checkLub(B, S, Object_);

-    checkLub(B, T, B);

-    checkLub(B, U, B);

-    checkLub(B, V, B);

-    checkLub(B, W, B);

-    checkLub(B, X, B);

-

-    checkLub(C, Object_, Object_);

-    checkLub(C, A, Object_);

-    checkLub(C, B, B);

-    checkLub(C, C, C);

-    checkLub(C, S, Object_);

-    checkLub(C, T, B);

-    checkLub(C, U, C);

-    checkLub(C, V, B);

-    checkLub(C, W, B);

-    checkLub(C, X, B);

-

-    checkLub(S, Object_, Object_);

-    checkLub(S, A, A);

-    checkLub(S, B, Object_);

-    checkLub(S, C, Object_);

-    checkLub(S, S, S);

-    checkLub(S, T, Object_);

-    checkLub(S, U, Object_);

-    checkLub(S, V, Object_);

-    checkLub(S, W, Object_);

-    checkLub(S, X, Object_);

-

-    checkLub(T, Object_, Object_);

-    checkLub(T, A, Object_);

-    checkLub(T, B, B);

-    checkLub(T, C, B);

-    checkLub(T, S, Object_);

-    checkLub(T, T, T);

-    checkLub(T, U, B);

-    checkLub(T, V, T);

-    checkLub(T, W, T);

-    checkLub(T, X, T);

-

-    checkLub(U, Object_, Object_);

-    checkLub(U, A, Object_);

-    checkLub(U, B, B);

-    checkLub(U, C, C);

-    checkLub(U, S, Object_);

-    checkLub(U, T, B);

-    checkLub(U, U, U);

-    checkLub(U, V, B);

-    checkLub(U, W, B);

-    checkLub(U, X, B);

-

-    checkLub(V, Object_, Object_);

-    checkLub(V, A, Object_);

-    checkLub(V, B, B);

-    checkLub(V, C, B);

-    checkLub(V, S, Object_);

-    checkLub(V, T, T);

-    checkLub(V, U, B);

-    checkLub(V, V, V);

-    checkLub(V, W, V);

-    checkLub(V, X, T);

-

-    checkLub(W, Object_, Object_);

-    checkLub(W, A, Object_);

-    checkLub(W, B, B);

-    checkLub(W, C, B);

-    checkLub(W, S, Object_);

-    checkLub(W, T, T);

-    checkLub(W, U, B);

-    checkLub(W, V, V);

-    checkLub(W, W, W);

-    checkLub(W, X, T);

-

-    checkLub(X, Object_, Object_);

-    checkLub(X, A, Object_);

-    checkLub(X, B, B);

-    checkLub(X, C, B);

-    checkLub(X, S, Object_);

-    checkLub(X, T, T);

-    checkLub(X, U, B);

-    checkLub(X, V, T);

-    checkLub(X, W, T);

-    checkLub(X, X, X);

-  }));

-}

-

-

+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library subtype_test;
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'type_test_helper.dart';
+import 'package:compiler/src/dart_types.dart';
+import "package:compiler/src/elements/elements.dart"
+       show Element, ClassElement;
+import 'package:compiler/src/util/util.dart';
+
+void main() {
+  testInterface1();
+  testInterface2();
+  testGeneric();
+  testMixin();
+  testFunction();
+  testTypeVariable();
+}
+
+void testInterface1() {
+  asyncTest(() => TypeEnvironment.create(r"""
+      class A {} // A and B have equal depth.
+      class B {}
+      class I implements A, B {}
+      class J implements A, B {}
+      """).then((env) {
+
+    DartType Object_ = env['Object'];
+    DartType A = env['A'];
+    DartType B = env['B'];
+    DartType I = env['I'];
+    DartType J = env['J'];
+
+    checkLub(DartType a, DartType b, DartType expect) {
+      DartType lub = env.computeLeastUpperBound(a, b);
+      Expect.equals(expect, lub,
+          'Unexpected lub($a,$b) = $lub, expected $expect.');
+    }
+
+    checkLub(Object_, Object_, Object_);
+    checkLub(Object_, A, Object_);
+    checkLub(Object_, B, Object_);
+    checkLub(Object_, I, Object_);
+    checkLub(Object_, J, Object_);
+
+    checkLub(A, Object_, Object_);
+    checkLub(A, A, A);
+    checkLub(A, B, Object_);
+    checkLub(A, I, A);
+    checkLub(A, J, A);
+
+    checkLub(B, Object_, Object_);
+    checkLub(B, A, Object_);
+    checkLub(B, B, B);
+    checkLub(B, I, B);
+    checkLub(B, J, B);
+
+    checkLub(I, Object_, Object_);
+    checkLub(I, A, A);
+    checkLub(I, B, B);
+    checkLub(I, I, I);
+    checkLub(I, J, Object_);
+
+    checkLub(J, Object_, Object_);
+    checkLub(J, A, A);
+    checkLub(J, B, B);
+    checkLub(J, I, Object_);
+    checkLub(J, J, J);
+  }));
+}
+
+void testInterface2() {
+  asyncTest(() => TypeEnvironment.create(r"""
+      class A {}
+      class B {}
+      class C extends B {} // This makes C have higher depth than A.
+      class I implements A, C {}
+      class J implements A, C {}
+      """).then((env) {
+
+    DartType Object_ = env['Object'];
+    DartType A = env['A'];
+    DartType B = env['B'];
+    DartType C = env['C'];
+    DartType I = env['I'];
+    DartType J = env['J'];
+
+    checkLub(DartType a, DartType b, DartType expectedLub) {
+      DartType lub = env.computeLeastUpperBound(a, b);
+      Expect.equals(expectedLub, lub,
+          'Unexpected lub($a,$b) = $lub, expected $expectedLub');
+    }
+
+    checkLub(Object_, Object_, Object_);
+    checkLub(Object_, A, Object_);
+    checkLub(Object_, B, Object_);
+    checkLub(Object_, C, Object_);
+    checkLub(Object_, I, Object_);
+    checkLub(Object_, J, Object_);
+
+    checkLub(A, Object_, Object_);
+    checkLub(A, A, A);
+    checkLub(A, B, Object_);
+    checkLub(A, C, Object_);
+    checkLub(A, I, A);
+    checkLub(A, J, A);
+
+    checkLub(B, Object_, Object_);
+    checkLub(B, A, Object_);
+    checkLub(B, B, B);
+    checkLub(B, C, B);
+    checkLub(B, I, B);
+    checkLub(B, J, B);
+
+    checkLub(C, Object_, Object_);
+    checkLub(C, A, Object_);
+    checkLub(C, B, B);
+    checkLub(C, C, C);
+    checkLub(C, I, C);
+    checkLub(C, J, C);
+
+    checkLub(I, Object_, Object_);
+    checkLub(I, A, A);
+    checkLub(I, B, B);
+    checkLub(I, C, C);
+    checkLub(I, I, I);
+    checkLub(I, J, C);
+
+    checkLub(J, Object_, Object_);
+    checkLub(J, A, A);
+    checkLub(J, B, B);
+    checkLub(J, C, C);
+    checkLub(J, I, C);
+    checkLub(J, J, J);
+  }));
+}
+
+void testGeneric() {
+  asyncTest(() => TypeEnvironment.create(r"""
+      class A {}
+      class B {}
+      class C extends B {}
+      class I<T> {}
+      """).then((env) {
+
+    DartType Object_ = env['Object'];
+    DartType A = env['A'];
+    DartType B = env['B'];
+    DartType C = env['C'];
+    ClassElement I = env.getElement('I');
+    DartType I_A = instantiate(I, [A]);
+    DartType I_B = instantiate(I, [B]);
+    DartType I_C = instantiate(I, [C]);
+
+    checkLub(DartType a, DartType b, DartType expectedLub) {
+      DartType lub = env.computeLeastUpperBound(a, b);
+      Expect.equals(expectedLub, lub,
+          'Unexpected lub($a,$b) = $lub, expected $expectedLub');
+    }
+
+    checkLub(Object_, Object_, Object_);
+    checkLub(Object_, A, Object_);
+    checkLub(Object_, B, Object_);
+    checkLub(Object_, C, Object_);
+    checkLub(Object_, I_A, Object_);
+    checkLub(Object_, I_B, Object_);
+    checkLub(Object_, I_C, Object_);
+
+    checkLub(A, Object_, Object_);
+    checkLub(A, A, A);
+    checkLub(A, B, Object_);
+    checkLub(A, C, Object_);
+    checkLub(A, I_A, Object_);
+    checkLub(A, I_B, Object_);
+    checkLub(A, I_C, Object_);
+
+    checkLub(B, Object_, Object_);
+    checkLub(B, A, Object_);
+    checkLub(B, B, B);
+    checkLub(B, C, B);
+    checkLub(B, I_A, Object_);
+    checkLub(B, I_B, Object_);
+    checkLub(B, I_C, Object_);
+
+    checkLub(C, Object_, Object_);
+    checkLub(C, A, Object_);
+    checkLub(C, B, B);
+    checkLub(C, C, C);
+    checkLub(C, I_A, Object_);
+    checkLub(C, I_B, Object_);
+    checkLub(C, I_C, Object_);
+
+    checkLub(I_A, Object_, Object_);
+    checkLub(I_A, A, Object_);
+    checkLub(I_A, B, Object_);
+    checkLub(I_A, C, Object_);
+    checkLub(I_A, I_A, I_A);
+    checkLub(I_A, I_B, Object_);
+    checkLub(I_A, I_C, Object_);
+
+    checkLub(I_B, Object_, Object_);
+    checkLub(I_B, A, Object_);
+    checkLub(I_B, B, Object_);
+    checkLub(I_B, C, Object_);
+    checkLub(I_B, I_A, Object_);
+    checkLub(I_B, I_B, I_B);
+    checkLub(I_B, I_C, Object_);
+
+    checkLub(I_C, Object_, Object_);
+    checkLub(I_C, A, Object_);
+    checkLub(I_C, B, Object_);
+    checkLub(I_C, C, Object_);
+    checkLub(I_C, I_A, Object_);
+    checkLub(I_C, I_B, Object_);
+    checkLub(I_C, I_C, I_C);
+  }));
+}
+
+void testMixin() {
+  asyncTest(() => TypeEnvironment.create(r"""
+      class A {}
+      class B {}
+      class C extends B {}
+      class D extends C {} // This makes D have higher depth than Object+A.
+      class I extends Object with A, B implements A, D {}
+      class I2 extends Object with A, B implements A, D {}
+      class J extends Object with B, A implements A, D {}
+      """).then((env) {
+
+    DartType Object_ = env['Object'];
+    DartType A = env['A'];
+    DartType B = env['B'];
+    DartType C = env['C'];
+    DartType D = env['D'];
+    DartType I = env['I'];
+    DartType I2 = env['I2'];
+    DartType J = env['J'];
+
+    checkLub(DartType a, DartType b, DartType expectedLub) {
+      DartType lub = env.computeLeastUpperBound(a, b);
+      Expect.equals(expectedLub, lub,
+          'Unexpected lub($a,$b) = $lub, expected $expectedLub');
+    }
+
+    checkLub(Object_, Object_, Object_);
+    checkLub(Object_, A, Object_);
+    checkLub(Object_, B, Object_);
+    checkLub(Object_, C, Object_);
+    checkLub(Object_, D, Object_);
+    checkLub(Object_, I, Object_);
+    checkLub(Object_, I2, Object_);
+    checkLub(Object_, J, Object_);
+
+    checkLub(A, Object_, Object_);
+    checkLub(A, A, A);
+    checkLub(A, B, Object_);
+    checkLub(A, C, Object_);
+    checkLub(A, D, Object_);
+    checkLub(A, I, A);
+    checkLub(A, I2, A);
+    checkLub(A, J, A);
+
+    checkLub(B, Object_, Object_);
+    checkLub(B, A, Object_);
+    checkLub(B, B, B);
+    checkLub(B, C, B);
+    checkLub(B, D, B);
+    checkLub(B, I, B);
+    checkLub(B, I2, B);
+    checkLub(B, J, B);
+
+    checkLub(C, Object_, Object_);
+    checkLub(C, A, Object_);
+    checkLub(C, B, B);
+    checkLub(C, C, C);
+    checkLub(C, D, C);
+    checkLub(C, I, C);
+    checkLub(C, I2, C);
+    checkLub(C, J, C);
+
+    checkLub(D, Object_, Object_);
+    checkLub(D, A, Object_);
+    checkLub(D, B, B);
+    checkLub(D, C, C);
+    checkLub(D, D, D);
+    checkLub(D, I, D);
+    checkLub(D, I2, D);
+    checkLub(D, J, D);
+
+    checkLub(I, Object_, Object_);
+    checkLub(I, A, A);
+    checkLub(I, B, B);
+    checkLub(I, C, C);
+    checkLub(I, D, D);
+    checkLub(I, I, I);
+    checkLub(I, I2, D);
+    checkLub(I, J, D);
+
+    checkLub(I2, Object_, Object_);
+    checkLub(I2, A, A);
+    checkLub(I2, B, B);
+    checkLub(I2, C, C);
+    checkLub(I2, D, D);
+    checkLub(I2, I, D);
+    checkLub(I2, I2, I2);
+    checkLub(I2, J, D);
+
+    checkLub(J, Object_, Object_);
+    checkLub(J, A, A);
+    checkLub(J, B, B);
+    checkLub(J, C, C);
+    checkLub(J, D, D);
+    checkLub(J, I, D);
+    checkLub(J, I2, D);
+    checkLub(J, J, J);
+  }));
+}
+
+void testFunction() {
+  asyncTest(() => TypeEnvironment.create(r"""
+      class A {}
+      class B {}
+      class C extends B {}
+
+      typedef dynamic__();
+      typedef void void__();
+      typedef A A__();
+      typedef B B__();
+      typedef C C__();
+
+      typedef void void__A_B(A a, B b);
+      typedef void void__A_C(A a, C b);
+      typedef void void__B_A(B a, A b);
+      typedef void void__B_C(B a, C b);
+
+      typedef void void___B([B a]);
+      typedef void void___B_C([B a, C b]);
+      typedef void void___C_C([C a, C b]);
+
+      typedef void void____B({B a});
+      typedef void void____B_C({B a, C b});
+      typedef void void____C_C({C a, C b});
+      """).then((env) {
+
+    DartType Object_ = env['Object'];
+    DartType Function_ = env['Function'];
+    DartType dynamic__ = env['dynamic__'];
+    DartType void__ = env['void__'];
+    DartType A__ = env['A__'];
+    DartType B__ = env['B__'];
+    DartType C__ = env['C__'];
+    DartType void__A_B = env['void__A_B'];
+    DartType void__A_C = env['void__A_C'];
+    DartType void__B_A = env['void__B_A'];
+    DartType void__B_C = env['void__B_C'];
+    DartType void___B = env['void___B'];
+    DartType void___B_C = env['void___B_C'];
+    DartType void___C_C = env['void___C_C'];
+    DartType void____B = env['void____B'];
+    DartType void____B_C = env['void____B_C'];
+    DartType void____C_C = env['void____C_C'];
+
+    // Types used only for checking results.
+    DartType void_ = env['void'];
+    DartType B = env['B'];
+    DartType C = env['C'];
+    FunctionType Object__ = env.functionType(Object_, []);
+    FunctionType void__Object_Object =
+        env.functionType(void_, [Object_, Object_]);
+    FunctionType void__Object_B =
+        env.functionType(void_, [Object_, B]);
+    FunctionType void__Object_C =
+        env.functionType(void_, [Object_, C]);
+    FunctionType void__B_Object =
+        env.functionType(void_, [B, Object_]);
+
+    checkLub(DartType a, DartType b, DartType expectedLub) {
+      DartType lub = env.computeLeastUpperBound(a, b);
+      if (a != b) {
+        expectedLub = expectedLub.unalias(env.compiler);
+        lub = lub.unalias(env.compiler);
+      }
+      Expect.equals(expectedLub, lub,
+          'Unexpected lub(${a.unalias(env.compiler)},'
+                         '${b.unalias(env.compiler)}) = '
+                         '${lub}, expected ${expectedLub}');
+    }
+
+    checkLub(Object_, Object_, Object_);
+    checkLub(Object_, Function_, Object_);
+    checkLub(Object_, dynamic__, Object_);
+    checkLub(Object_, void__, Object_);
+    checkLub(Object_, A__, Object_);
+    checkLub(Object_, B__, Object_);
+    checkLub(Object_, C__, Object_);
+    checkLub(Object_, void__A_B, Object_);
+    checkLub(Object_, void__A_C, Object_);
+    checkLub(Object_, void__B_A, Object_);
+    checkLub(Object_, void__B_C, Object_);
+    checkLub(Object_, void___B, Object_);
+    checkLub(Object_, void___B_C, Object_);
+    checkLub(Object_, void___C_C, Object_);
+    checkLub(Object_, void____B, Object_);
+    checkLub(Object_, void____B_C, Object_);
+    checkLub(Object_, void____C_C, Object_);
+
+    checkLub(Function_, Object_, Object_);
+    checkLub(Function_, Function_, Function_);
+    checkLub(Function_, dynamic__, Function_);
+    checkLub(Function_, void__, Function_);
+    checkLub(Function_, A__, Function_);
+    checkLub(Function_, B__, Function_);
+    checkLub(Function_, C__, Function_);
+    checkLub(Function_, void__A_B, Function_);
+    checkLub(Function_, void__A_C, Function_);
+    checkLub(Function_, void__B_A, Function_);
+    checkLub(Function_, void__B_C, Function_);
+    checkLub(Function_, void___B, Function_);
+    checkLub(Function_, void___B_C, Function_);
+    checkLub(Function_, void___C_C, Function_);
+    checkLub(Function_, void____B, Function_);
+    checkLub(Function_, void____B_C, Function_);
+    checkLub(Function_, void____C_C, Function_);
+
+    checkLub(dynamic__, Object_, Object_);
+    checkLub(dynamic__, Function_, Function_);
+    checkLub(dynamic__, dynamic__, dynamic__);
+    checkLub(dynamic__, void__, dynamic__);
+    checkLub(dynamic__, A__, dynamic__);
+    checkLub(dynamic__, B__, dynamic__);
+    checkLub(dynamic__, C__, dynamic__);
+    checkLub(dynamic__, void__A_B, Function_);
+    checkLub(dynamic__, void__A_C, Function_);
+    checkLub(dynamic__, void__B_A, Function_);
+    checkLub(dynamic__, void__B_C, Function_);
+    checkLub(dynamic__, void___B, dynamic__);
+    checkLub(dynamic__, void___B_C, dynamic__);
+    checkLub(dynamic__, void___C_C, dynamic__);
+    checkLub(dynamic__, void____B, dynamic__);
+    checkLub(dynamic__, void____B_C, dynamic__);
+    checkLub(dynamic__, void____C_C, dynamic__);
+
+    checkLub(void__, Object_, Object_);
+    checkLub(void__, Function_, Function_);
+    checkLub(void__, dynamic__, dynamic__);
+    checkLub(void__, void__, void__);
+    checkLub(void__, A__, void__);
+    checkLub(void__, B__, void__);
+    checkLub(void__, C__, void__);
+    checkLub(void__, void__A_B, Function_);
+    checkLub(void__, void__A_C, Function_);
+    checkLub(void__, void__B_A, Function_);
+    checkLub(void__, void__B_C, Function_);
+    checkLub(void__, void___B, void__);
+    checkLub(void__, void___B_C, void__);
+    checkLub(void__, void___C_C, void__);
+    checkLub(void__, void____B, void__);
+    checkLub(void__, void____B_C, void__);
+    checkLub(void__, void____C_C, void__);
+
+    checkLub(A__, Object_, Object_);
+    checkLub(A__, Function_, Function_);
+    checkLub(A__, dynamic__, dynamic__);
+    checkLub(A__, void__, void__);
+    checkLub(A__, A__, A__);
+    checkLub(A__, B__, Object__);
+    checkLub(A__, C__, Object__);
+    checkLub(A__, void__A_B, Function_);
+    checkLub(A__, void__A_C, Function_);
+    checkLub(A__, void__B_A, Function_);
+    checkLub(A__, void__B_C, Function_);
+    checkLub(A__, void___B, void__);
+    checkLub(A__, void___B_C, void__);
+    checkLub(A__, void___C_C, void__);
+    checkLub(A__, void____B, void__);
+    checkLub(A__, void____B_C, void__);
+    checkLub(A__, void____C_C, void__);
+
+    checkLub(B__, Object_, Object_);
+    checkLub(B__, Function_, Function_);
+    checkLub(B__, dynamic__, dynamic__);
+    checkLub(B__, void__, void__);
+    checkLub(B__, A__, Object__);
+    checkLub(B__, B__, B__);
+    checkLub(B__, C__, B__);
+    checkLub(B__, void__A_B, Function_);
+    checkLub(B__, void__A_C, Function_);
+    checkLub(B__, void__B_A, Function_);
+    checkLub(B__, void__B_C, Function_);
+    checkLub(B__, void___B, void__);
+    checkLub(B__, void___B_C, void__);
+    checkLub(B__, void___C_C, void__);
+    checkLub(B__, void____B, void__);
+    checkLub(B__, void____B_C, void__);
+    checkLub(B__, void____C_C, void__);
+
+    checkLub(C__, Object_, Object_);
+    checkLub(C__, Function_, Function_);
+    checkLub(C__, dynamic__, dynamic__);
+    checkLub(C__, void__, void__);
+    checkLub(C__, A__, Object__);
+    checkLub(C__, B__, B__);
+    checkLub(C__, C__, C__);
+    checkLub(C__, void__A_B, Function_);
+    checkLub(C__, void__A_C, Function_);
+    checkLub(C__, void__B_A, Function_);
+    checkLub(C__, void__B_C, Function_);
+    checkLub(C__, void___B, void__);
+    checkLub(C__, void___B_C, void__);
+    checkLub(C__, void___C_C, void__);
+    checkLub(C__, void____B, void__);
+    checkLub(C__, void____B_C, void__);
+    checkLub(C__, void____C_C, void__);
+
+    checkLub(void__A_B, Object_, Object_);
+    checkLub(void__A_B, Function_, Function_);
+    checkLub(void__A_B, dynamic__, Function_);
+    checkLub(void__A_B, void__, Function_);
+    checkLub(void__A_B, A__, Function_);
+    checkLub(void__A_B, B__, Function_);
+    checkLub(void__A_B, C__, Function_);
+    checkLub(void__A_B, void__A_B, void__A_B);
+    checkLub(void__A_B, void__A_C, void__A_B);
+    checkLub(void__A_B, void__B_A, void__Object_Object);
+    checkLub(void__A_B, void__B_C, void__Object_B);
+    checkLub(void__A_B, void___B, Function_);
+    checkLub(void__A_B, void___B_C, Function_);
+    checkLub(void__A_B, void___C_C, Function_);
+    checkLub(void__A_B, void____B, Function_);
+    checkLub(void__A_B, void____B_C, Function_);
+    checkLub(void__A_B, void____C_C, Function_);
+
+    checkLub(void__A_C, Object_, Object_);
+    checkLub(void__A_C, Function_, Function_);
+    checkLub(void__A_C, dynamic__, Function_);
+    checkLub(void__A_C, void__, Function_);
+    checkLub(void__A_C, A__, Function_);
+    checkLub(void__A_C, B__, Function_);
+    checkLub(void__A_C, C__, Function_);
+    checkLub(void__A_C, void__A_B, void__A_B);
+    checkLub(void__A_C, void__A_C, void__A_C);
+    checkLub(void__A_C, void__B_A, void__Object_Object);
+    checkLub(void__A_C, void__B_C, void__Object_C);
+    checkLub(void__A_C, void___B, Function_);
+    checkLub(void__A_C, void___B_C, Function_);
+    checkLub(void__A_C, void___C_C, Function_);
+    checkLub(void__A_C, void____B, Function_);
+    checkLub(void__A_C, void____B_C, Function_);
+    checkLub(void__A_C, void____C_C, Function_);
+
+    checkLub(void__B_A, Object_, Object_);
+    checkLub(void__B_A, Function_, Function_);
+    checkLub(void__B_A, dynamic__, Function_);
+    checkLub(void__B_A, void__, Function_);
+    checkLub(void__B_A, A__, Function_);
+    checkLub(void__B_A, B__, Function_);
+    checkLub(void__B_A, C__, Function_);
+    checkLub(void__B_A, void__A_B, void__Object_Object);
+    checkLub(void__B_A, void__A_C, void__Object_Object);
+    checkLub(void__B_A, void__B_A, void__B_A);
+    checkLub(void__B_A, void__B_C, void__B_Object);
+    checkLub(void__B_A, void___B, Function_);
+    checkLub(void__B_A, void___B_C, Function_);
+    checkLub(void__B_A, void___C_C, Function_);
+    checkLub(void__B_A, void____B, Function_);
+    checkLub(void__B_A, void____B_C, Function_);
+    checkLub(void__B_A, void____C_C, Function_);
+
+    checkLub(void__B_C, Object_, Object_);
+    checkLub(void__B_C, Function_, Function_);
+    checkLub(void__B_C, dynamic__, Function_);
+    checkLub(void__B_C, void__, Function_);
+    checkLub(void__B_C, A__, Function_);
+    checkLub(void__B_C, B__, Function_);
+    checkLub(void__B_C, C__, Function_);
+    checkLub(void__B_C, void__A_B, void__Object_B);
+    checkLub(void__B_C, void__A_C, void__Object_C);
+    checkLub(void__B_C, void__B_A, void__B_Object);
+    checkLub(void__B_C, void__B_C, void__B_C);
+    checkLub(void__B_C, void___B, Function_);
+    checkLub(void__B_C, void___B_C, Function_);
+    checkLub(void__B_C, void___C_C, Function_);
+    checkLub(void__B_C, void____B, Function_);
+    checkLub(void__B_C, void____B_C, Function_);
+    checkLub(void__B_C, void____C_C, Function_);
+
+    checkLub(void___B, Object_, Object_);
+    checkLub(void___B, Function_, Function_);
+    checkLub(void___B, dynamic__, dynamic__);
+    checkLub(void___B, void__, void__);
+    checkLub(void___B, A__, void__);
+    checkLub(void___B, B__, void__);
+    checkLub(void___B, C__, void__);
+    checkLub(void___B, void__A_B, Function_);
+    checkLub(void___B, void__A_C, Function_);
+    checkLub(void___B, void__B_A, Function_);
+    checkLub(void___B, void__B_C, Function_);
+    checkLub(void___B, void___B, void___B);
+    checkLub(void___B, void___B_C, void___B);
+    checkLub(void___B, void___C_C, void___B);
+    checkLub(void___B, void____B, void__);
+    checkLub(void___B, void____B_C, void__);
+    checkLub(void___B, void____C_C, void__);
+
+    checkLub(void___B_C, Object_, Object_);
+    checkLub(void___B_C, Function_, Function_);
+    checkLub(void___B_C, dynamic__, dynamic__);
+    checkLub(void___B_C, void__, void__);
+    checkLub(void___B_C, A__, void__);
+    checkLub(void___B_C, B__, void__);
+    checkLub(void___B_C, C__, void__);
+    checkLub(void___B_C, void__A_B, Function_);
+    checkLub(void___B_C, void__A_C, Function_);
+    checkLub(void___B_C, void__B_A, Function_);
+    checkLub(void___B_C, void__B_C, Function_);
+    checkLub(void___B_C, void___B, void___B);
+    checkLub(void___B_C, void___B_C, void___B_C);
+    checkLub(void___B_C, void___C_C, void___B_C);
+    checkLub(void___B_C, void____B, void__);
+    checkLub(void___B_C, void____B_C, void__);
+    checkLub(void___B_C, void____C_C, void__);
+
+    checkLub(void___C_C, Object_, Object_);
+    checkLub(void___C_C, Function_, Function_);
+    checkLub(void___C_C, dynamic__, dynamic__);
+    checkLub(void___C_C, void__, void__);
+    checkLub(void___C_C, A__, void__);
+    checkLub(void___C_C, B__, void__);
+    checkLub(void___C_C, C__, void__);
+    checkLub(void___C_C, void__A_B, Function_);
+    checkLub(void___C_C, void__A_C, Function_);
+    checkLub(void___C_C, void__B_A, Function_);
+    checkLub(void___C_C, void__B_C, Function_);
+    checkLub(void___C_C, void___B, void___B);
+    checkLub(void___C_C, void___B_C, void___B_C);
+    checkLub(void___C_C, void___C_C, void___C_C);
+    checkLub(void___C_C, void____B, void__);
+    checkLub(void___C_C, void____B_C, void__);
+    checkLub(void___C_C, void____C_C, void__);
+
+    checkLub(void____B, Object_, Object_);
+    checkLub(void____B, Function_, Function_);
+    checkLub(void____B, dynamic__, dynamic__);
+    checkLub(void____B, void__, void__);
+    checkLub(void____B, A__, void__);
+    checkLub(void____B, B__, void__);
+    checkLub(void____B, C__, void__);
+    checkLub(void____B, void__A_B, Function_);
+    checkLub(void____B, void__A_C, Function_);
+    checkLub(void____B, void__B_A, Function_);
+    checkLub(void____B, void__B_C, Function_);
+    checkLub(void____B, void___B, void__);
+    checkLub(void____B, void___B_C, void__);
+    checkLub(void____B, void___C_C, void__);
+    checkLub(void____B, void____B, void____B);
+    checkLub(void____B, void____B_C, void____B);
+    checkLub(void____B, void____C_C, void____B);
+
+    checkLub(void____B_C, Object_, Object_);
+    checkLub(void____B_C, Function_, Function_);
+    checkLub(void____B_C, dynamic__, dynamic__);
+    checkLub(void____B_C, void__, void__);
+    checkLub(void____B_C, A__, void__);
+    checkLub(void____B_C, B__, void__);
+    checkLub(void____B_C, C__, void__);
+    checkLub(void____B_C, void__A_B, Function_);
+    checkLub(void____B_C, void__A_C, Function_);
+    checkLub(void____B_C, void__B_A, Function_);
+    checkLub(void____B_C, void__B_C, Function_);
+    checkLub(void____B_C, void___B, void__);
+    checkLub(void____B_C, void___B_C, void__);
+    checkLub(void____B_C, void___C_C, void__);
+    checkLub(void____B_C, void____B, void____B);
+    checkLub(void____B_C, void____B_C, void____B_C);
+    checkLub(void____B_C, void____C_C, void____B_C);
+
+    checkLub(void____C_C, Object_, Object_);
+    checkLub(void____C_C, Function_, Function_);
+    checkLub(void____C_C, dynamic__, dynamic__);
+    checkLub(void____C_C, void__, void__);
+    checkLub(void____C_C, A__, void__);
+    checkLub(void____C_C, B__, void__);
+    checkLub(void____C_C, C__, void__);
+    checkLub(void____C_C, void__A_B, Function_);
+    checkLub(void____C_C, void__A_C, Function_);
+    checkLub(void____C_C, void__B_A, Function_);
+    checkLub(void____C_C, void__B_C, Function_);
+    checkLub(void____C_C, void___B, void__);
+    checkLub(void____C_C, void___B_C, void__);
+    checkLub(void____C_C, void___C_C, void__);
+    checkLub(void____C_C, void____B, void____B);
+    checkLub(void____C_C, void____B_C, void____B_C);
+    checkLub(void____C_C, void____C_C, void____C_C);
+  }));
+}
+
+void testTypeVariable() {
+  asyncTest(() => TypeEnvironment.create(r"""
+      class A {}
+      class B {}
+      class C extends B {}
+      class I<S extends A,
+              T extends B,
+              U extends C,
+              V extends T,
+              W extends V,
+              X extends T> {}
+      """).then((env) {
+
+    //  A     B
+    //  |    / \
+    //  S   T   C
+    //     / \   \
+    //    V   X   U
+    //   /
+    //  W
+
+    DartType Object_ = env['Object'];
+    DartType A = env['A'];
+    DartType B = env['B'];
+    DartType C = env['C'];
+    ClassElement I = env.getElement('I');
+    DartType S = I.typeVariables[0];
+    DartType T = I.typeVariables[1];
+    DartType U = I.typeVariables[2];
+    DartType V = I.typeVariables[3];
+    DartType W = I.typeVariables[4];
+    DartType X = I.typeVariables[5];
+
+    checkLub(DartType a, DartType b, DartType expectedLub) {
+      DartType lub = env.computeLeastUpperBound(a, b);
+      Expect.equals(expectedLub, lub,
+          'Unexpected lub($a,$b) = $lub, expected $expectedLub');
+    }
+
+    checkLub(Object_, Object_, Object_);
+    checkLub(Object_, A, Object_);
+    checkLub(Object_, B, Object_);
+    checkLub(Object_, C, Object_);
+    checkLub(Object_, S, Object_);
+    checkLub(Object_, T, Object_);
+    checkLub(Object_, U, Object_);
+    checkLub(Object_, V, Object_);
+    checkLub(Object_, W, Object_);
+    checkLub(Object_, X, Object_);
+
+    checkLub(A, Object_, Object_);
+    checkLub(A, A, A);
+    checkLub(A, B, Object_);
+    checkLub(A, C, Object_);
+    checkLub(A, S, A);
+    checkLub(A, T, Object_);
+    checkLub(A, U, Object_);
+    checkLub(A, V, Object_);
+    checkLub(A, W, Object_);
+    checkLub(A, X, Object_);
+
+    checkLub(B, Object_, Object_);
+    checkLub(B, A, Object_);
+    checkLub(B, B, B);
+    checkLub(B, C, B);
+    checkLub(B, S, Object_);
+    checkLub(B, T, B);
+    checkLub(B, U, B);
+    checkLub(B, V, B);
+    checkLub(B, W, B);
+    checkLub(B, X, B);
+
+    checkLub(C, Object_, Object_);
+    checkLub(C, A, Object_);
+    checkLub(C, B, B);
+    checkLub(C, C, C);
+    checkLub(C, S, Object_);
+    checkLub(C, T, B);
+    checkLub(C, U, C);
+    checkLub(C, V, B);
+    checkLub(C, W, B);
+    checkLub(C, X, B);
+
+    checkLub(S, Object_, Object_);
+    checkLub(S, A, A);
+    checkLub(S, B, Object_);
+    checkLub(S, C, Object_);
+    checkLub(S, S, S);
+    checkLub(S, T, Object_);
+    checkLub(S, U, Object_);
+    checkLub(S, V, Object_);
+    checkLub(S, W, Object_);
+    checkLub(S, X, Object_);
+
+    checkLub(T, Object_, Object_);
+    checkLub(T, A, Object_);
+    checkLub(T, B, B);
+    checkLub(T, C, B);
+    checkLub(T, S, Object_);
+    checkLub(T, T, T);
+    checkLub(T, U, B);
+    checkLub(T, V, T);
+    checkLub(T, W, T);
+    checkLub(T, X, T);
+
+    checkLub(U, Object_, Object_);
+    checkLub(U, A, Object_);
+    checkLub(U, B, B);
+    checkLub(U, C, C);
+    checkLub(U, S, Object_);
+    checkLub(U, T, B);
+    checkLub(U, U, U);
+    checkLub(U, V, B);
+    checkLub(U, W, B);
+    checkLub(U, X, B);
+
+    checkLub(V, Object_, Object_);
+    checkLub(V, A, Object_);
+    checkLub(V, B, B);
+    checkLub(V, C, B);
+    checkLub(V, S, Object_);
+    checkLub(V, T, T);
+    checkLub(V, U, B);
+    checkLub(V, V, V);
+    checkLub(V, W, V);
+    checkLub(V, X, T);
+
+    checkLub(W, Object_, Object_);
+    checkLub(W, A, Object_);
+    checkLub(W, B, B);
+    checkLub(W, C, B);
+    checkLub(W, S, Object_);
+    checkLub(W, T, T);
+    checkLub(W, U, B);
+    checkLub(W, V, V);
+    checkLub(W, W, W);
+    checkLub(W, X, T);
+
+    checkLub(X, Object_, Object_);
+    checkLub(X, A, Object_);
+    checkLub(X, B, B);
+    checkLub(X, C, B);
+    checkLub(X, S, Object_);
+    checkLub(X, T, T);
+    checkLub(X, U, B);
+    checkLub(X, V, T);
+    checkLub(X, W, T);
+    checkLub(X, X, X);
+  }));
+}
+
+
diff --git a/tests/compiler/dart2js/library_resolution_test.dart b/tests/compiler/dart2js/library_resolution_test.dart
index 1a44800..c7058471 100644
--- a/tests/compiler/dart2js/library_resolution_test.dart
+++ b/tests/compiler/dart2js/library_resolution_test.dart
@@ -24,7 +24,7 @@
     MessageKind,
     NullSink;
 
-import 'package:_internal/libraries.dart' show
+import 'package:sdk_library_metadata/libraries.dart' show
     DART2JS_PLATFORM,
     LibraryInfo;
 
diff --git a/tests/compiler/dart2js/line_column_provider_test.dart b/tests/compiler/dart2js/line_column_provider_test.dart
index c1cdded..ae90daf 100644
--- a/tests/compiler/dart2js/line_column_provider_test.dart
+++ b/tests/compiler/dart2js/line_column_provider_test.dart
@@ -1,84 +1,84 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file

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

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

-

-// Unittest for the [LineColumnCollector].

-

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

-import 'package:compiler/src/io/code_output.dart';

-import 'package:compiler/src/io/line_column_provider.dart';

-

-import 'output_collector.dart';

-

-test(List events, Map<int, List<int>> expectedPositions) {

-  BufferedEventSink sink = new BufferedEventSink();

-  LineColumnProvider lineColumnProvider = new LineColumnCollector();

-  CodeOutput output = new StreamCodeOutput(sink, [lineColumnProvider]);

-  for (var event in events) {

-    if (event is String) {

-      output.add(event);

-    } else if (event is CodeBuffer) {

-      output.addBuffer(event);

-    }

-  }

-  output.close();

-

-  expectedPositions.forEach((int offset, List<int> expectedPosition) {

-    if (expectedPosition == null) {

-      Expect.throws(() => lineColumnProvider.getLine(offset),

-                    (e) => true,

-                    'Expected out-of-bounds offset: $offset\n'

-                    'text:"""${sink.text}"""\n'

-                    'lineColumnProvider:$lineColumnProvider');

-    } else {

-      int line = lineColumnProvider.getLine(offset);

-      int column = lineColumnProvider.getColumn(line, offset);

-      Expect.equals(expectedPosition[0], line,

-          'Unexpected result: $offset -> $expectedPosition = [$line,$column]\n'

-          'text:"""${sink.text}"""\n'

-          'lineColumnProvider:$lineColumnProvider');

-      Expect.equals(expectedPosition[1], column,

-          'Unexpected result: $offset -> $expectedPosition = [$line,$column]\n'

-          'text:"""${sink.text}"""\n'

-          'lineColumnProvider:$lineColumnProvider');

-    }

-  });

-}

-

-main() {

-  test([""], {0: [0, 0], 1: null});

-

-  test([" "], {0: [0, 0], 1: [0, 1], 2: null});

-

-  test(["\n "], {0: [0, 0], 1: [1, 0], 2: [1, 1], 3: null});

-

-  Map positions = {0: [0, 0],

-                   1: [0, 1],

-                   2: [1, 0],

-                   3: [1, 1],

-                   4: [2, 0],

-                   5: [2, 1],

-                   6: null};

-

-  test(["a\nb\nc"], positions);

-

-  test(["a", "\nb\nc"], positions);

-

-  test(["a", "\n", "b\nc"], positions);

-

-  CodeBuffer buffer1 = new CodeBuffer();

-  buffer1.add("a\nb\nc");

-  test([buffer1], positions);

-

-  CodeBuffer buffer2 = new CodeBuffer();

-  buffer2.add("\nb\nc");

-  test(["a", buffer2], positions);

-

-  CodeBuffer buffer3 = new CodeBuffer();

-  buffer3.add("a");

-  test([buffer3, buffer2], positions);

-

-  CodeBuffer buffer4 = new CodeBuffer();

-  buffer4.addBuffer(buffer3);

-  test([buffer4, buffer2], positions);

-}

+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Unittest for the [LineColumnCollector].
+
+import 'package:expect/expect.dart';
+import 'package:compiler/src/io/code_output.dart';
+import 'package:compiler/src/io/line_column_provider.dart';
+
+import 'output_collector.dart';
+
+test(List events, Map<int, List<int>> expectedPositions) {
+  BufferedEventSink sink = new BufferedEventSink();
+  LineColumnProvider lineColumnProvider = new LineColumnCollector();
+  CodeOutput output = new StreamCodeOutput(sink, [lineColumnProvider]);
+  for (var event in events) {
+    if (event is String) {
+      output.add(event);
+    } else if (event is CodeBuffer) {
+      output.addBuffer(event);
+    }
+  }
+  output.close();
+
+  expectedPositions.forEach((int offset, List<int> expectedPosition) {
+    if (expectedPosition == null) {
+      Expect.throws(() => lineColumnProvider.getLine(offset),
+                    (e) => true,
+                    'Expected out-of-bounds offset: $offset\n'
+                    'text:"""${sink.text}"""\n'
+                    'lineColumnProvider:$lineColumnProvider');
+    } else {
+      int line = lineColumnProvider.getLine(offset);
+      int column = lineColumnProvider.getColumn(line, offset);
+      Expect.equals(expectedPosition[0], line,
+          'Unexpected result: $offset -> $expectedPosition = [$line,$column]\n'
+          'text:"""${sink.text}"""\n'
+          'lineColumnProvider:$lineColumnProvider');
+      Expect.equals(expectedPosition[1], column,
+          'Unexpected result: $offset -> $expectedPosition = [$line,$column]\n'
+          'text:"""${sink.text}"""\n'
+          'lineColumnProvider:$lineColumnProvider');
+    }
+  });
+}
+
+main() {
+  test([""], {0: [0, 0], 1: null});
+
+  test([" "], {0: [0, 0], 1: [0, 1], 2: null});
+
+  test(["\n "], {0: [0, 0], 1: [1, 0], 2: [1, 1], 3: null});
+
+  Map positions = {0: [0, 0],
+                   1: [0, 1],
+                   2: [1, 0],
+                   3: [1, 1],
+                   4: [2, 0],
+                   5: [2, 1],
+                   6: null};
+
+  test(["a\nb\nc"], positions);
+
+  test(["a", "\nb\nc"], positions);
+
+  test(["a", "\n", "b\nc"], positions);
+
+  CodeBuffer buffer1 = new CodeBuffer();
+  buffer1.add("a\nb\nc");
+  test([buffer1], positions);
+
+  CodeBuffer buffer2 = new CodeBuffer();
+  buffer2.add("\nb\nc");
+  test(["a", buffer2], positions);
+
+  CodeBuffer buffer3 = new CodeBuffer();
+  buffer3.add("a");
+  test([buffer3, buffer2], positions);
+
+  CodeBuffer buffer4 = new CodeBuffer();
+  buffer4.addBuffer(buffer3);
+  test([buffer4, buffer2], positions);
+}
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index b9de4fe..7a4a809 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -11,8 +11,11 @@
 import 'package:compiler/src/dart2jslib.dart'
        show NullSink;
 
-import 'package:compiler/compiler.dart'
-    show Diagnostic, DiagnosticHandler, CompilerOutputProvider;
+import 'package:compiler/compiler.dart' show
+    CompilerOutputProvider,
+    Diagnostic,
+    DiagnosticHandler,
+    PackagesDiscoveryProvider;
 
 import 'dart:async';
 
@@ -89,15 +92,20 @@
 Expando<MemorySourceFileProvider> expando =
     new Expando<MemorySourceFileProvider>();
 
-Compiler compilerFor(Map<String,String> memorySourceFiles,
-                     {DiagnosticHandler diagnosticHandler,
-                      CompilerOutputProvider outputProvider,
-                      List<String> options: const [],
-                      Compiler cachedCompiler,
-                      bool showDiagnostics: true,
-                      Uri packageRoot}) {
+Compiler compilerFor(
+    Map<String, String> memorySourceFiles,
+    {DiagnosticHandler diagnosticHandler,
+     CompilerOutputProvider outputProvider,
+     List<String> options: const [],
+     Compiler cachedCompiler,
+     bool showDiagnostics: true,
+     Uri packageRoot,
+     Uri packageConfig,
+     PackagesDiscoveryProvider packagesDiscoveryProvider}) {
   Uri libraryRoot = Uri.base.resolve('sdk/');
-  if (packageRoot == null) {
+  if (packageRoot == null &&
+      packageConfig == null &&
+      packagesDiscoveryProvider == null) {
     packageRoot = Uri.base.resolveUri(new Uri.file('${Platform.packageRoot}/'));
   }
 
@@ -127,13 +135,17 @@
     outputProvider = noOutputProvider;
   }
 
-  Compiler compiler = new Compiler(readStringFromUri,
-                                   outputProvider,
-                                   handler,
-                                   libraryRoot,
-                                   packageRoot,
-                                   options,
-                                   {});
+  Compiler compiler = new Compiler(
+      readStringFromUri,
+      outputProvider,
+      handler,
+      libraryRoot,
+      packageRoot,
+      options,
+      {},
+      packageConfig,
+      packagesDiscoveryProvider);
+
   if (cachedCompiler != null) {
     compiler.coreLibrary =
         cachedCompiler.libraryLoader.lookupLibrary(Uri.parse('dart:core'));
diff --git a/tests/compiler/dart2js/mirror_system_helper.dart b/tests/compiler/dart2js/mirror_system_helper.dart
index 497e6a3..7c97ebd 100644
--- a/tests/compiler/dart2js/mirror_system_helper.dart
+++ b/tests/compiler/dart2js/mirror_system_helper.dart
@@ -1,139 +1,139 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file

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

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

-

-library mirror_system_helper;

-

-import 'dart:async';

-import 'package:compiler/src/mirrors/source_mirrors.dart';

-import 'package:compiler/src/mirrors/dart2js_mirrors.dart';

-import 'mock_compiler.dart';

-

-export 'package:compiler/src/mirrors/source_mirrors.dart';

-export 'package:compiler/src/mirrors/mirrors_util.dart';

-

-const String SOURCE = 'source';

-final Uri SOURCE_URI = new Uri(scheme: SOURCE, path: SOURCE);

-

-// TODO(johnniwinther): Move this to a mirrors helper library.

-Future<MirrorSystem> createMirrorSystem(String source) {

-  MockCompiler compiler = new MockCompiler.internal(

-      analyzeOnly: true,

-      analyzeAll: true,

-      preserveComments: true);

-    compiler.registerSource(SOURCE_URI, source);

-    compiler.librariesToAnalyzeWhenRun = <Uri>[SOURCE_URI];

-  return compiler.runCompiler(null).then((_) {

-    return new Dart2JsMirrorSystem(compiler);

-  });

-}

-

-/**

- * Returns [:true:] if [type] is an instance of [:decl:] with type arguments

- * equal to [typeArgument].

- */

-bool isInstance(ClassMirror decl, List<TypeMirror> typeArguments,

-            ClassMirror type) {

-  if (type.isOriginalDeclaration) return false;

-  if (!isSameDeclaration(decl, type)) return false;

-  return areEqualsTypes(typeArguments, type.typeArguments);

-}

-

-/**

- * Returns [:true:] if [type] is the same type as [expected]. This method

- * equates a non-generic declaration with its instantiation.

- */

-bool isEqualType(TypeMirror expected, TypeMirror type) {

-  if (expected == type) return true;

-  if (expected is ClassMirror && type is ClassMirror) {

-    if (!isSameDeclaration(expected, type)) return false;

-    if (expected.isOriginalDeclaration || expected.typeArguments.isEmpty) {

-      return type.isOriginalDeclaration || type.typeArguments.isEmpty;

-    }

-    return areEqualsTypes(expected.typeArguments, type.typeArguments);

-  }

-  return true;

-}

-

-/**

- * Returns [:true:] if [types] are equals to [expected] using the equalitry

- * defined by [isEqualType].

- */

-bool areEqualsTypes(List<TypeMirror> expected, List<TypeMirror> types) {

-  return checkSameList(expected, types, isEqualType);

-}

-

-/**

- * Returns [:true:] if an instance of [type] with type arguments equal to

- * [typeArguments] is found in [types].

- */

-bool containsType(ClassMirror decl, List<TypeMirror> typeArguments,

-                  Iterable<TypeMirror> types) {

-  return types.any((type) => isInstance(decl, typeArguments, type));

-}

-

-/**

- * Returns the declaration of [type].

- */

-TypeMirror toDeclaration(TypeMirror type) {

-  return type is ClassMirror ? type.originalDeclaration : type;

-}

-

-/**

- * Returns [:true:] if [type] is of the same declaration as [expected].

- */

-bool isSameDeclaration(TypeMirror expected, TypeMirror type) {

-  return toDeclaration(expected) == toDeclaration(type);

-}

-

-/**

- * Returns [:true:] if a type of the declaration of [expected] is in [types].

- */

-bool containsDeclaration(TypeMirror expected, Iterable<TypeMirror> types) {

-  for (var type in types) {

-    if (isSameDeclaration(expected, type)) {

-      return true;

-    }

-  }

-  return false;

-}

-

-/**

- * Returns [:true:] if declarations of [expected] are the same as those of

- * [types], taking order into account.

- */

-bool isSameDeclarationList(Iterable<TypeMirror> expected,

-                           Iterable<TypeMirror> types) {

-  return checkSameList(expected, types, isSameDeclaration);

-}

-

-/**

- * Returns [:true:] if declarations of [expected] are the same as those of

- * [iterable], not taking order into account.

- */

-bool isSameDeclarationSet(Iterable<TypeMirror> expected,

-                          Iterable<TypeMirror> types) {

-   Set<TypeMirror> expectedSet = expected.map(toDeclaration).toSet();

-   Set<TypeMirror> typesSet = types.map(toDeclaration).toSet();

-   return expectedSet.length == typesSet.length &&

-          expectedSet.containsAll(typesSet);

-}

-

-/**

- * Utility method for checking whether [expected] and [iterable] contains the

- * same elements with respect to the checking function [check], takin order

- * into account.

- */

-bool checkSameList(Iterable<TypeMirror> expected,

-                   Iterable<TypeMirror> types,

-                   bool check(TypeMirror a, TypeMirror b)) {

-  if (expected.length != types.length) return false;

-  Iterator<TypeMirror> expectedIterator = expected.iterator;

-  Iterator<TypeMirror> typesIterator = types.iterator;

-  while (expectedIterator.moveNext() && typesIterator.moveNext()) {

-    if (!check(expectedIterator.current, typesIterator.current)) {

-      return false;

-    }

-  }

-  return true;

-}

+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library mirror_system_helper;
+
+import 'dart:async';
+import 'package:compiler/src/mirrors/source_mirrors.dart';
+import 'package:compiler/src/mirrors/dart2js_mirrors.dart';
+import 'mock_compiler.dart';
+
+export 'package:compiler/src/mirrors/source_mirrors.dart';
+export 'package:compiler/src/mirrors/mirrors_util.dart';
+
+const String SOURCE = 'source';
+final Uri SOURCE_URI = new Uri(scheme: SOURCE, path: SOURCE);
+
+// TODO(johnniwinther): Move this to a mirrors helper library.
+Future<MirrorSystem> createMirrorSystem(String source) {
+  MockCompiler compiler = new MockCompiler.internal(
+      analyzeOnly: true,
+      analyzeAll: true,
+      preserveComments: true);
+    compiler.registerSource(SOURCE_URI, source);
+    compiler.librariesToAnalyzeWhenRun = <Uri>[SOURCE_URI];
+  return compiler.runCompiler(null).then((_) {
+    return new Dart2JsMirrorSystem(compiler);
+  });
+}
+
+/**
+ * Returns [:true:] if [type] is an instance of [:decl:] with type arguments
+ * equal to [typeArgument].
+ */
+bool isInstance(ClassMirror decl, List<TypeMirror> typeArguments,
+            ClassMirror type) {
+  if (type.isOriginalDeclaration) return false;
+  if (!isSameDeclaration(decl, type)) return false;
+  return areEqualsTypes(typeArguments, type.typeArguments);
+}
+
+/**
+ * Returns [:true:] if [type] is the same type as [expected]. This method
+ * equates a non-generic declaration with its instantiation.
+ */
+bool isEqualType(TypeMirror expected, TypeMirror type) {
+  if (expected == type) return true;
+  if (expected is ClassMirror && type is ClassMirror) {
+    if (!isSameDeclaration(expected, type)) return false;
+    if (expected.isOriginalDeclaration || expected.typeArguments.isEmpty) {
+      return type.isOriginalDeclaration || type.typeArguments.isEmpty;
+    }
+    return areEqualsTypes(expected.typeArguments, type.typeArguments);
+  }
+  return true;
+}
+
+/**
+ * Returns [:true:] if [types] are equals to [expected] using the equalitry
+ * defined by [isEqualType].
+ */
+bool areEqualsTypes(List<TypeMirror> expected, List<TypeMirror> types) {
+  return checkSameList(expected, types, isEqualType);
+}
+
+/**
+ * Returns [:true:] if an instance of [type] with type arguments equal to
+ * [typeArguments] is found in [types].
+ */
+bool containsType(ClassMirror decl, List<TypeMirror> typeArguments,
+                  Iterable<TypeMirror> types) {
+  return types.any((type) => isInstance(decl, typeArguments, type));
+}
+
+/**
+ * Returns the declaration of [type].
+ */
+TypeMirror toDeclaration(TypeMirror type) {
+  return type is ClassMirror ? type.originalDeclaration : type;
+}
+
+/**
+ * Returns [:true:] if [type] is of the same declaration as [expected].
+ */
+bool isSameDeclaration(TypeMirror expected, TypeMirror type) {
+  return toDeclaration(expected) == toDeclaration(type);
+}
+
+/**
+ * Returns [:true:] if a type of the declaration of [expected] is in [types].
+ */
+bool containsDeclaration(TypeMirror expected, Iterable<TypeMirror> types) {
+  for (var type in types) {
+    if (isSameDeclaration(expected, type)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+/**
+ * Returns [:true:] if declarations of [expected] are the same as those of
+ * [types], taking order into account.
+ */
+bool isSameDeclarationList(Iterable<TypeMirror> expected,
+                           Iterable<TypeMirror> types) {
+  return checkSameList(expected, types, isSameDeclaration);
+}
+
+/**
+ * Returns [:true:] if declarations of [expected] are the same as those of
+ * [iterable], not taking order into account.
+ */
+bool isSameDeclarationSet(Iterable<TypeMirror> expected,
+                          Iterable<TypeMirror> types) {
+   Set<TypeMirror> expectedSet = expected.map(toDeclaration).toSet();
+   Set<TypeMirror> typesSet = types.map(toDeclaration).toSet();
+   return expectedSet.length == typesSet.length &&
+          expectedSet.containsAll(typesSet);
+}
+
+/**
+ * Utility method for checking whether [expected] and [iterable] contains the
+ * same elements with respect to the checking function [check], takin order
+ * into account.
+ */
+bool checkSameList(Iterable<TypeMirror> expected,
+                   Iterable<TypeMirror> types,
+                   bool check(TypeMirror a, TypeMirror b)) {
+  if (expected.length != types.length) return false;
+  Iterator<TypeMirror> expectedIterator = expected.iterator;
+  Iterator<TypeMirror> typesIterator = types.iterator;
+  while (expectedIterator.moveNext() && typesIterator.moveNext()) {
+    if (!check(expectedIterator.current, typesIterator.current)) {
+      return false;
+    }
+  }
+  return true;
+}
diff --git a/tests/compiler/dart2js/mirrors/class_mirror_type_variables_test.dart b/tests/compiler/dart2js/mirrors/class_mirror_type_variables_test.dart
index a3f6871..b8b2e56f 100644
--- a/tests/compiler/dart2js/mirrors/class_mirror_type_variables_test.dart
+++ b/tests/compiler/dart2js/mirrors/class_mirror_type_variables_test.dart
@@ -1,42 +1,42 @@
-// 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:mirrors";

-

-import "package:async_helper/async_helper.dart";

-

-import "mirrors_test_helper.dart";

-import "../../../lib/mirrors/class_mirror_type_variables_expect.dart";

-

-class CompileTimeEnv implements Env {

-  final MirrorSystem mirrors;

-

-  CompileTimeEnv(this.mirrors);

-

-  LibraryMirror get core => mirrors.libraries[Uri.parse('dart:core')];

-

-  LibraryMirror get test =>

-      mirrors.findLibrary(#class_mirror_type_variables_data);

-

-

-  ClassMirror getA() => test.declarations[#A];

-  ClassMirror getB() => test.declarations[#B];

-  ClassMirror getC() => test.declarations[#C];

-  ClassMirror getD() => test.declarations[#D];

-  ClassMirror getE() => test.declarations[#E];

-  ClassMirror getF() => test.declarations[#F];

-  ClassMirror getNoTypeParams() => test.declarations[#NoTypeParams];

-  ClassMirror getObject() => core.declarations[#Object];

-  ClassMirror getString() => core.declarations[#String];

-  ClassMirror getHelperOfString() =>

-      createInstantiation(test.declarations[#Helper], [getString()]);

-}

-

-main() {

-  asyncTest(() => analyze("class_mirror_type_variables_data.dart").

-      then((MirrorSystem mirrors) {

-    test(new CompileTimeEnv(mirrors));

-  }));

-

-}

+// 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:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/class_mirror_type_variables_expect.dart";
+
+class CompileTimeEnv implements Env {
+  final MirrorSystem mirrors;
+
+  CompileTimeEnv(this.mirrors);
+
+  LibraryMirror get core => mirrors.libraries[Uri.parse('dart:core')];
+
+  LibraryMirror get test =>
+      mirrors.findLibrary(#class_mirror_type_variables_data);
+
+
+  ClassMirror getA() => test.declarations[#A];
+  ClassMirror getB() => test.declarations[#B];
+  ClassMirror getC() => test.declarations[#C];
+  ClassMirror getD() => test.declarations[#D];
+  ClassMirror getE() => test.declarations[#E];
+  ClassMirror getF() => test.declarations[#F];
+  ClassMirror getNoTypeParams() => test.declarations[#NoTypeParams];
+  ClassMirror getObject() => core.declarations[#Object];
+  ClassMirror getString() => core.declarations[#String];
+  ClassMirror getHelperOfString() =>
+      createInstantiation(test.declarations[#Helper], [getString()]);
+}
+
+main() {
+  asyncTest(() => analyze("class_mirror_type_variables_data.dart").
+      then((MirrorSystem mirrors) {
+    test(new CompileTimeEnv(mirrors));
+  }));
+
+}
diff --git a/tests/compiler/dart2js/mirrors/default_value_test.dart b/tests/compiler/dart2js/mirrors/default_value_test.dart
index 53b8721..b4ea3dc 100644
--- a/tests/compiler/dart2js/mirrors/default_value_test.dart
+++ b/tests/compiler/dart2js/mirrors/default_value_test.dart
@@ -1,62 +1,62 @@
-// 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:mirrors";

-

-import "package:async_helper/async_helper.dart";

-import "package:expect/expect.dart";

-import "../memory_compiler.dart";

-

-const SOURCE = const {

-  'main.dart': """

-library main;

-

-class Class {

-  var a, b, c, d, e, f, g, h;

-  Class.optional(this.a, int b, void this.c(), 

-                 [this.d, int this.e, void this.f(), 

-                  this.g = 0, int this.h = 0]);

-  Class.named(this.a, int b, void this.c(), 

-                 {this.d, int this.e, void this.f(), 

-                  this.g: 0, int this.h: 0});

-  methodOptional(a, int b, void c(), 

-                 [d, int e, void f(), 

-                  g = 0, int h = 0]) {}

-  methodNamed(a, int b, void c(), 

-              {d, int e, void f(), 

-               g: 0, int h: 0}) {}

-} 

-""",

-};

-

-main() {

-  asyncTest(() => mirrorSystemFor(SOURCE).then((MirrorSystem mirrors) {

-    LibraryMirror dartCore = mirrors.libraries[Uri.parse('memory:main.dart')];

-    ClassMirror classMirror = dartCore.declarations[#Class];

-    testMethod(classMirror.declarations[#optional]);

-    testMethod(classMirror.declarations[#named]);

-    testMethod(classMirror.declarations[#methodOptional]);

-    testMethod(classMirror.declarations[#methodNamed]);

-  }));

-}

-

-testMethod(MethodMirror mirror) {

-  Expect.equals(8, mirror.parameters.length);

-  for (int i = 0 ; i < 6 ; i++) {

-    testParameter(mirror.parameters[i], false);

-  }

-  for (int i = 6 ; i < 8 ; i++) {

-    testParameter(mirror.parameters[i], true);

-  }

-}

-

-testParameter(ParameterMirror mirror, bool expectDefaultValue) {

-  if (expectDefaultValue) {

-    Expect.isTrue(mirror.hasDefaultValue);

-    Expect.isNotNull(mirror.defaultValue);

-  } else {

-    Expect.isFalse(mirror.hasDefaultValue);

-    Expect.isNull(mirror.defaultValue);

-  }

-}

+// 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:mirrors";
+
+import "package:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+import "../memory_compiler.dart";
+
+const SOURCE = const {
+  'main.dart': """
+library main;
+
+class Class {
+  var a, b, c, d, e, f, g, h;
+  Class.optional(this.a, int b, void this.c(), 
+                 [this.d, int this.e, void this.f(), 
+                  this.g = 0, int this.h = 0]);
+  Class.named(this.a, int b, void this.c(), 
+                 {this.d, int this.e, void this.f(), 
+                  this.g: 0, int this.h: 0});
+  methodOptional(a, int b, void c(), 
+                 [d, int e, void f(), 
+                  g = 0, int h = 0]) {}
+  methodNamed(a, int b, void c(), 
+              {d, int e, void f(), 
+               g: 0, int h: 0}) {}
+} 
+""",
+};
+
+main() {
+  asyncTest(() => mirrorSystemFor(SOURCE).then((MirrorSystem mirrors) {
+    LibraryMirror dartCore = mirrors.libraries[Uri.parse('memory:main.dart')];
+    ClassMirror classMirror = dartCore.declarations[#Class];
+    testMethod(classMirror.declarations[#optional]);
+    testMethod(classMirror.declarations[#named]);
+    testMethod(classMirror.declarations[#methodOptional]);
+    testMethod(classMirror.declarations[#methodNamed]);
+  }));
+}
+
+testMethod(MethodMirror mirror) {
+  Expect.equals(8, mirror.parameters.length);
+  for (int i = 0 ; i < 6 ; i++) {
+    testParameter(mirror.parameters[i], false);
+  }
+  for (int i = 6 ; i < 8 ; i++) {
+    testParameter(mirror.parameters[i], true);
+  }
+}
+
+testParameter(ParameterMirror mirror, bool expectDefaultValue) {
+  if (expectDefaultValue) {
+    Expect.isTrue(mirror.hasDefaultValue);
+    Expect.isNotNull(mirror.defaultValue);
+  } else {
+    Expect.isFalse(mirror.hasDefaultValue);
+    Expect.isNull(mirror.defaultValue);
+  }
+}
diff --git a/tests/compiler/dart2js/mirrors/library_exports_hidden_test.dart b/tests/compiler/dart2js/mirrors/library_exports_hidden_test.dart
index f01441e..ec22898 100644
--- a/tests/compiler/dart2js/mirrors/library_exports_hidden_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_exports_hidden_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file

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

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

-

-import "dart:mirrors";

-

-import "package:async_helper/async_helper.dart";

-

-import "mirrors_test_helper.dart";

-import "../../../lib/mirrors/library_exports_hidden_test.dart";

-

-main() {

-  asyncTest(() => analyze("library_exports_hidden_test.dart").

-      then((MirrorSystem mirrors) {

-    test(mirrors);

-  }));

-}

+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_exports_hidden_test.dart";
+
+main() {
+  asyncTest(() => analyze("library_exports_hidden_test.dart").
+      then((MirrorSystem mirrors) {
+    test(mirrors);
+  }));
+}
diff --git a/tests/compiler/dart2js/mirrors/library_exports_shown_test.dart b/tests/compiler/dart2js/mirrors/library_exports_shown_test.dart
index 87f3369..0234524 100644
--- a/tests/compiler/dart2js/mirrors/library_exports_shown_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_exports_shown_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file

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

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

-

-import "dart:mirrors";

-

-import "package:async_helper/async_helper.dart";

-

-import "mirrors_test_helper.dart";

-import "../../../lib/mirrors/library_exports_shown_test.dart";

-

-main() {

-  asyncTest(() => analyze("library_exports_shown_test.dart").

-      then((MirrorSystem mirrors) {

-    test(mirrors);

-  }));

-}

+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_exports_shown_test.dart";
+
+main() {
+  asyncTest(() => analyze("library_exports_shown_test.dart").
+      then((MirrorSystem mirrors) {
+    test(mirrors);
+  }));
+}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_hidden_test.dart b/tests/compiler/dart2js/mirrors/library_imports_hidden_test.dart
index ad4ba20..d72132d 100644
--- a/tests/compiler/dart2js/mirrors/library_imports_hidden_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_imports_hidden_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file

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

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

-

-import "dart:mirrors";

-

-import "package:async_helper/async_helper.dart";

-

-import "mirrors_test_helper.dart";

-import "../../../lib/mirrors/library_imports_hidden_test.dart";

-

-main() {

-  asyncTest(() => analyze("library_imports_hidden_test.dart").

-      then((MirrorSystem mirrors) {

-    test(mirrors);

-  }));

-}

+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_imports_hidden_test.dart";
+
+main() {
+  asyncTest(() => analyze("library_imports_hidden_test.dart").
+      then((MirrorSystem mirrors) {
+    test(mirrors);
+  }));
+}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_prefixed_show_hide_test.dart b/tests/compiler/dart2js/mirrors/library_imports_prefixed_show_hide_test.dart
index 910dde5..45b7dd5 100644
--- a/tests/compiler/dart2js/mirrors/library_imports_prefixed_show_hide_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_imports_prefixed_show_hide_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file

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

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

-

-import "dart:mirrors";

-

-import "package:async_helper/async_helper.dart";

-

-import "mirrors_test_helper.dart";

-import "../../../lib/mirrors/library_imports_prefixed_show_hide_test.dart";

-

-main() {

-  asyncTest(() => analyze("library_imports_prefixed_show_hide_test.dart").

-      then((MirrorSystem mirrors) {

-    test(mirrors);

-  }));

-}

+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_imports_prefixed_show_hide_test.dart";
+
+main() {
+  asyncTest(() => analyze("library_imports_prefixed_show_hide_test.dart").
+      then((MirrorSystem mirrors) {
+    test(mirrors);
+  }));
+}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_prefixed_test.dart b/tests/compiler/dart2js/mirrors/library_imports_prefixed_test.dart
index 5695e98..528247d 100644
--- a/tests/compiler/dart2js/mirrors/library_imports_prefixed_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_imports_prefixed_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file

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

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

-

-import "dart:mirrors";

-

-import "package:async_helper/async_helper.dart";

-

-import "mirrors_test_helper.dart";

-import "../../../lib/mirrors/library_imports_prefixed_test.dart";

-

-main() {

-  asyncTest(() => analyze("library_imports_prefixed_test.dart").

-      then((MirrorSystem mirrors) {

-    test(mirrors);

-  }));

-}

+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_imports_prefixed_test.dart";
+
+main() {
+  asyncTest(() => analyze("library_imports_prefixed_test.dart").
+      then((MirrorSystem mirrors) {
+    test(mirrors);
+  }));
+}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_shown_test.dart b/tests/compiler/dart2js/mirrors/library_imports_shown_test.dart
index 3f84ce7..83a77b0 100644
--- a/tests/compiler/dart2js/mirrors/library_imports_shown_test.dart
+++ b/tests/compiler/dart2js/mirrors/library_imports_shown_test.dart
@@ -1,17 +1,17 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file

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

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

-

-import "dart:mirrors";

-

-import "package:async_helper/async_helper.dart";

-

-import "mirrors_test_helper.dart";

-import "../../../lib/mirrors/library_imports_shown_test.dart";

-

-main() {

-  asyncTest(() => analyze("library_imports_shown_test.dart").

-      then((MirrorSystem mirrors) {

-    test(mirrors);

-  }));

-}

+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/library_imports_shown_test.dart";
+
+main() {
+  asyncTest(() => analyze("library_imports_shown_test.dart").
+      then((MirrorSystem mirrors) {
+    test(mirrors);
+  }));
+}
diff --git a/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart b/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
index 908c20c..bd41ab2 100644
--- a/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
+++ b/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
@@ -1,141 +1,141 @@
-// 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.

-

-// Test that everything reachable from a [MirrorSystem] can be accessed.

-

-library test.mirrors.reader;

-

-import "dart:mirrors" hide SourceLocation;

-

-import "package:async_helper/async_helper.dart";

-

-import "mirrors_test_helper.dart";

-import "../../../lib/mirrors/mirrors_reader.dart";

-import "package:compiler/src/util/util.dart";

-import "package:compiler/src/mirrors/dart2js_mirrors.dart";

-import "package:compiler/src/mirrors/source_mirrors.dart";

-

-class SourceMirrorsReader extends MirrorsReader {

-  final Dart2JsMirrorSystem mirrorSystem;

-

-  SourceMirrorsReader(this.mirrorSystem,

-                      {bool verbose: false, bool includeStackTrace: false})

-      : super(verbose: verbose, includeStackTrace: includeStackTrace);

-

-  evaluate(f()) {

-    try {

-      return f();

-    } on SpannableAssertionFailure catch (e) {

-      mirrorSystem.compiler.reportAssertionFailure(e);

-      rethrow;

-    }

-  }

-

-  visitMirror(Mirror mirror) {

-    if (mirror is CombinatorMirror) {

-      visitCombinatorMirror(mirror);

-    } else if (mirror is LibraryDependencyMirror) {

-      visitLibraryDependencyMirror(mirror);

-    } else if (mirror is CommentInstanceMirror) {

-      visitCommentInstanceMirror(mirror);

-    } else if (mirror is ListInstanceMirror) {

-      visitListInstanceMirror(mirror);

-    } else if (mirror is MapInstanceMirror) {

-      visitMapInstanceMirror(mirror);

-    } else if (mirror is TypeInstanceMirror) {

-      visitTypeInstanceMirror(mirror);

-    } else {

-      super.visitMirror(mirror);

-    }

-  }

-

-  visitDeclarationMirror(DeclarationSourceMirror mirror) {

-    super.visitDeclarationMirror(mirror);

-    visit(mirror, 'isNameSynthetic', () => mirror.isNameSynthetic);

-  }

-

-  visitClassMirror(ClassSourceMirror mirror) {

-    super.visitClassMirror(mirror);

-    visit(mirror, 'isAbstract', () => mirror.isAbstract);

-  }

-

-  visitLibraryMirror(LibrarySourceMirror mirror) {

-    super.visitLibraryMirror(mirror);

-    visit(mirror, 'libraryDependencies', () => mirror.libraryDependencies);

-  }

-

-  visitParameterMirror(ParameterMirror mirror) {

-    super.visitParameterMirror(mirror);

-    if (mirror is ParameterSourceMirror) {

-      visit(mirror, 'isInitializingFormal', () => mirror.isInitializingFormal);

-      visit(mirror, 'initializedField', () => mirror.initializedField);

-    }

-  }

-

-  visitTypeMirror(TypeSourceMirror mirror) {

-    super.visitTypeMirror(mirror);

-    visit(mirror, 'isVoid', () => mirror.isVoid);

-    visit(mirror, 'isDynamic', () => mirror.isDynamic);

-  }

-

-  visitSourceLocation(SourceLocation location) {

-    super.visitSourceLocation(location);

-    visit(location, 'line', () => location.line);

-    visit(location, 'column', () => location.column);

-    visit(location, 'offset', () => location.offset);

-    visit(location, 'length', () => location.length);

-    visit(location, 'text', () => location.text);

-    visit(location, 'sourceUri', () => location.sourceUri);

-    visit(location, 'sourceText', () => location.sourceText);

-  }

-

-  visitCombinatorMirror(CombinatorMirror mirror) {

-    visit(mirror, 'identifiers', () => mirror.identifiers);

-    visit(mirror, 'isShow', () => mirror.isShow);

-    visit(mirror, 'isHide', () => mirror.isHide);

-  }

-

-  visitLibraryDependencyMirror(LibraryDependencyMirror mirror) {

-    visit(mirror, 'isImport', () => mirror.isImport);

-    visit(mirror, 'isExport', () => mirror.isExport);

-    visit(mirror, 'sourceLibrary', () => mirror.sourceLibrary);

-    visit(mirror, 'targetLibrary', () => mirror.targetLibrary);

-    visit(mirror, 'prefix', () => mirror.prefix);

-    visit(mirror, 'combinators', () => mirror.combinators);

-    visit(mirror, 'location', () => mirror.location);

-  }

-

-  visitCommentInstanceMirror(CommentInstanceMirror mirror) {

-    visitInstanceMirror(mirror);

-    visit(mirror, 'text', () => mirror.text);

-    visit(mirror, 'trimmedText', () => mirror.trimmedText);

-    visit(mirror, 'isDocComment', () => mirror.isDocComment);

-  }

-

-  visitListInstanceMirror(ListInstanceMirror mirror) {

-    visitInstanceMirror(mirror);

-    visit(mirror, 'length', () => mirror.length);

-  }

-

-  visitMapInstanceMirror(MapInstanceMirror mirror) {

-    visitInstanceMirror(mirror);

-    visit(mirror, 'keys', () => mirror.keys);

-    visit(mirror, 'length', () => mirror.length);

-  }

-

-  visitTypeInstanceMirror(TypeInstanceMirror mirror) {

-    visitInstanceMirror(mirror);

-    visit(mirror, 'representedType', () => mirror.representedType);

-  }

-}

-

-main(List<String> arguments) {

-  asyncTest(() => analyzeUri(Uri.parse('dart:core')).

-      then((MirrorSystem mirrors) {

-    MirrorsReader reader = new SourceMirrorsReader(mirrors,

-        verbose: arguments.contains('-v'),

-        includeStackTrace: arguments.contains('-s'));

-    reader.checkMirrorSystem(mirrors);

-  }));

-}

+// 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.
+
+// Test that everything reachable from a [MirrorSystem] can be accessed.
+
+library test.mirrors.reader;
+
+import "dart:mirrors" hide SourceLocation;
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/mirrors_reader.dart";
+import "package:compiler/src/util/util.dart";
+import "package:compiler/src/mirrors/dart2js_mirrors.dart";
+import "package:compiler/src/mirrors/source_mirrors.dart";
+
+class SourceMirrorsReader extends MirrorsReader {
+  final Dart2JsMirrorSystem mirrorSystem;
+
+  SourceMirrorsReader(this.mirrorSystem,
+                      {bool verbose: false, bool includeStackTrace: false})
+      : super(verbose: verbose, includeStackTrace: includeStackTrace);
+
+  evaluate(f()) {
+    try {
+      return f();
+    } on SpannableAssertionFailure catch (e) {
+      mirrorSystem.compiler.reportAssertionFailure(e);
+      rethrow;
+    }
+  }
+
+  visitMirror(Mirror mirror) {
+    if (mirror is CombinatorMirror) {
+      visitCombinatorMirror(mirror);
+    } else if (mirror is LibraryDependencyMirror) {
+      visitLibraryDependencyMirror(mirror);
+    } else if (mirror is CommentInstanceMirror) {
+      visitCommentInstanceMirror(mirror);
+    } else if (mirror is ListInstanceMirror) {
+      visitListInstanceMirror(mirror);
+    } else if (mirror is MapInstanceMirror) {
+      visitMapInstanceMirror(mirror);
+    } else if (mirror is TypeInstanceMirror) {
+      visitTypeInstanceMirror(mirror);
+    } else {
+      super.visitMirror(mirror);
+    }
+  }
+
+  visitDeclarationMirror(DeclarationSourceMirror mirror) {
+    super.visitDeclarationMirror(mirror);
+    visit(mirror, 'isNameSynthetic', () => mirror.isNameSynthetic);
+  }
+
+  visitClassMirror(ClassSourceMirror mirror) {
+    super.visitClassMirror(mirror);
+    visit(mirror, 'isAbstract', () => mirror.isAbstract);
+  }
+
+  visitLibraryMirror(LibrarySourceMirror mirror) {
+    super.visitLibraryMirror(mirror);
+    visit(mirror, 'libraryDependencies', () => mirror.libraryDependencies);
+  }
+
+  visitParameterMirror(ParameterMirror mirror) {
+    super.visitParameterMirror(mirror);
+    if (mirror is ParameterSourceMirror) {
+      visit(mirror, 'isInitializingFormal', () => mirror.isInitializingFormal);
+      visit(mirror, 'initializedField', () => mirror.initializedField);
+    }
+  }
+
+  visitTypeMirror(TypeSourceMirror mirror) {
+    super.visitTypeMirror(mirror);
+    visit(mirror, 'isVoid', () => mirror.isVoid);
+    visit(mirror, 'isDynamic', () => mirror.isDynamic);
+  }
+
+  visitSourceLocation(SourceLocation location) {
+    super.visitSourceLocation(location);
+    visit(location, 'line', () => location.line);
+    visit(location, 'column', () => location.column);
+    visit(location, 'offset', () => location.offset);
+    visit(location, 'length', () => location.length);
+    visit(location, 'text', () => location.text);
+    visit(location, 'sourceUri', () => location.sourceUri);
+    visit(location, 'sourceText', () => location.sourceText);
+  }
+
+  visitCombinatorMirror(CombinatorMirror mirror) {
+    visit(mirror, 'identifiers', () => mirror.identifiers);
+    visit(mirror, 'isShow', () => mirror.isShow);
+    visit(mirror, 'isHide', () => mirror.isHide);
+  }
+
+  visitLibraryDependencyMirror(LibraryDependencyMirror mirror) {
+    visit(mirror, 'isImport', () => mirror.isImport);
+    visit(mirror, 'isExport', () => mirror.isExport);
+    visit(mirror, 'sourceLibrary', () => mirror.sourceLibrary);
+    visit(mirror, 'targetLibrary', () => mirror.targetLibrary);
+    visit(mirror, 'prefix', () => mirror.prefix);
+    visit(mirror, 'combinators', () => mirror.combinators);
+    visit(mirror, 'location', () => mirror.location);
+  }
+
+  visitCommentInstanceMirror(CommentInstanceMirror mirror) {
+    visitInstanceMirror(mirror);
+    visit(mirror, 'text', () => mirror.text);
+    visit(mirror, 'trimmedText', () => mirror.trimmedText);
+    visit(mirror, 'isDocComment', () => mirror.isDocComment);
+  }
+
+  visitListInstanceMirror(ListInstanceMirror mirror) {
+    visitInstanceMirror(mirror);
+    visit(mirror, 'length', () => mirror.length);
+  }
+
+  visitMapInstanceMirror(MapInstanceMirror mirror) {
+    visitInstanceMirror(mirror);
+    visit(mirror, 'keys', () => mirror.keys);
+    visit(mirror, 'length', () => mirror.length);
+  }
+
+  visitTypeInstanceMirror(TypeInstanceMirror mirror) {
+    visitInstanceMirror(mirror);
+    visit(mirror, 'representedType', () => mirror.representedType);
+  }
+}
+
+main(List<String> arguments) {
+  asyncTest(() => analyzeUri(Uri.parse('dart:core')).
+      then((MirrorSystem mirrors) {
+    MirrorsReader reader = new SourceMirrorsReader(mirrors,
+        verbose: arguments.contains('-v'),
+        includeStackTrace: arguments.contains('-s'));
+    reader.checkMirrorSystem(mirrors);
+  }));
+}
diff --git a/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart b/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
index 1f57a03..0aa116f 100644
--- a/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
+++ b/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
@@ -1,37 +1,37 @@
-// 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:io';

-import 'dart:async';

-

-import 'package:compiler/src/mirrors/source_mirrors.dart';

-import 'package:compiler/src/mirrors/analyze.dart' as source_mirrors;

-import 'package:compiler/src/source_file_provider.dart';

-

-TypeMirror createInstantiation(TypeSourceMirror type,

-                               List<TypeMirror> typeArguments) {

-  return type.createInstantiation(typeArguments);

-}

-

-Future<MirrorSystem> analyze(String test) {

-  Uri repository = Platform.script.resolve('../../../../');

-  Uri testUri = repository.resolve('tests/lib/mirrors/$test');

-  return analyzeUri(testUri);

-}

-

-

-Future<MirrorSystem> analyzeUri(Uri testUri) {

-  Uri repository = Platform.script.resolve('../../../../');

-  Uri libraryRoot = repository.resolve('sdk/');

-  Uri packageRoot = Uri.base.resolveUri(

-      new Uri.file('${Platform.packageRoot}/'));

-  var provider = new CompilerSourceFileProvider();

-  var handler = new FormattingDiagnosticHandler(provider);

-  return source_mirrors.analyze(

-      [testUri],

-      libraryRoot,

-      packageRoot,

-      provider,

-      handler);

+// 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:io';
+import 'dart:async';
+
+import 'package:compiler/src/mirrors/source_mirrors.dart';
+import 'package:compiler/src/mirrors/analyze.dart' as source_mirrors;
+import 'package:compiler/src/source_file_provider.dart';
+
+TypeMirror createInstantiation(TypeSourceMirror type,
+                               List<TypeMirror> typeArguments) {
+  return type.createInstantiation(typeArguments);
+}
+
+Future<MirrorSystem> analyze(String test) {
+  Uri repository = Platform.script.resolve('../../../../');
+  Uri testUri = repository.resolve('tests/lib/mirrors/$test');
+  return analyzeUri(testUri);
+}
+
+
+Future<MirrorSystem> analyzeUri(Uri testUri) {
+  Uri repository = Platform.script.resolve('../../../../');
+  Uri libraryRoot = repository.resolve('sdk/');
+  Uri packageRoot = Uri.base.resolveUri(
+      new Uri.file('${Platform.packageRoot}/'));
+  var provider = new CompilerSourceFileProvider();
+  var handler = new FormattingDiagnosticHandler(provider);
+  return source_mirrors.analyze(
+      [testUri],
+      libraryRoot,
+      packageRoot,
+      provider,
+      handler);
 }
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mirrors/relation_assignable_test.dart b/tests/compiler/dart2js/mirrors/relation_assignable_test.dart
index 3f57a14..eeb6190 100644
--- a/tests/compiler/dart2js/mirrors/relation_assignable_test.dart
+++ b/tests/compiler/dart2js/mirrors/relation_assignable_test.dart
@@ -1,17 +1,17 @@
-// 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:mirrors";

-

-import "package:async_helper/async_helper.dart";

-

-import "mirrors_test_helper.dart";

-import "../../../lib/mirrors/relation_assignable_test.dart";

-

-main() {

-  asyncTest(() => analyze("relation_assignable_test.dart").

-      then((MirrorSystem mirrors) {

-    test(mirrors);

-  }));

-}

+// 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:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/relation_assignable_test.dart";
+
+main() {
+  asyncTest(() => analyze("relation_assignable_test.dart").
+      then((MirrorSystem mirrors) {
+    test(mirrors);
+  }));
+}
diff --git a/tests/compiler/dart2js/mirrors/relation_subclass_test.dart b/tests/compiler/dart2js/mirrors/relation_subclass_test.dart
index eaab608..86503eb 100644
--- a/tests/compiler/dart2js/mirrors/relation_subclass_test.dart
+++ b/tests/compiler/dart2js/mirrors/relation_subclass_test.dart
@@ -1,17 +1,17 @@
-// 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:mirrors";

-

-import "package:async_helper/async_helper.dart";

-

-import "mirrors_test_helper.dart";

-import "../../../lib/mirrors/relation_subclass_test.dart";

-

-main() {

-  asyncTest(() => analyze("relation_subclass_test.dart").

-      then((MirrorSystem mirrors) {

-    test(mirrors);

-  }));

-}

+// 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:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/relation_subclass_test.dart";
+
+main() {
+  asyncTest(() => analyze("relation_subclass_test.dart").
+      then((MirrorSystem mirrors) {
+    test(mirrors);
+  }));
+}
diff --git a/tests/compiler/dart2js/mirrors/relation_subtype_test.dart b/tests/compiler/dart2js/mirrors/relation_subtype_test.dart
index 036af05..2fca90c 100644
--- a/tests/compiler/dart2js/mirrors/relation_subtype_test.dart
+++ b/tests/compiler/dart2js/mirrors/relation_subtype_test.dart
@@ -1,17 +1,17 @@
-// 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:mirrors";

-

-import "package:async_helper/async_helper.dart";

-

-import "mirrors_test_helper.dart";

-import "../../../lib/mirrors/relation_subtype_test.dart";

-

-main() {

-  asyncTest(() => analyze("relation_subtype_test.dart").

-      then((MirrorSystem mirrors) {

-    test(mirrors);

-  }));

-}

+// 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:mirrors";
+
+import "package:async_helper/async_helper.dart";
+
+import "mirrors_test_helper.dart";
+import "../../../lib/mirrors/relation_subtype_test.dart";
+
+main() {
+  asyncTest(() => analyze("relation_subtype_test.dart").
+      then((MirrorSystem mirrors) {
+    test(mirrors);
+  }));
+}
diff --git a/tests/compiler/dart2js/mirrors_exports_test.dart b/tests/compiler/dart2js/mirrors_exports_test.dart
index 0f0a127..07b70e7 100644
--- a/tests/compiler/dart2js/mirrors_exports_test.dart
+++ b/tests/compiler/dart2js/mirrors_exports_test.dart
@@ -1,183 +1,183 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file

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

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

-

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

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

-import 'dart:async';

-import 'memory_compiler.dart';

-import 'package:compiler/src/mirrors/source_mirrors.dart';

-

-const SOURCE_FILES = const {

-'main.dart': '''

-import 'a.dart' show A1, A2;

-import 'b.dart' as b hide B1;

-export 'a.dart' show A2 hide A3, A1;

-export 'b.dart' hide B1, B2 show B3;

-import 'dart:core' as core;

-import 'c.dart' deferred as c;

-

-main() {}

-''',

-'a.dart': '''

-class A1 {}

-class A2 {}

-class A3 {}

-''',

-'b.dart': '''

-class B1 {}

-class B2 {}

-class B3 {}

-''',

-'c.dart': '''

-foo() => 499;

-'''

-};

-

-void main() {

-  asyncTest(() => mirrorSystemFor(SOURCE_FILES).then((MirrorSystem mirrors) {

-    LibrarySourceMirror mainLibrary =

-        mirrors.libraries[Uri.parse('memory:main.dart')];

-    Expect.isNotNull(mainLibrary);

-

-    LibrarySourceMirror aLibrary =

-        mirrors.libraries[Uri.parse('memory:a.dart')];

-    Expect.isNotNull(aLibrary);

-

-    LibrarySourceMirror bLibrary =

-        mirrors.libraries[Uri.parse('memory:b.dart')];

-    Expect.isNotNull(bLibrary);

-

-    LibrarySourceMirror cLibrary =

-        mirrors.libraries[Uri.parse('memory:c.dart')];

-    Expect.isNotNull(cLibrary);

-

-    LibrarySourceMirror coreLibrary =

-        mirrors.libraries[Uri.parse('dart:core')];

-    Expect.isNotNull(coreLibrary);

-

-    var dependencies = mainLibrary.libraryDependencies;

-    Expect.isNotNull(dependencies);

-    Expect.equals(6, dependencies.length);

-

-    // import 'a.dart' show A1, A2;

-    var dependency = dependencies[0];

-    Expect.isNotNull(dependency);

-    Expect.isTrue(dependency.isImport);

-    Expect.isFalse(dependency.isExport);

-    Expect.equals(mainLibrary, dependency.sourceLibrary);

-    Expect.equals(aLibrary, dependency.targetLibrary);

-    Expect.isNull(dependency.prefix);

-    Expect.isFalse(dependency.isDeferred);

-

-    var combinators = dependency.combinators;

-    Expect.isNotNull(combinators);

-    Expect.equals(1, combinators.length);

-

-    var combinator = combinators[0];

-    Expect.isNotNull(combinator);

-    Expect.isTrue(combinator.isShow);

-    Expect.isFalse(combinator.isHide);

-    Expect.listEquals(['A1', 'A2'], combinator.identifiers);

-

-    // import 'b.dart' as b hide B1;

-    dependency = dependencies[1];

-    Expect.isNotNull(dependency);

-    Expect.isTrue(dependency.isImport);

-    Expect.isFalse(dependency.isExport);

-    Expect.equals(mainLibrary, dependency.sourceLibrary);

-    Expect.equals(bLibrary, dependency.targetLibrary);

-    Expect.equals('b', dependency.prefix);

-    Expect.isFalse(dependency.isDeferred);

-

-    combinators = dependency.combinators;

-    Expect.isNotNull(combinators);

-    Expect.equals(1, combinators.length);

-

-    combinator = combinators[0];

-    Expect.isNotNull(combinator);

-    Expect.isFalse(combinator.isShow);

-    Expect.isTrue(combinator.isHide);

-    Expect.listEquals(['B1'], combinator.identifiers);

-

-    // export 'a.dart' show A2 hide A3, A1;

-    dependency = dependencies[2];

-    Expect.isNotNull(dependency);

-    Expect.isFalse(dependency.isImport);

-    Expect.isTrue(dependency.isExport);

-    Expect.equals(mainLibrary, dependency.sourceLibrary);

-    Expect.equals(aLibrary, dependency.targetLibrary);

-    Expect.isNull(dependency.prefix);

-    Expect.isFalse(dependency.isDeferred);

-

-    combinators = dependency.combinators;

-    Expect.isNotNull(combinators);

-    Expect.equals(2, combinators.length);

-

-    combinator = combinators[0];

-    Expect.isNotNull(combinator);

-    Expect.isTrue(combinator.isShow);

-    Expect.isFalse(combinator.isHide);

-    Expect.listEquals(['A2'], combinator.identifiers);

-

-    combinator = combinators[1];

-    Expect.isNotNull(combinator);

-    Expect.isFalse(combinator.isShow);

-    Expect.isTrue(combinator.isHide);

-    Expect.listEquals(['A3', 'A1'], combinator.identifiers);

-

-    // export 'b.dart' hide B1, B2 show B3;

-    dependency = dependencies[3];

-    Expect.isNotNull(dependency);

-    Expect.isFalse(dependency.isImport);

-    Expect.isTrue(dependency.isExport);

-    Expect.equals(mainLibrary, dependency.sourceLibrary);

-    Expect.equals(bLibrary, dependency.targetLibrary);

-    Expect.isNull(dependency.prefix);

-    Expect.isFalse(dependency.isDeferred);

-

-    combinators = dependency.combinators;

-    Expect.isNotNull(combinators);

-    Expect.equals(2, combinators.length);

-

-    combinator = combinators[0];

-    Expect.isNotNull(combinator);

-    Expect.isFalse(combinator.isShow);

-    Expect.isTrue(combinator.isHide);

-    Expect.listEquals(['B1', 'B2'], combinator.identifiers);

-

-    combinator = combinators[1];

-    Expect.isNotNull(combinator);

-    Expect.isTrue(combinator.isShow);

-    Expect.isFalse(combinator.isHide);

-    Expect.listEquals(['B3'], combinator.identifiers);

-

-    // import 'dart:core' as core;

-    dependency = dependencies[4];

-    Expect.isNotNull(dependency);

-    Expect.isTrue(dependency.isImport);

-    Expect.isFalse(dependency.isExport);

-    Expect.equals(mainLibrary, dependency.sourceLibrary);

-    Expect.equals(coreLibrary, dependency.targetLibrary);

-    Expect.equals('core', dependency.prefix);

-    Expect.isFalse(dependency.isDeferred);

-

-    combinators = dependency.combinators;

-    Expect.isNotNull(combinators);

-    Expect.equals(0, combinators.length);

-

-    // import 'c.dart' deferred as c;

-    dependency = dependencies[5];

-    Expect.isNotNull(dependency);

-    Expect.isTrue(dependency.isImport);

-    Expect.isFalse(dependency.isExport);

-    Expect.equals(mainLibrary, dependency.sourceLibrary);

-    Expect.equals(cLibrary, dependency.targetLibrary);

-    Expect.equals('c', dependency.prefix);

-    Expect.isTrue(dependency.isDeferred);

-

-    combinators = dependency.combinators;

-    Expect.isNotNull(combinators);

-    Expect.equals(0, combinators.length);

-  }));

+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'dart:async';
+import 'memory_compiler.dart';
+import 'package:compiler/src/mirrors/source_mirrors.dart';
+
+const SOURCE_FILES = const {
+'main.dart': '''
+import 'a.dart' show A1, A2;
+import 'b.dart' as b hide B1;
+export 'a.dart' show A2 hide A3, A1;
+export 'b.dart' hide B1, B2 show B3;
+import 'dart:core' as core;
+import 'c.dart' deferred as c;
+
+main() {}
+''',
+'a.dart': '''
+class A1 {}
+class A2 {}
+class A3 {}
+''',
+'b.dart': '''
+class B1 {}
+class B2 {}
+class B3 {}
+''',
+'c.dart': '''
+foo() => 499;
+'''
+};
+
+void main() {
+  asyncTest(() => mirrorSystemFor(SOURCE_FILES).then((MirrorSystem mirrors) {
+    LibrarySourceMirror mainLibrary =
+        mirrors.libraries[Uri.parse('memory:main.dart')];
+    Expect.isNotNull(mainLibrary);
+
+    LibrarySourceMirror aLibrary =
+        mirrors.libraries[Uri.parse('memory:a.dart')];
+    Expect.isNotNull(aLibrary);
+
+    LibrarySourceMirror bLibrary =
+        mirrors.libraries[Uri.parse('memory:b.dart')];
+    Expect.isNotNull(bLibrary);
+
+    LibrarySourceMirror cLibrary =
+        mirrors.libraries[Uri.parse('memory:c.dart')];
+    Expect.isNotNull(cLibrary);
+
+    LibrarySourceMirror coreLibrary =
+        mirrors.libraries[Uri.parse('dart:core')];
+    Expect.isNotNull(coreLibrary);
+
+    var dependencies = mainLibrary.libraryDependencies;
+    Expect.isNotNull(dependencies);
+    Expect.equals(6, dependencies.length);
+
+    // import 'a.dart' show A1, A2;
+    var dependency = dependencies[0];
+    Expect.isNotNull(dependency);
+    Expect.isTrue(dependency.isImport);
+    Expect.isFalse(dependency.isExport);
+    Expect.equals(mainLibrary, dependency.sourceLibrary);
+    Expect.equals(aLibrary, dependency.targetLibrary);
+    Expect.isNull(dependency.prefix);
+    Expect.isFalse(dependency.isDeferred);
+
+    var combinators = dependency.combinators;
+    Expect.isNotNull(combinators);
+    Expect.equals(1, combinators.length);
+
+    var combinator = combinators[0];
+    Expect.isNotNull(combinator);
+    Expect.isTrue(combinator.isShow);
+    Expect.isFalse(combinator.isHide);
+    Expect.listEquals(['A1', 'A2'], combinator.identifiers);
+
+    // import 'b.dart' as b hide B1;
+    dependency = dependencies[1];
+    Expect.isNotNull(dependency);
+    Expect.isTrue(dependency.isImport);
+    Expect.isFalse(dependency.isExport);
+    Expect.equals(mainLibrary, dependency.sourceLibrary);
+    Expect.equals(bLibrary, dependency.targetLibrary);
+    Expect.equals('b', dependency.prefix);
+    Expect.isFalse(dependency.isDeferred);
+
+    combinators = dependency.combinators;
+    Expect.isNotNull(combinators);
+    Expect.equals(1, combinators.length);
+
+    combinator = combinators[0];
+    Expect.isNotNull(combinator);
+    Expect.isFalse(combinator.isShow);
+    Expect.isTrue(combinator.isHide);
+    Expect.listEquals(['B1'], combinator.identifiers);
+
+    // export 'a.dart' show A2 hide A3, A1;
+    dependency = dependencies[2];
+    Expect.isNotNull(dependency);
+    Expect.isFalse(dependency.isImport);
+    Expect.isTrue(dependency.isExport);
+    Expect.equals(mainLibrary, dependency.sourceLibrary);
+    Expect.equals(aLibrary, dependency.targetLibrary);
+    Expect.isNull(dependency.prefix);
+    Expect.isFalse(dependency.isDeferred);
+
+    combinators = dependency.combinators;
+    Expect.isNotNull(combinators);
+    Expect.equals(2, combinators.length);
+
+    combinator = combinators[0];
+    Expect.isNotNull(combinator);
+    Expect.isTrue(combinator.isShow);
+    Expect.isFalse(combinator.isHide);
+    Expect.listEquals(['A2'], combinator.identifiers);
+
+    combinator = combinators[1];
+    Expect.isNotNull(combinator);
+    Expect.isFalse(combinator.isShow);
+    Expect.isTrue(combinator.isHide);
+    Expect.listEquals(['A3', 'A1'], combinator.identifiers);
+
+    // export 'b.dart' hide B1, B2 show B3;
+    dependency = dependencies[3];
+    Expect.isNotNull(dependency);
+    Expect.isFalse(dependency.isImport);
+    Expect.isTrue(dependency.isExport);
+    Expect.equals(mainLibrary, dependency.sourceLibrary);
+    Expect.equals(bLibrary, dependency.targetLibrary);
+    Expect.isNull(dependency.prefix);
+    Expect.isFalse(dependency.isDeferred);
+
+    combinators = dependency.combinators;
+    Expect.isNotNull(combinators);
+    Expect.equals(2, combinators.length);
+
+    combinator = combinators[0];
+    Expect.isNotNull(combinator);
+    Expect.isFalse(combinator.isShow);
+    Expect.isTrue(combinator.isHide);
+    Expect.listEquals(['B1', 'B2'], combinator.identifiers);
+
+    combinator = combinators[1];
+    Expect.isNotNull(combinator);
+    Expect.isTrue(combinator.isShow);
+    Expect.isFalse(combinator.isHide);
+    Expect.listEquals(['B3'], combinator.identifiers);
+
+    // import 'dart:core' as core;
+    dependency = dependencies[4];
+    Expect.isNotNull(dependency);
+    Expect.isTrue(dependency.isImport);
+    Expect.isFalse(dependency.isExport);
+    Expect.equals(mainLibrary, dependency.sourceLibrary);
+    Expect.equals(coreLibrary, dependency.targetLibrary);
+    Expect.equals('core', dependency.prefix);
+    Expect.isFalse(dependency.isDeferred);
+
+    combinators = dependency.combinators;
+    Expect.isNotNull(combinators);
+    Expect.equals(0, combinators.length);
+
+    // import 'c.dart' deferred as c;
+    dependency = dependencies[5];
+    Expect.isNotNull(dependency);
+    Expect.isTrue(dependency.isImport);
+    Expect.isFalse(dependency.isExport);
+    Expect.equals(mainLibrary, dependency.sourceLibrary);
+    Expect.equals(cLibrary, dependency.targetLibrary);
+    Expect.equals('c', dependency.prefix);
+    Expect.isTrue(dependency.isDeferred);
+
+    combinators = dependency.combinators;
+    Expect.isNotNull(combinators);
+    Expect.equals(0, combinators.length);
+  }));
 }
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mirrors_mixin_test.dart b/tests/compiler/dart2js/mirrors_mixin_test.dart
index 0a94a06..d5ab821 100644
--- a/tests/compiler/dart2js/mirrors_mixin_test.dart
+++ b/tests/compiler/dart2js/mirrors_mixin_test.dart
@@ -1,240 +1,240 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file

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

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

-

-library mirrors_mixin_test;

-

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

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

-import 'mirror_system_helper.dart';

-

-const String CLASS_SOURCE = '''

-class A {}

-

-class S {}

-class M1<T> {}

-class M2 {}

-

-class C extends S with M1<A> {}

-class D extends S with M1, M2 {}

-class E extends S with M2, M1 implements A, M1 {}

-class E2 extends E {}

-

-class F = S with M1<A>;

-abstract class G = S with M1, M2;

-class H = S with M2, M1 implements A, M1;

-class H2 extends H {}

-''';

-

-void main() {

-  asyncTest(() => createMirrorSystem(CLASS_SOURCE).then((MirrorSystem mirrors) {

-    LibraryMirror library = mirrors.libraries[SOURCE_URI];

-

-    checkSimpleClass(var cls) {

-      Expect.isNotNull(cls);

-      Expect.isTrue(cls is ClassMirror);

-      Expect.isFalse(isMixinApplication(cls));

-      Expect.isFalse(cls.isNameSynthetic);

-      Expect.isFalse(isObject(cls));

-      Expect.isTrue(isObject(cls.superclass));

-      Expect.equals(0, cls.superinterfaces.length);

-

-      Expect.isTrue(isObject(getSuperclass(cls)));

-      Expect.isTrue(getAppliedMixins(cls).isEmpty);

-      Expect.isTrue(getExplicitInterfaces(cls).isEmpty);

-    }

-

-    // class A {}

-    var A = library.declarations[#A];

-    checkSimpleClass(A);

-

-    // class S {}

-    var S = library.declarations[#S];

-    checkSimpleClass(S);

-

-    // class M1 {}

-    var M1 = library.declarations[#M1];

-    checkSimpleClass(M1);

-

-    // class M2 {}

-    var M2 = library.declarations[#M2];

-    checkSimpleClass(M2);

-

-    // class C extends S with M1<A> {}

-    var C = library.declarations[#C];

-    Expect.isNotNull(C);

-    Expect.isTrue(C is ClassMirror);

-    Expect.isFalse(isMixinApplication(C));

-    Expect.isFalse(isObject(C));

-    Expect.equals(0, C.superinterfaces.length);

-    var C_super = C.superclass;

-    Expect.isNotNull(C_super);

-    Expect.isTrue(C_super is ClassMirror);

-    Expect.isTrue(isMixinApplication(C_super));

-    Expect.isTrue(C_super.isNameSynthetic);

-    Expect.equals(1, C_super.superinterfaces.length);

-    Expect.isTrue(containsType(M1, [A], C_super.superinterfaces));

-    Expect.isTrue(isInstance(M1, [A], C_super.mixin));

-    Expect.isFalse(isObject(C_super));

-    Expect.isTrue(isSameDeclaration(S, C_super.superclass));

-

-    Expect.isTrue(isSameDeclaration(S, getSuperclass(C)));

-    Expect.isTrue(isSameDeclarationList([M1], getAppliedMixins(C)));

-    Expect.isTrue(getExplicitInterfaces(C).isEmpty);

-

-    // D extends S with M1, M2 {}

-    var D = library.declarations[#D];

-    Expect.isNotNull(D);

-    Expect.isTrue(D is ClassMirror);

-    Expect.isFalse(isMixinApplication(D));

-    Expect.isFalse(isObject(D));

-    Expect.equals(0, D.superinterfaces.length);

-    var D_super = D.superclass;

-    Expect.isNotNull(D_super);

-    Expect.isTrue(D_super is ClassMirror);

-    Expect.isTrue(isMixinApplication(D_super));

-    Expect.isTrue(D_super.isNameSynthetic);

-    Expect.equals(1, D_super.superinterfaces.length);

-    Expect.isTrue(containsDeclaration(M2, D_super.superinterfaces));

-    Expect.isTrue(isSameDeclaration(M2, D_super.mixin));

-    Expect.isFalse(isObject(D_super));

-    Expect.isFalse(isSameDeclaration(S, D_super.superclass));

-    var D_super_super = D_super.superclass;

-    Expect.isNotNull(D_super_super);

-    Expect.isTrue(D_super_super is ClassMirror);

-    Expect.isTrue(isMixinApplication(D_super_super));

-    Expect.isTrue(D_super_super.isNameSynthetic);

-    Expect.equals(1, D_super_super.superinterfaces.length);

-    Expect.isTrue(containsDeclaration(M1, D_super_super.superinterfaces));

-    Expect.isTrue(isSameDeclaration(M1, D_super_super.mixin));

-    Expect.isFalse(isObject(D_super_super));

-    Expect.isTrue(isSameDeclaration(S, D_super_super.superclass));

-

-    Expect.isTrue(isSameDeclaration(S, getSuperclass(D)));

-    Expect.isTrue(isSameDeclarationList([M1, M2], getAppliedMixins(D)));

-    Expect.isTrue(getExplicitInterfaces(D).isEmpty);

-

-    // class E extends S with M2, M1 implements A, M1 {}

-    var E = library.declarations[#E];

-    Expect.isNotNull(E);

-    Expect.isTrue(E is ClassMirror);

-    Expect.isFalse(isMixinApplication(E));

-    Expect.isFalse(isObject(E));

-    Expect.equals(2, E.superinterfaces.length);

-    Expect.isTrue(containsDeclaration(A, E.superinterfaces));

-    Expect.isTrue(containsDeclaration(M1, E.superinterfaces));

-    var E_super = E.superclass;

-    Expect.isNotNull(E_super);

-    Expect.isTrue(E_super is ClassMirror);

-    Expect.isTrue(isMixinApplication(E_super));

-    Expect.isTrue(E_super.isNameSynthetic);

-    Expect.equals(1, E_super.superinterfaces.length);

-    Expect.isTrue(containsDeclaration(M1, E_super.superinterfaces));

-    Expect.isTrue(isSameDeclaration(M1, E_super.mixin));

-    Expect.isFalse(isObject(E_super));

-    Expect.isFalse(isSameDeclaration(S, E_super.superclass));

-    var E_super_super = E_super.superclass;

-    Expect.isNotNull(E_super_super);

-    Expect.isTrue(E_super_super is ClassMirror);

-    Expect.isTrue(isMixinApplication(E_super_super));

-    Expect.isTrue(E_super_super.isNameSynthetic);

-    Expect.equals(1, E_super_super.superinterfaces.length);

-    Expect.isTrue(containsDeclaration(M2, E_super_super.superinterfaces));

-    Expect.isTrue(isSameDeclaration(M2, E_super_super.mixin));

-    Expect.isFalse(isObject(E_super_super));

-    Expect.isTrue(isSameDeclaration(S, E_super_super.superclass));

-

-    Expect.isTrue(isSameDeclaration(S, getSuperclass(E)));

-    Expect.isTrue(isSameDeclarationList([M2, M1], getAppliedMixins(E)));

-    Expect.isTrue(isSameDeclarationSet([A, M1], getExplicitInterfaces(E)));

-

-    // class E2 extends E {}

-    var E2 = library.declarations[#E2];

-    Expect.isTrue(isSameDeclaration(E, getSuperclass(E2)));

-    Expect.isTrue(getAppliedMixins(E2).isEmpty);

-    Expect.isTrue(getExplicitInterfaces(E2).isEmpty);

-

-    // class F = S with M1<A>;

-    var F = library.declarations[#F];

-    Expect.isNotNull(F);

-    Expect.isTrue(F is ClassMirror);

-    Expect.isFalse(F.isAbstract);

-    Expect.isTrue(isMixinApplication(F));

-    Expect.isFalse(F.isNameSynthetic);

-    Expect.equals(#F, F.simpleName);

-    Expect.isFalse(isObject(F));

-    Expect.equals(1, F.superinterfaces.length);

-    Expect.isTrue(containsDeclaration(M1, F.superinterfaces));

-    Expect.isTrue(isInstance(M1, [A], F.mixin));

-    var F_super = F.superclass;

-    Expect.isNotNull(F_super);

-    Expect.isTrue(F_super is ClassMirror);

-    Expect.isFalse(isMixinApplication(F_super));

-    Expect.isFalse(isObject(F_super));

-    Expect.isTrue(isSameDeclaration(S, F_super));

-

-    Expect.isTrue(isSameDeclaration(S, getSuperclass(F)));

-    Expect.isTrue(isSameDeclarationList([M1], getAppliedMixins(F)));

-    Expect.isTrue(getExplicitInterfaces(F).isEmpty);

-

-    // typedef G = abstract S with M1, M2;

-    var G = library.declarations[#G];

-    Expect.isNotNull(G);

-    Expect.isTrue(G is ClassMirror);

-    Expect.isTrue(G.isAbstract);

-    Expect.isTrue(isMixinApplication(G));

-    Expect.isFalse(G.isNameSynthetic);

-    Expect.equals(#G, G.simpleName);

-    Expect.isFalse(isObject(G));

-    Expect.equals(1, G.superinterfaces.length);

-    Expect.isTrue(containsDeclaration(M2, G.superinterfaces));

-    Expect.isTrue(isSameDeclaration(M2, G.mixin));

-    var G_super = G.superclass;

-    Expect.isNotNull(G_super);

-    Expect.isTrue(G_super is ClassMirror);

-    Expect.isTrue(isMixinApplication(G_super));

-    Expect.equals(1, G_super.superinterfaces.length);

-    Expect.isTrue(containsDeclaration(M1, G_super.superinterfaces));

-    Expect.isTrue(isSameDeclaration(M1, G_super.mixin));

-    Expect.isFalse(isObject(G_super));

-    Expect.isTrue(isSameDeclaration(S, G_super.superclass));

-

-    Expect.isTrue(isSameDeclaration(S, getSuperclass(G)));

-    Expect.isTrue(isSameDeclarationList([M1, M2], getAppliedMixins(G)));

-    Expect.isTrue(getExplicitInterfaces(G).isEmpty);

-

-    // typedef H = S with M2, M1 implements A, M1;

-    var H = library.declarations[#H];

-    Expect.isNotNull(H);

-    Expect.isTrue(H is ClassMirror);

-    Expect.isFalse(H.isAbstract);

-    Expect.isTrue(isMixinApplication(H));

-    Expect.isFalse(H.isNameSynthetic);

-    Expect.equals(#H, H.simpleName);

-    Expect.isFalse(isObject(H));

-    Expect.equals(3, H.superinterfaces.length);

-    Expect.isTrue(containsDeclaration(A, H.superinterfaces));

-    Expect.isTrue(containsDeclaration(M1, H.superinterfaces));

-    Expect.isFalse(containsDeclaration(M2, H.superinterfaces));

-    Expect.isTrue(isSameDeclaration(M1, H.mixin));

-    var H_super = H.superclass;

-    Expect.isNotNull(H_super);

-    Expect.isTrue(H_super is ClassMirror);

-    Expect.isTrue(isMixinApplication(H_super));

-    Expect.equals(1, H_super.superinterfaces.length);

-    Expect.isTrue(containsDeclaration(M2, H_super.superinterfaces));

-    Expect.isTrue(isSameDeclaration(M2, H_super.mixin));

-    Expect.isFalse(isObject(H_super));

-    Expect.isTrue(isSameDeclaration(S, H_super.superclass));

-

-    Expect.isTrue(isSameDeclaration(S, getSuperclass(H)));

-    Expect.isTrue(isSameDeclarationList([M2, M1], getAppliedMixins(H)));

-    Expect.isTrue(isSameDeclarationSet([A, M1], getExplicitInterfaces(H)));

-

-    // class H2 extends H {}

-    var H2 = library.declarations[#H2];

-    Expect.isTrue(isSameDeclaration(H, getSuperclass(H2)));

-    Expect.isTrue(getAppliedMixins(H2).isEmpty);

-    Expect.isTrue(getExplicitInterfaces(H2).isEmpty);

-  }));

+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library mirrors_mixin_test;
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'mirror_system_helper.dart';
+
+const String CLASS_SOURCE = '''
+class A {}
+
+class S {}
+class M1<T> {}
+class M2 {}
+
+class C extends S with M1<A> {}
+class D extends S with M1, M2 {}
+class E extends S with M2, M1 implements A, M1 {}
+class E2 extends E {}
+
+class F = S with M1<A>;
+abstract class G = S with M1, M2;
+class H = S with M2, M1 implements A, M1;
+class H2 extends H {}
+''';
+
+void main() {
+  asyncTest(() => createMirrorSystem(CLASS_SOURCE).then((MirrorSystem mirrors) {
+    LibraryMirror library = mirrors.libraries[SOURCE_URI];
+
+    checkSimpleClass(var cls) {
+      Expect.isNotNull(cls);
+      Expect.isTrue(cls is ClassMirror);
+      Expect.isFalse(isMixinApplication(cls));
+      Expect.isFalse(cls.isNameSynthetic);
+      Expect.isFalse(isObject(cls));
+      Expect.isTrue(isObject(cls.superclass));
+      Expect.equals(0, cls.superinterfaces.length);
+
+      Expect.isTrue(isObject(getSuperclass(cls)));
+      Expect.isTrue(getAppliedMixins(cls).isEmpty);
+      Expect.isTrue(getExplicitInterfaces(cls).isEmpty);
+    }
+
+    // class A {}
+    var A = library.declarations[#A];
+    checkSimpleClass(A);
+
+    // class S {}
+    var S = library.declarations[#S];
+    checkSimpleClass(S);
+
+    // class M1 {}
+    var M1 = library.declarations[#M1];
+    checkSimpleClass(M1);
+
+    // class M2 {}
+    var M2 = library.declarations[#M2];
+    checkSimpleClass(M2);
+
+    // class C extends S with M1<A> {}
+    var C = library.declarations[#C];
+    Expect.isNotNull(C);
+    Expect.isTrue(C is ClassMirror);
+    Expect.isFalse(isMixinApplication(C));
+    Expect.isFalse(isObject(C));
+    Expect.equals(0, C.superinterfaces.length);
+    var C_super = C.superclass;
+    Expect.isNotNull(C_super);
+    Expect.isTrue(C_super is ClassMirror);
+    Expect.isTrue(isMixinApplication(C_super));
+    Expect.isTrue(C_super.isNameSynthetic);
+    Expect.equals(1, C_super.superinterfaces.length);
+    Expect.isTrue(containsType(M1, [A], C_super.superinterfaces));
+    Expect.isTrue(isInstance(M1, [A], C_super.mixin));
+    Expect.isFalse(isObject(C_super));
+    Expect.isTrue(isSameDeclaration(S, C_super.superclass));
+
+    Expect.isTrue(isSameDeclaration(S, getSuperclass(C)));
+    Expect.isTrue(isSameDeclarationList([M1], getAppliedMixins(C)));
+    Expect.isTrue(getExplicitInterfaces(C).isEmpty);
+
+    // D extends S with M1, M2 {}
+    var D = library.declarations[#D];
+    Expect.isNotNull(D);
+    Expect.isTrue(D is ClassMirror);
+    Expect.isFalse(isMixinApplication(D));
+    Expect.isFalse(isObject(D));
+    Expect.equals(0, D.superinterfaces.length);
+    var D_super = D.superclass;
+    Expect.isNotNull(D_super);
+    Expect.isTrue(D_super is ClassMirror);
+    Expect.isTrue(isMixinApplication(D_super));
+    Expect.isTrue(D_super.isNameSynthetic);
+    Expect.equals(1, D_super.superinterfaces.length);
+    Expect.isTrue(containsDeclaration(M2, D_super.superinterfaces));
+    Expect.isTrue(isSameDeclaration(M2, D_super.mixin));
+    Expect.isFalse(isObject(D_super));
+    Expect.isFalse(isSameDeclaration(S, D_super.superclass));
+    var D_super_super = D_super.superclass;
+    Expect.isNotNull(D_super_super);
+    Expect.isTrue(D_super_super is ClassMirror);
+    Expect.isTrue(isMixinApplication(D_super_super));
+    Expect.isTrue(D_super_super.isNameSynthetic);
+    Expect.equals(1, D_super_super.superinterfaces.length);
+    Expect.isTrue(containsDeclaration(M1, D_super_super.superinterfaces));
+    Expect.isTrue(isSameDeclaration(M1, D_super_super.mixin));
+    Expect.isFalse(isObject(D_super_super));
+    Expect.isTrue(isSameDeclaration(S, D_super_super.superclass));
+
+    Expect.isTrue(isSameDeclaration(S, getSuperclass(D)));
+    Expect.isTrue(isSameDeclarationList([M1, M2], getAppliedMixins(D)));
+    Expect.isTrue(getExplicitInterfaces(D).isEmpty);
+
+    // class E extends S with M2, M1 implements A, M1 {}
+    var E = library.declarations[#E];
+    Expect.isNotNull(E);
+    Expect.isTrue(E is ClassMirror);
+    Expect.isFalse(isMixinApplication(E));
+    Expect.isFalse(isObject(E));
+    Expect.equals(2, E.superinterfaces.length);
+    Expect.isTrue(containsDeclaration(A, E.superinterfaces));
+    Expect.isTrue(containsDeclaration(M1, E.superinterfaces));
+    var E_super = E.superclass;
+    Expect.isNotNull(E_super);
+    Expect.isTrue(E_super is ClassMirror);
+    Expect.isTrue(isMixinApplication(E_super));
+    Expect.isTrue(E_super.isNameSynthetic);
+    Expect.equals(1, E_super.superinterfaces.length);
+    Expect.isTrue(containsDeclaration(M1, E_super.superinterfaces));
+    Expect.isTrue(isSameDeclaration(M1, E_super.mixin));
+    Expect.isFalse(isObject(E_super));
+    Expect.isFalse(isSameDeclaration(S, E_super.superclass));
+    var E_super_super = E_super.superclass;
+    Expect.isNotNull(E_super_super);
+    Expect.isTrue(E_super_super is ClassMirror);
+    Expect.isTrue(isMixinApplication(E_super_super));
+    Expect.isTrue(E_super_super.isNameSynthetic);
+    Expect.equals(1, E_super_super.superinterfaces.length);
+    Expect.isTrue(containsDeclaration(M2, E_super_super.superinterfaces));
+    Expect.isTrue(isSameDeclaration(M2, E_super_super.mixin));
+    Expect.isFalse(isObject(E_super_super));
+    Expect.isTrue(isSameDeclaration(S, E_super_super.superclass));
+
+    Expect.isTrue(isSameDeclaration(S, getSuperclass(E)));
+    Expect.isTrue(isSameDeclarationList([M2, M1], getAppliedMixins(E)));
+    Expect.isTrue(isSameDeclarationSet([A, M1], getExplicitInterfaces(E)));
+
+    // class E2 extends E {}
+    var E2 = library.declarations[#E2];
+    Expect.isTrue(isSameDeclaration(E, getSuperclass(E2)));
+    Expect.isTrue(getAppliedMixins(E2).isEmpty);
+    Expect.isTrue(getExplicitInterfaces(E2).isEmpty);
+
+    // class F = S with M1<A>;
+    var F = library.declarations[#F];
+    Expect.isNotNull(F);
+    Expect.isTrue(F is ClassMirror);
+    Expect.isFalse(F.isAbstract);
+    Expect.isTrue(isMixinApplication(F));
+    Expect.isFalse(F.isNameSynthetic);
+    Expect.equals(#F, F.simpleName);
+    Expect.isFalse(isObject(F));
+    Expect.equals(1, F.superinterfaces.length);
+    Expect.isTrue(containsDeclaration(M1, F.superinterfaces));
+    Expect.isTrue(isInstance(M1, [A], F.mixin));
+    var F_super = F.superclass;
+    Expect.isNotNull(F_super);
+    Expect.isTrue(F_super is ClassMirror);
+    Expect.isFalse(isMixinApplication(F_super));
+    Expect.isFalse(isObject(F_super));
+    Expect.isTrue(isSameDeclaration(S, F_super));
+
+    Expect.isTrue(isSameDeclaration(S, getSuperclass(F)));
+    Expect.isTrue(isSameDeclarationList([M1], getAppliedMixins(F)));
+    Expect.isTrue(getExplicitInterfaces(F).isEmpty);
+
+    // typedef G = abstract S with M1, M2;
+    var G = library.declarations[#G];
+    Expect.isNotNull(G);
+    Expect.isTrue(G is ClassMirror);
+    Expect.isTrue(G.isAbstract);
+    Expect.isTrue(isMixinApplication(G));
+    Expect.isFalse(G.isNameSynthetic);
+    Expect.equals(#G, G.simpleName);
+    Expect.isFalse(isObject(G));
+    Expect.equals(1, G.superinterfaces.length);
+    Expect.isTrue(containsDeclaration(M2, G.superinterfaces));
+    Expect.isTrue(isSameDeclaration(M2, G.mixin));
+    var G_super = G.superclass;
+    Expect.isNotNull(G_super);
+    Expect.isTrue(G_super is ClassMirror);
+    Expect.isTrue(isMixinApplication(G_super));
+    Expect.equals(1, G_super.superinterfaces.length);
+    Expect.isTrue(containsDeclaration(M1, G_super.superinterfaces));
+    Expect.isTrue(isSameDeclaration(M1, G_super.mixin));
+    Expect.isFalse(isObject(G_super));
+    Expect.isTrue(isSameDeclaration(S, G_super.superclass));
+
+    Expect.isTrue(isSameDeclaration(S, getSuperclass(G)));
+    Expect.isTrue(isSameDeclarationList([M1, M2], getAppliedMixins(G)));
+    Expect.isTrue(getExplicitInterfaces(G).isEmpty);
+
+    // typedef H = S with M2, M1 implements A, M1;
+    var H = library.declarations[#H];
+    Expect.isNotNull(H);
+    Expect.isTrue(H is ClassMirror);
+    Expect.isFalse(H.isAbstract);
+    Expect.isTrue(isMixinApplication(H));
+    Expect.isFalse(H.isNameSynthetic);
+    Expect.equals(#H, H.simpleName);
+    Expect.isFalse(isObject(H));
+    Expect.equals(3, H.superinterfaces.length);
+    Expect.isTrue(containsDeclaration(A, H.superinterfaces));
+    Expect.isTrue(containsDeclaration(M1, H.superinterfaces));
+    Expect.isFalse(containsDeclaration(M2, H.superinterfaces));
+    Expect.isTrue(isSameDeclaration(M1, H.mixin));
+    var H_super = H.superclass;
+    Expect.isNotNull(H_super);
+    Expect.isTrue(H_super is ClassMirror);
+    Expect.isTrue(isMixinApplication(H_super));
+    Expect.equals(1, H_super.superinterfaces.length);
+    Expect.isTrue(containsDeclaration(M2, H_super.superinterfaces));
+    Expect.isTrue(isSameDeclaration(M2, H_super.mixin));
+    Expect.isFalse(isObject(H_super));
+    Expect.isTrue(isSameDeclaration(S, H_super.superclass));
+
+    Expect.isTrue(isSameDeclaration(S, getSuperclass(H)));
+    Expect.isTrue(isSameDeclarationList([M2, M1], getAppliedMixins(H)));
+    Expect.isTrue(isSameDeclarationSet([A, M1], getExplicitInterfaces(H)));
+
+    // class H2 extends H {}
+    var H2 = library.declarations[#H2];
+    Expect.isTrue(isSameDeclaration(H, getSuperclass(H2)));
+    Expect.isTrue(getAppliedMixins(H2).isEmpty);
+    Expect.isTrue(getExplicitInterfaces(H2).isEmpty);
+  }));
 }
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mixin_language_test.dart b/tests/compiler/dart2js/mixin_language_test.dart
index f4be3b2..11f708b 100644
--- a/tests/compiler/dart2js/mixin_language_test.dart
+++ b/tests/compiler/dart2js/mixin_language_test.dart
@@ -1,21 +1,21 @@
-// 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.

-

-// Test that dart2js produces the expected static type warnings for these

-// language tests. This ensures that the analyzer and dart2js agrees on the

-// tests.

-

-import 'warnings_checker.dart';

-

-/// Map from test files to a map of their expected status. If the status map is

-/// `null` no warnings must be missing or unexpected, otherwise the status map

-/// can contain a list of line numbers for keys 'missing' and 'unexpected' for

-/// the warnings of each category.

-const Map<String, dynamic> TESTS = const {

-    'language/typevariable_substitution2_test.dart': null,

-};

-

-void main(List<String> arguments) {

-  checkWarnings(TESTS, arguments);

-}

+// 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.
+
+// Test that dart2js produces the expected static type warnings for these
+// language tests. This ensures that the analyzer and dart2js agrees on the
+// tests.
+
+import 'warnings_checker.dart';
+
+/// Map from test files to a map of their expected status. If the status map is
+/// `null` no warnings must be missing or unexpected, otherwise the status map
+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
+/// the warnings of each category.
+const Map<String, dynamic> TESTS = const {
+    'language/typevariable_substitution2_test.dart': null,
+};
+
+void main(List<String> arguments) {
+  checkWarnings(TESTS, arguments);
+}
diff --git a/tests/compiler/dart2js/mixin_typevariable_test.dart b/tests/compiler/dart2js/mixin_typevariable_test.dart
index 0553589..27fe4bb 100644
--- a/tests/compiler/dart2js/mixin_typevariable_test.dart
+++ b/tests/compiler/dart2js/mixin_typevariable_test.dart
@@ -1,158 +1,158 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file

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

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

-

-library mixin_typevariable_test;

-

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

-import "package:async_helper/async_helper.dart";

-import 'type_test_helper.dart';

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

-import "package:compiler/src/elements/elements.dart"

-       show Element, ClassElement;

-

-void main() {

-  testMixinSupertypes();

-  testNonTrivialSubstitutions();

-}

-

-void testMixinSupertypes() {

-  asyncTest(() => TypeEnvironment.create(r"""

-      class S<S_T> {}

-      class M1<M1_T> {}

-      class M2<M2_T> {}

-      class M3<M3_T> {}

-

-      class C1<C1_T> extends S<C1_T> with M1<C1_T>, M2<C1_T>, M3<C1_T> {}

-      class C2<C2_T> = S<C2_T> with M1<C2_T>, M2<C2_T>, M3<C2_T>;

-      """, expectNoWarningsOrErrors: true).then((env) {

-

-    ClassElement Object = env.getElement('Object');

-    ClassElement S = env.getElement('S');

-    ClassElement M1 = env.getElement('M1');

-    ClassElement M2 = env.getElement('M2');

-    ClassElement M3 = env.getElement('M3');

-    ClassElement C1 = env.getElement('C1');

-    ClassElement C2 = env.getElement('C2');

-

-    ClassElement C1_S_M1_M2_M3 = C1.superclass;

-    ClassElement C1_S_M1_M2 = C1_S_M1_M2_M3.superclass;

-    ClassElement C1_S_M1 = C1_S_M1_M2.superclass;

-

-    ClassElement C2_S_M1_M2 = C2.superclass;

-    ClassElement C2_S_M1 = C2_S_M1_M2.superclass;

-

-    void testSupertypes(ClassElement element) {

-      if (element != Object) {

-        Expect.isTrue(element.typeVariables.length == 1);

-        Expect.equals(element,

-                      element.typeVariables.first.element.enclosingElement);

-      }

-      for (InterfaceType supertype in element.allSupertypesAndSelf.types) {

-        if (!supertype.typeArguments.isEmpty) {

-          Expect.listEquals(element.typeVariables, supertype.typeArguments,

-              "Type argument mismatch on supertype $supertype of $element.");

-        } else {

-          Expect.equals(Object, supertype.element);

-        }

-      }

-    }

-

-    testSupertypes(Object);

-    testSupertypes(S);

-    testSupertypes(M1);

-    testSupertypes(M2);

-    testSupertypes(C1_S_M1);

-    testSupertypes(C1_S_M1_M2);

-    testSupertypes(C1_S_M1_M2_M3);

-    testSupertypes(C1);

-    testSupertypes(C2_S_M1);

-    testSupertypes(C2_S_M1_M2);

-    testSupertypes(C2);

-  }));

-}

-

-void testNonTrivialSubstitutions() {

-  asyncTest(() => TypeEnvironment.create(r"""

-      class _ {}

-      class A<A_T> {}

-      class B<B_T, B_S> {}

-

-      class C1<C1_T> extends A with B {}

-      class C2<C2_T> = A with B;

-

-      class D1<D1_T> extends A<D1_T> with B<D1_T, A<D1_T>> {}

-      class D2<D2_T> = A<D2_T> with B<D2_T, A<D2_T>>;

-

-      class E1<E1_T> extends A<_> with B<_, A<_>> {}

-      class E2<E2_T> = A<_> with B<_, A<_>>;

-

-      class F1<F1_T> extends A<_> with B<_, B<F1_T, _>> {}

-      class F2<F2_T> = A<_> with B<_, B<F2_T, _>>;

-      """, expectNoWarningsOrErrors: true).then((env) {

-    DartType _dynamic = env['dynamic'];

-    DartType _ = env['_'];

-

-    ClassElement Object = env.getElement('Object');

-    ClassElement A = env.getElement('A');

-    ClassElement B = env.getElement('B');

-    ClassElement C1 = env.getElement('C1');

-    ClassElement C2 = env.getElement('C2');

-    ClassElement D1 = env.getElement('D1');

-    ClassElement D2 = env.getElement('D2');

-    ClassElement E1 = env.getElement('E1');

-    ClassElement E2 = env.getElement('E2');

-    ClassElement F1 = env.getElement('F1');

-    ClassElement F2 = env.getElement('F2');

-

-    ClassElement C1_A_B = C1.superclass;

-    ClassElement D1_A_B = D1.superclass;

-    ClassElement E1_A_B = E1.superclass;

-    ClassElement F1_A_B = F1.superclass;

-

-    void testSupertypes(ClassElement element,

-                        Map<ClassElement, List<DartType>> typeArguments) {

-      if (element != Object) {

-        Expect.isTrue(element.typeVariables.length == 1);

-        Expect.equals(element,

-                      element.typeVariables.first.element.enclosingElement);

-      }

-      for (InterfaceType supertype in element.allSupertypesAndSelf.types) {

-        if (typeArguments.containsKey(supertype.element)) {

-          Expect.listEquals(typeArguments[supertype.element],

-                            supertype.typeArguments,

-              "Type argument mismatch on supertype $supertype of $element.");

-        } else if (!supertype.typeArguments.isEmpty) {

-          Expect.listEquals(element.typeVariables, supertype.typeArguments,

-              "Type argument mismatch on supertype $supertype of $element.");

-        } else {

-          Expect.equals(Object, supertype.element);

-        }

-      }

-    }

-

-    testSupertypes(C1, {A: [_dynamic], B: [_dynamic, _dynamic]});

-    testSupertypes(C1.superclass, {A: [_dynamic], B: [_dynamic, _dynamic]});

-    testSupertypes(C2, {A: [_dynamic], B: [_dynamic, _dynamic]});

-

-    DartType D1_T = D1.typeVariables.first;

-    testSupertypes(D1, {A: [D1_T], B: [D1_T, instantiate(A, [D1_T])]});

-    DartType D1_superclass_T = D1.superclass.typeVariables.first;

-    testSupertypes(D1.superclass,

-        {A: [D1_superclass_T],

-         B: [D1_superclass_T, instantiate(A, [D1_superclass_T])]});

-    DartType D2_T = D2.typeVariables.first;

-    testSupertypes(D2, {A: [D2_T], B: [D2_T, instantiate(A, [D2_T])]});

-

-    testSupertypes(E1, {A: [_], B: [_, instantiate(A, [_])]});

-    testSupertypes(E1.superclass, {A: [_], B: [_, instantiate(A, [_])]});

-    testSupertypes(E2, {A: [_], B: [_, instantiate(A, [_])]});

-

-    DartType F1_T = F1.typeVariables.first;

-    testSupertypes(F1, {A: [_], B: [_, instantiate(B, [F1_T, _])]});

-    DartType F1_superclass_T = F1.superclass.typeVariables.first;

-    testSupertypes(F1.superclass, {A: [_], B: [_, instantiate(B, [F1_superclass_T, _])]});

-    DartType F2_T = F2.typeVariables.first;

-    testSupertypes(F2, {A: [_], B: [_, instantiate(B, [F2_T, _])]});

-  }));

-}

+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library mixin_typevariable_test;
+
+import 'package:expect/expect.dart';
+import "package:async_helper/async_helper.dart";
+import 'type_test_helper.dart';
+import 'package:compiler/src/dart_types.dart';
+import "package:compiler/src/elements/elements.dart"
+       show Element, ClassElement;
+
+void main() {
+  testMixinSupertypes();
+  testNonTrivialSubstitutions();
+}
+
+void testMixinSupertypes() {
+  asyncTest(() => TypeEnvironment.create(r"""
+      class S<S_T> {}
+      class M1<M1_T> {}
+      class M2<M2_T> {}
+      class M3<M3_T> {}
+
+      class C1<C1_T> extends S<C1_T> with M1<C1_T>, M2<C1_T>, M3<C1_T> {}
+      class C2<C2_T> = S<C2_T> with M1<C2_T>, M2<C2_T>, M3<C2_T>;
+      """, expectNoWarningsOrErrors: true).then((env) {
+
+    ClassElement Object = env.getElement('Object');
+    ClassElement S = env.getElement('S');
+    ClassElement M1 = env.getElement('M1');
+    ClassElement M2 = env.getElement('M2');
+    ClassElement M3 = env.getElement('M3');
+    ClassElement C1 = env.getElement('C1');
+    ClassElement C2 = env.getElement('C2');
+
+    ClassElement C1_S_M1_M2_M3 = C1.superclass;
+    ClassElement C1_S_M1_M2 = C1_S_M1_M2_M3.superclass;
+    ClassElement C1_S_M1 = C1_S_M1_M2.superclass;
+
+    ClassElement C2_S_M1_M2 = C2.superclass;
+    ClassElement C2_S_M1 = C2_S_M1_M2.superclass;
+
+    void testSupertypes(ClassElement element) {
+      if (element != Object) {
+        Expect.isTrue(element.typeVariables.length == 1);
+        Expect.equals(element,
+                      element.typeVariables.first.element.enclosingElement);
+      }
+      for (InterfaceType supertype in element.allSupertypesAndSelf.types) {
+        if (!supertype.typeArguments.isEmpty) {
+          Expect.listEquals(element.typeVariables, supertype.typeArguments,
+              "Type argument mismatch on supertype $supertype of $element.");
+        } else {
+          Expect.equals(Object, supertype.element);
+        }
+      }
+    }
+
+    testSupertypes(Object);
+    testSupertypes(S);
+    testSupertypes(M1);
+    testSupertypes(M2);
+    testSupertypes(C1_S_M1);
+    testSupertypes(C1_S_M1_M2);
+    testSupertypes(C1_S_M1_M2_M3);
+    testSupertypes(C1);
+    testSupertypes(C2_S_M1);
+    testSupertypes(C2_S_M1_M2);
+    testSupertypes(C2);
+  }));
+}
+
+void testNonTrivialSubstitutions() {
+  asyncTest(() => TypeEnvironment.create(r"""
+      class _ {}
+      class A<A_T> {}
+      class B<B_T, B_S> {}
+
+      class C1<C1_T> extends A with B {}
+      class C2<C2_T> = A with B;
+
+      class D1<D1_T> extends A<D1_T> with B<D1_T, A<D1_T>> {}
+      class D2<D2_T> = A<D2_T> with B<D2_T, A<D2_T>>;
+
+      class E1<E1_T> extends A<_> with B<_, A<_>> {}
+      class E2<E2_T> = A<_> with B<_, A<_>>;
+
+      class F1<F1_T> extends A<_> with B<_, B<F1_T, _>> {}
+      class F2<F2_T> = A<_> with B<_, B<F2_T, _>>;
+      """, expectNoWarningsOrErrors: true).then((env) {
+    DartType _dynamic = env['dynamic'];
+    DartType _ = env['_'];
+
+    ClassElement Object = env.getElement('Object');
+    ClassElement A = env.getElement('A');
+    ClassElement B = env.getElement('B');
+    ClassElement C1 = env.getElement('C1');
+    ClassElement C2 = env.getElement('C2');
+    ClassElement D1 = env.getElement('D1');
+    ClassElement D2 = env.getElement('D2');
+    ClassElement E1 = env.getElement('E1');
+    ClassElement E2 = env.getElement('E2');
+    ClassElement F1 = env.getElement('F1');
+    ClassElement F2 = env.getElement('F2');
+
+    ClassElement C1_A_B = C1.superclass;
+    ClassElement D1_A_B = D1.superclass;
+    ClassElement E1_A_B = E1.superclass;
+    ClassElement F1_A_B = F1.superclass;
+
+    void testSupertypes(ClassElement element,
+                        Map<ClassElement, List<DartType>> typeArguments) {
+      if (element != Object) {
+        Expect.isTrue(element.typeVariables.length == 1);
+        Expect.equals(element,
+                      element.typeVariables.first.element.enclosingElement);
+      }
+      for (InterfaceType supertype in element.allSupertypesAndSelf.types) {
+        if (typeArguments.containsKey(supertype.element)) {
+          Expect.listEquals(typeArguments[supertype.element],
+                            supertype.typeArguments,
+              "Type argument mismatch on supertype $supertype of $element.");
+        } else if (!supertype.typeArguments.isEmpty) {
+          Expect.listEquals(element.typeVariables, supertype.typeArguments,
+              "Type argument mismatch on supertype $supertype of $element.");
+        } else {
+          Expect.equals(Object, supertype.element);
+        }
+      }
+    }
+
+    testSupertypes(C1, {A: [_dynamic], B: [_dynamic, _dynamic]});
+    testSupertypes(C1.superclass, {A: [_dynamic], B: [_dynamic, _dynamic]});
+    testSupertypes(C2, {A: [_dynamic], B: [_dynamic, _dynamic]});
+
+    DartType D1_T = D1.typeVariables.first;
+    testSupertypes(D1, {A: [D1_T], B: [D1_T, instantiate(A, [D1_T])]});
+    DartType D1_superclass_T = D1.superclass.typeVariables.first;
+    testSupertypes(D1.superclass,
+        {A: [D1_superclass_T],
+         B: [D1_superclass_T, instantiate(A, [D1_superclass_T])]});
+    DartType D2_T = D2.typeVariables.first;
+    testSupertypes(D2, {A: [D2_T], B: [D2_T, instantiate(A, [D2_T])]});
+
+    testSupertypes(E1, {A: [_], B: [_, instantiate(A, [_])]});
+    testSupertypes(E1.superclass, {A: [_], B: [_, instantiate(A, [_])]});
+    testSupertypes(E2, {A: [_], B: [_, instantiate(A, [_])]});
+
+    DartType F1_T = F1.typeVariables.first;
+    testSupertypes(F1, {A: [_], B: [_, instantiate(B, [F1_T, _])]});
+    DartType F1_superclass_T = F1.superclass.typeVariables.first;
+    testSupertypes(F1.superclass, {A: [_], B: [_, instantiate(B, [F1_superclass_T, _])]});
+    DartType F2_T = F2.typeVariables.first;
+    testSupertypes(F2, {A: [_], B: [_, instantiate(B, [F2_T, _])]});
+  }));
+}
diff --git a/tests/compiler/dart2js/override_inheritance_test.dart b/tests/compiler/dart2js/override_inheritance_test.dart
index 1407156..0e24785 100644
--- a/tests/compiler/dart2js/override_inheritance_test.dart
+++ b/tests/compiler/dart2js/override_inheritance_test.dart
@@ -1,1546 +1,1546 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file

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

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

-

-import 'dart:async';

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

-import 'compiler_helper.dart';

-import 'package:compiler/src/resolution/class_members.dart'

-    show MembersCreator;

-

-main() {

-  asyncTest(() => Future.wait([

-    testRequiredParameters(),

-    testPositionalParameters(),

-    testNamedParameters(),

-    testNotSubtype(),

-    testGetterNotSubtype(),

-    testSetterNotSubtype(),

-    testGenericNotSubtype(),

-    testFieldNotSubtype(),

-    testMixedOverride(),

-    testAbstractMethods(),

-    testNoSuchMethod(),

-  ]));

-}

-

-Future check(String source, {errors, warnings, hints, infos}) {

-  return MockCompiler.create((MockCompiler compiler) {

-    compiler.diagnosticHandler = createHandler(compiler, source);

-    compiler.parseScript(source);

-    var cls = compiler.mainApp.find('Class');

-    cls.ensureResolved(compiler);

-    MembersCreator.computeAllClassMembers(compiler, cls);

-

-    toList(o) => o == null ? [] : o is List ? o : [o];

-

-    compareMessageKinds(source, toList(errors), compiler.errors, 'error');

-

-    compareMessageKinds(source, toList(warnings), compiler.warnings, 'warning');

-

-    if (infos != null) {

-      compareMessageKinds(source, toList(infos), compiler.infos, 'info');

-    }

-

-    if (hints != null) {

-      compareMessageKinds(source, toList(hints), compiler.hints, 'hint');

-    }

-  });

-}

-

-Future testRequiredParameters() {

-  return Future.wait([

-    check("""

-          class A {

-            method() => null; // testRequiredParameters:0

-          }

-          class Class extends A {

-            method() => null; // testRequiredParameters:1

-          }

-          """),

-

-    check("""

-          class A {

-            method(a) => null; // testRequiredParameters:2

-          }

-          class Class extends A {

-            method(b) => null; // testRequiredParameters:3

-          }

-          """),

-

-    check("""

-          class A {

-            method(a, b, c, d) => null; // testRequiredParameters:3

-          }

-          class Class extends A {

-            method(b, a, d, c) => null; // testRequiredParameters:4

-          }

-          """),

-

-    check("""

-          class A {

-            method() => null; // testRequiredParameters:5

-          }

-          class Class extends A {

-            method(a) => null; // testRequiredParameters:6

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A {

-            method() => null; // testRequiredParameters:7

-          }

-          class Class implements A {

-            method(a) => null; // testRequiredParameters:8

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A {

-            method(a, b, c) => null; // testRequiredParameters:9

-          }

-          class Class extends A {

-            method(a, b, c, d) => null; // testRequiredParameters:10

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-  ]);

-}

-

-Future testPositionalParameters() {

-  return Future.wait([

-    check("""

-          class A {

-            method([a]) => null; // testPositionalParameters:1

-          }

-          class Class extends A {

-            method([a]) => null; // testPositionalParameters:2

-          }

-          """),

-

-    check("""

-          class A {

-            method([a, b]) => null; // testPositionalParameters:3

-          }

-          class Class extends A {

-            method([b, a]) => null; // testPositionalParameters:4

-          }

-          """),

-

-    check("""

-          class A {

-            method([a, b, c]) => null; // testPositionalParameters:5

-          }

-          class Class extends A {

-            method([b, d, a, c]) => null; // testPositionalParameters:6

-          }

-          """),

-

-    check("""

-          class A {

-            method([a]) => null; // testPositionalParameters:7

-          }

-          class Class extends A {

-            method([a]) => null; // testPositionalParameters:8

-          }

-          """),

-

-    check("""

-          class A {

-            method(a) => null; // testPositionalParameters:9

-          }

-          class Class extends A {

-            method() => null; // testPositionalParameters:10

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A {

-            method(a, [b]) => null; // testPositionalParameters:11

-          }

-          class Class extends A {

-            method(a) => null; // testPositionalParameters:12

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A {

-            method(a, [b]) => null; // testPositionalParameters:13

-          }

-          class Class extends A {

-            method([a]) => null; // testPositionalParameters:14

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A {

-            method(a, b, [c, d, e]) => null; // testPositionalParameters:15

-          }

-          class Class extends A {

-            method([a, b, c, d]) => null; // testPositionalParameters:16

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-  ]);

-}

-

-Future testNamedParameters() {

-  return Future.wait([

-    check("""

-          class A {

-            method({a}) => null; // testNamedParameters:1

-          }

-          class Class extends A {

-            method({a}) => null; // testNamedParameters:2

-          }

-          """),

-

-    check("""

-          class A {

-            method({a, b}) => null; // testNamedParameters:3

-          }

-          class Class extends A {

-            method({b, a}) => null; // testNamedParameters:4

-          }

-          """),

-

-    check("""

-          class A {

-            method({a, b, c}) => null; // testNamedParameters:5

-          }

-          class Class extends A {

-            method({b, c, a, d}) => null; // testNamedParameters:6

-          }

-          """),

-

-    check("""

-          class A {

-            method(d, {a, b, c}) => null; // testNamedParameters:7

-          }

-          class Class extends A {

-            method(e, {b, c, a, d}) => null; // testNamedParameters:8

-          }

-          """),

-

-    check("""

-          class A {

-            method({a}) => null; // testNamedParameters:9

-          }

-          class Class extends A {

-            method() => null; // testNamedParameters:10

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A {

-            method({a, b}) => null; // testNamedParameters:11

-          }

-          class Class extends A {

-            method({b}) => null; // testNamedParameters:12

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A {

-            method({a, b, c, d}) => null; // testNamedParameters:13

-          }

-          class Class extends A {

-            method({a, e, d, c}) => null; // testNamedParameters:14

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-  ]);

-}

-

-Future testNotSubtype() {

-  return Future.wait([

-    check("""

-          class A {

-            method(int a) => null; // testNotSubtype:1

-          }

-          class Class extends A {

-            method(int a) => null; // testNotSubtype:2

-          }

-          """),

-

-    check("""

-          class A {

-            method(int a) => null; // testNotSubtype:3

-          }

-          class Class extends A {

-            method(num a) => null; // testNotSubtype:4

-          }

-          """),

-

-    check("""

-          class A {

-            void method() {} // testNotSubtype:5

-          }

-          class Class extends A {

-            method() => null; // testNotSubtype:6

-          }

-          """),

-

-    check("""

-          class A {

-            method() => null; // testNotSubtype:7

-          }

-          class Class extends A {

-            void method() {} // testNotSubtype:8

-          }

-          """),

-

-    check("""

-          class A {

-            void method() {} // testNotSubtype:9

-          }

-          class Class extends A {

-            int method() => null; // testNotSubtype:10

-          }

-          """),

-

-    check("""

-          class A {

-            int method() => null; // testNotSubtype:11

-          }

-          class Class extends A {

-            void method() {} // testNotSubtype:12

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A {

-            method(int a) => null; // testNotSubtype:13

-          }

-          class B extends A {

-            method(num a) => null; // testNotSubtype:14

-          }

-          class Class extends B {

-            method(double a) => null; // testNotSubtype:15

-          }

-          """),

-

-    check("""

-          class A {

-            method(int a) => null; // testNotSubtype:16

-          }

-          class B extends A {

-            method(a) => null; // testNotSubtype:17

-          }

-          class Class extends B {

-            method(String a) => null; // testNotSubtype:18

-          }

-          """),

-

-    check("""

-          class A {

-            method(int a) => null; // testNotSubtype:19

-          }

-          class Class extends A {

-            method(String a) => null; // testNotSubtype:20

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.

-    check("""

-          class A {

-            method(int a) => null; // testNotSubtype:23

-          }

-          class B {

-            method(num a) => null; // testNotSubtype:24

-          }

-          abstract class C implements A, B {

-          }

-          class Class implements C {

-            method(double a) => null; // testNotSubtype:25

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A {

-            method(num a) => null; // testNotSubtype:29

-          }

-          class B {

-            method(int a) => null; // testNotSubtype:30

-          }

-          abstract class C implements A, B {

-          }

-          class Class implements C {

-            method(double a) => null; // testNotSubtype:31

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A {

-            method(int a) => null; // testNotSubtype:26

-          }

-          class B {

-            method(num a) => null; // testNotSubtype:27

-          }

-          abstract class C implements A, B {

-          }

-          class Class implements C {

-            method(String a) => null; // testNotSubtype:28

-          }

-          """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,

-                          MessageKind.INVALID_OVERRIDE_METHOD],

-               infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,

-                       MessageKind.INVALID_OVERRIDDEN_METHOD]),

-  ]);

-}

-

-Future testGetterNotSubtype() {

-  return Future.wait([

-    check("""

-          class A {

-            get getter => null; // testGetterNotSubtype:1

-          }

-          class Class extends A {

-            get getter => null; // testGetterNotSubtype:2

-          }

-          """),

-

-    check("""

-          class A {

-            num get getter => null; // testGetterNotSubtype:3

-          }

-          class Class extends A {

-            num get getter => null; // testGetterNotSubtype:4

-          }

-          """),

-

-    check("""

-          class A {

-            num get getter => null; // testGetterNotSubtype:5

-          }

-          class Class extends A {

-            int get getter => null; // testGetterNotSubtype:6

-          }

-          """),

-

-    check("""

-          class A {

-            int get getter => null; // testGetterNotSubtype:7

-          }

-          class Class extends A {

-            num get getter => null; // testGetterNotSubtype:8

-          }

-          """),

-

-    check("""

-          class A {

-            int get getter => null; // testGetterNotSubtype:9

-          }

-          class Class extends A {

-            double get getter => null; // testGetterNotSubtype:10

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,

-               infos: MessageKind.INVALID_OVERRIDDEN_GETTER),

-

-    check("""

-          class A {

-            int get getter => null; // testGetterNotSubtype:11

-          }

-          class B extends A {

-            num get getter => null; // testGetterNotSubtype:12

-          }

-          class Class extends B {

-            double get getter => null; // testGetterNotSubtype:13

-          }

-          """),

-

-    check("""

-          class A {

-            int get getter => null; // testGetterNotSubtype:14

-          }

-          class B {

-            num get getter => null; // testGetterNotSubtype:15

-          }

-          class Class extends A implements B {

-            double get getter => null; // testGetterNotSubtype:16

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,

-               infos: MessageKind.INVALID_OVERRIDDEN_GETTER),

-

-    check("""

-          class A {

-            int get getter => null; // testGetterNotSubtype:17

-          }

-          class B {

-            String get getter => null; // testGetterNotSubtype:18

-          }

-          class Class extends A implements B {

-            double get getter => null; // testGetterNotSubtype:19

-          }

-          """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,

-                          MessageKind.INVALID_OVERRIDE_GETTER],

-               infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,

-                       MessageKind.INVALID_OVERRIDDEN_GETTER]),

-

-    check("""

-          class A {

-            int get getter => null; // testGetterNotSubtype:20

-          }

-          class B {

-            String get getter => null; // testGetterNotSubtype:21

-          }

-          class Class implements A, B {

-            double get getter => null; // testGetterNotSubtype:22

-          }

-          """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,

-                          MessageKind.INVALID_OVERRIDE_GETTER],

-               infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,

-                       MessageKind.INVALID_OVERRIDDEN_GETTER]),

-

-    // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.

-    check("""

-          class A {

-            int get getter => null; // testGetterNotSubtype:23

-          }

-          class B {

-            num get getter => null; // testGetterNotSubtype:24

-          }

-          abstract class C implements A, B {

-          }

-          class Class implements C {

-            double get getter => null; // testGetterNotSubtype:25

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,

-               infos: MessageKind.INVALID_OVERRIDDEN_GETTER),

-

-    check("""

-          class A {

-            int get getter => null; // testGetterNotSubtype:26

-          }

-          class B {

-            num get getter => null; // testGetterNotSubtype:27

-          }

-          abstract class C implements A, B {

-          }

-          class Class implements C {

-            String get getter => null; // testGetterNotSubtype:28

-          }

-          """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,

-                          MessageKind.INVALID_OVERRIDE_GETTER],

-               infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,

-                       MessageKind.INVALID_OVERRIDDEN_GETTER]),

-  ]);

-}

-

-Future testGenericNotSubtype() {

-  return Future.wait([

-    check("""

-          class A<T> {

-            method(T t) => null; // testGenericNotSubtype:1

-          }

-          class Class<S> extends A<S> {

-            method(S s) => null; // testGenericNotSubtype:2

-          }

-          """),

-

-    check("""

-          class A<T> {

-            method(T t) => null; // testGenericNotSubtype:3

-          }

-          class Class extends A<num> {

-            method(int i) => null; // testGenericNotSubtype:4

-          }

-          """),

-

-    check("""

-          class A<T> {

-            method(T t) => null; // testGenericNotSubtype:5

-          }

-          class B<S> {

-            method(S s) => null; // testGenericNotSubtype:6

-          }

-          class Class extends A<double> implements B<int> {

-            method(num i) => null; // testGenericNotSubtype:7

-          }

-          """),

-

-    check("""

-          class A<T> {

-            method(T t) => null; // testGenericNotSubtype:8

-          }

-          class Class<S> extends A<S> {

-            method(int i) => null; // testGenericNotSubtype:9

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A<T> {

-            method(T t) => null; // testGenericNotSubtype:10

-          }

-          class B<S> extends A<S> {

-

-          }

-          class Class<U> extends B<U> {

-            method(U u) => null; // testGenericNotSubtype:11

-          }

-          """),

-

-    check("""

-          class A<T> {

-            method(T t) => null; // testGenericNotSubtype:12

-          }

-          class B<S> {

-            method(S s) => null; // testGenericNotSubtype:13

-          }

-          class Class<U> extends A<U> implements B<num> {

-            method(int i) => null; // testGenericNotSubtype:14

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A<T> {

-            method(T t) => null; // testGenericNotSubtype:15

-          }

-          class B<S> {

-            method(S s) => null; // testGenericNotSubtype:16

-          }

-          class Class extends A<int> implements B<String> {

-            method(double d) => null; // testGenericNotSubtype:17

-          }

-          """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,

-                          MessageKind.INVALID_OVERRIDE_METHOD],

-               infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,

-                       MessageKind.INVALID_OVERRIDDEN_METHOD]),

-

-    check("""

-          class A<T> {

-            method(T t) => null; // testGenericNotSubtype:18

-          }

-          class B<S> {

-            method(S s) => null; // testGenericNotSubtype:19

-          }

-          class Class implements A<int>, B<String> {

-            method(double d) => null; // testGenericNotSubtype:20

-          }

-          """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,

-                          MessageKind.INVALID_OVERRIDE_METHOD],

-               infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,

-                       MessageKind.INVALID_OVERRIDDEN_METHOD]),

-

-    // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.

-    check("""

-          class A<T> {

-            method(T t) => null; // testGenericNotSubtype:21

-          }

-          class B<S> {

-            method(S s) => null; // testGenericNotSubtype:22

-          }

-          abstract class C implements A<int>, B<num> {

-          }

-          class Class implements C {

-            method(double d) => null; // testGenericNotSubtype:23

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,

-               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),

-

-    check("""

-          class A<T> {

-            method(T t) => null; // testGenericNotSubtype:24

-          }

-          class B<S> {

-            method(S s) => null; // testGenericNotSubtype:25

-          }

-          abstract class C implements A<int>, B<num> {

-          }

-          class Class implements C {

-            method(String s) => null; // testGenericNotSubtype:26

-          }

-          """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,

-                          MessageKind.INVALID_OVERRIDE_METHOD],

-               infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,

-                       MessageKind.INVALID_OVERRIDDEN_METHOD]),

-  ]);

-}

-

-Future testSetterNotSubtype() {

-  return Future.wait([

-  check("""

-        class A {

-          set setter(_) => null; // testSetterNotSubtype:1

-        }

-        class Class extends A {

-          set setter(_) => null; // testSetterNotSubtype:2

-        }

-        """),

-

-  check("""

-        class A {

-          void set setter(_) {} // testSetterNotSubtype:3

-        }

-        class Class extends A {

-          set setter(_) => null; // testSetterNotSubtype:4

-        }

-        """),

-

-  check("""

-        class A {

-          set setter(_) => null; // testSetterNotSubtype:5

-        }

-        class Class extends A {

-          void set setter(_) {} // testSetterNotSubtype:6

-        }

-        """),

-

-  check("""

-        class A {

-          set setter(_) => null; // testSetterNotSubtype:7

-        }

-        class Class extends A {

-          void set setter(_) {} // testSetterNotSubtype:8

-        }

-        """),

-

-  check("""

-        class A {

-          set setter(num _) => null; // testSetterNotSubtype:9

-        }

-        class Class extends A {

-          set setter(num _) => null; // testSetterNotSubtype:10

-        }

-        """),

-

-  check("""

-        class A {

-          set setter(num _) => null; // testSetterNotSubtype:11

-        }

-        class Class extends A {

-          set setter(int _) => null; // testSetterNotSubtype:12

-        }

-        """),

-

-  check("""

-        class A {

-          set setter(int _) => null; // testSetterNotSubtype:13

-        }

-        class Class extends A {

-          set setter(num _) => null; // testSetterNotSubtype:14

-        }

-        """),

-

-  check("""

-        class A {

-          set setter(int _) => null; // testSetterNotSubtype:15

-        }

-        class Class extends A {

-          set setter(double _) => null; // testSetterNotSubtype:16

-        }

-        """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,

-             infos: MessageKind.INVALID_OVERRIDDEN_SETTER),

-

-  check("""

-        class A {

-          set setter(int _) => null; // testSetterNotSubtype:17

-        }

-        class B extends A {

-          set setter(num _) => null; // testSetterNotSubtype:18

-        }

-        class Class extends B {

-          set setter(double _) => null; // testSetterNotSubtype:19

-        }

-        """),

-

-  check("""

-        class A {

-          set setter(int _) => null; // testSetterNotSubtype:20

-        }

-        class B {

-          set setter(num _) => null; // testSetterNotSubtype:21

-        }

-        class Class extends A implements B {

-          set setter(double _) => null; // testSetterNotSubtype:22

-        }

-        """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,

-             infos: MessageKind.INVALID_OVERRIDDEN_SETTER),

-

-  check("""

-        class A {

-          set setter(int _) => null; // testSetterNotSubtype:23

-        }

-        class B {

-          set setter(String _) => null; // testSetterNotSubtype:24

-        }

-        class Class extends A implements B {

-          set setter(double _) => null; // testSetterNotSubtype:25

-        }

-        """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,

-                        MessageKind.INVALID_OVERRIDE_SETTER],

-             infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,

-                     MessageKind.INVALID_OVERRIDDEN_SETTER]),

-

-  check("""

-        class A {

-          set setter(int _) => null; // testSetterNotSubtype:26

-        }

-        class B {

-          set setter(String _) => null; // testSetterNotSubtype:27

-        }

-        class Class implements A, B {

-          set setter(double _) => null; // testSetterNotSubtype:28

-        }

-        """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,

-                        MessageKind.INVALID_OVERRIDE_SETTER],

-             infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,

-                     MessageKind.INVALID_OVERRIDDEN_SETTER]),

-

-  // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.

-  check("""

-        class A {

-          set setter(int _) => null; // testSetterNotSubtype:29

-        }

-        class B {

-          set setter(num _) => null; // testSetterNotSubtype:30

-        }

-        abstract class C implements A, B {

-        }

-        class Class implements C {

-          set setter(double _) => null; // testSetterNotSubtype:31

-        }

-        """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,

-             infos: MessageKind.INVALID_OVERRIDDEN_SETTER),

-

-  check("""

-        class A {

-          set setter(int _) => null; // testSetterNotSubtype:32

-        }

-        class B {

-          set setter(num _) => null; // testSetterNotSubtype:33

-        }

-        abstract class C implements A, B {

-        }

-        class Class implements C {

-          set setter(String _) => null; // testSetterNotSubtype:34

-        }

-        """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,

-                        MessageKind.INVALID_OVERRIDE_SETTER],

-             infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,

-                     MessageKind.INVALID_OVERRIDDEN_SETTER]),

-  ]);

-}

-

-Future testFieldNotSubtype() {

-  return Future.wait([

-    check("""

-          class A {

-            int field; // testFieldNotSubtype:1

-          }

-          class Class extends A {

-            int field; // testFieldNotSubtype:2

-          }

-          """),

-

-    check("""

-          class A {

-            num field; // testFieldNotSubtype:3

-          }

-          class Class extends A {

-            int field; // testFieldNotSubtype:4

-          }

-          """),

-

-    check("""

-          class A {

-            int field; // testFieldNotSubtype:5

-          }

-          class Class extends A {

-            num field; // testFieldNotSubtype:6

-          }

-          """),

-

-    check("""

-          class A {

-            int field; // testFieldNotSubtype:7

-          }

-          class Class extends A {

-            double field; // testFieldNotSubtype:8

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_FIELD,

-               infos: MessageKind.INVALID_OVERRIDDEN_FIELD),

-

-    check("""

-          class A {

-            int field; // testFieldNotSubtype:9

-          }

-          class B extends A {

-            num field; // testFieldNotSubtype:10

-          }

-          class Class extends B {

-            double field; // testFieldNotSubtype:11

-          }

-          """),

-

-    check("""

-          class A {

-            num field; // testFieldNotSubtype:12

-          }

-          class Class extends A {

-            int get field => null; // testFieldNotSubtype:13

-          }

-          """),

-

-    check("""

-          class A {

-            num field; // testFieldNotSubtype:14

-          }

-          class Class extends A {

-            String get field => null; // testFieldNotSubtype:15

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,

-               infos: MessageKind.INVALID_OVERRIDDEN_FIELD),

-

-    check("""

-          class A {

-            num get field => null; // testFieldNotSubtype:16

-          }

-          class Class extends A {

-            String field; // testFieldNotSubtype:17

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,

-               infos: MessageKind.INVALID_OVERRIDDEN_GETTER),

-

-    check("""

-          class A {

-            num field; // testFieldNotSubtype:18

-          }

-          class Class extends A {

-            set field(int _) {} // testFieldNotSubtype:19

-          }

-          """),

-

-    check("""

-          class A {

-            num field; // testFieldNotSubtype:19

-          }

-          class Class extends A {

-            void set field(int _) {} // testFieldNotSubtype:20

-          }

-          """),

-

-    check("""

-          class A {

-            set field(int _) {} // testFieldNotSubtype:21

-          }

-          class Class extends A {

-            num field; // testFieldNotSubtype:22

-          }

-          """),

-

-    check("""

-          class A {

-            void set field(int _) {} // testFieldNotSubtype:23

-          }

-          class Class extends A {

-            num field; // testFieldNotSubtype:24

-          }

-          """),

-

-    check("""

-          class A {

-            num field; // testFieldNotSubtype:25

-          }

-          class Class extends A {

-            set field(String _) {} // testFieldNotSubtype:26

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER,

-               infos: MessageKind.INVALID_OVERRIDDEN_FIELD),

-

-    check("""

-          class A {

-            set field(num _) {} // testFieldNotSubtype:27

-          }

-          class Class extends A {

-            String field; // testFieldNotSubtype:28

-          }

-          """, warnings: MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD,

-               infos: MessageKind.INVALID_OVERRIDDEN_SETTER),

-

-    check("""

-          class A {

-            int field; // testFieldNotSubtype:29

-          }

-          class Class implements A {

-            String get field => null; // testFieldNotSubtype:30

-            void set field(String s) {} // testFieldNotSubtype:31

-          }

-          """, warnings: [MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,

-                          MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER],

-               infos: [MessageKind.INVALID_OVERRIDDEN_FIELD,

-                       MessageKind.INVALID_OVERRIDDEN_FIELD]),

-

-

-    check("""

-          class A {

-            String get field => null; // testFieldNotSubtype:32

-            void set field(String s) {} // testFieldNotSubtype:33

-          }

-          class Class implements A {

-            int field; // testFieldNotSubtype:34

-          }

-          """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,

-                          MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD],

-               infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,

-                       MessageKind.INVALID_OVERRIDDEN_SETTER]),

-  ]);

-}

-

-Future testMixedOverride() {

-  return Future.wait([

-    check("""

-          class A {

-            var member; // testMixedOverride:1

-          }

-          class Class extends A {

-            member() {} // testMixedOverride:2

-          }

-          """, errors: MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,

-               infos: MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT),

-

-    check("""

-          class A {

-            member() {} // testMixedOverride:3

-          }

-          class Class extends A {

-            var member; // testMixedOverride:4

-          }

-          """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,

-               infos: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT),

-

-    check("""

-          class A {

-            get member => null; // testMixedOverride:5

-          }

-          class Class extends A {

-            member() {} // testMixedOverride:6

-          }

-          """, errors: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,

-               infos: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT),

-

-    check("""

-          class A {

-            member() {} // testMixedOverride:7

-          }

-          class Class extends A {

-            get member => null; // testMixedOverride:8

-          }

-          """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,

-               infos: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT),

-

-    check("""

-          abstract class A {

-            var member; // testMixedOverride:9

-          }

-          abstract class B {

-            get member; // testMixedOverride:10

-          }

-          abstract class Class implements A, B {

-          }

-          """),

-

-    check("""

-          abstract class A {

-            var member; // testMixedOverride:11

-          }

-          abstract class B {

-            member() {} // testMixedOverride:12

-          }

-          abstract class Class implements A, B {

-          }

-          """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,

-               infos: [MessageKind.INHERITED_METHOD,

-                       MessageKind.INHERITED_IMPLICIT_GETTER]),

-

-    check("""

-          abstract class A {

-            get member; // testMixedOverride:13

-          }

-          abstract class B {

-            member() {} // testMixedOverride:14

-          }

-          abstract class Class implements A, B {

-          }

-          """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,

-               infos: [MessageKind.INHERITED_METHOD,

-                       MessageKind.INHERITED_EXPLICIT_GETTER]),

-

-    check("""

-          abstract class A {

-            get member; // testMixedOverride:15

-          }

-          abstract class B {

-            member() {} // testMixedOverride:16

-          }

-          abstract class C {

-            var member; // testMixedOverride:17

-          }

-          abstract class D {

-            member() {} // testMixedOverride:18

-          }

-          abstract class E {

-            get member; // testMixedOverride:19

-          }

-          abstract class Class implements A, B, C, D, E {

-          }

-          """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,

-               infos: [MessageKind.INHERITED_EXPLICIT_GETTER,

-                       MessageKind.INHERITED_METHOD,

-                       MessageKind.INHERITED_IMPLICIT_GETTER,

-                       MessageKind.INHERITED_METHOD,

-                       MessageKind.INHERITED_EXPLICIT_GETTER]),

-

-    check("""

-          abstract class A {

-            get member; // testMixedOverride:20

-          }

-          abstract class B {

-            member() {} // testMixedOverride:21

-          }

-          abstract class C implements A, B {

-          }

-          class Class extends C {

-            member() {} // testMixedOverride:22

-          }

-          """, errors: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,

-               warnings: MessageKind.INHERIT_GETTER_AND_METHOD,

-               infos: [MessageKind.INHERITED_METHOD,

-                       MessageKind.INHERITED_EXPLICIT_GETTER,

-                       MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT]),

-

-    check("""

-          abstract class A {

-            get member; // testMixedOverride:23

-          }

-          abstract class B {

-            member() {} // testMixedOverride:24

-          }

-          abstract class C implements A, B {

-          }

-          class Class extends C {

-            get member => null; // testMixedOverride:25

-          }

-          """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,

-               warnings: MessageKind.INHERIT_GETTER_AND_METHOD,

-               infos: [MessageKind.INHERITED_METHOD,

-                       MessageKind.INHERITED_EXPLICIT_GETTER,

-                       MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT]),

-  ]);

-}

-

-Future testAbstractMethods() {

-  return Future.wait([

-    check("""

-          abstract class Class {

-            method(); // testAbstractMethod:1

-          }

-          """),

-

-    check("""

-          class Class {

-            method(); // testAbstractMethod:2

-          }

-          """, warnings: MessageKind.ABSTRACT_METHOD,

-               infos: []),

-

-    check("""

-          class Class {

-            get getter; // testAbstractMethod:3

-          }

-          """, warnings: MessageKind.ABSTRACT_GETTER,

-               infos: []),

-

-    check("""

-          class Class {

-            set setter(_); // testAbstractMethod:4

-          }

-          """, warnings: MessageKind.ABSTRACT_SETTER,

-               infos: []),

-

-    check("""

-          abstract class A {

-            method(); // testAbstractMethod:5

-          }

-          class Class extends A {

-            method() {} // testAbstractMethod:6

-          }

-          """),

-

-    check("""

-          abstract class A {

-            method(); // testAbstractMethod:7

-          }

-          class Class extends A {

-            method([a]) {} // testAbstractMethod:8

-          }

-          """),

-

-    check("""

-          abstract class A {

-            method(); // testAbstractMethod:9

-          }

-          class Class extends A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,

-               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),

-

-    check("""

-          abstract class A {

-            get getter; // testAbstractMethod:10

-          }

-          class Class extends A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,

-               infos: MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER),

-

-    check("""

-          abstract class A {

-            set setter(_); // testAbstractMethod:11

-          }

-          class Class extends A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,

-               infos: MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER),

-

-    check("""

-          abstract class A {

-            method(); // testAbstractMethod:12

-          }

-          class B {

-            method() {} // testAbstractMethod:13

-          }

-          class Class extends A implements B {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_METHOD,

-               infos: [MessageKind.UNIMPLEMENTED_METHOD_CONT,

-                       MessageKind.UNIMPLEMENTED_METHOD_CONT]),

-

-    check("""

-          class Class implements Function {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,

-               infos: []),

-

-    check("""

-          abstract class A {

-            get getter; // testAbstractMethod:14

-          }

-          class B {

-            get getter => 0; // testAbstractMethod:15

-          }

-          class Class extends A implements B {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_GETTER,

-               infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,

-                       MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER]),

-

-    check("""

-          abstract class A {

-            set setter(_); // testAbstractMethod:16

-          }

-          class B {

-            set setter(_) {} // testAbstractMethod:17

-          }

-          class Class extends A implements B {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_SETTER,

-               infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,

-                       MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER]),

-

-    check("""

-          abstract class A {

-            get field; // testAbstractMethod:18

-          }

-          class B {

-            var field; // testAbstractMethod:19

-          }

-          class Class extends A implements B {

-            set field(_) {} // testAbstractMethod:20

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_GETTER,

-               infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,

-                       MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER]),

-

-    check("""

-          abstract class A {

-            set field(_); // testAbstractMethod:21

-          }

-          class B {

-            var field; // testAbstractMethod:22

-          }

-          class Class extends A implements B {

-            get field => 0; // testAbstractMethod:23

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_SETTER,

-               infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,

-                       MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),

-

-    check("""

-          class A {

-            method() {} // testAbstractMethod:24

-          }

-          class Class implements A {

-            method() {} // testAbstractMethod:25

-          }

-          """),

-

-    check("""

-          class A {

-            method() {} // testAbstractMethod:26

-          }

-          class Class implements A {

-            method([a]) {} // testAbstractMethod:27

-          }

-          """),

-

-    check("""

-          class A {

-            method() {} // testAbstractMethod:28

-          }

-          class Class implements A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,

-               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),

-

-    check("""

-          class A {

-            method() {} // testAbstractMethod:29

-          }

-          class B {

-            method() {} // testAbstractMethod:30

-          }

-          class Class extends A implements B {

-          }

-          """),

-

-    check("""

-          class A {

-            var member; // testAbstractMethod:31

-          }

-          class Class implements A {

-          }

-          """, warnings: [MessageKind.UNIMPLEMENTED_GETTER_ONE,

-                          MessageKind.UNIMPLEMENTED_SETTER_ONE],

-               infos: [MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,

-                       MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),

-

-    check("""

-          class A {

-            var member; // testAbstractMethod:32

-          }

-          class B {

-            get member => null; // testAbstractMethod:33

-            set member(_) {} // testAbstractMethod:34

-          }

-          class Class implements A, B {

-          }

-          """, warnings: [MessageKind.UNIMPLEMENTED_GETTER,

-                          MessageKind.UNIMPLEMENTED_SETTER],

-               infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,

-                       MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,

-                       MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,

-                       MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),

-

-    check("""

-          class A {

-            var member; // testAbstractMethod:35

-          }

-          class B {

-            var member; // testAbstractMethod:36

-          }

-          class Class implements A, B {

-          }

-          """, warnings: [MessageKind.UNIMPLEMENTED_GETTER,

-                          MessageKind.UNIMPLEMENTED_SETTER],

-               infos: [MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,

-                       MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,

-                       MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER,

-                       MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),

-

-    check("""

-          class A {

-            get member => 0; // testAbstractMethod:37

-          }

-          class Class implements A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,

-               infos: MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER),

-

-    check("""

-          class A {

-            set member(_) {} // testAbstractMethod:38

-          }

-          class Class implements A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,

-               infos: MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER),

-

-    check("""

-          class A {

-            var member; // testAbstractMethod:39

-          }

-          class Class implements A {

-            get member => 0;

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,

-               infos: MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER),

-

-    check("""

-          class A {

-            var field; // testAbstractMethod:40

-          }

-          class Class implements A {

-            final field = 0; // testAbstractMethod:41

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,

-               infos: MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER),

-

-    check("""

-          class A {

-            var member; // testAbstractMethod:42

-          }

-          class Class implements A {

-            set member(_) {}

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,

-               infos: MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER),

-

-    check("""

-          abstract class A {

-            method() {} // testAbstractMethod:43

-          }

-          class Class extends A {

-            method();

-          }

-          """),

-  ]);

-}

-

-Future testNoSuchMethod() {

-  return Future.wait([

-    check("""

-          class Class {

-            method(); // testNoSuchMethod:1

-          }

-          """, warnings: MessageKind.ABSTRACT_METHOD,

-               infos: []),

-

-    check("""

-          @proxy

-          class Class {

-            method(); // testNoSuchMethod:2

-          }

-          """, warnings: MessageKind.ABSTRACT_METHOD,

-               infos: []),

-

-    check("""

-          class Class {

-            noSuchMethod(_) => null;

-            method(); // testNoSuchMethod:3

-          }

-          """),

-

-    check("""

-          class Class {

-            noSuchMethod(_, [__]) => null;

-            method(); // testNoSuchMethod:4

-          }

-          """),

-

-    check("""

-          class Class {

-            noSuchMethod(_);

-            method(); // testNoSuchMethod:5

-          }

-          """),

-

-    check("""

-          abstract class A {

-            method(); // testNoSuchMethod:6

-          }

-          class Class extends A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,

-               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),

-

-    check("""

-          abstract class A {

-            method(); // testNoSuchMethod:7

-          }

-          @proxy

-          class Class extends A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,

-               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),

-

-    check("""

-          abstract class A {

-            method(); // testNoSuchMethod:8

-          }

-          class Class extends A {

-            noSuchMethod(_) => null;

-          }

-          """),

-

-    check("""

-          class A {

-            method() {} // testNoSuchMethod:9

-          }

-          class Class implements A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,

-               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),

-

-    check("""

-          class A {

-            method() {} // testNoSuchMethod:10

-          }

-          class Class implements A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,

-               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),

-

-    check("""

-          class A {

-            method() {} // testNoSuchMethod:11

-          }

-          @proxy

-          class Class implements A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,

-               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),

-

-    check("""

-          class A {

-            method() {} // testNoSuchMethod:12

-          }

-          class Class implements A {

-            noSuchMethod(_) => null;

-          }

-          """),

-

-    check("""

-          class A {

-            noSuchMethod(_) => null;

-            method(); // testNoSuchMethod:13

-          }

-          class Class extends A {

-          }

-          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,

-               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),

-  ]);

-}

+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'compiler_helper.dart';
+import 'package:compiler/src/resolution/class_members.dart'
+    show MembersCreator;
+
+main() {
+  asyncTest(() => Future.wait([
+    testRequiredParameters(),
+    testPositionalParameters(),
+    testNamedParameters(),
+    testNotSubtype(),
+    testGetterNotSubtype(),
+    testSetterNotSubtype(),
+    testGenericNotSubtype(),
+    testFieldNotSubtype(),
+    testMixedOverride(),
+    testAbstractMethods(),
+    testNoSuchMethod(),
+  ]));
+}
+
+Future check(String source, {errors, warnings, hints, infos}) {
+  return MockCompiler.create((MockCompiler compiler) {
+    compiler.diagnosticHandler = createHandler(compiler, source);
+    compiler.parseScript(source);
+    var cls = compiler.mainApp.find('Class');
+    cls.ensureResolved(compiler);
+    MembersCreator.computeAllClassMembers(compiler, cls);
+
+    toList(o) => o == null ? [] : o is List ? o : [o];
+
+    compareMessageKinds(source, toList(errors), compiler.errors, 'error');
+
+    compareMessageKinds(source, toList(warnings), compiler.warnings, 'warning');
+
+    if (infos != null) {
+      compareMessageKinds(source, toList(infos), compiler.infos, 'info');
+    }
+
+    if (hints != null) {
+      compareMessageKinds(source, toList(hints), compiler.hints, 'hint');
+    }
+  });
+}
+
+Future testRequiredParameters() {
+  return Future.wait([
+    check("""
+          class A {
+            method() => null; // testRequiredParameters:0
+          }
+          class Class extends A {
+            method() => null; // testRequiredParameters:1
+          }
+          """),
+
+    check("""
+          class A {
+            method(a) => null; // testRequiredParameters:2
+          }
+          class Class extends A {
+            method(b) => null; // testRequiredParameters:3
+          }
+          """),
+
+    check("""
+          class A {
+            method(a, b, c, d) => null; // testRequiredParameters:3
+          }
+          class Class extends A {
+            method(b, a, d, c) => null; // testRequiredParameters:4
+          }
+          """),
+
+    check("""
+          class A {
+            method() => null; // testRequiredParameters:5
+          }
+          class Class extends A {
+            method(a) => null; // testRequiredParameters:6
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A {
+            method() => null; // testRequiredParameters:7
+          }
+          class Class implements A {
+            method(a) => null; // testRequiredParameters:8
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A {
+            method(a, b, c) => null; // testRequiredParameters:9
+          }
+          class Class extends A {
+            method(a, b, c, d) => null; // testRequiredParameters:10
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+  ]);
+}
+
+Future testPositionalParameters() {
+  return Future.wait([
+    check("""
+          class A {
+            method([a]) => null; // testPositionalParameters:1
+          }
+          class Class extends A {
+            method([a]) => null; // testPositionalParameters:2
+          }
+          """),
+
+    check("""
+          class A {
+            method([a, b]) => null; // testPositionalParameters:3
+          }
+          class Class extends A {
+            method([b, a]) => null; // testPositionalParameters:4
+          }
+          """),
+
+    check("""
+          class A {
+            method([a, b, c]) => null; // testPositionalParameters:5
+          }
+          class Class extends A {
+            method([b, d, a, c]) => null; // testPositionalParameters:6
+          }
+          """),
+
+    check("""
+          class A {
+            method([a]) => null; // testPositionalParameters:7
+          }
+          class Class extends A {
+            method([a]) => null; // testPositionalParameters:8
+          }
+          """),
+
+    check("""
+          class A {
+            method(a) => null; // testPositionalParameters:9
+          }
+          class Class extends A {
+            method() => null; // testPositionalParameters:10
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A {
+            method(a, [b]) => null; // testPositionalParameters:11
+          }
+          class Class extends A {
+            method(a) => null; // testPositionalParameters:12
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A {
+            method(a, [b]) => null; // testPositionalParameters:13
+          }
+          class Class extends A {
+            method([a]) => null; // testPositionalParameters:14
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A {
+            method(a, b, [c, d, e]) => null; // testPositionalParameters:15
+          }
+          class Class extends A {
+            method([a, b, c, d]) => null; // testPositionalParameters:16
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+  ]);
+}
+
+Future testNamedParameters() {
+  return Future.wait([
+    check("""
+          class A {
+            method({a}) => null; // testNamedParameters:1
+          }
+          class Class extends A {
+            method({a}) => null; // testNamedParameters:2
+          }
+          """),
+
+    check("""
+          class A {
+            method({a, b}) => null; // testNamedParameters:3
+          }
+          class Class extends A {
+            method({b, a}) => null; // testNamedParameters:4
+          }
+          """),
+
+    check("""
+          class A {
+            method({a, b, c}) => null; // testNamedParameters:5
+          }
+          class Class extends A {
+            method({b, c, a, d}) => null; // testNamedParameters:6
+          }
+          """),
+
+    check("""
+          class A {
+            method(d, {a, b, c}) => null; // testNamedParameters:7
+          }
+          class Class extends A {
+            method(e, {b, c, a, d}) => null; // testNamedParameters:8
+          }
+          """),
+
+    check("""
+          class A {
+            method({a}) => null; // testNamedParameters:9
+          }
+          class Class extends A {
+            method() => null; // testNamedParameters:10
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A {
+            method({a, b}) => null; // testNamedParameters:11
+          }
+          class Class extends A {
+            method({b}) => null; // testNamedParameters:12
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A {
+            method({a, b, c, d}) => null; // testNamedParameters:13
+          }
+          class Class extends A {
+            method({a, e, d, c}) => null; // testNamedParameters:14
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+  ]);
+}
+
+Future testNotSubtype() {
+  return Future.wait([
+    check("""
+          class A {
+            method(int a) => null; // testNotSubtype:1
+          }
+          class Class extends A {
+            method(int a) => null; // testNotSubtype:2
+          }
+          """),
+
+    check("""
+          class A {
+            method(int a) => null; // testNotSubtype:3
+          }
+          class Class extends A {
+            method(num a) => null; // testNotSubtype:4
+          }
+          """),
+
+    check("""
+          class A {
+            void method() {} // testNotSubtype:5
+          }
+          class Class extends A {
+            method() => null; // testNotSubtype:6
+          }
+          """),
+
+    check("""
+          class A {
+            method() => null; // testNotSubtype:7
+          }
+          class Class extends A {
+            void method() {} // testNotSubtype:8
+          }
+          """),
+
+    check("""
+          class A {
+            void method() {} // testNotSubtype:9
+          }
+          class Class extends A {
+            int method() => null; // testNotSubtype:10
+          }
+          """),
+
+    check("""
+          class A {
+            int method() => null; // testNotSubtype:11
+          }
+          class Class extends A {
+            void method() {} // testNotSubtype:12
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A {
+            method(int a) => null; // testNotSubtype:13
+          }
+          class B extends A {
+            method(num a) => null; // testNotSubtype:14
+          }
+          class Class extends B {
+            method(double a) => null; // testNotSubtype:15
+          }
+          """),
+
+    check("""
+          class A {
+            method(int a) => null; // testNotSubtype:16
+          }
+          class B extends A {
+            method(a) => null; // testNotSubtype:17
+          }
+          class Class extends B {
+            method(String a) => null; // testNotSubtype:18
+          }
+          """),
+
+    check("""
+          class A {
+            method(int a) => null; // testNotSubtype:19
+          }
+          class Class extends A {
+            method(String a) => null; // testNotSubtype:20
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
+    check("""
+          class A {
+            method(int a) => null; // testNotSubtype:23
+          }
+          class B {
+            method(num a) => null; // testNotSubtype:24
+          }
+          abstract class C implements A, B {
+          }
+          class Class implements C {
+            method(double a) => null; // testNotSubtype:25
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A {
+            method(num a) => null; // testNotSubtype:29
+          }
+          class B {
+            method(int a) => null; // testNotSubtype:30
+          }
+          abstract class C implements A, B {
+          }
+          class Class implements C {
+            method(double a) => null; // testNotSubtype:31
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A {
+            method(int a) => null; // testNotSubtype:26
+          }
+          class B {
+            method(num a) => null; // testNotSubtype:27
+          }
+          abstract class C implements A, B {
+          }
+          class Class implements C {
+            method(String a) => null; // testNotSubtype:28
+          }
+          """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
+                          MessageKind.INVALID_OVERRIDE_METHOD],
+               infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
+                       MessageKind.INVALID_OVERRIDDEN_METHOD]),
+  ]);
+}
+
+Future testGetterNotSubtype() {
+  return Future.wait([
+    check("""
+          class A {
+            get getter => null; // testGetterNotSubtype:1
+          }
+          class Class extends A {
+            get getter => null; // testGetterNotSubtype:2
+          }
+          """),
+
+    check("""
+          class A {
+            num get getter => null; // testGetterNotSubtype:3
+          }
+          class Class extends A {
+            num get getter => null; // testGetterNotSubtype:4
+          }
+          """),
+
+    check("""
+          class A {
+            num get getter => null; // testGetterNotSubtype:5
+          }
+          class Class extends A {
+            int get getter => null; // testGetterNotSubtype:6
+          }
+          """),
+
+    check("""
+          class A {
+            int get getter => null; // testGetterNotSubtype:7
+          }
+          class Class extends A {
+            num get getter => null; // testGetterNotSubtype:8
+          }
+          """),
+
+    check("""
+          class A {
+            int get getter => null; // testGetterNotSubtype:9
+          }
+          class Class extends A {
+            double get getter => null; // testGetterNotSubtype:10
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,
+               infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
+
+    check("""
+          class A {
+            int get getter => null; // testGetterNotSubtype:11
+          }
+          class B extends A {
+            num get getter => null; // testGetterNotSubtype:12
+          }
+          class Class extends B {
+            double get getter => null; // testGetterNotSubtype:13
+          }
+          """),
+
+    check("""
+          class A {
+            int get getter => null; // testGetterNotSubtype:14
+          }
+          class B {
+            num get getter => null; // testGetterNotSubtype:15
+          }
+          class Class extends A implements B {
+            double get getter => null; // testGetterNotSubtype:16
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,
+               infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
+
+    check("""
+          class A {
+            int get getter => null; // testGetterNotSubtype:17
+          }
+          class B {
+            String get getter => null; // testGetterNotSubtype:18
+          }
+          class Class extends A implements B {
+            double get getter => null; // testGetterNotSubtype:19
+          }
+          """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,
+                          MessageKind.INVALID_OVERRIDE_GETTER],
+               infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
+                       MessageKind.INVALID_OVERRIDDEN_GETTER]),
+
+    check("""
+          class A {
+            int get getter => null; // testGetterNotSubtype:20
+          }
+          class B {
+            String get getter => null; // testGetterNotSubtype:21
+          }
+          class Class implements A, B {
+            double get getter => null; // testGetterNotSubtype:22
+          }
+          """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,
+                          MessageKind.INVALID_OVERRIDE_GETTER],
+               infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
+                       MessageKind.INVALID_OVERRIDDEN_GETTER]),
+
+    // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
+    check("""
+          class A {
+            int get getter => null; // testGetterNotSubtype:23
+          }
+          class B {
+            num get getter => null; // testGetterNotSubtype:24
+          }
+          abstract class C implements A, B {
+          }
+          class Class implements C {
+            double get getter => null; // testGetterNotSubtype:25
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_GETTER,
+               infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
+
+    check("""
+          class A {
+            int get getter => null; // testGetterNotSubtype:26
+          }
+          class B {
+            num get getter => null; // testGetterNotSubtype:27
+          }
+          abstract class C implements A, B {
+          }
+          class Class implements C {
+            String get getter => null; // testGetterNotSubtype:28
+          }
+          """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER,
+                          MessageKind.INVALID_OVERRIDE_GETTER],
+               infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
+                       MessageKind.INVALID_OVERRIDDEN_GETTER]),
+  ]);
+}
+
+Future testGenericNotSubtype() {
+  return Future.wait([
+    check("""
+          class A<T> {
+            method(T t) => null; // testGenericNotSubtype:1
+          }
+          class Class<S> extends A<S> {
+            method(S s) => null; // testGenericNotSubtype:2
+          }
+          """),
+
+    check("""
+          class A<T> {
+            method(T t) => null; // testGenericNotSubtype:3
+          }
+          class Class extends A<num> {
+            method(int i) => null; // testGenericNotSubtype:4
+          }
+          """),
+
+    check("""
+          class A<T> {
+            method(T t) => null; // testGenericNotSubtype:5
+          }
+          class B<S> {
+            method(S s) => null; // testGenericNotSubtype:6
+          }
+          class Class extends A<double> implements B<int> {
+            method(num i) => null; // testGenericNotSubtype:7
+          }
+          """),
+
+    check("""
+          class A<T> {
+            method(T t) => null; // testGenericNotSubtype:8
+          }
+          class Class<S> extends A<S> {
+            method(int i) => null; // testGenericNotSubtype:9
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A<T> {
+            method(T t) => null; // testGenericNotSubtype:10
+          }
+          class B<S> extends A<S> {
+
+          }
+          class Class<U> extends B<U> {
+            method(U u) => null; // testGenericNotSubtype:11
+          }
+          """),
+
+    check("""
+          class A<T> {
+            method(T t) => null; // testGenericNotSubtype:12
+          }
+          class B<S> {
+            method(S s) => null; // testGenericNotSubtype:13
+          }
+          class Class<U> extends A<U> implements B<num> {
+            method(int i) => null; // testGenericNotSubtype:14
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A<T> {
+            method(T t) => null; // testGenericNotSubtype:15
+          }
+          class B<S> {
+            method(S s) => null; // testGenericNotSubtype:16
+          }
+          class Class extends A<int> implements B<String> {
+            method(double d) => null; // testGenericNotSubtype:17
+          }
+          """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
+                          MessageKind.INVALID_OVERRIDE_METHOD],
+               infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
+                       MessageKind.INVALID_OVERRIDDEN_METHOD]),
+
+    check("""
+          class A<T> {
+            method(T t) => null; // testGenericNotSubtype:18
+          }
+          class B<S> {
+            method(S s) => null; // testGenericNotSubtype:19
+          }
+          class Class implements A<int>, B<String> {
+            method(double d) => null; // testGenericNotSubtype:20
+          }
+          """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
+                          MessageKind.INVALID_OVERRIDE_METHOD],
+               infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
+                       MessageKind.INVALID_OVERRIDDEN_METHOD]),
+
+    // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
+    check("""
+          class A<T> {
+            method(T t) => null; // testGenericNotSubtype:21
+          }
+          class B<S> {
+            method(S s) => null; // testGenericNotSubtype:22
+          }
+          abstract class C implements A<int>, B<num> {
+          }
+          class Class implements C {
+            method(double d) => null; // testGenericNotSubtype:23
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_METHOD,
+               infos: MessageKind.INVALID_OVERRIDDEN_METHOD),
+
+    check("""
+          class A<T> {
+            method(T t) => null; // testGenericNotSubtype:24
+          }
+          class B<S> {
+            method(S s) => null; // testGenericNotSubtype:25
+          }
+          abstract class C implements A<int>, B<num> {
+          }
+          class Class implements C {
+            method(String s) => null; // testGenericNotSubtype:26
+          }
+          """, warnings: [MessageKind.INVALID_OVERRIDE_METHOD,
+                          MessageKind.INVALID_OVERRIDE_METHOD],
+               infos: [MessageKind.INVALID_OVERRIDDEN_METHOD,
+                       MessageKind.INVALID_OVERRIDDEN_METHOD]),
+  ]);
+}
+
+Future testSetterNotSubtype() {
+  return Future.wait([
+  check("""
+        class A {
+          set setter(_) => null; // testSetterNotSubtype:1
+        }
+        class Class extends A {
+          set setter(_) => null; // testSetterNotSubtype:2
+        }
+        """),
+
+  check("""
+        class A {
+          void set setter(_) {} // testSetterNotSubtype:3
+        }
+        class Class extends A {
+          set setter(_) => null; // testSetterNotSubtype:4
+        }
+        """),
+
+  check("""
+        class A {
+          set setter(_) => null; // testSetterNotSubtype:5
+        }
+        class Class extends A {
+          void set setter(_) {} // testSetterNotSubtype:6
+        }
+        """),
+
+  check("""
+        class A {
+          set setter(_) => null; // testSetterNotSubtype:7
+        }
+        class Class extends A {
+          void set setter(_) {} // testSetterNotSubtype:8
+        }
+        """),
+
+  check("""
+        class A {
+          set setter(num _) => null; // testSetterNotSubtype:9
+        }
+        class Class extends A {
+          set setter(num _) => null; // testSetterNotSubtype:10
+        }
+        """),
+
+  check("""
+        class A {
+          set setter(num _) => null; // testSetterNotSubtype:11
+        }
+        class Class extends A {
+          set setter(int _) => null; // testSetterNotSubtype:12
+        }
+        """),
+
+  check("""
+        class A {
+          set setter(int _) => null; // testSetterNotSubtype:13
+        }
+        class Class extends A {
+          set setter(num _) => null; // testSetterNotSubtype:14
+        }
+        """),
+
+  check("""
+        class A {
+          set setter(int _) => null; // testSetterNotSubtype:15
+        }
+        class Class extends A {
+          set setter(double _) => null; // testSetterNotSubtype:16
+        }
+        """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,
+             infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
+
+  check("""
+        class A {
+          set setter(int _) => null; // testSetterNotSubtype:17
+        }
+        class B extends A {
+          set setter(num _) => null; // testSetterNotSubtype:18
+        }
+        class Class extends B {
+          set setter(double _) => null; // testSetterNotSubtype:19
+        }
+        """),
+
+  check("""
+        class A {
+          set setter(int _) => null; // testSetterNotSubtype:20
+        }
+        class B {
+          set setter(num _) => null; // testSetterNotSubtype:21
+        }
+        class Class extends A implements B {
+          set setter(double _) => null; // testSetterNotSubtype:22
+        }
+        """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,
+             infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
+
+  check("""
+        class A {
+          set setter(int _) => null; // testSetterNotSubtype:23
+        }
+        class B {
+          set setter(String _) => null; // testSetterNotSubtype:24
+        }
+        class Class extends A implements B {
+          set setter(double _) => null; // testSetterNotSubtype:25
+        }
+        """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,
+                        MessageKind.INVALID_OVERRIDE_SETTER],
+             infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,
+                     MessageKind.INVALID_OVERRIDDEN_SETTER]),
+
+  check("""
+        class A {
+          set setter(int _) => null; // testSetterNotSubtype:26
+        }
+        class B {
+          set setter(String _) => null; // testSetterNotSubtype:27
+        }
+        class Class implements A, B {
+          set setter(double _) => null; // testSetterNotSubtype:28
+        }
+        """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,
+                        MessageKind.INVALID_OVERRIDE_SETTER],
+             infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,
+                     MessageKind.INVALID_OVERRIDDEN_SETTER]),
+
+  // TODO(johnniwinther): These are unclear. Issue 16443 has been filed.
+  check("""
+        class A {
+          set setter(int _) => null; // testSetterNotSubtype:29
+        }
+        class B {
+          set setter(num _) => null; // testSetterNotSubtype:30
+        }
+        abstract class C implements A, B {
+        }
+        class Class implements C {
+          set setter(double _) => null; // testSetterNotSubtype:31
+        }
+        """, warnings: MessageKind.INVALID_OVERRIDE_SETTER,
+             infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
+
+  check("""
+        class A {
+          set setter(int _) => null; // testSetterNotSubtype:32
+        }
+        class B {
+          set setter(num _) => null; // testSetterNotSubtype:33
+        }
+        abstract class C implements A, B {
+        }
+        class Class implements C {
+          set setter(String _) => null; // testSetterNotSubtype:34
+        }
+        """, warnings: [MessageKind.INVALID_OVERRIDE_SETTER,
+                        MessageKind.INVALID_OVERRIDE_SETTER],
+             infos: [MessageKind.INVALID_OVERRIDDEN_SETTER,
+                     MessageKind.INVALID_OVERRIDDEN_SETTER]),
+  ]);
+}
+
+Future testFieldNotSubtype() {
+  return Future.wait([
+    check("""
+          class A {
+            int field; // testFieldNotSubtype:1
+          }
+          class Class extends A {
+            int field; // testFieldNotSubtype:2
+          }
+          """),
+
+    check("""
+          class A {
+            num field; // testFieldNotSubtype:3
+          }
+          class Class extends A {
+            int field; // testFieldNotSubtype:4
+          }
+          """),
+
+    check("""
+          class A {
+            int field; // testFieldNotSubtype:5
+          }
+          class Class extends A {
+            num field; // testFieldNotSubtype:6
+          }
+          """),
+
+    check("""
+          class A {
+            int field; // testFieldNotSubtype:7
+          }
+          class Class extends A {
+            double field; // testFieldNotSubtype:8
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_FIELD,
+               infos: MessageKind.INVALID_OVERRIDDEN_FIELD),
+
+    check("""
+          class A {
+            int field; // testFieldNotSubtype:9
+          }
+          class B extends A {
+            num field; // testFieldNotSubtype:10
+          }
+          class Class extends B {
+            double field; // testFieldNotSubtype:11
+          }
+          """),
+
+    check("""
+          class A {
+            num field; // testFieldNotSubtype:12
+          }
+          class Class extends A {
+            int get field => null; // testFieldNotSubtype:13
+          }
+          """),
+
+    check("""
+          class A {
+            num field; // testFieldNotSubtype:14
+          }
+          class Class extends A {
+            String get field => null; // testFieldNotSubtype:15
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
+               infos: MessageKind.INVALID_OVERRIDDEN_FIELD),
+
+    check("""
+          class A {
+            num get field => null; // testFieldNotSubtype:16
+          }
+          class Class extends A {
+            String field; // testFieldNotSubtype:17
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
+               infos: MessageKind.INVALID_OVERRIDDEN_GETTER),
+
+    check("""
+          class A {
+            num field; // testFieldNotSubtype:18
+          }
+          class Class extends A {
+            set field(int _) {} // testFieldNotSubtype:19
+          }
+          """),
+
+    check("""
+          class A {
+            num field; // testFieldNotSubtype:19
+          }
+          class Class extends A {
+            void set field(int _) {} // testFieldNotSubtype:20
+          }
+          """),
+
+    check("""
+          class A {
+            set field(int _) {} // testFieldNotSubtype:21
+          }
+          class Class extends A {
+            num field; // testFieldNotSubtype:22
+          }
+          """),
+
+    check("""
+          class A {
+            void set field(int _) {} // testFieldNotSubtype:23
+          }
+          class Class extends A {
+            num field; // testFieldNotSubtype:24
+          }
+          """),
+
+    check("""
+          class A {
+            num field; // testFieldNotSubtype:25
+          }
+          class Class extends A {
+            set field(String _) {} // testFieldNotSubtype:26
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER,
+               infos: MessageKind.INVALID_OVERRIDDEN_FIELD),
+
+    check("""
+          class A {
+            set field(num _) {} // testFieldNotSubtype:27
+          }
+          class Class extends A {
+            String field; // testFieldNotSubtype:28
+          }
+          """, warnings: MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD,
+               infos: MessageKind.INVALID_OVERRIDDEN_SETTER),
+
+    check("""
+          class A {
+            int field; // testFieldNotSubtype:29
+          }
+          class Class implements A {
+            String get field => null; // testFieldNotSubtype:30
+            void set field(String s) {} // testFieldNotSubtype:31
+          }
+          """, warnings: [MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
+                          MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER],
+               infos: [MessageKind.INVALID_OVERRIDDEN_FIELD,
+                       MessageKind.INVALID_OVERRIDDEN_FIELD]),
+
+
+    check("""
+          class A {
+            String get field => null; // testFieldNotSubtype:32
+            void set field(String s) {} // testFieldNotSubtype:33
+          }
+          class Class implements A {
+            int field; // testFieldNotSubtype:34
+          }
+          """, warnings: [MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
+                          MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD],
+               infos: [MessageKind.INVALID_OVERRIDDEN_GETTER,
+                       MessageKind.INVALID_OVERRIDDEN_SETTER]),
+  ]);
+}
+
+Future testMixedOverride() {
+  return Future.wait([
+    check("""
+          class A {
+            var member; // testMixedOverride:1
+          }
+          class Class extends A {
+            member() {} // testMixedOverride:2
+          }
+          """, errors: MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
+               infos: MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT),
+
+    check("""
+          class A {
+            member() {} // testMixedOverride:3
+          }
+          class Class extends A {
+            var member; // testMixedOverride:4
+          }
+          """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
+               infos: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT),
+
+    check("""
+          class A {
+            get member => null; // testMixedOverride:5
+          }
+          class Class extends A {
+            member() {} // testMixedOverride:6
+          }
+          """, errors: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
+               infos: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT),
+
+    check("""
+          class A {
+            member() {} // testMixedOverride:7
+          }
+          class Class extends A {
+            get member => null; // testMixedOverride:8
+          }
+          """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
+               infos: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT),
+
+    check("""
+          abstract class A {
+            var member; // testMixedOverride:9
+          }
+          abstract class B {
+            get member; // testMixedOverride:10
+          }
+          abstract class Class implements A, B {
+          }
+          """),
+
+    check("""
+          abstract class A {
+            var member; // testMixedOverride:11
+          }
+          abstract class B {
+            member() {} // testMixedOverride:12
+          }
+          abstract class Class implements A, B {
+          }
+          """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
+               infos: [MessageKind.INHERITED_METHOD,
+                       MessageKind.INHERITED_IMPLICIT_GETTER]),
+
+    check("""
+          abstract class A {
+            get member; // testMixedOverride:13
+          }
+          abstract class B {
+            member() {} // testMixedOverride:14
+          }
+          abstract class Class implements A, B {
+          }
+          """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
+               infos: [MessageKind.INHERITED_METHOD,
+                       MessageKind.INHERITED_EXPLICIT_GETTER]),
+
+    check("""
+          abstract class A {
+            get member; // testMixedOverride:15
+          }
+          abstract class B {
+            member() {} // testMixedOverride:16
+          }
+          abstract class C {
+            var member; // testMixedOverride:17
+          }
+          abstract class D {
+            member() {} // testMixedOverride:18
+          }
+          abstract class E {
+            get member; // testMixedOverride:19
+          }
+          abstract class Class implements A, B, C, D, E {
+          }
+          """, warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
+               infos: [MessageKind.INHERITED_EXPLICIT_GETTER,
+                       MessageKind.INHERITED_METHOD,
+                       MessageKind.INHERITED_IMPLICIT_GETTER,
+                       MessageKind.INHERITED_METHOD,
+                       MessageKind.INHERITED_EXPLICIT_GETTER]),
+
+    check("""
+          abstract class A {
+            get member; // testMixedOverride:20
+          }
+          abstract class B {
+            member() {} // testMixedOverride:21
+          }
+          abstract class C implements A, B {
+          }
+          class Class extends C {
+            member() {} // testMixedOverride:22
+          }
+          """, errors: MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
+               warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
+               infos: [MessageKind.INHERITED_METHOD,
+                       MessageKind.INHERITED_EXPLICIT_GETTER,
+                       MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT]),
+
+    check("""
+          abstract class A {
+            get member; // testMixedOverride:23
+          }
+          abstract class B {
+            member() {} // testMixedOverride:24
+          }
+          abstract class C implements A, B {
+          }
+          class Class extends C {
+            get member => null; // testMixedOverride:25
+          }
+          """, errors: MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
+               warnings: MessageKind.INHERIT_GETTER_AND_METHOD,
+               infos: [MessageKind.INHERITED_METHOD,
+                       MessageKind.INHERITED_EXPLICIT_GETTER,
+                       MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT]),
+  ]);
+}
+
+Future testAbstractMethods() {
+  return Future.wait([
+    check("""
+          abstract class Class {
+            method(); // testAbstractMethod:1
+          }
+          """),
+
+    check("""
+          class Class {
+            method(); // testAbstractMethod:2
+          }
+          """, warnings: MessageKind.ABSTRACT_METHOD,
+               infos: []),
+
+    check("""
+          class Class {
+            get getter; // testAbstractMethod:3
+          }
+          """, warnings: MessageKind.ABSTRACT_GETTER,
+               infos: []),
+
+    check("""
+          class Class {
+            set setter(_); // testAbstractMethod:4
+          }
+          """, warnings: MessageKind.ABSTRACT_SETTER,
+               infos: []),
+
+    check("""
+          abstract class A {
+            method(); // testAbstractMethod:5
+          }
+          class Class extends A {
+            method() {} // testAbstractMethod:6
+          }
+          """),
+
+    check("""
+          abstract class A {
+            method(); // testAbstractMethod:7
+          }
+          class Class extends A {
+            method([a]) {} // testAbstractMethod:8
+          }
+          """),
+
+    check("""
+          abstract class A {
+            method(); // testAbstractMethod:9
+          }
+          class Class extends A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+    check("""
+          abstract class A {
+            get getter; // testAbstractMethod:10
+          }
+          class Class extends A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,
+               infos: MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER),
+
+    check("""
+          abstract class A {
+            set setter(_); // testAbstractMethod:11
+          }
+          class Class extends A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
+               infos: MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER),
+
+    check("""
+          abstract class A {
+            method(); // testAbstractMethod:12
+          }
+          class B {
+            method() {} // testAbstractMethod:13
+          }
+          class Class extends A implements B {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_METHOD,
+               infos: [MessageKind.UNIMPLEMENTED_METHOD_CONT,
+                       MessageKind.UNIMPLEMENTED_METHOD_CONT]),
+
+    check("""
+          class Class implements Function {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+               infos: []),
+
+    check("""
+          abstract class A {
+            get getter; // testAbstractMethod:14
+          }
+          class B {
+            get getter => 0; // testAbstractMethod:15
+          }
+          class Class extends A implements B {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_GETTER,
+               infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
+                       MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER]),
+
+    check("""
+          abstract class A {
+            set setter(_); // testAbstractMethod:16
+          }
+          class B {
+            set setter(_) {} // testAbstractMethod:17
+          }
+          class Class extends A implements B {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_SETTER,
+               infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
+                       MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER]),
+
+    check("""
+          abstract class A {
+            get field; // testAbstractMethod:18
+          }
+          class B {
+            var field; // testAbstractMethod:19
+          }
+          class Class extends A implements B {
+            set field(_) {} // testAbstractMethod:20
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_GETTER,
+               infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
+                       MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER]),
+
+    check("""
+          abstract class A {
+            set field(_); // testAbstractMethod:21
+          }
+          class B {
+            var field; // testAbstractMethod:22
+          }
+          class Class extends A implements B {
+            get field => 0; // testAbstractMethod:23
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_SETTER,
+               infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
+                       MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
+
+    check("""
+          class A {
+            method() {} // testAbstractMethod:24
+          }
+          class Class implements A {
+            method() {} // testAbstractMethod:25
+          }
+          """),
+
+    check("""
+          class A {
+            method() {} // testAbstractMethod:26
+          }
+          class Class implements A {
+            method([a]) {} // testAbstractMethod:27
+          }
+          """),
+
+    check("""
+          class A {
+            method() {} // testAbstractMethod:28
+          }
+          class Class implements A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+    check("""
+          class A {
+            method() {} // testAbstractMethod:29
+          }
+          class B {
+            method() {} // testAbstractMethod:30
+          }
+          class Class extends A implements B {
+          }
+          """),
+
+    check("""
+          class A {
+            var member; // testAbstractMethod:31
+          }
+          class Class implements A {
+          }
+          """, warnings: [MessageKind.UNIMPLEMENTED_GETTER_ONE,
+                          MessageKind.UNIMPLEMENTED_SETTER_ONE],
+               infos: [MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
+                       MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
+
+    check("""
+          class A {
+            var member; // testAbstractMethod:32
+          }
+          class B {
+            get member => null; // testAbstractMethod:33
+            set member(_) {} // testAbstractMethod:34
+          }
+          class Class implements A, B {
+          }
+          """, warnings: [MessageKind.UNIMPLEMENTED_GETTER,
+                          MessageKind.UNIMPLEMENTED_SETTER],
+               infos: [MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
+                       MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
+                       MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
+                       MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
+
+    check("""
+          class A {
+            var member; // testAbstractMethod:35
+          }
+          class B {
+            var member; // testAbstractMethod:36
+          }
+          class Class implements A, B {
+          }
+          """, warnings: [MessageKind.UNIMPLEMENTED_GETTER,
+                          MessageKind.UNIMPLEMENTED_SETTER],
+               infos: [MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
+                       MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
+                       MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER,
+                       MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER]),
+
+    check("""
+          class A {
+            get member => 0; // testAbstractMethod:37
+          }
+          class Class implements A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,
+               infos: MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER),
+
+    check("""
+          class A {
+            set member(_) {} // testAbstractMethod:38
+          }
+          class Class implements A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
+               infos: MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER),
+
+    check("""
+          class A {
+            var member; // testAbstractMethod:39
+          }
+          class Class implements A {
+            get member => 0;
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
+               infos: MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER),
+
+    check("""
+          class A {
+            var field; // testAbstractMethod:40
+          }
+          class Class implements A {
+            final field = 0; // testAbstractMethod:41
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_SETTER_ONE,
+               infos: MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER),
+
+    check("""
+          class A {
+            var member; // testAbstractMethod:42
+          }
+          class Class implements A {
+            set member(_) {}
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_GETTER_ONE,
+               infos: MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER),
+
+    check("""
+          abstract class A {
+            method() {} // testAbstractMethod:43
+          }
+          class Class extends A {
+            method();
+          }
+          """),
+  ]);
+}
+
+Future testNoSuchMethod() {
+  return Future.wait([
+    check("""
+          class Class {
+            method(); // testNoSuchMethod:1
+          }
+          """, warnings: MessageKind.ABSTRACT_METHOD,
+               infos: []),
+
+    check("""
+          @proxy
+          class Class {
+            method(); // testNoSuchMethod:2
+          }
+          """, warnings: MessageKind.ABSTRACT_METHOD,
+               infos: []),
+
+    check("""
+          class Class {
+            noSuchMethod(_) => null;
+            method(); // testNoSuchMethod:3
+          }
+          """),
+
+    check("""
+          class Class {
+            noSuchMethod(_, [__]) => null;
+            method(); // testNoSuchMethod:4
+          }
+          """),
+
+    check("""
+          class Class {
+            noSuchMethod(_);
+            method(); // testNoSuchMethod:5
+          }
+          """),
+
+    check("""
+          abstract class A {
+            method(); // testNoSuchMethod:6
+          }
+          class Class extends A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+    check("""
+          abstract class A {
+            method(); // testNoSuchMethod:7
+          }
+          @proxy
+          class Class extends A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+    check("""
+          abstract class A {
+            method(); // testNoSuchMethod:8
+          }
+          class Class extends A {
+            noSuchMethod(_) => null;
+          }
+          """),
+
+    check("""
+          class A {
+            method() {} // testNoSuchMethod:9
+          }
+          class Class implements A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+    check("""
+          class A {
+            method() {} // testNoSuchMethod:10
+          }
+          class Class implements A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+    check("""
+          class A {
+            method() {} // testNoSuchMethod:11
+          }
+          @proxy
+          class Class implements A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+
+    check("""
+          class A {
+            method() {} // testNoSuchMethod:12
+          }
+          class Class implements A {
+            noSuchMethod(_) => null;
+          }
+          """),
+
+    check("""
+          class A {
+            noSuchMethod(_) => null;
+            method(); // testNoSuchMethod:13
+          }
+          class Class extends A {
+          }
+          """, warnings: MessageKind.UNIMPLEMENTED_METHOD_ONE,
+               infos: MessageKind.UNIMPLEMENTED_METHOD_CONT),
+  ]);
+}
diff --git a/tests/compiler/dart2js/package_root_test.dart b/tests/compiler/dart2js/package_root_test.dart
index 5a173f5..f1e6ee6 100644
--- a/tests/compiler/dart2js/package_root_test.dart
+++ b/tests/compiler/dart2js/package_root_test.dart
@@ -6,18 +6,17 @@
 
 library dart2js.test.package_root;
 
-import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
-import 'memory_source_file_helper.dart';
-
-import 'package:compiler/src/dart2jslib.dart'
-       show NullSink;
-
-import 'package:compiler/compiler.dart'
-       show DiagnosticHandler, Diagnostic;
-
 import 'dart:async';
 
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/compiler.dart'
+       show DiagnosticHandler, Diagnostic, PackagesDiscoveryProvider;
+import 'package:package_config/packages.dart';
+
+import 'memory_compiler.dart';
+import 'memory_source_file_helper.dart';
+
 const MEMORY_SOURCE_FILES = const {
   'main.dart': '''
 
@@ -25,46 +24,66 @@
 
 main() {}
 ''',
+  'package.config': '''
+''',
 };
 
-void runCompiler(Uri main) {
-  Uri script = currentDirectory.resolveUri(Platform.script);
-  Uri libraryRoot = script.resolve('../../../sdk/');
-  Uri packageRoot = script.resolve('./packages/');
+final Uri PACKAGE_CONFIG_URI = Uri.parse('memory:package.config');
 
-  var provider = new MemorySourceFileProvider(MEMORY_SOURCE_FILES);
-  var handler = new FormattingDiagnosticHandler(provider);
-  var errors = [];
-
-  void diagnosticHandler(Uri uri, int begin, int end, String message,
-                         Diagnostic kind) {
-    if (kind == Diagnostic.ERROR) {
-      errors.add(message);
-    }
-    handler(uri, begin, end, message, kind);
-  }
-
-
-  EventSink<String> outputProvider(String name, String extension) {
-    if (name != '') throw 'Attempt to output file "$name.$extension"';
-    return new NullSink('$name.$extension');
-  }
-
-  Compiler compiler = new Compiler(provider,
-                                   outputProvider,
-                                   diagnosticHandler,
-                                   libraryRoot,
-                                   packageRoot,
-                                   [],
-                                   {});
+void runCompiler(Uri main,
+                 bool checkError(DiagnosticMessage message),
+                 {Uri packageRoot,
+                  Uri packageConfig,
+                  PackagesDiscoveryProvider packagesDiscoveryProvider}) {
+  DiagnosticCollector collector = new DiagnosticCollector();
+  Compiler compiler = compilerFor(
+      MEMORY_SOURCE_FILES,
+      diagnosticHandler: collector,
+      packageRoot: packageRoot,
+      packageConfig: packageConfig,
+      packagesDiscoveryProvider: packagesDiscoveryProvider);
 
   asyncTest(() => compiler.run(main).then((_) {
-    Expect.equals(1, errors.length);
-    Expect.isTrue(errors[0].contains("Error reading "));
+    Expect.equals(1, collector.errors.length,
+        "Unexpected errors: ${collector.errors}");
+    Expect.isTrue(checkError(collector.errors.first),
+        "Unexpected error: ${collector.errors.first}");
   }));
 }
 
 void main() {
-  runCompiler(Uri.parse('memory:main.dart'));
-  runCompiler(Uri.parse('package:foo/foo.dart'));
+  Uri script = currentDirectory.resolveUri(Platform.script);
+  Uri packageRoot = script.resolve('./packages/');
+
+  PackagesDiscoveryProvider noPackagesDiscovery = (Uri uri) {
+    return new Future.value(Packages.noPackages);
+  };
+
+  bool containsErrorReading(DiagnosticMessage message) {
+    return message.message.contains("Error reading ");
+  }
+
+  bool isLibraryNotFound(DiagnosticMessage message) {
+    return message.message.startsWith("Library not found ");
+  }
+
+  runCompiler(Uri.parse('memory:main.dart'),
+              containsErrorReading,
+              packageRoot: packageRoot);
+  runCompiler(Uri.parse('memory:main.dart'),
+              isLibraryNotFound,
+              packageConfig: PACKAGE_CONFIG_URI);
+  runCompiler(Uri.parse('memory:main.dart'),
+              isLibraryNotFound,
+              packagesDiscoveryProvider: noPackagesDiscovery);
+
+  runCompiler(Uri.parse('package:foo/foo.dart'),
+              containsErrorReading,
+              packageRoot: packageRoot);
+  runCompiler(Uri.parse('package:foo/foo.dart'),
+              isLibraryNotFound,
+              packageConfig: PACKAGE_CONFIG_URI);
+  runCompiler(Uri.parse('package:foo/foo.dart'),
+              isLibraryNotFound,
+              packagesDiscoveryProvider: noPackagesDiscovery);
 }
diff --git a/tests/compiler/dart2js/proxy_test.dart b/tests/compiler/dart2js/proxy_test.dart
index c558350..b9d8444 100644
--- a/tests/compiler/dart2js/proxy_test.dart
+++ b/tests/compiler/dart2js/proxy_test.dart
@@ -1,22 +1,22 @@
-// 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.

-

-// Test that dart2js produces the expected static type warnings for proxy

-// language tests. This ensures that the analyzer and dart2js agrees on these

-// tests.

-

-import 'warnings_checker.dart';

-

-/// Map from test files to a map of their expected status. If the status map is

-/// `null` no warnings must be missing or unexpected, otherwise the status map

-/// can contain a list of line numbers for keys 'missing' and 'unexpected' for

-/// the warnings of each category.

-const Map<String, dynamic> TESTS = const {

-    'language/proxy_test.dart': null,

-    'language/proxy2_test.dart': null,

-};

-

-void main() {

-  checkWarnings(TESTS);

-}

+// 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.
+
+// Test that dart2js produces the expected static type warnings for proxy
+// language tests. This ensures that the analyzer and dart2js agrees on these
+// tests.
+
+import 'warnings_checker.dart';
+
+/// Map from test files to a map of their expected status. If the status map is
+/// `null` no warnings must be missing or unexpected, otherwise the status map
+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
+/// the warnings of each category.
+const Map<String, dynamic> TESTS = const {
+    'language/proxy_test.dart': null,
+    'language/proxy2_test.dart': null,
+};
+
+void main() {
+  checkWarnings(TESTS);
+}
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index 5084fe3..c25eb93 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -686,7 +686,7 @@
         new ResolverVisitor(compiler, element,
             new ResolutionRegistry.internal(compiler,
                 new CollectingTreeElements(element)));
-    new InitializerResolver(visitor).resolveInitializers(element, tree);
+    new InitializerResolver(visitor, element, tree).resolveInitializers();
     visitor.visit(tree.body);
     Expect.equals(expectedElementCount, map(visitor).length,
         "${map(visitor).values} for '$statement' in context of `$script`");
diff --git a/tests/compiler/dart2js/semantic_visitor_test.dart b/tests/compiler/dart2js/semantic_visitor_test.dart
index 69fad43..19c1694 100644
--- a/tests/compiler/dart2js/semantic_visitor_test.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test.dart
@@ -1,706 +1,706 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file

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

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

-

-library dart2js.semantics_visitor_test;

-

-import 'dart:async';

-import 'dart:mirrors';

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

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

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

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

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

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

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

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

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

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

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

-import 'memory_compiler.dart';

-

-part 'semantic_visitor_test_send_data.dart';

-part 'semantic_visitor_test_send_visitor.dart';

-part 'semantic_visitor_test_decl_data.dart';

-part 'semantic_visitor_test_decl_visitor.dart';

-

-class Visit {

-  final VisitKind method;

-  final element;

-  final rhs;

-  final arguments;

-  final receiver;

-  final name;

-  final expression;

-  final left;

-  final right;

-  final type;

-  final operator;

-  final index;

-  final getter;

-  final setter;

-  final constant;

-  final selector;

-  final parameters;

-  final body;

-  final target;

-  final targetType;

-  final initializers;

-

-  const Visit(this.method,

-              {this.element,

-               this.rhs,

-               this.arguments,

-               this.receiver,

-               this.name,

-               this.expression,

-               this.left,

-               this.right,

-               this.type,

-               this.operator,

-               this.index,

-               this.getter,

-               this.setter,

-               this.constant,

-               this.selector,

-               this.parameters,

-               this.body,

-               this.target,

-               this.targetType,

-               this.initializers});

-

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

-

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

-

-  String toString() {

-    StringBuffer sb = new StringBuffer();

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

-    if (element != null) {

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

-    }

-    if (rhs != null) {

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

-    }

-    if (arguments != null) {

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

-    }

-    if (receiver != null) {

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

-    }

-    if (name != null) {

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

-    }

-    if (expression != null) {

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

-    }

-    if (left != null) {

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

-    }

-    if (right != null) {

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

-    }

-    if (type != null) {

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

-    }

-    if (operator != null) {

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

-    }

-    if (index != null) {

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

-    }

-    if (getter != null) {

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

-    }

-    if (setter != null) {

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

-    }

-    if (constant != null) {

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

-    }

-    if (selector != null) {

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

-    }

-    if (parameters != null) {

-      sb.write(',parameters=$parameters');

-    }

-    if (body != null) {

-      sb.write(',body=$body');

-    }

-    if (target != null) {

-      sb.write(',target=$target');

-    }

-    if (targetType != null) {

-      sb.write(',targetType=$targetType');

-    }

-    if (initializers != null) {

-      sb.write(',initializers=$initializers');

-    }

-    return sb.toString();

-  }

-}

-

-class Test {

-  final String codeByPrefix;

-  final String code;

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

-  final String cls;

-  final String method;

-

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

-      : cls = null, method = 'm', codeByPrefix = null;

-  const Test.clazz(this.code, this.expectedVisits,

-                   {this.cls: 'C', this.method: 'm'})

-      : codeByPrefix = null;

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

-      : cls = null, method = 'm';

-

-  String toString() {

-    StringBuffer sb = new StringBuffer();

-    sb.writeln();

-    sb.writeln(code);

-    if (codeByPrefix != null) {

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

-      sb.writeln(codeByPrefix);

-    }

-    return sb.toString();

-  }

-}

-

-const List<VisitKind> UNTESTABLE_KINDS = const <VisitKind>[

-  // A final field shadowing a non-final field is currently not supported in

-  // resolution.

-  VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,

-  VisitKind.VISIT_SUPER_FIELD_FIELD_PREFIX,

-  VisitKind.VISIT_SUPER_FIELD_FIELD_POSTFIX,

-  // Combination of method and setter with the same name is currently not

-  // supported by the element model.

-  VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,

-  VisitKind.VISIT_STATIC_METHOD_SETTER_PREFIX,

-  VisitKind.VISIT_STATIC_METHOD_SETTER_POSTFIX,

-  VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,

-  VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,

-  VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,

-  VisitKind.VISIT_SUPER_METHOD_SETTER_COMPOUND,

-  VisitKind.VISIT_SUPER_METHOD_SETTER_PREFIX,

-  VisitKind.VISIT_SUPER_METHOD_SETTER_POSTFIX,

-  // The constant expressions of assignment to constant type literals cannot be

-  // handled the compile constant evaluator.

-  VisitKind.VISIT_CLASS_TYPE_LITERAL_SET,

-  VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET,

-  VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET,

-  // Invalid assignments is currently report through an erroneous element.

-  VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,

-  VisitKind.VISIT_FINAL_PARAMETER_SET,

-  VisitKind.VISIT_FINAL_LOCAL_VARIABLE_SET,

-  VisitKind.VISIT_LOCAL_FUNCTION_SET,

-  VisitKind.VISIT_STATIC_GETTER_SET,

-  VisitKind.VISIT_FINAL_STATIC_FIELD_SET,

-  VisitKind.VISIT_STATIC_FUNCTION_SET,

-  VisitKind.VISIT_FINAL_TOP_LEVEL_FIELD_SET,

-  VisitKind.VISIT_TOP_LEVEL_GETTER_SET,

-  VisitKind.VISIT_TOP_LEVEL_FUNCTION_SET,

-  VisitKind.VISIT_FINAL_SUPER_FIELD_SET,

-  VisitKind.VISIT_SUPER_GETTER_SET,

-  VisitKind.VISIT_SUPER_METHOD_SET,

-  // The only undefined unary, `+`, is currently handled and skipped in the

-  // parser.

-  VisitKind.ERROR_UNDEFINED_UNARY_EXPRESSION,

-  // Constant expression are currently not computed during resolution.

-  VisitKind.VISIT_CONSTANT_GET,

-  VisitKind.VISIT_CONSTANT_INVOKE,

-];

-

-main(List<String> arguments) {

-  Set<VisitKind> kinds = new Set<VisitKind>.from(VisitKind.values);

-  asyncTest(() => Future.forEach([

-    () {

-      return test(

-          kinds,

-          arguments,

-          SEND_TESTS,

-          (elements) => new SemanticSendTestVisitor(elements));

-    },

-    () {

-      return test(

-          kinds,

-          arguments,

-          DECL_TESTS,

-          (elements) => new SemanticDeclarationTestVisitor(elements));

-    },

-    () {

-      Set<VisitKind> unvisitedKindSet =

-          kinds.toSet()..removeAll(UNTESTABLE_KINDS);

-      List<VisitKind> unvisitedKindList = unvisitedKindSet.toList();

-      unvisitedKindList..sort((a, b) => a.index.compareTo(b.index));

-

-      Expect.isTrue(unvisitedKindList.isEmpty,

-          "Untested visit kinds:\n  ${unvisitedKindList.join(',\n  ')},\n");

-

-      Set<VisitKind> testedUntestableKinds =

-          UNTESTABLE_KINDS.toSet()..removeAll(kinds);

-      Expect.isTrue(testedUntestableKinds.isEmpty,

-          "Tested untestable visit kinds (remove from UNTESTABLE_KINDS):\n  "

-          "${testedUntestableKinds.join(',\n  ')},\n");

-    },

-    () {

-      ClassMirror mirror1 = reflectType(SemanticSendTestVisitor);

-      Set<Symbol> symbols1 = mirror1.declarations.keys.toSet();

-      ClassMirror mirror2 = reflectType(SemanticSendVisitor);

-      Set<Symbol> symbols2 =

-          mirror2.declarations.values

-              .where((m) => m is MethodMirror &&

-                            !m.isConstructor &&

-                            m.simpleName != #apply)

-              .map((m) => m.simpleName).toSet();

-      symbols2.removeAll(symbols1);

-      Expect.isTrue(symbols2.isEmpty,

-          "Untested visit methods:\n  ${symbols2.join(',\n  ')},\n");

-    }

-  ], (f) => f()));

-}

-

-Future test(Set<VisitKind> unvisitedKinds,

-            List<String> arguments,

-            Map<String, List<Test>> TESTS,

-            SemanticTestVisitor createVisitor(TreeElements elements)) {

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

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

-  StringBuffer mainSource = new StringBuffer();

-  int index = 0;

-  TESTS.forEach((String group, List<Test> tests) {

-    if (arguments.isNotEmpty && !arguments.contains(group)) return;

-

-    tests.forEach((Test test) {

-      StringBuffer testSource = new StringBuffer();

-      if (test.codeByPrefix != null) {

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

-        sourceFiles[prefixFilename] = test.codeByPrefix;

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

-      }

-

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

-      testSource.writeln(test.code);

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

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

-      testMap[filename] = test;

-      index++;

-    });

-  });

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

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

-

-  Compiler compiler = compilerFor(sourceFiles,

-      options: ['--analyze-all',

-                '--analyze-only',

-                '--enable-null-aware-operators']);

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

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

-      LibraryElement library = compiler.libraryLoader.lookupLibrary(

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

-      Element element;

-      String cls = test.cls;

-      String method = test.method;

-      if (cls == null) {

-        element = library.find(method);

-      } else {

-        ClassElement classElement = library.find(cls);

-        Expect.isNotNull(classElement,

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

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

-        element = classElement.localLookup(method);

-      }

-      var expectedVisits = test.expectedVisits;

-      if (expectedVisits == null) {

-        Expect.isTrue(element.isErroneous,

-            "Element '$method' expected to be have parse errors in:\n"

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

-        return;

-      } else if (expectedVisits is! List) {

-        expectedVisits = [expectedVisits];

-      }

-      Expect.isFalse(element.isErroneous,

-          "Element '$method' is not expected to be have parse errors in:\n"

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

-

-      void testAstElement(AstElement astElement) {

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

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

-        ResolvedAst resolvedAst = astElement.resolvedAst;

-        SemanticTestVisitor visitor = createVisitor(resolvedAst.elements);

-        try {

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

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

-            resolvedAst.node.accept(visitor);

-          });

-        } catch (e, s) {

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

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

-        }

-        Expect.listEquals(expectedVisits, visitor.visits,

-            "In test:\n"

-            "${library.compilationUnit.script.text}\n\n"

-            "Expected: $expectedVisits\n"

-            "Found: ${visitor.visits}");

-        unvisitedKinds.removeAll(visitor.visits.map((visit) => visit.method));

-      }

-      if (element.isAbstractField) {

-        AbstractFieldElement abstractFieldElement = element;

-        if (abstractFieldElement.getter != null) {

-          testAstElement(abstractFieldElement.getter);

-        } else if (abstractFieldElement.setter != null) {

-          testAstElement(abstractFieldElement.setter);

-        }

-      } else {

-        testAstElement(element);

-      }

-    });

-  });

-}

-

-abstract class SemanticTestVisitor extends TraversalVisitor {

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

-

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

-

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

-

-  internalError(Spannable spannable, String message) {

-    throw new SpannableAssertionFailure(spannable, message);

-  }

-}

-

-enum VisitKind {

-  VISIT_PARAMETER_GET,

-  VISIT_PARAMETER_SET,

-  VISIT_PARAMETER_INVOKE,

-  VISIT_PARAMETER_COMPOUND,

-  VISIT_PARAMETER_PREFIX,

-  VISIT_PARAMETER_POSTFIX,

-  VISIT_FINAL_PARAMETER_SET,

-  VISIT_FINAL_PARAMETER_COMPOUND,

-  VISIT_FINAL_PARAMETER_PREFIX,

-  VISIT_FINAL_PARAMETER_POSTFIX,

-

-  VISIT_LOCAL_VARIABLE_GET,

-  VISIT_LOCAL_VARIABLE_SET,

-  VISIT_LOCAL_VARIABLE_INVOKE,

-  VISIT_LOCAL_VARIABLE_COMPOUND,

-  VISIT_LOCAL_VARIABLE_PREFIX,

-  VISIT_LOCAL_VARIABLE_POSTFIX,

-  VISIT_LOCAL_VARIABLE_DECL,

-  VISIT_LOCAL_CONSTANT_DECL,

-  VISIT_FINAL_LOCAL_VARIABLE_SET,

-  VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,

-  VISIT_FINAL_LOCAL_VARIABLE_PREFIX,

-  VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,

-

-  VISIT_LOCAL_FUNCTION_GET,

-  VISIT_LOCAL_FUNCTION_INVOKE,

-  VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,

-  VISIT_LOCAL_FUNCTION_DECL,

-  VISIT_CLOSURE_DECL,

-  VISIT_LOCAL_FUNCTION_SET,

-  VISIT_LOCAL_FUNCTION_COMPOUND,

-  VISIT_LOCAL_FUNCTION_PREFIX,

-  VISIT_LOCAL_FUNCTION_POSTFIX,

-

-  VISIT_STATIC_FIELD_GET,

-  VISIT_STATIC_FIELD_SET,

-  VISIT_STATIC_FIELD_INVOKE,

-  VISIT_STATIC_FIELD_COMPOUND,

-  VISIT_STATIC_FIELD_PREFIX,

-  VISIT_STATIC_FIELD_POSTFIX,

-  VISIT_STATIC_FIELD_DECL,

-  VISIT_STATIC_CONSTANT_DECL,

-

-  VISIT_STATIC_GETTER_GET,

-  VISIT_STATIC_GETTER_SET,

-  VISIT_STATIC_GETTER_INVOKE,

-

-  VISIT_STATIC_SETTER_GET,

-  VISIT_STATIC_SETTER_SET,

-  VISIT_STATIC_SETTER_INVOKE,

-

-  VISIT_STATIC_GETTER_SETTER_COMPOUND,

-  VISIT_STATIC_METHOD_SETTER_COMPOUND,

-  VISIT_STATIC_GETTER_SETTER_PREFIX,

-  VISIT_STATIC_GETTER_SETTER_POSTFIX,

-

-  VISIT_STATIC_GETTER_DECL,

-  VISIT_STATIC_SETTER_DECL,

-

-  VISIT_FINAL_STATIC_FIELD_SET,

-  VISIT_STATIC_FINAL_FIELD_COMPOUND,

-  VISIT_STATIC_FINAL_FIELD_POSTFIX,

-  VISIT_STATIC_FINAL_FIELD_PREFIX,

-

-  VISIT_STATIC_FUNCTION_GET,

-  VISIT_STATIC_FUNCTION_SET,

-  VISIT_STATIC_FUNCTION_INVOKE,

-  VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,

-  VISIT_STATIC_FUNCTION_DECL,

-  VISIT_STATIC_METHOD_SETTER_PREFIX,

-  VISIT_STATIC_METHOD_SETTER_POSTFIX,

-

-  VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,

-  VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,

-  VISIT_STATIC_METHOD_COMPOUND,

-  VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,

-  VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,

-  VISIT_STATIC_METHOD_PREFIX,

-  VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,

-  VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,

-  VISIT_STATIC_METHOD_POSTFIX,

-

-  VISIT_TOP_LEVEL_FIELD_GET,

-  VISIT_TOP_LEVEL_FIELD_SET,

-  VISIT_TOP_LEVEL_FIELD_INVOKE,

-  VISIT_FINAL_TOP_LEVEL_FIELD_SET,

-  VISIT_TOP_LEVEL_FIELD_COMPOUND,

-  VISIT_TOP_LEVEL_FIELD_PREFIX,

-  VISIT_TOP_LEVEL_FIELD_POSTFIX,

-  VISIT_TOP_LEVEL_FIELD_DECL,

-  VISIT_TOP_LEVEL_CONSTANT_DECL,

-  VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,

-  VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,

-  VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,

-

-  VISIT_TOP_LEVEL_GETTER_GET,

-  VISIT_TOP_LEVEL_GETTER_SET,

-  VISIT_TOP_LEVEL_GETTER_INVOKE,

-  VISIT_TOP_LEVEL_SETTER_GET,

-  VISIT_TOP_LEVEL_SETTER_SET,

-  VISIT_TOP_LEVEL_SETTER_INVOKE,

-  VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,

-  VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,

-  VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,

-  VISIT_TOP_LEVEL_GETTER_DECL,

-  VISIT_TOP_LEVEL_SETTER_DECL,

-

-  VISIT_TOP_LEVEL_FUNCTION_GET,

-  VISIT_TOP_LEVEL_FUNCTION_SET,

-  VISIT_TOP_LEVEL_FUNCTION_INVOKE,

-  VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,

-  VISIT_TOP_LEVEL_FUNCTION_DECL,

-  VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,

-  VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,

-  VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,

-

-  VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,

-  VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,

-  VISIT_TOP_LEVEL_METHOD_COMPOUND,

-  VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,

-  VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,

-  VISIT_TOP_LEVEL_METHOD_PREFIX,

-  VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,

-  VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,

-  VISIT_TOP_LEVEL_METHOD_POSTFIX,

-

-  VISIT_DYNAMIC_PROPERTY_GET,

-  VISIT_DYNAMIC_PROPERTY_SET,

-  VISIT_DYNAMIC_PROPERTY_INVOKE,

-  VISIT_DYNAMIC_PROPERTY_COMPOUND,

-  VISIT_DYNAMIC_PROPERTY_PREFIX,

-  VISIT_DYNAMIC_PROPERTY_POSTFIX,

-

-  VISIT_THIS_GET,

-  VISIT_THIS_INVOKE,

-

-  VISIT_THIS_PROPERTY_GET,

-  VISIT_THIS_PROPERTY_SET,

-  VISIT_THIS_PROPERTY_INVOKE,

-  VISIT_THIS_PROPERTY_COMPOUND,

-  VISIT_THIS_PROPERTY_PREFIX,

-  VISIT_THIS_PROPERTY_POSTFIX,

-

-  VISIT_SUPER_FIELD_GET,

-  VISIT_SUPER_FIELD_SET,

-  VISIT_FINAL_SUPER_FIELD_SET,

-  VISIT_SUPER_FIELD_INVOKE,

-  VISIT_SUPER_FIELD_COMPOUND,

-  VISIT_SUPER_FIELD_PREFIX,

-  VISIT_SUPER_FIELD_POSTFIX,

-  VISIT_SUPER_FINAL_FIELD_COMPOUND,

-  VISIT_SUPER_FINAL_FIELD_PREFIX,

-  VISIT_SUPER_FINAL_FIELD_POSTFIX,

-  VISIT_SUPER_FIELD_FIELD_COMPOUND,

-  VISIT_SUPER_FIELD_FIELD_PREFIX,

-  VISIT_SUPER_FIELD_FIELD_POSTFIX,

-

-  VISIT_SUPER_GETTER_GET,

-  VISIT_SUPER_GETTER_SET,

-  VISIT_SUPER_GETTER_INVOKE,

-  VISIT_SUPER_SETTER_GET,

-  VISIT_SUPER_SETTER_SET,

-  VISIT_SUPER_SETTER_INVOKE,

-  VISIT_SUPER_GETTER_SETTER_COMPOUND,

-  VISIT_SUPER_GETTER_FIELD_COMPOUND,

-  VISIT_SUPER_FIELD_SETTER_COMPOUND,

-  VISIT_SUPER_GETTER_SETTER_PREFIX,

-  VISIT_SUPER_GETTER_FIELD_PREFIX,

-  VISIT_SUPER_FIELD_SETTER_PREFIX,

-  VISIT_SUPER_GETTER_SETTER_POSTFIX,

-  VISIT_SUPER_GETTER_FIELD_POSTFIX,

-  VISIT_SUPER_FIELD_SETTER_POSTFIX,

-

-  VISIT_SUPER_METHOD_GET,

-  VISIT_SUPER_METHOD_SET,

-  VISIT_SUPER_METHOD_INVOKE,

-  VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,

-  VISIT_SUPER_METHOD_SETTER_COMPOUND,

-  VISIT_SUPER_METHOD_SETTER_PREFIX,

-  VISIT_SUPER_METHOD_SETTER_POSTFIX,

-  VISIT_SUPER_METHOD_COMPOUND,

-  VISIT_SUPER_METHOD_PREFIX,

-  VISIT_SUPER_METHOD_POSTFIX,

-

-  VISIT_UNRESOLVED_GET,

-  VISIT_UNRESOLVED_SET,

-  VISIT_UNRESOLVED_INVOKE,

-  VISIT_UNRESOLVED_SUPER_GET,

-  VISIT_UNRESOLVED_SUPER_INVOKE,

-

-  VISIT_BINARY,

-  VISIT_INDEX,

-  VISIT_EQUALS,

-  VISIT_NOT_EQUALS,

-  VISIT_INDEX_PREFIX,

-  VISIT_INDEX_POSTFIX,

-

-  VISIT_SUPER_BINARY,

-  VISIT_UNRESOLVED_SUPER_BINARY,

-  VISIT_SUPER_INDEX,

-  VISIT_UNRESOLVED_SUPER_INDEX,

-  VISIT_SUPER_EQUALS,

-  VISIT_SUPER_NOT_EQUALS,

-  VISIT_SUPER_INDEX_PREFIX,

-  VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,

-  VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,

-  VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,

-  VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,

-  VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,

-  VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,

-  VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,

-  VISIT_SUPER_INDEX_POSTFIX,

-  VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,

-  VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,

-  VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,

-  VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,

-  VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,

-

-  VISIT_UNRESOLVED_SUPER_COMPOUND,

-  VISIT_UNRESOLVED_SUPER_PREFIX,

-  VISIT_UNRESOLVED_SUPER_POSTFIX,

-

-  VISIT_UNARY,

-  VISIT_SUPER_UNARY,

-  VISIT_UNRESOLVED_SUPER_UNARY,

-  VISIT_NOT,

-

-  VISIT_EXPRESSION_INVOKE,

-

-  VISIT_CLASS_TYPE_LITERAL_GET,

-  VISIT_CLASS_TYPE_LITERAL_SET,

-  VISIT_CLASS_TYPE_LITERAL_INVOKE,

-  VISIT_CLASS_TYPE_LITERAL_COMPOUND,

-  VISIT_CLASS_TYPE_LITERAL_PREFIX,

-  VISIT_CLASS_TYPE_LITERAL_POSTFIX,

-

-  VISIT_TYPEDEF_TYPE_LITERAL_GET,

-  VISIT_TYPEDEF_TYPE_LITERAL_SET,

-  VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,

-  VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,

-  VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,

-  VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,

-

-  VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,

-  VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,

-  VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,

-  VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

-  VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,

-  VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,

-

-  VISIT_DYNAMIC_TYPE_LITERAL_GET,

-  VISIT_DYNAMIC_TYPE_LITERAL_SET,

-  VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,

-  VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,

-  VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,

-  VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,

-

-  VISIT_INDEX_SET,

-  VISIT_COMPOUND_INDEX_SET,

-  VISIT_SUPER_INDEX_SET,

-  VISIT_UNRESOLVED_SUPER_INDEX_SET,

-  VISIT_SUPER_COMPOUND_INDEX_SET,

-  VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,

-  VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,

-  VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,

-

-  VISIT_ASSERT,

-  VISIT_LOGICAL_AND,

-  VISIT_LOGICAL_OR,

-  VISIT_IS,

-  VISIT_IS_NOT,

-  VISIT_AS,

-

-  VISIT_CONST_CONSTRUCTOR_INVOKE,

-  VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,

-  VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,

-  VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,

-  VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,

-  VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,

-  VISIT_FACTORY_CONSTRUCTOR_INVOKE,

-  VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-  VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,

-  ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,

-

-  VISIT_SUPER_CONSTRUCTOR_INVOKE,

-  VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,

-  VISIT_THIS_CONSTRUCTOR_INVOKE,

-  VISIT_FIELD_INITIALIZER,

-

-  VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,

-  VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,

-  VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,

-  VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-

-  VISIT_INSTANCE_GETTER_DECL,

-  VISIT_INSTANCE_SETTER_DECL,

-  VISIT_INSTANCE_METHOD_DECL,

-  VISIT_ABSTRACT_GETTER_DECL,

-  VISIT_ABSTRACT_SETTER_DECL,

-  VISIT_ABSTRACT_METHOD_DECL,

-  VISIT_INSTANCE_FIELD_DECL,

-

-  VISIT_GENERATIVE_CONSTRUCTOR_DECL,

-  VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,

-  VISIT_FACTORY_CONSTRUCTOR_DECL,

-  VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,

-

-  VISIT_REQUIRED_PARAMETER_DECL,

-  VISIT_OPTIONAL_PARAMETER_DECL,

-  VISIT_NAMED_PARAMETER_DECL,

-  VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,

-  VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,

-  VISIT_NAMED_INITIALIZING_FORMAL_DECL,

-

-  VISIT_UNRESOLVED_COMPOUND,

-  VISIT_UNRESOLVED_PREFIX,

-  VISIT_UNRESOLVED_POSTFIX,

-

-  VISIT_IF_NULL,

-  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,

-  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,

-  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,

-  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,

-  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,

-  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,

-

-  ERROR_INVALID_ASSERT,

-  ERROR_UNDEFINED_UNARY_EXPRESSION,

-  ERROR_UNDEFINED_BINARY_EXPRESSION,

-

-  VISIT_CONSTANT_GET,

-  VISIT_CONSTANT_INVOKE,

-}

+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.semantics_visitor_test;
+
+import 'dart:async';
+import 'dart:mirrors';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/constants/expressions.dart';
+import 'package:compiler/src/dart_types.dart';
+import 'package:compiler/src/dart2jslib.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/resolution/resolution.dart';
+import 'package:compiler/src/resolution/semantic_visitor.dart';
+import 'package:compiler/src/resolution/operators.dart';
+import 'package:compiler/src/tree/tree.dart';
+import 'package:compiler/src/util/util.dart';
+import 'memory_compiler.dart';
+
+part 'semantic_visitor_test_send_data.dart';
+part 'semantic_visitor_test_send_visitor.dart';
+part 'semantic_visitor_test_decl_data.dart';
+part 'semantic_visitor_test_decl_visitor.dart';
+
+class Visit {
+  final VisitKind method;
+  final element;
+  final rhs;
+  final arguments;
+  final receiver;
+  final name;
+  final expression;
+  final left;
+  final right;
+  final type;
+  final operator;
+  final index;
+  final getter;
+  final setter;
+  final constant;
+  final selector;
+  final parameters;
+  final body;
+  final target;
+  final targetType;
+  final initializers;
+
+  const Visit(this.method,
+              {this.element,
+               this.rhs,
+               this.arguments,
+               this.receiver,
+               this.name,
+               this.expression,
+               this.left,
+               this.right,
+               this.type,
+               this.operator,
+               this.index,
+               this.getter,
+               this.setter,
+               this.constant,
+               this.selector,
+               this.parameters,
+               this.body,
+               this.target,
+               this.targetType,
+               this.initializers});
+
+  int get hashCode => toString().hashCode;
+
+  bool operator ==(other) => '$this' == '$other';
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.write('method=$method');
+    if (element != null) {
+      sb.write(',element=$element');
+    }
+    if (rhs != null) {
+      sb.write(',rhs=$rhs');
+    }
+    if (arguments != null) {
+      sb.write(',arguments=$arguments');
+    }
+    if (receiver != null) {
+      sb.write(',receiver=$receiver');
+    }
+    if (name != null) {
+      sb.write(',name=$name');
+    }
+    if (expression != null) {
+      sb.write(',expression=$expression');
+    }
+    if (left != null) {
+      sb.write(',left=$left');
+    }
+    if (right != null) {
+      sb.write(',right=$right');
+    }
+    if (type != null) {
+      sb.write(',type=$type');
+    }
+    if (operator != null) {
+      sb.write(',operator=$operator');
+    }
+    if (index != null) {
+      sb.write(',index=$index');
+    }
+    if (getter != null) {
+      sb.write(',getter=$getter');
+    }
+    if (setter != null) {
+      sb.write(',setter=$setter');
+    }
+    if (constant != null) {
+      sb.write(',constant=$constant');
+    }
+    if (selector != null) {
+      sb.write(',selector=$selector');
+    }
+    if (parameters != null) {
+      sb.write(',parameters=$parameters');
+    }
+    if (body != null) {
+      sb.write(',body=$body');
+    }
+    if (target != null) {
+      sb.write(',target=$target');
+    }
+    if (targetType != null) {
+      sb.write(',targetType=$targetType');
+    }
+    if (initializers != null) {
+      sb.write(',initializers=$initializers');
+    }
+    return sb.toString();
+  }
+}
+
+class Test {
+  final String codeByPrefix;
+  final String code;
+  final /*Visit | List<Visit>*/ expectedVisits;
+  final String cls;
+  final String method;
+
+  const Test(this.code, this.expectedVisits)
+      : cls = null, method = 'm', codeByPrefix = null;
+  const Test.clazz(this.code, this.expectedVisits,
+                   {this.cls: 'C', this.method: 'm'})
+      : codeByPrefix = null;
+  const Test.prefix(this.codeByPrefix, this.code, this.expectedVisits)
+      : cls = null, method = 'm';
+
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    sb.writeln();
+    sb.writeln(code);
+    if (codeByPrefix != null) {
+      sb.writeln('imported by prefix:');
+      sb.writeln(codeByPrefix);
+    }
+    return sb.toString();
+  }
+}
+
+const List<VisitKind> UNTESTABLE_KINDS = const <VisitKind>[
+  // A final field shadowing a non-final field is currently not supported in
+  // resolution.
+  VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,
+  VisitKind.VISIT_SUPER_FIELD_FIELD_PREFIX,
+  VisitKind.VISIT_SUPER_FIELD_FIELD_POSTFIX,
+  // Combination of method and setter with the same name is currently not
+  // supported by the element model.
+  VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+  VisitKind.VISIT_STATIC_METHOD_SETTER_PREFIX,
+  VisitKind.VISIT_STATIC_METHOD_SETTER_POSTFIX,
+  VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,
+  VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,
+  VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,
+  VisitKind.VISIT_SUPER_METHOD_SETTER_COMPOUND,
+  VisitKind.VISIT_SUPER_METHOD_SETTER_PREFIX,
+  VisitKind.VISIT_SUPER_METHOD_SETTER_POSTFIX,
+  // The constant expressions of assignment to constant type literals cannot be
+  // handled the compile constant evaluator.
+  VisitKind.VISIT_CLASS_TYPE_LITERAL_SET,
+  VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET,
+  VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET,
+  // Invalid assignments is currently report through an erroneous element.
+  VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,
+  VisitKind.VISIT_FINAL_PARAMETER_SET,
+  VisitKind.VISIT_FINAL_LOCAL_VARIABLE_SET,
+  VisitKind.VISIT_LOCAL_FUNCTION_SET,
+  VisitKind.VISIT_STATIC_GETTER_SET,
+  VisitKind.VISIT_FINAL_STATIC_FIELD_SET,
+  VisitKind.VISIT_STATIC_FUNCTION_SET,
+  VisitKind.VISIT_FINAL_TOP_LEVEL_FIELD_SET,
+  VisitKind.VISIT_TOP_LEVEL_GETTER_SET,
+  VisitKind.VISIT_TOP_LEVEL_FUNCTION_SET,
+  VisitKind.VISIT_FINAL_SUPER_FIELD_SET,
+  VisitKind.VISIT_SUPER_GETTER_SET,
+  VisitKind.VISIT_SUPER_METHOD_SET,
+  // The only undefined unary, `+`, is currently handled and skipped in the
+  // parser.
+  VisitKind.ERROR_UNDEFINED_UNARY_EXPRESSION,
+  // Constant expression are currently not computed during resolution.
+  VisitKind.VISIT_CONSTANT_GET,
+  VisitKind.VISIT_CONSTANT_INVOKE,
+];
+
+main(List<String> arguments) {
+  Set<VisitKind> kinds = new Set<VisitKind>.from(VisitKind.values);
+  asyncTest(() => Future.forEach([
+    () {
+      return test(
+          kinds,
+          arguments,
+          SEND_TESTS,
+          (elements) => new SemanticSendTestVisitor(elements));
+    },
+    () {
+      return test(
+          kinds,
+          arguments,
+          DECL_TESTS,
+          (elements) => new SemanticDeclarationTestVisitor(elements));
+    },
+    () {
+      Set<VisitKind> unvisitedKindSet =
+          kinds.toSet()..removeAll(UNTESTABLE_KINDS);
+      List<VisitKind> unvisitedKindList = unvisitedKindSet.toList();
+      unvisitedKindList..sort((a, b) => a.index.compareTo(b.index));
+
+      Expect.isTrue(unvisitedKindList.isEmpty,
+          "Untested visit kinds:\n  ${unvisitedKindList.join(',\n  ')},\n");
+
+      Set<VisitKind> testedUntestableKinds =
+          UNTESTABLE_KINDS.toSet()..removeAll(kinds);
+      Expect.isTrue(testedUntestableKinds.isEmpty,
+          "Tested untestable visit kinds (remove from UNTESTABLE_KINDS):\n  "
+          "${testedUntestableKinds.join(',\n  ')},\n");
+    },
+    () {
+      ClassMirror mirror1 = reflectType(SemanticSendTestVisitor);
+      Set<Symbol> symbols1 = mirror1.declarations.keys.toSet();
+      ClassMirror mirror2 = reflectType(SemanticSendVisitor);
+      Set<Symbol> symbols2 =
+          mirror2.declarations.values
+              .where((m) => m is MethodMirror &&
+                            !m.isConstructor &&
+                            m.simpleName != #apply)
+              .map((m) => m.simpleName).toSet();
+      symbols2.removeAll(symbols1);
+      Expect.isTrue(symbols2.isEmpty,
+          "Untested visit methods:\n  ${symbols2.join(',\n  ')},\n");
+    }
+  ], (f) => f()));
+}
+
+Future test(Set<VisitKind> unvisitedKinds,
+            List<String> arguments,
+            Map<String, List<Test>> TESTS,
+            SemanticTestVisitor createVisitor(TreeElements elements)) {
+  Map<String, String> sourceFiles = {};
+  Map<String, Test> testMap = {};
+  StringBuffer mainSource = new StringBuffer();
+  int index = 0;
+  TESTS.forEach((String group, List<Test> tests) {
+    if (arguments.isNotEmpty && !arguments.contains(group)) return;
+
+    tests.forEach((Test test) {
+      StringBuffer testSource = new StringBuffer();
+      if (test.codeByPrefix != null) {
+        String prefixFilename = 'pre$index.dart';
+        sourceFiles[prefixFilename] = test.codeByPrefix;
+        testSource.writeln("import '$prefixFilename' as p;");
+      }
+
+      String filename = 'lib$index.dart';
+      testSource.writeln(test.code);
+      sourceFiles[filename] = testSource.toString();
+      mainSource.writeln("import '$filename';");
+      testMap[filename] = test;
+      index++;
+    });
+  });
+  mainSource.writeln("main() {}");
+  sourceFiles['main.dart'] = mainSource.toString();
+
+  Compiler compiler = compilerFor(sourceFiles,
+      options: ['--analyze-all',
+                '--analyze-only',
+                '--enable-null-aware-operators']);
+  return compiler.run(Uri.parse('memory:main.dart')).then((_) {
+    testMap.forEach((String filename, Test test) {
+      LibraryElement library = compiler.libraryLoader.lookupLibrary(
+          Uri.parse('memory:$filename'));
+      Element element;
+      String cls = test.cls;
+      String method = test.method;
+      if (cls == null) {
+        element = library.find(method);
+      } else {
+        ClassElement classElement = library.find(cls);
+        Expect.isNotNull(classElement,
+                         "Class '$cls' not found in:\n"
+                         "${library.compilationUnit.script.text}");
+        element = classElement.localLookup(method);
+      }
+      var expectedVisits = test.expectedVisits;
+      if (expectedVisits == null) {
+        Expect.isTrue(element.isErroneous,
+            "Element '$method' expected to be have parse errors in:\n"
+            "${library.compilationUnit.script.text}");
+        return;
+      } else if (expectedVisits is! List) {
+        expectedVisits = [expectedVisits];
+      }
+      Expect.isFalse(element.isErroneous,
+          "Element '$method' is not expected to be have parse errors in:\n"
+          "${library.compilationUnit.script.text}");
+
+      void testAstElement(AstElement astElement) {
+        Expect.isNotNull(astElement, "Element '$method' not found in:\n"
+                                     "${library.compilationUnit.script.text}");
+        ResolvedAst resolvedAst = astElement.resolvedAst;
+        SemanticTestVisitor visitor = createVisitor(resolvedAst.elements);
+        try {
+          compiler.withCurrentElement(resolvedAst.element, () {
+            //print(resolvedAst.node.toDebugString());
+            resolvedAst.node.accept(visitor);
+          });
+        } catch (e, s) {
+          Expect.fail("$e:\n$s\nIn test:\n"
+                      "${library.compilationUnit.script.text}");
+        }
+        Expect.listEquals(expectedVisits, visitor.visits,
+            "In test:\n"
+            "${library.compilationUnit.script.text}\n\n"
+            "Expected: $expectedVisits\n"
+            "Found: ${visitor.visits}");
+        unvisitedKinds.removeAll(visitor.visits.map((visit) => visit.method));
+      }
+      if (element.isAbstractField) {
+        AbstractFieldElement abstractFieldElement = element;
+        if (abstractFieldElement.getter != null) {
+          testAstElement(abstractFieldElement.getter);
+        } else if (abstractFieldElement.setter != null) {
+          testAstElement(abstractFieldElement.setter);
+        }
+      } else {
+        testAstElement(element);
+      }
+    });
+  });
+}
+
+abstract class SemanticTestVisitor extends TraversalVisitor {
+  List<Visit> visits = <Visit>[];
+
+  SemanticTestVisitor(TreeElements elements) : super(elements);
+
+  apply(Node node, arg) => node.accept(this);
+
+  internalError(Spannable spannable, String message) {
+    throw new SpannableAssertionFailure(spannable, message);
+  }
+}
+
+enum VisitKind {
+  VISIT_PARAMETER_GET,
+  VISIT_PARAMETER_SET,
+  VISIT_PARAMETER_INVOKE,
+  VISIT_PARAMETER_COMPOUND,
+  VISIT_PARAMETER_PREFIX,
+  VISIT_PARAMETER_POSTFIX,
+  VISIT_FINAL_PARAMETER_SET,
+  VISIT_FINAL_PARAMETER_COMPOUND,
+  VISIT_FINAL_PARAMETER_PREFIX,
+  VISIT_FINAL_PARAMETER_POSTFIX,
+
+  VISIT_LOCAL_VARIABLE_GET,
+  VISIT_LOCAL_VARIABLE_SET,
+  VISIT_LOCAL_VARIABLE_INVOKE,
+  VISIT_LOCAL_VARIABLE_COMPOUND,
+  VISIT_LOCAL_VARIABLE_PREFIX,
+  VISIT_LOCAL_VARIABLE_POSTFIX,
+  VISIT_LOCAL_VARIABLE_DECL,
+  VISIT_LOCAL_CONSTANT_DECL,
+  VISIT_FINAL_LOCAL_VARIABLE_SET,
+  VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,
+  VISIT_FINAL_LOCAL_VARIABLE_PREFIX,
+  VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,
+
+  VISIT_LOCAL_FUNCTION_GET,
+  VISIT_LOCAL_FUNCTION_INVOKE,
+  VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,
+  VISIT_LOCAL_FUNCTION_DECL,
+  VISIT_CLOSURE_DECL,
+  VISIT_LOCAL_FUNCTION_SET,
+  VISIT_LOCAL_FUNCTION_COMPOUND,
+  VISIT_LOCAL_FUNCTION_PREFIX,
+  VISIT_LOCAL_FUNCTION_POSTFIX,
+
+  VISIT_STATIC_FIELD_GET,
+  VISIT_STATIC_FIELD_SET,
+  VISIT_STATIC_FIELD_INVOKE,
+  VISIT_STATIC_FIELD_COMPOUND,
+  VISIT_STATIC_FIELD_PREFIX,
+  VISIT_STATIC_FIELD_POSTFIX,
+  VISIT_STATIC_FIELD_DECL,
+  VISIT_STATIC_CONSTANT_DECL,
+
+  VISIT_STATIC_GETTER_GET,
+  VISIT_STATIC_GETTER_SET,
+  VISIT_STATIC_GETTER_INVOKE,
+
+  VISIT_STATIC_SETTER_GET,
+  VISIT_STATIC_SETTER_SET,
+  VISIT_STATIC_SETTER_INVOKE,
+
+  VISIT_STATIC_GETTER_SETTER_COMPOUND,
+  VISIT_STATIC_METHOD_SETTER_COMPOUND,
+  VISIT_STATIC_GETTER_SETTER_PREFIX,
+  VISIT_STATIC_GETTER_SETTER_POSTFIX,
+
+  VISIT_STATIC_GETTER_DECL,
+  VISIT_STATIC_SETTER_DECL,
+
+  VISIT_FINAL_STATIC_FIELD_SET,
+  VISIT_STATIC_FINAL_FIELD_COMPOUND,
+  VISIT_STATIC_FINAL_FIELD_POSTFIX,
+  VISIT_STATIC_FINAL_FIELD_PREFIX,
+
+  VISIT_STATIC_FUNCTION_GET,
+  VISIT_STATIC_FUNCTION_SET,
+  VISIT_STATIC_FUNCTION_INVOKE,
+  VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,
+  VISIT_STATIC_FUNCTION_DECL,
+  VISIT_STATIC_METHOD_SETTER_PREFIX,
+  VISIT_STATIC_METHOD_SETTER_POSTFIX,
+
+  VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,
+  VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,
+  VISIT_STATIC_METHOD_COMPOUND,
+  VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,
+  VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,
+  VISIT_STATIC_METHOD_PREFIX,
+  VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,
+  VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,
+  VISIT_STATIC_METHOD_POSTFIX,
+
+  VISIT_TOP_LEVEL_FIELD_GET,
+  VISIT_TOP_LEVEL_FIELD_SET,
+  VISIT_TOP_LEVEL_FIELD_INVOKE,
+  VISIT_FINAL_TOP_LEVEL_FIELD_SET,
+  VISIT_TOP_LEVEL_FIELD_COMPOUND,
+  VISIT_TOP_LEVEL_FIELD_PREFIX,
+  VISIT_TOP_LEVEL_FIELD_POSTFIX,
+  VISIT_TOP_LEVEL_FIELD_DECL,
+  VISIT_TOP_LEVEL_CONSTANT_DECL,
+  VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,
+  VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,
+  VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,
+
+  VISIT_TOP_LEVEL_GETTER_GET,
+  VISIT_TOP_LEVEL_GETTER_SET,
+  VISIT_TOP_LEVEL_GETTER_INVOKE,
+  VISIT_TOP_LEVEL_SETTER_GET,
+  VISIT_TOP_LEVEL_SETTER_SET,
+  VISIT_TOP_LEVEL_SETTER_INVOKE,
+  VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,
+  VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,
+  VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,
+  VISIT_TOP_LEVEL_GETTER_DECL,
+  VISIT_TOP_LEVEL_SETTER_DECL,
+
+  VISIT_TOP_LEVEL_FUNCTION_GET,
+  VISIT_TOP_LEVEL_FUNCTION_SET,
+  VISIT_TOP_LEVEL_FUNCTION_INVOKE,
+  VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,
+  VISIT_TOP_LEVEL_FUNCTION_DECL,
+  VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,
+  VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,
+  VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,
+
+  VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,
+  VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,
+  VISIT_TOP_LEVEL_METHOD_COMPOUND,
+  VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,
+  VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,
+  VISIT_TOP_LEVEL_METHOD_PREFIX,
+  VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,
+  VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,
+  VISIT_TOP_LEVEL_METHOD_POSTFIX,
+
+  VISIT_DYNAMIC_PROPERTY_GET,
+  VISIT_DYNAMIC_PROPERTY_SET,
+  VISIT_DYNAMIC_PROPERTY_INVOKE,
+  VISIT_DYNAMIC_PROPERTY_COMPOUND,
+  VISIT_DYNAMIC_PROPERTY_PREFIX,
+  VISIT_DYNAMIC_PROPERTY_POSTFIX,
+
+  VISIT_THIS_GET,
+  VISIT_THIS_INVOKE,
+
+  VISIT_THIS_PROPERTY_GET,
+  VISIT_THIS_PROPERTY_SET,
+  VISIT_THIS_PROPERTY_INVOKE,
+  VISIT_THIS_PROPERTY_COMPOUND,
+  VISIT_THIS_PROPERTY_PREFIX,
+  VISIT_THIS_PROPERTY_POSTFIX,
+
+  VISIT_SUPER_FIELD_GET,
+  VISIT_SUPER_FIELD_SET,
+  VISIT_FINAL_SUPER_FIELD_SET,
+  VISIT_SUPER_FIELD_INVOKE,
+  VISIT_SUPER_FIELD_COMPOUND,
+  VISIT_SUPER_FIELD_PREFIX,
+  VISIT_SUPER_FIELD_POSTFIX,
+  VISIT_SUPER_FINAL_FIELD_COMPOUND,
+  VISIT_SUPER_FINAL_FIELD_PREFIX,
+  VISIT_SUPER_FINAL_FIELD_POSTFIX,
+  VISIT_SUPER_FIELD_FIELD_COMPOUND,
+  VISIT_SUPER_FIELD_FIELD_PREFIX,
+  VISIT_SUPER_FIELD_FIELD_POSTFIX,
+
+  VISIT_SUPER_GETTER_GET,
+  VISIT_SUPER_GETTER_SET,
+  VISIT_SUPER_GETTER_INVOKE,
+  VISIT_SUPER_SETTER_GET,
+  VISIT_SUPER_SETTER_SET,
+  VISIT_SUPER_SETTER_INVOKE,
+  VISIT_SUPER_GETTER_SETTER_COMPOUND,
+  VISIT_SUPER_GETTER_FIELD_COMPOUND,
+  VISIT_SUPER_FIELD_SETTER_COMPOUND,
+  VISIT_SUPER_GETTER_SETTER_PREFIX,
+  VISIT_SUPER_GETTER_FIELD_PREFIX,
+  VISIT_SUPER_FIELD_SETTER_PREFIX,
+  VISIT_SUPER_GETTER_SETTER_POSTFIX,
+  VISIT_SUPER_GETTER_FIELD_POSTFIX,
+  VISIT_SUPER_FIELD_SETTER_POSTFIX,
+
+  VISIT_SUPER_METHOD_GET,
+  VISIT_SUPER_METHOD_SET,
+  VISIT_SUPER_METHOD_INVOKE,
+  VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,
+  VISIT_SUPER_METHOD_SETTER_COMPOUND,
+  VISIT_SUPER_METHOD_SETTER_PREFIX,
+  VISIT_SUPER_METHOD_SETTER_POSTFIX,
+  VISIT_SUPER_METHOD_COMPOUND,
+  VISIT_SUPER_METHOD_PREFIX,
+  VISIT_SUPER_METHOD_POSTFIX,
+
+  VISIT_UNRESOLVED_GET,
+  VISIT_UNRESOLVED_SET,
+  VISIT_UNRESOLVED_INVOKE,
+  VISIT_UNRESOLVED_SUPER_GET,
+  VISIT_UNRESOLVED_SUPER_INVOKE,
+
+  VISIT_BINARY,
+  VISIT_INDEX,
+  VISIT_EQUALS,
+  VISIT_NOT_EQUALS,
+  VISIT_INDEX_PREFIX,
+  VISIT_INDEX_POSTFIX,
+
+  VISIT_SUPER_BINARY,
+  VISIT_UNRESOLVED_SUPER_BINARY,
+  VISIT_SUPER_INDEX,
+  VISIT_UNRESOLVED_SUPER_INDEX,
+  VISIT_SUPER_EQUALS,
+  VISIT_SUPER_NOT_EQUALS,
+  VISIT_SUPER_INDEX_PREFIX,
+  VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,
+  VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,
+  VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,
+  VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,
+  VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,
+  VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,
+  VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,
+  VISIT_SUPER_INDEX_POSTFIX,
+  VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,
+  VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,
+  VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,
+  VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,
+  VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,
+
+  VISIT_UNRESOLVED_SUPER_COMPOUND,
+  VISIT_UNRESOLVED_SUPER_PREFIX,
+  VISIT_UNRESOLVED_SUPER_POSTFIX,
+
+  VISIT_UNARY,
+  VISIT_SUPER_UNARY,
+  VISIT_UNRESOLVED_SUPER_UNARY,
+  VISIT_NOT,
+
+  VISIT_EXPRESSION_INVOKE,
+
+  VISIT_CLASS_TYPE_LITERAL_GET,
+  VISIT_CLASS_TYPE_LITERAL_SET,
+  VISIT_CLASS_TYPE_LITERAL_INVOKE,
+  VISIT_CLASS_TYPE_LITERAL_COMPOUND,
+  VISIT_CLASS_TYPE_LITERAL_PREFIX,
+  VISIT_CLASS_TYPE_LITERAL_POSTFIX,
+
+  VISIT_TYPEDEF_TYPE_LITERAL_GET,
+  VISIT_TYPEDEF_TYPE_LITERAL_SET,
+  VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,
+  VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,
+  VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,
+  VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,
+
+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,
+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,
+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,
+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,
+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,
+  VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,
+
+  VISIT_DYNAMIC_TYPE_LITERAL_GET,
+  VISIT_DYNAMIC_TYPE_LITERAL_SET,
+  VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,
+  VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,
+  VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,
+  VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,
+
+  VISIT_INDEX_SET,
+  VISIT_COMPOUND_INDEX_SET,
+  VISIT_SUPER_INDEX_SET,
+  VISIT_UNRESOLVED_SUPER_INDEX_SET,
+  VISIT_SUPER_COMPOUND_INDEX_SET,
+  VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,
+  VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,
+  VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,
+
+  VISIT_ASSERT,
+  VISIT_LOGICAL_AND,
+  VISIT_LOGICAL_OR,
+  VISIT_IS,
+  VISIT_IS_NOT,
+  VISIT_AS,
+
+  VISIT_CONST_CONSTRUCTOR_INVOKE,
+  VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+  VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+  VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+  VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+  VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
+  VISIT_FACTORY_CONSTRUCTOR_INVOKE,
+  VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+  VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
+  ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,
+
+  VISIT_SUPER_CONSTRUCTOR_INVOKE,
+  VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+  VISIT_THIS_CONSTRUCTOR_INVOKE,
+  VISIT_FIELD_INITIALIZER,
+
+  VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,
+  VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,
+  VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
+  VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+
+  VISIT_INSTANCE_GETTER_DECL,
+  VISIT_INSTANCE_SETTER_DECL,
+  VISIT_INSTANCE_METHOD_DECL,
+  VISIT_ABSTRACT_GETTER_DECL,
+  VISIT_ABSTRACT_SETTER_DECL,
+  VISIT_ABSTRACT_METHOD_DECL,
+  VISIT_INSTANCE_FIELD_DECL,
+
+  VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+  VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,
+  VISIT_FACTORY_CONSTRUCTOR_DECL,
+  VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+
+  VISIT_REQUIRED_PARAMETER_DECL,
+  VISIT_OPTIONAL_PARAMETER_DECL,
+  VISIT_NAMED_PARAMETER_DECL,
+  VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,
+  VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,
+  VISIT_NAMED_INITIALIZING_FORMAL_DECL,
+
+  VISIT_UNRESOLVED_COMPOUND,
+  VISIT_UNRESOLVED_PREFIX,
+  VISIT_UNRESOLVED_POSTFIX,
+
+  VISIT_IF_NULL,
+  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
+  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,
+  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,
+  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,
+  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,
+  VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,
+
+  ERROR_INVALID_ASSERT,
+  ERROR_UNDEFINED_UNARY_EXPRESSION,
+  ERROR_UNDEFINED_BINARY_EXPRESSION,
+
+  VISIT_CONSTANT_GET,
+  VISIT_CONSTANT_INVOKE,
+}
diff --git a/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart b/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
index ab22664..f31b688 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_decl_data.dart
@@ -1,870 +1,870 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file

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

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

-

-part of dart2js.semantics_visitor_test;

-

-const Map<String, List<Test>> DECL_TESTS = const {

-  'Function declarations': const [

-    const Test(

-        '''

-        m(a, b) {}

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '(a,b)',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#b)',

-              index: 1),

-        ]),

-    const Test(

-        '''

-        m(a, [b]) {}

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '(a,[b])',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,

-              element: 'parameter(m#b)',

-              index: 1,

-              constant: 'null'),

-        ]),

-    const Test(

-        '''

-        m(a, [b = null]) {}

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '(a,[b=null])',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,

-              element: 'parameter(m#b)',

-              constant: 'null',

-              index: 1),

-        ]),

-    const Test(

-        '''

-        m(a, [b = 42]) {}

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '(a,[b=42])',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,

-              element: 'parameter(m#b)',

-              constant: 42,

-              index: 1),

-        ]),

-    const Test(

-        '''

-        m(a, {b}) {}

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '(a,{b})',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,

-              element: 'parameter(m#b)',

-              constant: 'null'),

-        ]),

-    const Test(

-        '''

-        m(a, {b: null}) {}

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '(a,{b: null})',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,

-              element: 'parameter(m#b)',

-              constant: 'null'),

-        ]),

-    const Test(

-        '''

-        m(a, {b:42}) {}

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '(a,{b: 42})',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,

-              element: 'parameter(m#b)',

-              constant: 42),

-        ]),

-    const Test(

-        '''

-        get m => null;

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_DECL,

-              element: 'getter(m)',

-              body: '=>null;'),

-        ]),

-    const Test(

-        '''

-        set m(a) {}

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_DECL,

-              element: 'setter(m)',

-              parameters: '(a)',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          static m(a, b) {}

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_STATIC_FUNCTION_DECL,

-              element: 'function(C#m)',

-              parameters: '(a,b)',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#b)',

-              index: 1),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          static get m => null;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_STATIC_GETTER_DECL,

-              element: 'getter(C#m)',

-              body: '=>null;'),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          static set m(a) {}

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_STATIC_SETTER_DECL,

-              element: 'setter(C#m)',

-              parameters: '(a)',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          m(a, b) {}

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_INSTANCE_METHOD_DECL,

-              element: 'function(C#m)',

-              parameters: '(a,b)',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#b)',

-              index: 1),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          get m => null;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_INSTANCE_GETTER_DECL,

-              element: 'getter(C#m)',

-              body: '=>null;'),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          set m(a) {}

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_INSTANCE_SETTER_DECL,

-              element: 'setter(C#m)',

-              parameters: '(a)',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-        ]),

-    const Test.clazz(

-        '''

-        abstract class C {

-          m(a, b);

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_ABSTRACT_METHOD_DECL,

-              element: 'function(C#m)',

-              parameters: '(a,b)'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#b)',

-              index: 1),

-        ]),

-    const Test.clazz(

-        '''

-        abstract class C {

-          get m;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_ABSTRACT_GETTER_DECL,

-              element: 'getter(C#m)'),

-        ]),

-    const Test.clazz(

-        '''

-        abstract class C {

-          set m(a);

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_ABSTRACT_SETTER_DECL,

-              element: 'setter(C#m)',

-              parameters: '(a)'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-        ]),

-    const Test(

-        '''

-        m(a, b) {}

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '(a,b)',

-              body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(m#b)',

-              index: 1),

-        ]),

-    const Test(

-        '''

-        m() {

-          local(a, b) {}

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-               element: 'function(m)',

-               parameters: '()',

-               body: '{local(a,b){}}'),

-          const Visit(VisitKind.VISIT_LOCAL_FUNCTION_DECL,

-               element: 'function(m#local)',

-               parameters: '(a,b)',

-               body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(local#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(local#b)',

-              index: 1),

-        ]),

-    const Test(

-        '''

-        m() => (a, b) {};

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-               element: 'function(m)',

-               parameters: '()',

-               body: '=>(a,b){};'),

-          const Visit(VisitKind.VISIT_CLOSURE_DECL,

-               element: 'function(m#)',

-               parameters: '(a,b)',

-               body: '{}'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#b)',

-              index: 1),

-        ]),

-  ],

-  'Constructor declarations': const [

-    const Test.clazz(

-        '''

-        class C {

-          C(a, b);

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,

-              element: 'generative_constructor(C#)',

-              parameters: '(a,b)',

-              body: ';'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#b)',

-              index: 1),

-          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,

-              element: 'generative_constructor(Object#)',

-              type: 'Object'),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          var b;

-          C(a, this.b);

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,

-              element: 'generative_constructor(C#)',

-              parameters: '(a,this.b)',

-              body: ';'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,

-              element: 'initializing_formal(#b)',

-              index: 1),

-          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,

-              element: 'generative_constructor(Object#)',

-              type: 'Object'),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          var b;

-          C(a, [this.b = 42]);

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,

-              element: 'generative_constructor(C#)',

-              parameters: '(a,[this.b=42])',

-              body: ';'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,

-              element: 'initializing_formal(#b)',

-              constant: 42,

-              index: 1),

-          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,

-              element: 'generative_constructor(Object#)',

-              type: 'Object'),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          var b;

-          C(a, {this.b: 42});

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,

-              element: 'generative_constructor(C#)',

-              parameters: '(a,{this.b: 42})',

-              body: ';'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_NAMED_INITIALIZING_FORMAL_DECL,

-              element: 'initializing_formal(#b)',

-              constant: 42),

-          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,

-              element: 'generative_constructor(Object#)',

-              type: 'Object'),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          C(a, b) : super();

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,

-              element: 'generative_constructor(C#)',

-              parameters: '(a,b)',

-              body: ';'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#b)',

-              index: 1),

-          const Visit(VisitKind.VISIT_SUPER_CONSTRUCTOR_INVOKE,

-              element: 'generative_constructor(Object#)',

-              type: 'Object',

-              arguments: '()',

-              selector: 'CallStructure(arity=0)'),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          var field;

-          C(a, b) : this.field = a;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,

-              element: 'generative_constructor(C#)',

-              parameters: '(a,b)',

-              body: ';'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#b)',

-              index: 1),

-          const Visit(VisitKind.VISIT_FIELD_INITIALIZER,

-              element: 'field(C#field)',

-              rhs: 'a'),

-          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,

-              element: 'generative_constructor(Object#)',

-              type: 'Object'),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          var field1;

-          var field2;

-          C(a, b) : this.field1 = a, this.field2 = b;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,

-              element: 'generative_constructor(C#)',

-              parameters: '(a,b)',

-              body: ';'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#b)',

-              index: 1),

-          const Visit(VisitKind.VISIT_FIELD_INITIALIZER,

-              element: 'field(C#field1)',

-              rhs: 'a'),

-          const Visit(VisitKind.VISIT_FIELD_INITIALIZER,

-              element: 'field(C#field2)',

-              rhs: 'b'),

-          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,

-              element: 'generative_constructor(Object#)',

-              type: 'Object'),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          C(a, b) : this._(a, b);

-          C._(a, b);

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,

-              element: 'generative_constructor(C#)',

-              parameters: '(a,b)',

-              initializers: ':this._(a,b)'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#b)',

-              index: 1),

-          const Visit(VisitKind.VISIT_THIS_CONSTRUCTOR_INVOKE,

-              element: 'generative_constructor(C#_)',

-              arguments: '(a,b)',

-              selector: 'CallStructure(arity=2)'),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          factory C(a, b) => null;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_DECL,

-              element: 'function(C#)',

-              parameters: '(a,b)',

-              body: '=>null;'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#b)',

-              index: 1),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          factory C(a, b) = C._;

-          C._(a, b);

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,

-              element: 'function(C#)',

-              parameters: '(a,b)',

-              target: 'generative_constructor(C#_)',

-              type: 'C'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#b)',

-              index: 1),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          factory C(a, b) = D;

-        }

-        class D<T> {

-          D(a, b);

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,

-              element: 'function(C#)',

-              parameters: '(a,b)',

-              target: 'generative_constructor(D#)',

-              type: 'D'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#b)',

-              index: 1),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          factory C(a, b) = D<int>;

-        }

-        class D<T> {

-          D(a, b);

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,

-              element: 'function(C#)',

-              parameters: '(a,b)',

-              target: 'generative_constructor(D#)',

-              type: 'D<int>'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#b)',

-              index: 1),

-        ],

-        method: ''),

-    const Test.clazz(

-        '''

-        class C {

-          factory C(a, b) = D<int>;

-        }

-        class D<T> {

-          factory D(a, b) = E<D<T>>;

-        }

-        class E<S> {

-          E(a, b);

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,

-              element: 'function(C#)',

-              parameters: '(a,b)',

-              target: 'function(D#)',

-              type: 'D<int>'),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#a)',

-              index: 0),

-          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-              element: 'parameter(#b)',

-              index: 1),

-        ],

-        method: ''),

-  ],

-  "Field declarations": const [

-    const Test.clazz(

-        '''

-        class C {

-          var m;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,

-              element: 'field(C#m)'),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          var m, n;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,

-              element: 'field(C#m)'),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          var m = 42;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,

-              element: 'field(C#m)',

-              rhs: 42),

-        ]),

-    const Test(

-        '''

-        m() {

-          var local;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '()',

-              body: '{var local;}'),

-          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,

-              element: 'variable(m#local)'),

-        ]),

-    const Test(

-        '''

-        m() {

-          var local = 42;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '()',

-              body: '{var local=42;}'),

-          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,

-              element: 'variable(m#local)',

-              rhs: 42),

-        ]),

-    const Test(

-        '''

-        m() {

-          const local = 42;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '()',

-              body: '{const local=42;}'),

-          const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,

-              element: 'variable(m#local)',

-              constant: 42),

-        ]),

-    const Test(

-        '''

-        m() {

-          var local1, local2;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '()',

-              body: '{var local1,local2;}'),

-          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,

-              element: 'variable(m#local1)'),

-          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,

-              element: 'variable(m#local2)'),

-        ]),

-    const Test(

-        '''

-        m() {

-          var local1 = 42, local2 = true;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '()',

-              body: '{var local1=42,local2=true;}'),

-          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,

-              element: 'variable(m#local1)',

-              rhs: 42),

-          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,

-              element: 'variable(m#local2)',

-              rhs: true),

-        ]),

-    const Test(

-        '''

-        m() {

-          const local1 = 42, local2 = true;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-              element: 'function(m)',

-              parameters: '()',

-              body: '{const local1=42,local2=true;}'),

-          const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,

-              element: 'variable(m#local1)',

-              constant: 42),

-          const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,

-              element: 'variable(m#local2)',

-              constant: true),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          static var m;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,

-                element: 'field(C#m)'),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          static var m, n;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,

-                element: 'field(C#m)'),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          static var k, l, m, n;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,

-                element: 'field(C#m)'),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          static var m = 42;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,

-                element: 'field(C#m)',

-                rhs: 42),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          static var m = 42, n = true;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,

-                element: 'field(C#m)',

-                rhs: 42),

-        ]),

-    const Test.clazz(

-        '''

-        class C {

-          static const m = 42;

-        }

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_STATIC_CONSTANT_DECL,

-                element: 'field(C#m)',

-                constant: 42),

-        ]),

-    const Test(

-        '''

-        var m;

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,

-                element: 'field(m)'),

-        ]),

-    const Test(

-        '''

-        var m, n;

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,

-                element: 'field(m)'),

-        ]),

-    const Test(

-        '''

-        var m = 42;

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,

-                element: 'field(m)',

-                rhs: 42),

-        ]),

-    const Test(

-        '''

-        const m = 42;

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_TOP_LEVEL_CONSTANT_DECL,

-                element: 'field(m)',

-                constant: 42),

-        ]),

-  ],

-};

+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart2js.semantics_visitor_test;
+
+const Map<String, List<Test>> DECL_TESTS = const {
+  'Function declarations': const [
+    const Test(
+        '''
+        m(a, b) {}
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '(a,b)',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#b)',
+              index: 1),
+        ]),
+    const Test(
+        '''
+        m(a, [b]) {}
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '(a,[b])',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
+              element: 'parameter(m#b)',
+              index: 1,
+              constant: 'null'),
+        ]),
+    const Test(
+        '''
+        m(a, [b = null]) {}
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '(a,[b=null])',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
+              element: 'parameter(m#b)',
+              constant: 'null',
+              index: 1),
+        ]),
+    const Test(
+        '''
+        m(a, [b = 42]) {}
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '(a,[b=42])',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
+              element: 'parameter(m#b)',
+              constant: 42,
+              index: 1),
+        ]),
+    const Test(
+        '''
+        m(a, {b}) {}
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '(a,{b})',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
+              element: 'parameter(m#b)',
+              constant: 'null'),
+        ]),
+    const Test(
+        '''
+        m(a, {b: null}) {}
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '(a,{b: null})',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
+              element: 'parameter(m#b)',
+              constant: 'null'),
+        ]),
+    const Test(
+        '''
+        m(a, {b:42}) {}
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '(a,{b: 42})',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
+              element: 'parameter(m#b)',
+              constant: 42),
+        ]),
+    const Test(
+        '''
+        get m => null;
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_DECL,
+              element: 'getter(m)',
+              body: '=>null;'),
+        ]),
+    const Test(
+        '''
+        set m(a) {}
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_DECL,
+              element: 'setter(m)',
+              parameters: '(a)',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          static m(a, b) {}
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_STATIC_FUNCTION_DECL,
+              element: 'function(C#m)',
+              parameters: '(a,b)',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#b)',
+              index: 1),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          static get m => null;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_STATIC_GETTER_DECL,
+              element: 'getter(C#m)',
+              body: '=>null;'),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          static set m(a) {}
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_STATIC_SETTER_DECL,
+              element: 'setter(C#m)',
+              parameters: '(a)',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          m(a, b) {}
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_INSTANCE_METHOD_DECL,
+              element: 'function(C#m)',
+              parameters: '(a,b)',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#b)',
+              index: 1),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          get m => null;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_INSTANCE_GETTER_DECL,
+              element: 'getter(C#m)',
+              body: '=>null;'),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          set m(a) {}
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_INSTANCE_SETTER_DECL,
+              element: 'setter(C#m)',
+              parameters: '(a)',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+        ]),
+    const Test.clazz(
+        '''
+        abstract class C {
+          m(a, b);
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_ABSTRACT_METHOD_DECL,
+              element: 'function(C#m)',
+              parameters: '(a,b)'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#b)',
+              index: 1),
+        ]),
+    const Test.clazz(
+        '''
+        abstract class C {
+          get m;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_ABSTRACT_GETTER_DECL,
+              element: 'getter(C#m)'),
+        ]),
+    const Test.clazz(
+        '''
+        abstract class C {
+          set m(a);
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_ABSTRACT_SETTER_DECL,
+              element: 'setter(C#m)',
+              parameters: '(a)'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+        ]),
+    const Test(
+        '''
+        m(a, b) {}
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '(a,b)',
+              body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(m#b)',
+              index: 1),
+        ]),
+    const Test(
+        '''
+        m() {
+          local(a, b) {}
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+               element: 'function(m)',
+               parameters: '()',
+               body: '{local(a,b){}}'),
+          const Visit(VisitKind.VISIT_LOCAL_FUNCTION_DECL,
+               element: 'function(m#local)',
+               parameters: '(a,b)',
+               body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(local#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(local#b)',
+              index: 1),
+        ]),
+    const Test(
+        '''
+        m() => (a, b) {};
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+               element: 'function(m)',
+               parameters: '()',
+               body: '=>(a,b){};'),
+          const Visit(VisitKind.VISIT_CLOSURE_DECL,
+               element: 'function(m#)',
+               parameters: '(a,b)',
+               body: '{}'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#b)',
+              index: 1),
+        ]),
+  ],
+  'Constructor declarations': const [
+    const Test.clazz(
+        '''
+        class C {
+          C(a, b);
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+              element: 'generative_constructor(C#)',
+              parameters: '(a,b)',
+              body: ';'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#b)',
+              index: 1),
+          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+              element: 'generative_constructor(Object#)',
+              type: 'Object'),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          var b;
+          C(a, this.b);
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+              element: 'generative_constructor(C#)',
+              parameters: '(a,this.b)',
+              body: ';'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,
+              element: 'initializing_formal(#b)',
+              index: 1),
+          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+              element: 'generative_constructor(Object#)',
+              type: 'Object'),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          var b;
+          C(a, [this.b = 42]);
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+              element: 'generative_constructor(C#)',
+              parameters: '(a,[this.b=42])',
+              body: ';'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,
+              element: 'initializing_formal(#b)',
+              constant: 42,
+              index: 1),
+          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+              element: 'generative_constructor(Object#)',
+              type: 'Object'),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          var b;
+          C(a, {this.b: 42});
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+              element: 'generative_constructor(C#)',
+              parameters: '(a,{this.b: 42})',
+              body: ';'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_NAMED_INITIALIZING_FORMAL_DECL,
+              element: 'initializing_formal(#b)',
+              constant: 42),
+          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+              element: 'generative_constructor(Object#)',
+              type: 'Object'),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          C(a, b) : super();
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+              element: 'generative_constructor(C#)',
+              parameters: '(a,b)',
+              body: ';'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#b)',
+              index: 1),
+          const Visit(VisitKind.VISIT_SUPER_CONSTRUCTOR_INVOKE,
+              element: 'generative_constructor(Object#)',
+              type: 'Object',
+              arguments: '()',
+              selector: 'CallStructure(arity=0)'),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          var field;
+          C(a, b) : this.field = a;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+              element: 'generative_constructor(C#)',
+              parameters: '(a,b)',
+              body: ';'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#b)',
+              index: 1),
+          const Visit(VisitKind.VISIT_FIELD_INITIALIZER,
+              element: 'field(C#field)',
+              rhs: 'a'),
+          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+              element: 'generative_constructor(Object#)',
+              type: 'Object'),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          var field1;
+          var field2;
+          C(a, b) : this.field1 = a, this.field2 = b;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+              element: 'generative_constructor(C#)',
+              parameters: '(a,b)',
+              body: ';'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#b)',
+              index: 1),
+          const Visit(VisitKind.VISIT_FIELD_INITIALIZER,
+              element: 'field(C#field1)',
+              rhs: 'a'),
+          const Visit(VisitKind.VISIT_FIELD_INITIALIZER,
+              element: 'field(C#field2)',
+              rhs: 'b'),
+          const Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+              element: 'generative_constructor(Object#)',
+              type: 'Object'),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          C(a, b) : this._(a, b);
+          C._(a, b);
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,
+              element: 'generative_constructor(C#)',
+              parameters: '(a,b)',
+              initializers: ':this._(a,b)'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#b)',
+              index: 1),
+          const Visit(VisitKind.VISIT_THIS_CONSTRUCTOR_INVOKE,
+              element: 'generative_constructor(C#_)',
+              arguments: '(a,b)',
+              selector: 'CallStructure(arity=2)'),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          factory C(a, b) => null;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_DECL,
+              element: 'function(C#)',
+              parameters: '(a,b)',
+              body: '=>null;'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#b)',
+              index: 1),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          factory C(a, b) = C._;
+          C._(a, b);
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+              element: 'function(C#)',
+              parameters: '(a,b)',
+              target: 'generative_constructor(C#_)',
+              type: 'C'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#b)',
+              index: 1),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          factory C(a, b) = D;
+        }
+        class D<T> {
+          D(a, b);
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+              element: 'function(C#)',
+              parameters: '(a,b)',
+              target: 'generative_constructor(D#)',
+              type: 'D'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#b)',
+              index: 1),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          factory C(a, b) = D<int>;
+        }
+        class D<T> {
+          D(a, b);
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+              element: 'function(C#)',
+              parameters: '(a,b)',
+              target: 'generative_constructor(D#)',
+              type: 'D<int>'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#b)',
+              index: 1),
+        ],
+        method: ''),
+    const Test.clazz(
+        '''
+        class C {
+          factory C(a, b) = D<int>;
+        }
+        class D<T> {
+          factory D(a, b) = E<D<T>>;
+        }
+        class E<S> {
+          E(a, b);
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+              element: 'function(C#)',
+              parameters: '(a,b)',
+              target: 'function(D#)',
+              type: 'D<int>'),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#a)',
+              index: 0),
+          const Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+              element: 'parameter(#b)',
+              index: 1),
+        ],
+        method: ''),
+  ],
+  "Field declarations": const [
+    const Test.clazz(
+        '''
+        class C {
+          var m;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
+              element: 'field(C#m)'),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          var m, n;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
+              element: 'field(C#m)'),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          var m = 42;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
+              element: 'field(C#m)',
+              rhs: 42),
+        ]),
+    const Test(
+        '''
+        m() {
+          var local;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '()',
+              body: '{var local;}'),
+          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+              element: 'variable(m#local)'),
+        ]),
+    const Test(
+        '''
+        m() {
+          var local = 42;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '()',
+              body: '{var local=42;}'),
+          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+              element: 'variable(m#local)',
+              rhs: 42),
+        ]),
+    const Test(
+        '''
+        m() {
+          const local = 42;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '()',
+              body: '{const local=42;}'),
+          const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
+              element: 'variable(m#local)',
+              constant: 42),
+        ]),
+    const Test(
+        '''
+        m() {
+          var local1, local2;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '()',
+              body: '{var local1,local2;}'),
+          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+              element: 'variable(m#local1)'),
+          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+              element: 'variable(m#local2)'),
+        ]),
+    const Test(
+        '''
+        m() {
+          var local1 = 42, local2 = true;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '()',
+              body: '{var local1=42,local2=true;}'),
+          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+              element: 'variable(m#local1)',
+              rhs: 42),
+          const Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+              element: 'variable(m#local2)',
+              rhs: true),
+        ]),
+    const Test(
+        '''
+        m() {
+          const local1 = 42, local2 = true;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+              element: 'function(m)',
+              parameters: '()',
+              body: '{const local1=42,local2=true;}'),
+          const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
+              element: 'variable(m#local1)',
+              constant: 42),
+          const Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
+              element: 'variable(m#local2)',
+              constant: true),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          static var m;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+                element: 'field(C#m)'),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          static var m, n;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+                element: 'field(C#m)'),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          static var k, l, m, n;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+                element: 'field(C#m)'),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          static var m = 42;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+                element: 'field(C#m)',
+                rhs: 42),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          static var m = 42, n = true;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+                element: 'field(C#m)',
+                rhs: 42),
+        ]),
+    const Test.clazz(
+        '''
+        class C {
+          static const m = 42;
+        }
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_STATIC_CONSTANT_DECL,
+                element: 'field(C#m)',
+                constant: 42),
+        ]),
+    const Test(
+        '''
+        var m;
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
+                element: 'field(m)'),
+        ]),
+    const Test(
+        '''
+        var m, n;
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
+                element: 'field(m)'),
+        ]),
+    const Test(
+        '''
+        var m = 42;
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
+                element: 'field(m)',
+                rhs: 42),
+        ]),
+    const Test(
+        '''
+        const m = 42;
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_TOP_LEVEL_CONSTANT_DECL,
+                element: 'field(m)',
+                constant: 42),
+        ]),
+  ],
+};
diff --git a/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart b/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart
index 253f1f3..5382a29 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_decl_visitor.dart
@@ -1,483 +1,483 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file

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

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

-

-part of dart2js.semantics_visitor_test;

-

-class SemanticDeclarationTestVisitor extends SemanticTestVisitor {

-

-  SemanticDeclarationTestVisitor(TreeElements elements) : super(elements);

-

-  @override

-  errorUnresolvedSuperConstructorInvoke(

-      Send node,

-      Element element,

-      NodeList arguments,

-      Selector selector,

-      arg) {

-    // TODO: implement errorUnresolvedSuperConstructorInvoke

-  }

-

-  @override

-  errorUnresolvedThisConstructorInvoke(

-      Send node,

-      Element element,

-      NodeList arguments,

-      Selector selector,

-      arg) {

-    // TODO: implement errorUnresolvedThisConstructorInvoke

-  }

-

-  @override

-  visitAbstractMethodDeclaration(

-      FunctionExpression node,

-      MethodElement method,

-      NodeList parameters,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_ABSTRACT_METHOD_DECL,

-        element: method, parameters: parameters));

-    applyParameters(parameters, arg);

-  }

-

-  @override

-  visitClosureDeclaration(

-      FunctionExpression node,

-      LocalFunctionElement function,

-      NodeList parameters,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_CLOSURE_DECL,

-        element: function, parameters: parameters, body: body));

-    applyParameters(parameters, arg);

-    apply(body, arg);

-  }

-

-  @override

-  visitFactoryConstructorDeclaration(

-      FunctionExpression node,

-      ConstructorElement constructor,

-      NodeList parameters,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_DECL,

-        element: constructor, parameters: parameters, body: body));

-    applyParameters(parameters, arg);

-    apply(body, arg);

-  }

-

-  @override

-  visitFieldInitializer(

-      SendSet node,

-      FieldElement field,

-      Node initializer,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FIELD_INITIALIZER,

-        element: field, rhs: initializer));

-    apply(initializer, arg);

-  }

-

-  @override

-  visitGenerativeConstructorDeclaration(

-      FunctionExpression node,

-      ConstructorElement constructor,

-      NodeList parameters,

-      NodeList initializers,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,

-        element: constructor, parameters: parameters, body: body));

-    applyParameters(parameters, arg);

-    applyInitializers(node, arg);

-    apply(body, arg);

-  }

-

-  @override

-  visitInstanceMethodDeclaration(

-      FunctionExpression node,

-      MethodElement method,

-      NodeList parameters,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_INSTANCE_METHOD_DECL,

-        element: method, parameters: parameters, body: body));

-    applyParameters(parameters, arg);

-    apply(body, arg);

-  }

-

-  @override

-  visitLocalFunctionDeclaration(

-      FunctionExpression node,

-      LocalFunctionElement function,

-      NodeList parameters,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_DECL,

-        element: function, parameters: parameters, body: body));

-    applyParameters(parameters, arg);

-    apply(body, arg);

-  }

-

-  @override

-  visitRedirectingFactoryConstructorDeclaration(

-      FunctionExpression node,

-      ConstructorElement constructor,

-      NodeList parameters,

-      InterfaceType redirectionType,

-      ConstructorElement redirectionTarget,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,

-        element: constructor,

-        parameters: parameters,

-        target: redirectionTarget,

-        type: redirectionType));

-    applyParameters(parameters, arg);

-  }

-

-  @override

-  visitRedirectingGenerativeConstructorDeclaration(

-      FunctionExpression node,

-      ConstructorElement constructor,

-      NodeList parameters,

-      NodeList initializers,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,

-        element: constructor,

-        parameters: parameters,

-        initializers: initializers));

-    applyParameters(parameters, arg);

-    applyInitializers(node, arg);

-  }

-

-  @override

-  visitStaticFunctionDeclaration(

-      FunctionExpression node,

-      MethodElement function,

-      NodeList parameters,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_DECL,

-        element: function, parameters: parameters, body: body));

-    applyParameters(parameters, arg);

-    apply(body, arg);

-  }

-

-  @override

-  visitSuperConstructorInvoke(

-      Send node,

-      ConstructorElement superConstructor,

-      InterfaceType type,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_CONSTRUCTOR_INVOKE,

-        element: superConstructor, type: type,

-        arguments: arguments, selector: callStructure));

-    super.visitSuperConstructorInvoke(

-        node, superConstructor, type, arguments, callStructure, arg);

-  }

-

-  @override

-  visitImplicitSuperConstructorInvoke(

-      FunctionExpression node,

-      ConstructorElement superConstructor,

-      InterfaceType type,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,

-        element: superConstructor, type: type));

-    super.visitImplicitSuperConstructorInvoke(

-        node, superConstructor, type, arg);

-  }

-

-  @override

-  visitThisConstructorInvoke(

-      Send node,

-      ConstructorElement thisConstructor,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_THIS_CONSTRUCTOR_INVOKE,

-        element: thisConstructor,

-        arguments: arguments, selector: callStructure));

-    super.visitThisConstructorInvoke(

-        node, thisConstructor, arguments, callStructure, arg);

-  }

-

-  @override

-  visitTopLevelFunctionDeclaration(

-      FunctionExpression node,

-      MethodElement function,

-      NodeList parameters,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,

-        element: function, parameters: parameters, body: body));

-    applyParameters(parameters, arg);

-    apply(body, arg);

-  }

-

-  @override

-  errorUnresolvedFieldInitializer(

-      SendSet node,

-      Element element,

-      Node initializer,

-      arg) {

-    // TODO: implement errorUnresolvedFieldInitializer

-  }

-

-  @override

-  visitOptionalParameterDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      ParameterElement parameter,

-      ConstantExpression defaultValue,

-      int index,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,

-        element: parameter,

-        constant: defaultValue != null ? defaultValue.getText() : null,

-        index: index));

-  }

-

-  @override

-  visitParameterDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      ParameterElement parameter,

-      int index,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,

-        element: parameter, index: index));

-  }

-

-  @override

-  visitInitializingFormalDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      InitializingFormalElement initializingFormal,

-      int index,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,

-        element: initializingFormal, index: index));

-  }

-

-  @override

-  visitLocalVariableDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      LocalVariableElement variable,

-      Node initializer,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,

-        element: variable, rhs: initializer));

-    if (initializer != null) {

-      apply(initializer, arg);

-    }

-  }

-

-  @override

-  visitLocalConstantDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      LocalVariableElement variable,

-      ConstantExpression constant,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,

-        element: variable, constant: constant.getText()));

-  }

-

-  @override

-  visitNamedInitializingFormalDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      InitializingFormalElement initializingFormal,

-      ConstantExpression defaultValue,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_NAMED_INITIALIZING_FORMAL_DECL,

-        element: initializingFormal,

-        constant: defaultValue != null ? defaultValue.getText() : null));

-  }

-

-  @override

-  visitNamedParameterDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      ParameterElement parameter,

-      ConstantExpression defaultValue,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,

-        element: parameter,

-        constant: defaultValue != null ? defaultValue.getText() : null));

-  }

-

-  @override

-  visitOptionalInitializingFormalDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      InitializingFormalElement initializingFormal,

-      ConstantExpression defaultValue,

-      int index,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,

-        element: initializingFormal,

-        constant: defaultValue != null ? defaultValue.getText() : null,

-        index: index));

-  }

-

-  @override

-  visitInstanceFieldDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      FieldElement field,

-      Node initializer,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,

-        element: field, rhs: initializer));

-    if (initializer != null) {

-      apply(initializer, arg);

-    }

-  }

-

-  @override

-  visitStaticConstantDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      FieldElement field,

-      ConstantExpression constant,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_CONSTANT_DECL,

-        element: field, constant: constant.getText()));

-  }

-

-  @override

-  visitStaticFieldDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      FieldElement field,

-      Node initializer,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_DECL,

-        element: field, rhs: initializer));

-    if (initializer != null) {

-      apply(initializer, arg);

-    }

-  }

-

-  @override

-  visitTopLevelConstantDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      FieldElement field,

-      ConstantExpression constant,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_CONSTANT_DECL,

-        element: field, constant: constant.getText()));

-  }

-

-  @override

-  visitTopLevelFieldDeclaration(

-      VariableDefinitions node,

-      Node definition,

-      FieldElement field,

-      Node initializer,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,

-        element: field, rhs: initializer));

-    if (initializer != null) {

-      apply(initializer, arg);

-    }

-  }

-

-  @override

-  visitAbstractGetterDeclaration(

-      FunctionExpression node,

-      MethodElement getter,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_ABSTRACT_GETTER_DECL,

-        element: getter));

-  }

-

-  @override

-  visitAbstractSetterDeclaration(

-      FunctionExpression node,

-      MethodElement setter,

-      NodeList parameters,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_ABSTRACT_SETTER_DECL,

-        element: setter, parameters: parameters));

-    applyParameters(parameters, arg);

-  }

-

-  @override

-  visitInstanceGetterDeclaration(

-      FunctionExpression node,

-      MethodElement getter,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_INSTANCE_GETTER_DECL,

-        element: getter, body: body));

-    apply(body, arg);

-  }

-

-  @override

-  visitInstanceSetterDeclaration(

-      FunctionExpression node,

-      MethodElement setter,

-      NodeList parameters,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_INSTANCE_SETTER_DECL,

-        element: setter, parameters: parameters, body: body));

-    applyParameters(parameters, arg);

-    apply(body, arg);

-  }

-

-  @override

-  visitTopLevelGetterDeclaration(

-      FunctionExpression node,

-      MethodElement getter,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_DECL,

-        element: getter, body: body));

-    apply(body, arg);

-  }

-

-  @override

-  visitTopLevelSetterDeclaration(

-      FunctionExpression node,

-      MethodElement setter,

-      NodeList parameters,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_DECL,

-        element: setter, parameters: parameters, body: body));

-    applyParameters(parameters, arg);

-    apply(body, arg);

-  }

-

-  @override

-  visitStaticGetterDeclaration(

-      FunctionExpression node,

-      MethodElement getter,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_DECL,

-        element: getter, body: body));

-    apply(body, arg);

-  }

-

-  @override

-  visitStaticSetterDeclaration(

-      FunctionExpression node,

-      MethodElement setter,

-      NodeList parameters,

-      Node body,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_DECL,

-        element: setter, parameters: parameters, body: body));

-    applyParameters(parameters, arg);

-    apply(body, arg);

-  }

-}

+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart2js.semantics_visitor_test;
+
+class SemanticDeclarationTestVisitor extends SemanticTestVisitor {
+
+  SemanticDeclarationTestVisitor(TreeElements elements) : super(elements);
+
+  @override
+  errorUnresolvedSuperConstructorInvoke(
+      Send node,
+      Element element,
+      NodeList arguments,
+      Selector selector,
+      arg) {
+    // TODO: implement errorUnresolvedSuperConstructorInvoke
+  }
+
+  @override
+  errorUnresolvedThisConstructorInvoke(
+      Send node,
+      Element element,
+      NodeList arguments,
+      Selector selector,
+      arg) {
+    // TODO: implement errorUnresolvedThisConstructorInvoke
+  }
+
+  @override
+  visitAbstractMethodDeclaration(
+      FunctionExpression node,
+      MethodElement method,
+      NodeList parameters,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_ABSTRACT_METHOD_DECL,
+        element: method, parameters: parameters));
+    applyParameters(parameters, arg);
+  }
+
+  @override
+  visitClosureDeclaration(
+      FunctionExpression node,
+      LocalFunctionElement function,
+      NodeList parameters,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_CLOSURE_DECL,
+        element: function, parameters: parameters, body: body));
+    applyParameters(parameters, arg);
+    apply(body, arg);
+  }
+
+  @override
+  visitFactoryConstructorDeclaration(
+      FunctionExpression node,
+      ConstructorElement constructor,
+      NodeList parameters,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_DECL,
+        element: constructor, parameters: parameters, body: body));
+    applyParameters(parameters, arg);
+    apply(body, arg);
+  }
+
+  @override
+  visitFieldInitializer(
+      SendSet node,
+      FieldElement field,
+      Node initializer,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FIELD_INITIALIZER,
+        element: field, rhs: initializer));
+    apply(initializer, arg);
+  }
+
+  @override
+  visitGenerativeConstructorDeclaration(
+      FunctionExpression node,
+      ConstructorElement constructor,
+      NodeList parameters,
+      NodeList initializers,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_DECL,
+        element: constructor, parameters: parameters, body: body));
+    applyParameters(parameters, arg);
+    applyInitializers(node, arg);
+    apply(body, arg);
+  }
+
+  @override
+  visitInstanceMethodDeclaration(
+      FunctionExpression node,
+      MethodElement method,
+      NodeList parameters,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_INSTANCE_METHOD_DECL,
+        element: method, parameters: parameters, body: body));
+    applyParameters(parameters, arg);
+    apply(body, arg);
+  }
+
+  @override
+  visitLocalFunctionDeclaration(
+      FunctionExpression node,
+      LocalFunctionElement function,
+      NodeList parameters,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_DECL,
+        element: function, parameters: parameters, body: body));
+    applyParameters(parameters, arg);
+    apply(body, arg);
+  }
+
+  @override
+  visitRedirectingFactoryConstructorDeclaration(
+      FunctionExpression node,
+      ConstructorElement constructor,
+      NodeList parameters,
+      InterfaceType redirectionType,
+      ConstructorElement redirectionTarget,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_DECL,
+        element: constructor,
+        parameters: parameters,
+        target: redirectionTarget,
+        type: redirectionType));
+    applyParameters(parameters, arg);
+  }
+
+  @override
+  visitRedirectingGenerativeConstructorDeclaration(
+      FunctionExpression node,
+      ConstructorElement constructor,
+      NodeList parameters,
+      NodeList initializers,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_DECL,
+        element: constructor,
+        parameters: parameters,
+        initializers: initializers));
+    applyParameters(parameters, arg);
+    applyInitializers(node, arg);
+  }
+
+  @override
+  visitStaticFunctionDeclaration(
+      FunctionExpression node,
+      MethodElement function,
+      NodeList parameters,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_DECL,
+        element: function, parameters: parameters, body: body));
+    applyParameters(parameters, arg);
+    apply(body, arg);
+  }
+
+  @override
+  visitSuperConstructorInvoke(
+      Send node,
+      ConstructorElement superConstructor,
+      InterfaceType type,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_CONSTRUCTOR_INVOKE,
+        element: superConstructor, type: type,
+        arguments: arguments, selector: callStructure));
+    super.visitSuperConstructorInvoke(
+        node, superConstructor, type, arguments, callStructure, arg);
+  }
+
+  @override
+  visitImplicitSuperConstructorInvoke(
+      FunctionExpression node,
+      ConstructorElement superConstructor,
+      InterfaceType type,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_IMPLICIT_SUPER_CONSTRUCTOR_INVOKE,
+        element: superConstructor, type: type));
+    super.visitImplicitSuperConstructorInvoke(
+        node, superConstructor, type, arg);
+  }
+
+  @override
+  visitThisConstructorInvoke(
+      Send node,
+      ConstructorElement thisConstructor,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_THIS_CONSTRUCTOR_INVOKE,
+        element: thisConstructor,
+        arguments: arguments, selector: callStructure));
+    super.visitThisConstructorInvoke(
+        node, thisConstructor, arguments, callStructure, arg);
+  }
+
+  @override
+  visitTopLevelFunctionDeclaration(
+      FunctionExpression node,
+      MethodElement function,
+      NodeList parameters,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_DECL,
+        element: function, parameters: parameters, body: body));
+    applyParameters(parameters, arg);
+    apply(body, arg);
+  }
+
+  @override
+  errorUnresolvedFieldInitializer(
+      SendSet node,
+      Element element,
+      Node initializer,
+      arg) {
+    // TODO: implement errorUnresolvedFieldInitializer
+  }
+
+  @override
+  visitOptionalParameterDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      ParameterElement parameter,
+      ConstantExpression defaultValue,
+      int index,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_OPTIONAL_PARAMETER_DECL,
+        element: parameter,
+        constant: defaultValue != null ? defaultValue.getText() : null,
+        index: index));
+  }
+
+  @override
+  visitParameterDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      ParameterElement parameter,
+      int index,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_REQUIRED_PARAMETER_DECL,
+        element: parameter, index: index));
+  }
+
+  @override
+  visitInitializingFormalDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      InitializingFormalElement initializingFormal,
+      int index,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_REQUIRED_INITIALIZING_FORMAL_DECL,
+        element: initializingFormal, index: index));
+  }
+
+  @override
+  visitLocalVariableDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      LocalVariableElement variable,
+      Node initializer,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_DECL,
+        element: variable, rhs: initializer));
+    if (initializer != null) {
+      apply(initializer, arg);
+    }
+  }
+
+  @override
+  visitLocalConstantDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      LocalVariableElement variable,
+      ConstantExpression constant,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_CONSTANT_DECL,
+        element: variable, constant: constant.getText()));
+  }
+
+  @override
+  visitNamedInitializingFormalDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      InitializingFormalElement initializingFormal,
+      ConstantExpression defaultValue,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_NAMED_INITIALIZING_FORMAL_DECL,
+        element: initializingFormal,
+        constant: defaultValue != null ? defaultValue.getText() : null));
+  }
+
+  @override
+  visitNamedParameterDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      ParameterElement parameter,
+      ConstantExpression defaultValue,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_NAMED_PARAMETER_DECL,
+        element: parameter,
+        constant: defaultValue != null ? defaultValue.getText() : null));
+  }
+
+  @override
+  visitOptionalInitializingFormalDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      InitializingFormalElement initializingFormal,
+      ConstantExpression defaultValue,
+      int index,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_OPTIONAL_INITIALIZING_FORMAL_DECL,
+        element: initializingFormal,
+        constant: defaultValue != null ? defaultValue.getText() : null,
+        index: index));
+  }
+
+  @override
+  visitInstanceFieldDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      FieldElement field,
+      Node initializer,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_INSTANCE_FIELD_DECL,
+        element: field, rhs: initializer));
+    if (initializer != null) {
+      apply(initializer, arg);
+    }
+  }
+
+  @override
+  visitStaticConstantDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      FieldElement field,
+      ConstantExpression constant,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_CONSTANT_DECL,
+        element: field, constant: constant.getText()));
+  }
+
+  @override
+  visitStaticFieldDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      FieldElement field,
+      Node initializer,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_DECL,
+        element: field, rhs: initializer));
+    if (initializer != null) {
+      apply(initializer, arg);
+    }
+  }
+
+  @override
+  visitTopLevelConstantDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      FieldElement field,
+      ConstantExpression constant,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_CONSTANT_DECL,
+        element: field, constant: constant.getText()));
+  }
+
+  @override
+  visitTopLevelFieldDeclaration(
+      VariableDefinitions node,
+      Node definition,
+      FieldElement field,
+      Node initializer,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_DECL,
+        element: field, rhs: initializer));
+    if (initializer != null) {
+      apply(initializer, arg);
+    }
+  }
+
+  @override
+  visitAbstractGetterDeclaration(
+      FunctionExpression node,
+      MethodElement getter,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_ABSTRACT_GETTER_DECL,
+        element: getter));
+  }
+
+  @override
+  visitAbstractSetterDeclaration(
+      FunctionExpression node,
+      MethodElement setter,
+      NodeList parameters,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_ABSTRACT_SETTER_DECL,
+        element: setter, parameters: parameters));
+    applyParameters(parameters, arg);
+  }
+
+  @override
+  visitInstanceGetterDeclaration(
+      FunctionExpression node,
+      MethodElement getter,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_INSTANCE_GETTER_DECL,
+        element: getter, body: body));
+    apply(body, arg);
+  }
+
+  @override
+  visitInstanceSetterDeclaration(
+      FunctionExpression node,
+      MethodElement setter,
+      NodeList parameters,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_INSTANCE_SETTER_DECL,
+        element: setter, parameters: parameters, body: body));
+    applyParameters(parameters, arg);
+    apply(body, arg);
+  }
+
+  @override
+  visitTopLevelGetterDeclaration(
+      FunctionExpression node,
+      MethodElement getter,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_DECL,
+        element: getter, body: body));
+    apply(body, arg);
+  }
+
+  @override
+  visitTopLevelSetterDeclaration(
+      FunctionExpression node,
+      MethodElement setter,
+      NodeList parameters,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_DECL,
+        element: setter, parameters: parameters, body: body));
+    applyParameters(parameters, arg);
+    apply(body, arg);
+  }
+
+  @override
+  visitStaticGetterDeclaration(
+      FunctionExpression node,
+      MethodElement getter,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_DECL,
+        element: getter, body: body));
+    apply(body, arg);
+  }
+
+  @override
+  visitStaticSetterDeclaration(
+      FunctionExpression node,
+      MethodElement setter,
+      NodeList parameters,
+      Node body,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_DECL,
+        element: setter, parameters: parameters, body: body));
+    applyParameters(parameters, arg);
+    apply(body, arg);
+  }
+}
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
index ebad789..514aa2a 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_send_data.dart
@@ -1,3567 +1,3567 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file

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

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

-

-part of dart2js.semantics_visitor_test;

-

-const Map<String, List<Test>> SEND_TESTS = const {

-  'Parameters': const [

-    // Parameters

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

-        const Visit(VisitKind.VISIT_PARAMETER_GET,

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

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

-        const Visit(VisitKind.VISIT_PARAMETER_SET,

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

-                    rhs:'42')),

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

-        const Visit(VisitKind.VISIT_PARAMETER_INVOKE,

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

-                    arguments: '(null,42)',

-                    selector: 'CallStructure(arity=2)')),

-    // TODO(johnniwinther): Expect [VISIT_FINAL_PARAMETER_SET] instead.

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

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs:'42')),

-  ],

-  'Local variables': const [

-    // Local variables

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

-        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_GET,

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

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

-        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_SET,

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

-                    rhs:'42')),

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

-        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_INVOKE,

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

-                    arguments: '(null,42)',

-                    selector: 'CallStructure(arity=2)')),

-    // TODO(johnniwinther): Expect [VISIT_FINAL_LOCAL_VARIABLE_SET] instead.

-    const Test('m() { final o = 0; o = 42; }',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs:'42')),

-    // TODO(johnniwinther): Expect [VISIT_FINAL_LOCAL_VARIABLE_SET] instead.

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

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs:'42')),

-  ],

-  'Local functions': const [

-    // Local functions

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

-        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_GET,

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

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

-        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_INVOKE,

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

-                    arguments: '(null,42)',

-                    selector: 'CallStructure(arity=2)')),

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

-        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,

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

-                    arguments: '(null,42)',

-                    selector: 'CallStructure(arity=2)')),

-    // TODO(johnniwinther): Expect [VISIT_LOCAL_FUNCTION_SET] instead.

-    const Test('m() { o(a, b) {}; o = 42; }',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-  ],

-  'Static fields': const [

-    // Static fields

-    const Test(

-        '''

-        class C { static var o; }

-        m() => C.o;

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,

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

-    const Test.clazz(

-        '''

-        class C {

-          static var o;

-          m() => o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,

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

-    const Test.clazz(

-        '''

-        class C {

-          static var o;

-          m() => C.o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,

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

-    const Test.prefix(

-        '''

-        class C {

-          static var o;

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,

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

-    const Test(

-        '''

-        class C {

-          var o;

-        }

-        m() => C.o;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_GET,

-                    name: 'o')),

-    const Test(

-        '''

-        class C {

-          C.o();

-        }

-        m() => C.o;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_GET,

-                    name: 'o')),

-    const Test(

-        '''

-        class C {}

-        m() => C.this;

-        ''',

-        null),

-    const Test(

-        '''

-        class C { static var o; }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,

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

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static var o;

-          m() { o = 42; }

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,

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

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static var o;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,

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

-                    rhs: '42')),

-    const Test.prefix(

-        '''

-        class C {

-          static var o;

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,

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

-                    rhs: '42')),

-    const Test(

-        '''

-        class C { static var o; }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static var o;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static var o;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,

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

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

-    const Test.prefix(

-        '''

-        class C {

-          static var o;

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,

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

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

-    const Test(

-        '''

-        class C {}

-        m() => C.this(null, 42);

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

-                    name: 'this', arguments: '(null,42)')),

-    // TODO(johnniwinther): Expect [VISIT_FINAL_STATIC_FIELD_SET] instead.

-    const Test(

-        '''

-        class C { static final o = 0; }

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

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static final o = 0;

-          m() { o = 42; }

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static final o = 0;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.prefix(

-        '''

-        class C {

-          static final o = 0;

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test(

-        '''

-        class C { static const o = 0; }

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

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static const o = 0;

-          m() { o = 42; }

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static const o = 0;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.prefix(

-        '''

-        class C {

-          static const o = 0;

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-  ],

-  'Static properties': const [

-    // Static properties

-    const Test(

-        '''

-        class C {

-          static get o => null;

-        }

-        m() => C.o;

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,

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

-    const Test.clazz(

-        '''

-        class C {

-          static get o => null;

-          m() => o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,

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

-    const Test.clazz(

-        '''

-        class C {

-          static get o => null;

-          m() => C.o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,

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

-    const Test.prefix(

-        '''

-        class C {

-          static get o => null;

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,

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

-    // TODO(johnniwinther): Expected [VISIT_STATIC_GETTER_SET] instead.

-    const Test(

-        '''

-        class C { static get o => 42; }

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

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static get o => 42;

-          m() { o = 42; }

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static get o => 42;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.prefix(

-        '''

-        class C {

-          static get o => 42;

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test(

-        '''

-        class C {

-          static set o(_) {}

-        }

-        m() => C.o;

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_SETTER_GET,

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

-    const Test.clazz(

-        '''

-        class C {

-          static set o(_) {}

-          m() => o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_SETTER_GET,

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

-

-    const Test.clazz(

-        '''

-        class C {

-          static set o(_) {}

-          m() => C.o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_SETTER_GET,

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

-    const Test.prefix(

-        '''

-        class C {

-          static set o(_) {}

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_STATIC_SETTER_GET,

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

-    const Test(

-        '''

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

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,

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

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static set o(_) {}

-          m() { o = 42; }

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,

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

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static set o(_) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,

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

-                    rhs: '42')),

-    const Test.prefix(

-        '''

-        class C {

-          static set o(_) {}

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,

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

-                    rhs: '42')),

-    const Test(

-        '''

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

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static get o => null;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static get o => null;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,

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

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

-    const Test.prefix(

-        '''

-        class C {

-          static get o => null;

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,

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

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

-    const Test(

-        '''

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

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static set o(_) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static set o(_) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,

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

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

-    const Test.prefix(

-        '''

-        class C {

-          static set o(_) {}

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,

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

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

-  ],

-  'Static functions': const [

-    // Static functions

-    const Test(

-        '''

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

-        m() => C.o;

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,

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

-    const Test.clazz(

-        '''

-        class C {

-          static o(a, b) {}

-          m() => o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,

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

-    const Test.clazz(

-        '''

-        class C {

-          static o(a, b) {}

-          m() => C.o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,

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

-    const Test.prefix(

-        '''

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

-        ''',

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,

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

-    // TODO(johnniwinther): Expect [VISIT_STATIC_FUNCTION_SET] instead.

-    const Test(

-        '''

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

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

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static o(a, b) {}

-          m() { o = 42; }

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          static o(a, b) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.prefix(

-        '''

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

-        ''',

-        '''

-        m() { p.C.o = 42; }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test(

-        '''

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

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static o(a, b) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static o(a, b) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,

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

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

-    const Test.prefix(

-        '''

-        class C {

-          static o(a, b) {}

-        }

-        ''',

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

-        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,

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

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

-    const Test(

-        '''

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

-        m() => C.o(null);

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,

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

-                    arguments: '(null)')),

-  ],

-  'Top level fields': const [

-    // Top level fields

-    const Test(

-        '''

-        var o;

-        m() => o;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET,

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

-    const Test.prefix(

-        '''

-        var o;

-        ''',

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

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET,

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

-    const Test(

-        '''

-        var o;

-        m() { o = 42; }

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,

-                    element: 'field(o)',

-                    rhs: '42')),

-    const Test.prefix(

-        '''

-        var o;

-        ''',

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

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,

-                    element: 'field(o)',

-                    rhs: '42')),

-    // TODO(johnniwinther): Expect [VISIT_FINAL_TOP_LEVEL_FIELD_SET] instead.

-    const Test(

-        '''

-        final o = 0;

-        m() { o = 42; }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.prefix(

-        '''

-        final o = 0;

-        ''',

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

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test(

-        '''

-        const o = 0;

-        m() { o = 42; }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.prefix(

-        '''

-        const o = 0;

-        ''',

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

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test(

-        '''

-        var o;

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

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,

-                    element: 'field(o)',

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

-    const Test.prefix(

-        '''

-        var o;

-        ''',

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

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,

-                    element: 'field(o)',

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

-    const Test(

-        '''

-        m() => o;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_GET,

-                    name: 'o')),

-  ],

-  'Top level properties': const [

-    // Top level properties

-    const Test(

-        '''

-        get o => null;

-        m() => o;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,

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

-    const Test.prefix(

-        '''

-        get o => null;

-        ''',

-        '''

-        m() => p.o;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,

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

-    // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_SETTER_GET] instead.

-    const Test(

-        '''

-        set o(_) {}

-        m() => o;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_GET,

-                    element: 'setter(o)')),

-    const Test.prefix(

-        '''

-        set o(_) {}

-        ''',

-        '''

-        m() => p.o;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_GET,

-                    name: 'o')),

-    // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_GETTER_SET] instead.

-    const Test(

-        '''

-        get o => null;

-        m() { o = 42; }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.prefix(

-        '''

-        get o => null;

-        ''',

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

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test(

-        '''

-        set o(_) {}

-        m() { o = 42; }

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,

-                    element: 'setter(o)',

-                    rhs: '42')),

-    const Test.prefix(

-        '''

-        set o(_) {}

-        ''',

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

-        const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,

-                    element: 'setter(o)',

-                    rhs: '42')),

-    const Test(

-        '''

-        get o => null;

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

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,

-                    element: 'getter(o)',

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

-    const Test.prefix(

-        '''

-        get o => null;

-        ''',

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

-        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,

-                    element: 'getter(o)',

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

-    // TODO(johnniwinther): Expected [VISIT_TOP_LEVEL_SETTER_INVOKE] instead.

-    const Test(

-        '''

-        set o(_) {}

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

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_INVOKE,

-                    element: 'setter(o)',

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

-    const Test.prefix(

-        '''

-        set o(_) {}

-        ''',

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

-        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

-                    name: 'o',

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

-  ],

-  'Top level functions': const [

-    // Top level functions

-    const Test(

-        '''

-        o(a, b) {}

-        m() => o;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_GET,

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

-    const Test(

-        '''

-        o(a, b) {}

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

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,

-                    element: 'function(o)',

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

-    const Test(

-        '''

-        o(a, b) {}

-        m() => o(null);

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,

-                    element: 'function(o)',

-                    arguments: '(null)')),

-    const Test.prefix(

-        '''

-        o(a, b) {}

-        ''',

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

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,

-                    element: 'function(o)',

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

-    const Test(

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

-                    name: 'o',

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

-    // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_FUNCTION_SET] instead.

-    const Test(

-        '''

-        o(a, b) {}

-        m() { o = 42; }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.prefix(

-        '''

-        o(a, b) {}

-        ''',

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

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-  ],

-  'Dynamic properties': const [

-    // Dynamic properties

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

-        const [

-          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,

-                      receiver: 'o',

-                      name: 'foo'),

-          const Visit(VisitKind.VISIT_PARAMETER_GET,

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

-        ]),

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

-        const [

-          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,

-                      receiver: 'o',

-                      name: 'foo',

-                      rhs: '42'),

-          const Visit(VisitKind.VISIT_PARAMETER_GET,

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

-        ]),

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

-        const [

-          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,

-                      receiver: 'o',

-                      name: 'foo',

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

-          const Visit(VisitKind.VISIT_PARAMETER_GET,

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

-        ]),

-  ],

-  'This access': const [

-    // This access

-    const Test.clazz(

-        '''

-        class C {

-          m() => this;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_GET)),

-    const Test.clazz(

-        '''

-        class C {

-          call(a, b) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_INVOKE,

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

-  ],

-  'This properties': const [

-    // This properties

-    const Test.clazz(

-        '''

-        class C {

-          var foo;

-          m() => foo;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,

-                    name: 'foo')),

-    const Test.clazz(

-        '''

-        class C {

-          var foo;

-          m() => this.foo;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,

-                    name: 'foo')),

-    const Test.clazz(

-        '''

-        class C {

-          get foo => null;

-          m() => foo;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,

-                    name: 'foo')),

-    const Test.clazz(

-        '''

-        class C {

-          get foo => null;

-          m() => this.foo;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,

-                    name: 'foo')),

-    const Test.clazz(

-        '''

-        class C {

-          var foo;

-          m() { foo = 42; }

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,

-                    name: 'foo',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          var foo;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,

-                    name: 'foo',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          set foo(_) {}

-          m() { foo = 42; }

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,

-                    name: 'foo',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          set foo(_) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,

-                    name: 'foo',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C {

-          var foo;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,

-                    name: 'foo',

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

-    const Test.clazz(

-        '''

-        class C {

-          var foo;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,

-                    name: 'foo',

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

-  ],

-  'Super fields': const [

-    // Super fields

-    const Test.clazz(

-        '''

-        class B {

-          var o;

-        }

-        class C extends B {

-          m() => super.o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FIELD_GET,

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

-    const Test.clazz(

-        '''

-        class B {

-          var o;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FIELD_SET,

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

-                    rhs: '42')),

-    // TODO(johnniwinther): Expect [VISIT_FINAL_SUPER_FIELD_SET] instead.

-    const Test.clazz(

-        '''

-        class B {

-          final o = 0;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class B {

-          var o;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FIELD_INVOKE,

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

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

-    const Test.clazz(

-            '''

-        class B {

-        }

-        class C extends B {

-          m() => super.o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GET)),

-  ],

-  'Super properties': const [

-    // Super properties

-    const Test.clazz(

-        '''

-        class B {

-          get o => null;

-        }

-        class C extends B {

-          m() => super.o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_GETTER_GET,

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

-    const Test.clazz(

-        '''

-        class B {

-          set o(_) {}

-        }

-        class C extends B {

-          m() => super.o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_SETTER_GET,

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

-    // TODO(johnniwinther): Expect [VISIT_SUPER_GETTER_SET] instead.

-    const Test.clazz(

-        '''

-        class B {

-          get o => 0;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                    name: 'o',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class B {

-          set o(_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_SETTER_SET,

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

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class B {

-          get o => null;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,

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

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

-    const Test.clazz(

-        '''

-        class B {

-          set o(_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_SETTER_INVOKE,

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

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

-  ],

-  'Super methods': const [

-    // Super methods

-    const Test.clazz(

-        '''

-        class B {

-          o(a, b) {}

-        }

-        class C extends B {

-          m() => super.o;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_METHOD_GET,

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

-    const Test.clazz(

-        '''

-        class B {

-          o(a, b) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_METHOD_INVOKE,

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

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

-    const Test.clazz(

-        '''

-        class B {

-          o(a, b) {}

-        }

-        class C extends B {

-          m() { super.o(null); }

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,

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

-                    arguments: '(null)')),

-    const Test.clazz(

-            '''

-            class B {

-            }

-            class C extends B {

-              m() => super.o(null, 42);

-            }

-            ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INVOKE,

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

-  ],

-  'Expression invoke': const [

-    // Expression invoke

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

-        const Visit(VisitKind.VISIT_EXPRESSION_INVOKE,

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

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

-  ],

-  'Class type literals': const [

-    // Class type literals

-    const Test(

-        '''

-        class C {}

-        m() => C;

-        ''',

-        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,

-                    constant: 'C')),

-    const Test(

-        '''

-        class C {}

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

-        ''',

-        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,

-                    constant: 'C',

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

-    const Test(

-        '''

-        class C {}

-        m() => C += 42;

-        ''',

-        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,

-                    constant: 'C',

-                    operator: '+=',

-                    rhs: '42')),

-    const Test(

-        '''

-        class C {}

-        m() => ++C;

-        ''',

-        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,

-                    constant: 'C',

-                    operator: '++')),

-    const Test(

-        '''

-        class C {}

-        m() => C--;

-        ''',

-        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_POSTFIX,

-                    constant: 'C',

-                    operator: '--')),

-    const Test(

-        '''

-        class C {}

-        m() => (C).hashCode;

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,

-                      receiver: '(C)', name: 'hashCode'),

-          const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,

-                      constant: 'C'),

-        ]),

-  ],

-  'Typedef type literals': const [

-    // Typedef type literals

-    const Test(

-        '''

-        typedef F();

-        m() => F;

-        ''',

-        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_GET,

-                    constant: 'F')),

-    const Test(

-        '''

-        typedef F();

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

-        ''',

-        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,

-                    constant: 'F',

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

-    const Test(

-        '''

-        typedef F();

-        m() => F += 42;

-        ''',

-        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,

-                    constant: 'F',

-                    operator: '+=',

-                    rhs: '42')),

-    const Test(

-        '''

-        typedef F();

-        m() => ++F;

-        ''',

-        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,

-                    constant: 'F',

-                    operator: '++')),

-    const Test(

-        '''

-        typedef F();

-        m() => F--;

-        ''',

-        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,

-                    constant: 'F',

-                    operator: '--')),

-  ],

-  'Type variable type literals': const [

-    // Type variable type literals

-    const Test.clazz(

-        '''

-        class C<T> {

-          m() => T;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,

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

-    const Test.clazz(

-        '''

-        class C<T> {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,

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

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

-    const Test.clazz(

-        '''

-        class C<T> {

-          m() => T += 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

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

-                    operator: '+=',

-                    rhs: '42')),

-    const Test.clazz(

-        '''

-        class C<T> {

-          m() => ++T;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,

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

-                    operator: '++')),

-    const Test.clazz(

-        '''

-        class C<T> {

-          m() => T--;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,

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

-                    operator: '--')),

-

-  ],

-  'Dynamic type literals': const [

-    // Dynamic type literals

-    const Test(

-        '''

-        m() => dynamic;

-        ''',

-        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_GET,

-                    constant: 'dynamic')),

-    // TODO(johnniwinther): Update these to expect the constant to be `dynamic`

-    // instead of `Type`. Currently the compile time constant evaluator cannot

-    // detect `dynamic` as a constant subexpression.

-    const Test(

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,

-                    constant: 'Type',

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

-    const Test(

-        '''

-        m() => dynamic += 42;

-        ''',

-        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,

-                    constant: 'Type',

-                    operator: '+=',

-                    rhs: '42')),

-    const Test(

-        '''

-        m() => ++dynamic;

-        ''',

-        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,

-                    constant: 'Type',

-                    operator: '++')),

-    const Test(

-        '''

-        m() => dynamic--;

-        ''',

-        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,

-                    constant: 'Type',

-                    operator: '--')),

-  ],

-  'Assert': const [

-    // Assert

-    const Test(

-        '''

-        m() { assert(false); }

-        ''',

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

-    const Test(

-        '''

-        m() { assert(); }

-        ''',

-        const Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: '()')),

-    const Test(

-        '''

-        m() { assert(42, true); }

-        ''',

-        const Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: '(42,true)')),

-  ],

-  'Logical and': const [

-    // Logical and

-    const Test(

-        '''

-        m() => true && false;

-        ''',

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

-  ],

-  'Logical or': const [

-    // Logical or

-    const Test(

-        '''

-        m() => true || false;

-        ''',

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

-  ],

-  'Is test': const [

-    // Is test

-    const Test(

-        '''

-        class C {}

-        m() => 0 is C;

-        ''',

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

-  ],

-  'Is not test': const [

-    // Is not test

-    const Test(

-        '''

-        class C {}

-        m() => 0 is! C;

-        ''',

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

-  ],

-  'As test': const [

-    // As test

-    const Test(

-        '''

-        class C {}

-        m() => 0 as C;

-        ''',

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

-  ],

-  'Binary operators': const [

-    // Binary operators

-    const Test(

-        '''

-        m() => 2 + 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 - 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 * 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 / 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 ~/ 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 % 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 << 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 >> 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 <= 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 < 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 >= 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 > 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 & 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 | 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test(

-        '''

-        m() => 2 ^ 3;

-        ''',

-        const Visit(VisitKind.VISIT_BINARY,

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

-    const Test.clazz(

-        '''

-        class B {

-          operator +(_) => null;

-        }

-        class C extends B {

-          m() => super + 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_BINARY,

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

-                    operator: '+',

-                    right: '42')),

-    const Test.clazz(

-        '''

-        class B {}

-        class C extends B {

-          m() => super + 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_BINARY,

-                    operator: '+',

-                    right: '42')),

-    const Test(

-        '''

-        m() => 2 === 3;

-        ''',

-        const Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,

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

-    const Test(

-        '''

-        m() => 2 !== 3;

-        ''',

-        const Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,

-                    left: '2', operator: '!==', right: '3')),

-  ],

-  'Index': const [

-    // Index

-    const Test(

-        '''

-        m() => 2[3];

-        ''',

-        const Visit(VisitKind.VISIT_INDEX,

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

-    const Test(

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_INDEX_PREFIX,

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

-    const Test(

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_INDEX_POSTFIX,

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

-    const Test.clazz(

-        '''

-        class B {

-          operator [](_) => null;

-        }

-        class C extends B {

-          m() => super[42];

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_INDEX,

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

-                    index: '42')),

-    const Test.clazz(

-        '''

-        class B {

-        }

-        class C extends B {

-          m() => super[42];

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX,

-                    index: '42')),

-    const Test.clazz(

-        '''

-        class B {

-          operator [](_) => null;

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

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_INDEX_PREFIX,

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

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

-                    index: '42',

-                    operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

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

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,

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

-                    index: '42',

-                    operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,

-                    index: '42',

-                    operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

-          operator [](_) => null;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,

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

-                    index: '42',

-                    operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

-          operator [](_) => null;

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

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_INDEX_POSTFIX,

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

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

-                    index: '42',

-                    operator: '--')),

-    const Test.clazz(

-        '''

-        class B {

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

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,

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

-                    index: '42',

-                    operator: '--')),

-    const Test.clazz(

-        '''

-        class B {

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,

-                    index: '42',

-                    operator: '--')),

-    const Test.clazz(

-        '''

-        class B {

-          operator [](_) => null;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,

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

-                    index: '42',

-                    operator: '--')),

-  ],

-  'Equals': const [

-    // Equals

-    const Test(

-        '''

-        m() => 2 == 3;

-        ''',

-        const Visit(VisitKind.VISIT_EQUALS,

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

-    const Test.clazz(

-        '''

-        class B {

-          operator ==(_) => null;

-        }

-        class C extends B {

-          m() => super == 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_EQUALS,

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

-                    right: '42')),

-  ],

-  'Not equals': const [

-    // Not equals

-    const Test(

-        '''

-        m() => 2 != 3;

-        ''',

-        const Visit(VisitKind.VISIT_NOT_EQUALS,

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

-    const Test.clazz(

-        '''

-        class B {

-          operator ==(_) => null;

-        }

-        class C extends B {

-          m() => super != 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_NOT_EQUALS,

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

-                    right: '42')),

-  ],

-  'Unary expression': const [

-    // Unary expression

-    const Test(

-        '''

-        m() => -false;

-        ''',

-        const Visit(VisitKind.VISIT_UNARY,

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

-    const Test(

-        '''

-        m() => ~false;

-        ''',

-        const Visit(VisitKind.VISIT_UNARY,

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

-    const Test.clazz(

-        '''

-        class B {

-          operator -() => null;

-        }

-        class C extends B {

-          m() => -super;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_UNARY,

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

-    const Test.clazz(

-        '''

-        class B {

-        }

-        class C extends B {

-          m() => -super;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_UNARY,

-                    operator: '-')),

-    const Test.clazz(

-        '''

-        class B {

-          operator ~() => null;

-        }

-        class C extends B {

-          m() => ~super;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_UNARY,

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

-    const Test(

-        '''

-        m() => !0;

-        ''',

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

-    const Test(

-        '''

-        m() => +false;

-        ''',

-        // TODO(johnniwinther): Should this be an

-        // ERROR_UNDEFINED_UNARY_EXPRESSION? Currently the parser just skips

-        // the `+`.

-        const []),

-  ],

-  'Index set': const [

-    // Index set

-    const Test(

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_INDEX_SET,

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

-    const Test.clazz(

-        '''

-        class B {

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

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_INDEX_SET,

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

-    const Test.clazz(

-        '''

-        class B {

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_SET,

-            index: '1', rhs: '2')),

-  ],

-  'Compound assignment': const [

-    // Compound assignment

-    const Test(

-        '''

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

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_COMPOUND,

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

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

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

-          const Visit(VisitKind.VISIT_PARAMETER_GET,

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

-        ]),

-    const Test(

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_PARAMETER_COMPOUND,

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

-    const Test(

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_FINAL_PARAMETER_COMPOUND,

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

-    const Test(

-        '''

-        m() {

-          var a;

-          a += 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_COMPOUND,

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

-    const Test(

-        '''

-        m() {

-          final a = 0;

-          a += 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,

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

-    const Test(

-        '''

-        m() {

-          a() {}

-          a += 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_COMPOUND,

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

-    const Test(

-        '''

-        var a;

-        m() => a += 42;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_COMPOUND,

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

-    const Test(

-        '''

-        get a => 0;

-        set a(_) {}

-        m() => a += 42;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,

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

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

-    const Test(

-        '''

-        class C {

-          static var a;

-        }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,

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

-    const Test.clazz(

-        '''

-        class C {

-          static var a;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,

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

-    const Test.clazz(

-        '''

-        class C {

-          static var a;

-          m() => a += 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,

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

-    const Test.prefix(

-        '''

-        class C {

-          static var a;

-        }

-        ''',

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,

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

-    const Test(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

-        }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

-          m() => a += 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,

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

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

-    const Test.prefix(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

-        }

-        ''',

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,

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

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

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

-    // with the same name.

-    /*const Test(

-        '''

-        class C {

-          static a() {}

-          static set a(_) {}

-        }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static a() {}

-          static set a(_) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          static a() {}

-          static set a(_) {}

-          m() => a += 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,

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

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

-    const Test.prefix(

-        '''

-        class C {

-          static a() {}

-          static set a(_) {}

-        }

-        ''',

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,

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

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

-    const Test.clazz(

-        '''

-        class C {

-          var a;

-          m() => a += 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,

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

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

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

-    const Test.clazz(

-        '''

-        class C {

-          var a = 0;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,

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

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

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

-    const Test.clazz(

-        '''

-        class B {

-          var a = 0;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FIELD_COMPOUND,

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

-    const Test.clazz(

-        '''

-        class B {

-          final a = 0;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_COMPOUND,

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

-    const Test.clazz(

-        '''

-        class B {

-          get a => 0;

-          set a (_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,

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

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

-    const Test.clazz(

-        '''

-        class A {

-          get a => 0;

-        }

-        class B extends A {

-          set a (_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,

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

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

-    const Test.clazz(

-        '''

-        class A {

-          var a;

-        }

-        class B extends A {

-          get a => 0;

-        }

-

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_COMPOUND,

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

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

-    const Test.clazz(

-        '''

-        class A {

-          var a;

-        }

-        class B extends A {

-          set a(_) {}

-        }

-

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_COMPOUND,

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

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

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

-    /*const Test.clazz(

-        '''

-        class A {

-          var a;

-        }

-        class B extends A {

-          final a = 0;

-        }

-

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,

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

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

-    const Test.clazz(

-        '''

-        class B {

-          a() {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_METHOD_COMPOUND,

-            element: 'function(B#a)',

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

-    const Test.clazz(

-        '''

-        class B {

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND,

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

-    const Test.clazz(

-        '''

-        class B {

-          set a(_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,

-            setter: 'setter(B#a)', operator: '+=', rhs: '42')),

-    const Test.clazz(

-        '''

-        class B {

-          get a => 42;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,

-            getter: 'getter(B#a)', operator: '+=', rhs: '42')),

-

-    const Test.clazz(

-        '''

-        class C {

-          static set a(var value) { }

-          m() => a += 42;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,

-            setter: 'setter(C#a)', operator: '+=', rhs: '42')),

-

-    const Test.clazz(

-        '''

-        class C {

-          static get a => 42;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,

-            getter: 'getter(C#a)', operator: '+=', rhs: '42')),

-

-    const Test.clazz(

-        '''

-        class C {

-          static final a = 42;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_COMPOUND,

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

-

-    const Test(

-        '''

-        class C {

-          static a(var value) { }

-        }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_METHOD_COMPOUND,

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

-

-    const Test(

-        '''

-        set a(var value) { }

-        m() => a += 42;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,

-            setter: 'setter(a)', operator: '+=', rhs: '42')),

-

-    const Test(

-        '''

-        get a => 42;

-        m() => a += 42;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,

-            getter: 'getter(a)', operator: '+=', rhs: '42')),

-

-    const Test(

-        '''

-        a(var value) { }

-        m() => a += 42;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_COMPOUND,

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

-

-    const Test(

-        '''

-        final a = 42;

-        m() => a += 42;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,

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

-

-    const Test(

-        '''

-        m() => unresolved += 42;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_COMPOUND,

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

-  ],

-  'Compound index assignment': const [

-    // Compound index assignment

-    const Test(

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_COMPOUND_INDEX_SET,

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

-    const Test.clazz(

-        '''

-        class B {

-          operator [](_) {}

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

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_COMPOUND_INDEX_SET,

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

-            index: '1', operator: '+=', rhs: '42')),

-    const Test.clazz(

-        '''

-        class B {

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

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,

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

-            index: '1', operator: '+=', rhs: '42')),

-    const Test.clazz(

-        '''

-        class B {

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,

-            index: '1', operator: '+=', rhs: '42')),

-    const Test.clazz(

-        '''

-        class B {

-          operator [](_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,

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

-            index: '1', operator: '+=', rhs: '42')),

-  ],

-  'Prefix expression': const [

-    // Prefix expression

-    const Test(

-        '''

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

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_PREFIX,

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

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

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

-          const Visit(VisitKind.VISIT_PARAMETER_GET,

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

-        ]),

-    const Test(

-        '''

-        m(a) => ++a;

-        ''',

-        const Visit(VisitKind.VISIT_PARAMETER_PREFIX,

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

-    const Test(

-        '''

-        m(final a) => ++a;

-        ''',

-        const Visit(VisitKind.VISIT_FINAL_PARAMETER_PREFIX,

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

-    const Test(

-        '''

-        m() {

-          var a;

-          --a;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_PREFIX,

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

-    const Test(

-        '''

-        m() {

-          final a = 42;

-          --a;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_PREFIX,

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

-    const Test(

-        '''

-        m() {

-          a() {}

-          --a;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_PREFIX,

-            element: 'function(m#a)', operator: '--')),

-    const Test(

-        '''

-        var a;

-        m() => ++a;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_PREFIX,

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

-    const Test(

-        '''

-        get a => 0;

-        set a(_) {}

-        m() => --a;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,

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

-            operator: '--')),

-    const Test(

-        '''

-        class C {

-          static var a;

-        }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,

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

-    const Test.clazz(

-        '''

-        class C {

-          static var a;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,

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

-    const Test.clazz(

-        '''

-        class C {

-          static var a;

-          m() => --a;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,

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

-    const Test.prefix(

-        '''

-        class C {

-          static var a;

-        }

-        ''',

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,

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

-    const Test(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

-        }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,

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

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,

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

-            operator: '--')),

-    const Test.clazz(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

-          m() => --a;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,

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

-            operator: '--')),

-    const Test.prefix(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

-        }

-        ''',

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,

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

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class C {

-          var a;

-          m() => --a;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,

-            operator: '--',

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

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

-    const Test.clazz(

-        '''

-        class C {

-          var a = 0;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,

-            operator: '++',

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

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

-    const Test.clazz(

-        '''

-        class B {

-          var a = 0;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FIELD_PREFIX,

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

-    const Test.clazz(

-        '''

-        class B {

-          final a = 0;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_PREFIX,

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

-    const Test.clazz(

-        '''

-        class B {

-          get a => 0;

-          set a (_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,

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

-            operator: '--')),

-    const Test.clazz(

-        '''

-        class A {

-          get a => 0;

-        }

-        class B extends A {

-          set a (_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,

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

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class A {

-          var a;

-        }

-        class B extends A {

-          get a => 0;

-        }

-

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_PREFIX,

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

-            operator: '--')),

-    const Test.clazz(

-        '''

-        class A {

-          var a;

-        }

-        class B extends A {

-          set a(_) {}

-        }

-

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_PREFIX,

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

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

-          a() {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_METHOD_PREFIX,

-            element: 'function(B#a)',

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_PREFIX,

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

-          set a(_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,

-            setter: 'setter(B#a)', operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

-          get a => 42;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,

-            getter: 'getter(B#a)', operator: '++')),

-

-    const Test.clazz(

-        '''

-        class C {

-          static set a(var value) { }

-          m() => ++a;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,

-            setter: 'setter(C#a)', operator: '++')),

-

-    const Test.clazz(

-        '''

-        class C {

-          static get a => 42;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,

-            getter: 'getter(C#a)', operator: '++')),

-

-    const Test.clazz(

-        '''

-        class C {

-          static final a = 42;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_PREFIX,

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

-

-    const Test(

-        '''

-        class C {

-          static a(var value) { }

-        }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_METHOD_PREFIX,

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

-

-    const Test(

-        '''

-        set a(var value) { }

-        m() => ++a;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,

-            setter: 'setter(a)', operator: '++')),

-

-    const Test(

-        '''

-        get a => 42;

-        m() => ++a;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,

-            getter: 'getter(a)', operator: '++')),

-

-    const Test(

-        '''

-        a(var value) { }

-        m() => ++a;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_PREFIX,

-            element: 'function(a)', operator: '++')),

-

-    const Test(

-        '''

-        final a = 42;

-        m() => ++a;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,

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

-

-    const Test(

-        '''

-        m() => ++unresolved;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_PREFIX,

-            operator: '++')),

-  ],

-  'Postfix expression': const [

-    // Postfix expression

-    const Test(

-        '''

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

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_POSTFIX,

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

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

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

-          const Visit(VisitKind.VISIT_PARAMETER_GET,

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

-        ]),

-    const Test(

-        '''

-        m(a) => a++;

-        ''',

-        const Visit(VisitKind.VISIT_PARAMETER_POSTFIX,

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

-    const Test(

-        '''

-        m(final a) => a++;

-        ''',

-        const Visit(VisitKind.VISIT_FINAL_PARAMETER_POSTFIX,

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

-    const Test(

-        '''

-        m() {

-          var a;

-          a--;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_POSTFIX,

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

-    const Test(

-        '''

-        m() {

-          final a = 42;

-          a--;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,

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

-    const Test(

-        '''

-        m() {

-          a() {}

-          a--;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_POSTFIX,

-            element: 'function(m#a)', operator: '--')),

-    const Test(

-        '''

-        var a;

-        m() => a++;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_POSTFIX,

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

-    const Test(

-        '''

-        get a => 0;

-        set a(_) {}

-        m() => a--;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,

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

-            operator: '--')),

-    const Test(

-        '''

-        class C {

-          static var a;

-        }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,

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

-    const Test.clazz(

-        '''

-        class C {

-          static var a;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,

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

-    const Test.clazz(

-        '''

-        class C {

-          static var a;

-          m() => a--;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,

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

-    const Test.prefix(

-        '''

-        class C {

-          static var a;

-        }

-        ''',

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,

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

-    const Test(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

-        }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,

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

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,

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

-            operator: '--')),

-    const Test.clazz(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

-          m() => a--;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,

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

-            operator: '--')),

-    const Test.prefix(

-        '''

-        class C {

-          static get a => 0;

-          static set a(_) {}

-        }

-        ''',

-        '''

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,

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

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class C {

-          var a;

-          m() => a--;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,

-            operator: '--',

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

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

-    const Test.clazz(

-        '''

-        class C {

-          var a = 0;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,

-            operator: '++',

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

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

-    const Test.clazz(

-        '''

-        class B {

-          var a = 0;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FIELD_POSTFIX,

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

-    const Test.clazz(

-        '''

-        class B {

-          final a = 0;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_POSTFIX,

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

-    const Test.clazz(

-        '''

-        class B {

-          get a => 0;

-          set a (_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,

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

-            operator: '--')),

-    const Test.clazz(

-        '''

-        class A {

-          get a => 0;

-        }

-        class B extends A {

-          set a (_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,

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

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class A {

-          var a;

-        }

-        class B extends A {

-          get a => 0;

-        }

-

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_POSTFIX,

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

-            operator: '--')),

-    const Test.clazz(

-        '''

-        class A {

-          var a;

-        }

-        class B extends A {

-          set a(_) {}

-        }

-

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_POSTFIX,

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

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

-          a() {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_SUPER_METHOD_POSTFIX,

-            element: 'function(B#a)',

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_POSTFIX,

-            operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

-          set a(_) {}

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,

-            setter: 'setter(B#a)', operator: '++')),

-    const Test.clazz(

-        '''

-        class B {

-          get a => 42;

-        }

-        class C extends B {

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,

-            getter: 'getter(B#a)', operator: '++')),

-

-    const Test.clazz(

-        '''

-        class C {

-          static set a(var value) { }

-          m() => a++;

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,

-            setter: 'setter(C#a)', operator: '++')),

-

-    const Test.clazz(

-        '''

-        class C {

-          static get a => 42;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,

-            getter: 'getter(C#a)', operator: '++')),

-

-    const Test.clazz(

-        '''

-        class C {

-          static final a = 42;

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

-        }

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_POSTFIX,

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

-

-    const Test(

-        '''

-        class C {

-          static a(var value) { }

-        }

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

-        ''',

-        const Visit(VisitKind.VISIT_STATIC_METHOD_POSTFIX,

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

-

-    const Test(

-        '''

-        set a(var value) { }

-        m() => a++;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,

-            setter: 'setter(a)', operator: '++')),

-

-    const Test(

-        '''

-        get a => 42;

-        m() => a++;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,

-            getter: 'getter(a)', operator: '++')),

-

-    const Test(

-        '''

-        a(var value) { }

-        m() => a++;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_POSTFIX,

-            element: 'function(a)', operator: '++')),

-

-    const Test(

-        '''

-        final a = 42;

-        m() => a++;

-        ''',

-        const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,

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

-

-    const Test(

-        '''

-        m() => unresolved++;

-        ''',

-        const Visit(VisitKind.VISIT_UNRESOLVED_POSTFIX,

-            operator: '++')),

-  ],

-  'Constructor invocations': const [

-    const Test(

-        '''

-        class Class {

-          const Class(a, b);

-        }

-        m() => const Class(true, 42);

-        ''',

-        const Visit(VisitKind.VISIT_CONST_CONSTRUCTOR_INVOKE,

-            constant: 'const Class(true, 42)')),

-    const Test(

-        '''

-        m() => const bool.fromEnvironment('foo');

-        ''',

-        const Visit(VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,

-            constant:

-                'const bool.fromEnvironment("foo")')),

-    const Test(

-        '''

-        m() => const bool.fromEnvironment('foo', defaultValue: true);

-        ''',

-        const Visit(VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,

-            constant: 'const bool.fromEnvironment("foo", defaultValue: true)')),

-    const Test(

-        '''

-        m() => const int.fromEnvironment('foo');

-        ''',

-        const Visit(VisitKind.VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,

-            constant: 'const int.fromEnvironment("foo")')),

-    const Test(

-        '''

-        m() => const String.fromEnvironment('foo');

-        ''',

-        const Visit(VisitKind.VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,

-            constant:

-                'const String.fromEnvironment("foo")')),

-    const Test(

-        '''

-        class Class {

-          Class(a, b);

-        }

-        m() => const Class(true, 42);

-        ''',

-        const Visit(VisitKind.ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,

-            element: 'generative_constructor(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class {}

-        m() => new Class();

-        ''',

-        const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,

-            element: 'generative_constructor(Class#)',

-            arguments: '()',

-            type: 'Class',

-            selector: 'CallStructure(arity=0)')),

-    const Test(

-        '''

-        class Class {

-          Class(a, b);

-        }

-        m() => new Class(true, 42);

-        ''',

-        const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,

-            element: 'generative_constructor(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class {

-          Class.named(a, b);

-        }

-        m() => new Class.named(true, 42);

-        ''',

-        const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,

-            element: 'generative_constructor(Class#named)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class {}

-        m() => new Class(true, 42);

-        ''',

-        const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,

-            element: 'generative_constructor(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class {

-          Class(a, b) : this._(a, b);

-          Class._(a, b);

-        }

-        m() => new Class(true, 42);

-        ''',

-        const Visit(VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,

-            element: 'generative_constructor(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class {

-          Class() : this._(true, 42);

-          Class._(a, b);

-        }

-        m() => new Class(true, 42);

-        ''',

-        const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,

-            element: 'generative_constructor(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class {

-          factory Class(a, b) => new Class._(a, b);

-          Class._(a, b);

-        }

-        m() => new Class(true, 42);

-        ''',

-        const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,

-            element: 'function(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class {

-          factory Class() => new Class._(true, 42);

-          Class._(a, b);

-        }

-        m() => new Class(true, 42);

-        ''',

-        const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,

-            element: 'function(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class<T> {

-          factory Class(a, b) = Class<int>.a;

-          factory Class.a(a, b) = Class<Class<T>>.b;

-          Class.b(a, b);

-        }

-        m() => new Class<double>(true, 42);

-        ''',

-        const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-            element: 'function(Class#)',

-            arguments: '(true,42)',

-            type: 'Class<double>',

-            target: 'generative_constructor(Class#b)',

-            targetType: 'Class<Class<int>>',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class<T> {

-          factory Class(a) = Class<int>.a;

-          factory Class.a(a, [b]) = Class<Class<T>>.b;

-          Class.b(a, [b]);

-        }

-        m() => new Class<double>(true, 42);

-        ''',

-        const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-            element: 'function(Class#)',

-            arguments: '(true,42)',

-            type: 'Class<double>',

-            target: 'generative_constructor(Class#b)',

-            targetType: 'Class<Class<int>>',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class {

-          factory Class() = Class._;

-          Class._();

-        }

-        m() => new Class(true, 42);

-        ''',

-        const Visit(

-            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-            element: 'function(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class<T> {

-          factory Class(a, b) = Class<int>.a;

-          factory Class.a(a, b) = Class<Class<T>>.b;

-          Class.b(a);

-        }

-        m() => new Class<double>(true, 42);

-        ''',

-        const Visit(

-            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-            element: 'function(Class#)',

-            arguments: '(true,42)',

-            type: 'Class<double>',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class {

-          Class(a, b);

-        }

-        m() => new Class.unresolved(true, 42);

-        ''',

-        const Visit(

-            VisitKind.VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,

-            arguments: '(true,42)')),

-    const Test(

-        '''

-        m() => new Unresolved(true, 42);

-        ''',

-        const Visit(

-            VisitKind.VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,

-            arguments: '(true,42)')),

-    const Test(

-        '''

-        abstract class AbstractClass {}

-        m() => new AbstractClass();

-        ''',

-        const Visit(

-            VisitKind.VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,

-            element: 'generative_constructor(AbstractClass#)',

-            type: 'AbstractClass',

-            arguments: '()',

-            selector: 'CallStructure(arity=0)')),

-    const Test(

-        '''

-        class Class {

-          factory Class(a, b) = Unresolved;

-        }

-        m() => new Class(true, 42);

-        ''',

-        const Visit(

-            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-            element: 'function(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class {

-          factory Class(a, b) = Class.named;

-        }

-        m() => new Class(true, 42);

-        ''',

-        const Visit(

-            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-            element: 'function(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        class Class {

-          factory Class(a, b) = Class.named;

-          factory Class.named(a, b) = Class.unresolved;

-        }

-        m() => new Class(true, 42);

-        ''',

-        const Visit(

-            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-            element: 'function(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-    const Test(

-        '''

-        abstract class AbstractClass {

-          AbstractClass(a, b);

-        }

-        class Class {

-          factory Class(a, b) = AbstractClass;

-        }

-        m() => new Class(true, 42);

-        ''',

-        const Visit(

-            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-            element: 'function(Class#)',

-            arguments: '(true,42)',

-            type: 'Class',

-            selector: 'CallStructure(arity=2)')),

-  ],

-  'If not null expressions': const [

-    const Test(

-        '''

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

-        ''',

-        const [

-          const Visit(

-              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,

-              receiver: 'a',

-              name: 'b'),

-          const Visit(

-              VisitKind.VISIT_PARAMETER_GET,

-              element: 'parameter(m#a)'),

-        ]),

-    const Test(

-        '''

-        class C {

-          static var b;

-        }

-        m(a) => C?.b;

-        ''',

-        const [

-          const Visit(

-              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,

-              receiver: 'C',

-              name: 'b'),

-          const Visit(

-              VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,

-              constant: 'C'),

-        ]),

-    const Test(

-        '''

-        m(a) => a?.b = 42;

-        ''',

-        const [

-          const Visit(

-              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,

-              receiver: 'a',

-              name: 'b',

-              rhs: '42'),

-          const Visit(

-              VisitKind.VISIT_PARAMETER_GET,

-              element: 'parameter(m#a)'),

-        ]),

-    const Test(

-        '''

-        m(a) => a?.b(42, true);

-        ''',

-        const [

-          const Visit(

-              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,

-              receiver: 'a',

-              arguments: '(42,true)',

-              selector: 'Selector(call, b, arity=2)'),

-          const Visit(

-              VisitKind.VISIT_PARAMETER_GET,

-              element: 'parameter(m#a)'),

-        ]),

-    const Test(

-        '''

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

-        ''',

-        const [

-          const Visit(

-              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,

-              receiver: 'a',

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

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

-              operator: '++'),

-          const Visit(

-              VisitKind.VISIT_PARAMETER_GET,

-              element: 'parameter(m#a)'),

-        ]),

-    const Test(

-        '''

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

-        ''',

-        const [

-          const Visit(

-              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,

-              receiver: 'a',

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

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

-              operator: '--'),

-          const Visit(

-              VisitKind.VISIT_PARAMETER_GET,

-              element: 'parameter(m#a)'),

-        ]),

-    const Test(

-        '''

-        m(a) => a?.b *= 42;

-        ''',

-        const [

-          const Visit(

-              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,

-              receiver: 'a',

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

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

-              operator: '*=',

-              rhs: '42'),

-          const Visit(

-              VisitKind.VISIT_PARAMETER_GET,

-              element: 'parameter(m#a)'),

-        ]),

-    const Test(

-        '''

-        m(a, b) => a ?? b;

-        ''',

-        const [

-          const Visit(VisitKind.VISIT_IF_NULL,

-                      left: 'a', right: 'b'),

-          const Visit(

-              VisitKind.VISIT_PARAMETER_GET,

-              element: 'parameter(m#a)'),

-          const Visit(

-              VisitKind.VISIT_PARAMETER_GET,

-              element: 'parameter(m#b)'),

-       ]),

-    const Test(

-        '''

-        m(a) => a ??= 42;

-        ''',

-        const Visit(

-            VisitKind.VISIT_PARAMETER_COMPOUND,

-            element: 'parameter(m#a)',

-            operator: '??=',

-            rhs: '42')),

-  ],

-};

+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart2js.semantics_visitor_test;
+
+const Map<String, List<Test>> SEND_TESTS = const {
+  'Parameters': const [
+    // Parameters
+    const Test('m(o) => o;',
+        const Visit(VisitKind.VISIT_PARAMETER_GET,
+                    element: 'parameter(m#o)')),
+    const Test('m(o) { o = 42; }',
+        const Visit(VisitKind.VISIT_PARAMETER_SET,
+                    element: 'parameter(m#o)',
+                    rhs:'42')),
+    const Test('m(o) { o(null, 42); }',
+        const Visit(VisitKind.VISIT_PARAMETER_INVOKE,
+                    element: 'parameter(m#o)',
+                    arguments: '(null,42)',
+                    selector: 'CallStructure(arity=2)')),
+    // TODO(johnniwinther): Expect [VISIT_FINAL_PARAMETER_SET] instead.
+    const Test('m(final o) { o = 42; }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs:'42')),
+  ],
+  'Local variables': const [
+    // Local variables
+    const Test('m() { var o; return o; }',
+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_GET,
+                    element: 'variable(m#o)')),
+    const Test('m() { var o; o = 42; }',
+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_SET,
+                    element: 'variable(m#o)',
+                    rhs:'42')),
+    const Test('m() { var o; o(null, 42); }',
+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_INVOKE,
+                    element: 'variable(m#o)',
+                    arguments: '(null,42)',
+                    selector: 'CallStructure(arity=2)')),
+    // TODO(johnniwinther): Expect [VISIT_FINAL_LOCAL_VARIABLE_SET] instead.
+    const Test('m() { final o = 0; o = 42; }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs:'42')),
+    // TODO(johnniwinther): Expect [VISIT_FINAL_LOCAL_VARIABLE_SET] instead.
+    const Test('m() { const o = 0; o = 42; }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs:'42')),
+  ],
+  'Local functions': const [
+    // Local functions
+    const Test('m() { o(a, b) {}; return o; }',
+        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_GET,
+                    element: 'function(m#o)')),
+    const Test('m() { o(a, b) {}; o(null, 42); }',
+        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_INVOKE,
+                    element: 'function(m#o)',
+                    arguments: '(null,42)',
+                    selector: 'CallStructure(arity=2)')),
+    const Test('m() { o(a) {}; o(null, 42); }',
+        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,
+                    element: 'function(m#o)',
+                    arguments: '(null,42)',
+                    selector: 'CallStructure(arity=2)')),
+    // TODO(johnniwinther): Expect [VISIT_LOCAL_FUNCTION_SET] instead.
+    const Test('m() { o(a, b) {}; o = 42; }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+  ],
+  'Static fields': const [
+    // Static fields
+    const Test(
+        '''
+        class C { static var o; }
+        m() => C.o;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
+                    element: 'field(C#o)')),
+    const Test.clazz(
+        '''
+        class C {
+          static var o;
+          m() => o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
+                    element: 'field(C#o)')),
+    const Test.clazz(
+        '''
+        class C {
+          static var o;
+          m() => C.o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
+                    element: 'field(C#o)')),
+    const Test.prefix(
+        '''
+        class C {
+          static var o;
+        }
+        ''',
+        'm() => p.C.o;',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_GET,
+                    element: 'field(C#o)')),
+    const Test(
+        '''
+        class C {
+          var o;
+        }
+        m() => C.o;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_GET,
+                    name: 'o')),
+    const Test(
+        '''
+        class C {
+          C.o();
+        }
+        m() => C.o;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_GET,
+                    name: 'o')),
+    const Test(
+        '''
+        class C {}
+        m() => C.this;
+        ''',
+        null),
+    const Test(
+        '''
+        class C { static var o; }
+        m() { C.o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
+                    element: 'field(C#o)',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static var o;
+          m() { o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
+                    element: 'field(C#o)',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static var o;
+          m() { C.o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
+                    element: 'field(C#o)',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        class C {
+          static var o;
+        }
+        ''',
+        'm() { p.C.o = 42; }',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_SET,
+                    element: 'field(C#o)',
+                    rhs: '42')),
+    const Test(
+        '''
+        class C { static var o; }
+        m() { C.o(null, 42); }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
+                    element: 'field(C#o)',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class C {
+          static var o;
+          m() { o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
+                    element: 'field(C#o)',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class C {
+          static var o;
+          m() { C.o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
+                    element: 'field(C#o)',
+                    arguments: '(null,42)')),
+    const Test.prefix(
+        '''
+        class C {
+          static var o;
+        }
+        ''',
+        'm() { p.C.o(null, 42); }',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
+                    element: 'field(C#o)',
+                    arguments: '(null,42)')),
+    const Test(
+        '''
+        class C {}
+        m() => C.this(null, 42);
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
+                    name: 'this', arguments: '(null,42)')),
+    // TODO(johnniwinther): Expect [VISIT_FINAL_STATIC_FIELD_SET] instead.
+    const Test(
+        '''
+        class C { static final o = 0; }
+        m() { C.o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static final o = 0;
+          m() { o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static final o = 0;
+          m() { C.o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        class C {
+          static final o = 0;
+        }
+        ''',
+        'm() { p.C.o = 42; }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test(
+        '''
+        class C { static const o = 0; }
+        m() { C.o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static const o = 0;
+          m() { o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static const o = 0;
+          m() { C.o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        class C {
+          static const o = 0;
+        }
+        ''',
+        'm() { p.C.o = 42; }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+  ],
+  'Static properties': const [
+    // Static properties
+    const Test(
+        '''
+        class C {
+          static get o => null;
+        }
+        m() => C.o;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
+                    element: 'getter(C#o)')),
+    const Test.clazz(
+        '''
+        class C {
+          static get o => null;
+          m() => o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
+                    element: 'getter(C#o)')),
+    const Test.clazz(
+        '''
+        class C {
+          static get o => null;
+          m() => C.o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
+                    element: 'getter(C#o)')),
+    const Test.prefix(
+        '''
+        class C {
+          static get o => null;
+        }
+        ''',
+        'm() => p.C.o;',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_GET,
+                    element: 'getter(C#o)')),
+    // TODO(johnniwinther): Expected [VISIT_STATIC_GETTER_SET] instead.
+    const Test(
+        '''
+        class C { static get o => 42; }
+        m() { C.o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static get o => 42;
+          m() { o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static get o => 42;
+          m() { C.o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        class C {
+          static get o => 42;
+        }
+        ''',
+        'm() { p.C.o = 42; }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test(
+        '''
+        class C {
+          static set o(_) {}
+        }
+        m() => C.o;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
+                    element: 'setter(C#o)')),
+    const Test.clazz(
+        '''
+        class C {
+          static set o(_) {}
+          m() => o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
+                    element: 'setter(C#o)')),
+
+    const Test.clazz(
+        '''
+        class C {
+          static set o(_) {}
+          m() => C.o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
+                    element: 'setter(C#o)')),
+    const Test.prefix(
+        '''
+        class C {
+          static set o(_) {}
+        }
+        ''',
+        'm() => p.C.o;',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_GET,
+                    element: 'setter(C#o)')),
+    const Test(
+        '''
+        class C { static set o(_) {} }
+        m() { C.o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
+                    element: 'setter(C#o)',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static set o(_) {}
+          m() { o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
+                    element: 'setter(C#o)',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static set o(_) {}
+          m() { C.o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
+                    element: 'setter(C#o)',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        class C {
+          static set o(_) {}
+        }
+        ''',
+        'm() { p.C.o = 42; }',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_SET,
+                    element: 'setter(C#o)',
+                    rhs: '42')),
+    const Test(
+        '''
+        class C { static get o => null; }
+        m() => C.o(null, 42);
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
+                    element: 'getter(C#o)',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class C {
+          static get o => null;
+          m() { o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
+                    element: 'getter(C#o)',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class C {
+          static get o => null;
+          m() { C.o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
+                    element: 'getter(C#o)',
+                    arguments: '(null,42)')),
+    const Test.prefix(
+        '''
+        class C {
+          static get o => null;
+        }
+        ''',
+        'm() { p.C.o(null, 42); }',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
+                    element: 'getter(C#o)',
+                    arguments: '(null,42)')),
+    const Test(
+        '''
+        class C { static set o(_) {} }
+        m() => C.o(null, 42);
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
+                    element: 'setter(C#o)',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class C {
+          static set o(_) {}
+          m() { o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
+                    element: 'setter(C#o)',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class C {
+          static set o(_) {}
+          m() { C.o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
+                    element: 'setter(C#o)',
+                    arguments: '(null,42)')),
+    const Test.prefix(
+        '''
+        class C {
+          static set o(_) {}
+        }
+        ''',
+        'm() { p.C.o(null, 42); }',
+        const Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
+                    element: 'setter(C#o)',
+                    arguments: '(null,42)')),
+  ],
+  'Static functions': const [
+    // Static functions
+    const Test(
+        '''
+        class C { static o(a, b) {} }
+        m() => C.o;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
+                    element: 'function(C#o)')),
+    const Test.clazz(
+        '''
+        class C {
+          static o(a, b) {}
+          m() => o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
+                    element: 'function(C#o)')),
+    const Test.clazz(
+        '''
+        class C {
+          static o(a, b) {}
+          m() => C.o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
+                    element: 'function(C#o)')),
+    const Test.prefix(
+        '''
+        class C { static o(a, b) {} }
+        ''',
+        '''
+        m() => p.C.o;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
+                    element: 'function(C#o)')),
+    // TODO(johnniwinther): Expect [VISIT_STATIC_FUNCTION_SET] instead.
+    const Test(
+        '''
+        class C { static o(a, b) {} }
+        m() { C.o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static o(a, b) {}
+          m() { o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static o(a, b) {}
+          m() { C.o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        class C { static o(a, b) {} }
+        ''',
+        '''
+        m() { p.C.o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test(
+        '''
+        class C { static o(a, b) {} }
+        m() => C.o(null, 42);
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
+                    element: 'function(C#o)',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class C {
+          static o(a, b) {}
+          m() { o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
+                    element: 'function(C#o)',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class C {
+          static o(a, b) {}
+          m() { C.o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
+                    element: 'function(C#o)',
+                    arguments: '(null,42)')),
+    const Test.prefix(
+        '''
+        class C {
+          static o(a, b) {}
+        }
+        ''',
+        'm() { p.C.o(null, 42); }',
+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
+                    element: 'function(C#o)',
+                    arguments: '(null,42)')),
+    const Test(
+        '''
+        class C { static o(a, b) {} }
+        m() => C.o(null);
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,
+                    element: 'function(C#o)',
+                    arguments: '(null)')),
+  ],
+  'Top level fields': const [
+    // Top level fields
+    const Test(
+        '''
+        var o;
+        m() => o;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET,
+                    element: 'field(o)')),
+    const Test.prefix(
+        '''
+        var o;
+        ''',
+        'm() => p.o;',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET,
+                    element: 'field(o)')),
+    const Test(
+        '''
+        var o;
+        m() { o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,
+                    element: 'field(o)',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        var o;
+        ''',
+        'm() { p.o = 42; }',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,
+                    element: 'field(o)',
+                    rhs: '42')),
+    // TODO(johnniwinther): Expect [VISIT_FINAL_TOP_LEVEL_FIELD_SET] instead.
+    const Test(
+        '''
+        final o = 0;
+        m() { o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        final o = 0;
+        ''',
+        'm() { p.o = 42; }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test(
+        '''
+        const o = 0;
+        m() { o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        const o = 0;
+        ''',
+        'm() { p.o = 42; }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test(
+        '''
+        var o;
+        m() { o(null, 42); }
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
+                    element: 'field(o)',
+                    arguments: '(null,42)')),
+    const Test.prefix(
+        '''
+        var o;
+        ''',
+        'm() { p.o(null, 42); }',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
+                    element: 'field(o)',
+                    arguments: '(null,42)')),
+    const Test(
+        '''
+        m() => o;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_GET,
+                    name: 'o')),
+  ],
+  'Top level properties': const [
+    // Top level properties
+    const Test(
+        '''
+        get o => null;
+        m() => o;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,
+                    element: 'getter(o)')),
+    const Test.prefix(
+        '''
+        get o => null;
+        ''',
+        '''
+        m() => p.o;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,
+                    element: 'getter(o)')),
+    // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_SETTER_GET] instead.
+    const Test(
+        '''
+        set o(_) {}
+        m() => o;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_GET,
+                    element: 'setter(o)')),
+    const Test.prefix(
+        '''
+        set o(_) {}
+        ''',
+        '''
+        m() => p.o;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_GET,
+                    name: 'o')),
+    // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_GETTER_SET] instead.
+    const Test(
+        '''
+        get o => null;
+        m() { o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        get o => null;
+        ''',
+        'm() { p.o = 42; }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test(
+        '''
+        set o(_) {}
+        m() { o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,
+                    element: 'setter(o)',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        set o(_) {}
+        ''',
+        'm() { p.o = 42; }',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,
+                    element: 'setter(o)',
+                    rhs: '42')),
+    const Test(
+        '''
+        get o => null;
+        m() => o(null, 42);
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,
+                    element: 'getter(o)',
+                    arguments: '(null,42)')),
+    const Test.prefix(
+        '''
+        get o => null;
+        ''',
+        'm() { p.o(null, 42); }',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,
+                    element: 'getter(o)',
+                    arguments: '(null,42)')),
+    // TODO(johnniwinther): Expected [VISIT_TOP_LEVEL_SETTER_INVOKE] instead.
+    const Test(
+        '''
+        set o(_) {}
+        m() => o(null, 42);
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_INVOKE,
+                    element: 'setter(o)',
+                    arguments: '(null,42)')),
+    const Test.prefix(
+        '''
+        set o(_) {}
+        ''',
+        'm() { p.o(null, 42); }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
+                    name: 'o',
+                    arguments: '(null,42)')),
+  ],
+  'Top level functions': const [
+    // Top level functions
+    const Test(
+        '''
+        o(a, b) {}
+        m() => o;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_GET,
+                    element: 'function(o)')),
+    const Test(
+        '''
+        o(a, b) {}
+        m() => o(null, 42);
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,
+                    element: 'function(o)',
+                    arguments: '(null,42)')),
+    const Test(
+        '''
+        o(a, b) {}
+        m() => o(null);
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,
+                    element: 'function(o)',
+                    arguments: '(null)')),
+    const Test.prefix(
+        '''
+        o(a, b) {}
+        ''',
+        'm() { p.o(null, 42); }',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,
+                    element: 'function(o)',
+                    arguments: '(null,42)')),
+    const Test(
+        '''
+        m() => o(null, 42);
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
+                    name: 'o',
+                    arguments: '(null,42)')),
+    // TODO(johnniwinther): Expect [VISIT_TOP_LEVEL_FUNCTION_SET] instead.
+    const Test(
+        '''
+        o(a, b) {}
+        m() { o = 42; }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.prefix(
+        '''
+        o(a, b) {}
+        ''',
+        'm() { p.o = 42; }',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+  ],
+  'Dynamic properties': const [
+    // Dynamic properties
+    const Test('m(o) => o.foo;',
+        const [
+          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
+                      receiver: 'o',
+                      name: 'foo'),
+          const Visit(VisitKind.VISIT_PARAMETER_GET,
+                      element: 'parameter(m#o)'),
+        ]),
+    const Test('m(o) { o.foo = 42; }',
+        const [
+          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,
+                      receiver: 'o',
+                      name: 'foo',
+                      rhs: '42'),
+          const Visit(VisitKind.VISIT_PARAMETER_GET,
+                      element: 'parameter(m#o)'),
+        ]),
+    const Test('m(o) { o.foo(null, 42); }',
+        const [
+          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,
+                      receiver: 'o',
+                      name: 'foo',
+                      arguments: '(null,42)'),
+          const Visit(VisitKind.VISIT_PARAMETER_GET,
+                      element: 'parameter(m#o)'),
+        ]),
+  ],
+  'This access': const [
+    // This access
+    const Test.clazz(
+        '''
+        class C {
+          m() => this;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_GET)),
+    const Test.clazz(
+        '''
+        class C {
+          call(a, b) {}
+          m() { this(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_INVOKE,
+                    arguments: '(null,42)')),
+  ],
+  'This properties': const [
+    // This properties
+    const Test.clazz(
+        '''
+        class C {
+          var foo;
+          m() => foo;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
+                    name: 'foo')),
+    const Test.clazz(
+        '''
+        class C {
+          var foo;
+          m() => this.foo;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
+                    name: 'foo')),
+    const Test.clazz(
+        '''
+        class C {
+          get foo => null;
+          m() => foo;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
+                    name: 'foo')),
+    const Test.clazz(
+        '''
+        class C {
+          get foo => null;
+          m() => this.foo;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
+                    name: 'foo')),
+    const Test.clazz(
+        '''
+        class C {
+          var foo;
+          m() { foo = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
+                    name: 'foo',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          var foo;
+          m() { this.foo = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
+                    name: 'foo',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          set foo(_) {}
+          m() { foo = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
+                    name: 'foo',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          set foo(_) {}
+          m() { this.foo = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
+                    name: 'foo',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          var foo;
+          m() { foo(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,
+                    name: 'foo',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class C {
+          var foo;
+          m() { this.foo(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,
+                    name: 'foo',
+                    arguments: '(null,42)')),
+  ],
+  'Super fields': const [
+    // Super fields
+    const Test.clazz(
+        '''
+        class B {
+          var o;
+        }
+        class C extends B {
+          m() => super.o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FIELD_GET,
+                    element: 'field(B#o)')),
+    const Test.clazz(
+        '''
+        class B {
+          var o;
+        }
+        class C extends B {
+          m() { super.o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FIELD_SET,
+                    element: 'field(B#o)',
+                    rhs: '42')),
+    // TODO(johnniwinther): Expect [VISIT_FINAL_SUPER_FIELD_SET] instead.
+    const Test.clazz(
+        '''
+        class B {
+          final o = 0;
+        }
+        class C extends B {
+          m() { super.o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+          var o;
+        }
+        class C extends B {
+          m() { super.o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FIELD_INVOKE,
+                element: 'field(B#o)',
+                arguments: '(null,42)')),
+    const Test.clazz(
+            '''
+        class B {
+        }
+        class C extends B {
+          m() => super.o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GET)),
+  ],
+  'Super properties': const [
+    // Super properties
+    const Test.clazz(
+        '''
+        class B {
+          get o => null;
+        }
+        class C extends B {
+          m() => super.o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_GETTER_GET,
+                    element: 'getter(B#o)')),
+    const Test.clazz(
+        '''
+        class B {
+          set o(_) {}
+        }
+        class C extends B {
+          m() => super.o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_SETTER_GET,
+                    element: 'setter(B#o)')),
+    // TODO(johnniwinther): Expect [VISIT_SUPER_GETTER_SET] instead.
+    const Test.clazz(
+        '''
+        class B {
+          get o => 0;
+        }
+        class C extends B {
+          m() { super.o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                    name: 'o',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+          set o(_) {}
+        }
+        class C extends B {
+          m() { super.o = 42; }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_SETTER_SET,
+                    element: 'setter(B#o)',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+          get o => null;
+        }
+        class C extends B {
+          m() { super.o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,
+                    element: 'getter(B#o)',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class B {
+          set o(_) {}
+        }
+        class C extends B {
+          m() { super.o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_SETTER_INVOKE,
+                    element: 'setter(B#o)',
+                    arguments: '(null,42)')),
+  ],
+  'Super methods': const [
+    // Super methods
+    const Test.clazz(
+        '''
+        class B {
+          o(a, b) {}
+        }
+        class C extends B {
+          m() => super.o;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_METHOD_GET,
+                    element: 'function(B#o)')),
+    const Test.clazz(
+        '''
+        class B {
+          o(a, b) {}
+        }
+        class C extends B {
+          m() { super.o(null, 42); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_METHOD_INVOKE,
+                    element: 'function(B#o)',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class B {
+          o(a, b) {}
+        }
+        class C extends B {
+          m() { super.o(null); }
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,
+                    element: 'function(B#o)',
+                    arguments: '(null)')),
+    const Test.clazz(
+            '''
+            class B {
+            }
+            class C extends B {
+              m() => super.o(null, 42);
+            }
+            ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INVOKE,
+                    arguments: '(null,42)')),
+  ],
+  'Expression invoke': const [
+    // Expression invoke
+    const Test('m() => (a, b){}(null, 42);',
+        const Visit(VisitKind.VISIT_EXPRESSION_INVOKE,
+                    receiver: '(a,b){}',
+                    arguments: '(null,42)')),
+  ],
+  'Class type literals': const [
+    // Class type literals
+    const Test(
+        '''
+        class C {}
+        m() => C;
+        ''',
+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
+                    constant: 'C')),
+    const Test(
+        '''
+        class C {}
+        m() => C(null, 42);
+        ''',
+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,
+                    constant: 'C',
+                    arguments: '(null,42)')),
+    const Test(
+        '''
+        class C {}
+        m() => C += 42;
+        ''',
+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,
+                    constant: 'C',
+                    operator: '+=',
+                    rhs: '42')),
+    const Test(
+        '''
+        class C {}
+        m() => ++C;
+        ''',
+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,
+                    constant: 'C',
+                    operator: '++')),
+    const Test(
+        '''
+        class C {}
+        m() => C--;
+        ''',
+        const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_POSTFIX,
+                    constant: 'C',
+                    operator: '--')),
+    const Test(
+        '''
+        class C {}
+        m() => (C).hashCode;
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
+                      receiver: '(C)', name: 'hashCode'),
+          const Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
+                      constant: 'C'),
+        ]),
+  ],
+  'Typedef type literals': const [
+    // Typedef type literals
+    const Test(
+        '''
+        typedef F();
+        m() => F;
+        ''',
+        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_GET,
+                    constant: 'F')),
+    const Test(
+        '''
+        typedef F();
+        m() => F(null, 42);
+        ''',
+        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,
+                    constant: 'F',
+                    arguments: '(null,42)')),
+    const Test(
+        '''
+        typedef F();
+        m() => F += 42;
+        ''',
+        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,
+                    constant: 'F',
+                    operator: '+=',
+                    rhs: '42')),
+    const Test(
+        '''
+        typedef F();
+        m() => ++F;
+        ''',
+        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,
+                    constant: 'F',
+                    operator: '++')),
+    const Test(
+        '''
+        typedef F();
+        m() => F--;
+        ''',
+        const Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,
+                    constant: 'F',
+                    operator: '--')),
+  ],
+  'Type variable type literals': const [
+    // Type variable type literals
+    const Test.clazz(
+        '''
+        class C<T> {
+          m() => T;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,
+                    element: 'type_variable(C#T)')),
+    const Test.clazz(
+        '''
+        class C<T> {
+          m() => T(null, 42);
+        }
+        ''',
+        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,
+                    element: 'type_variable(C#T)',
+                    arguments: '(null,42)')),
+    const Test.clazz(
+        '''
+        class C<T> {
+          m() => T += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,
+                    element: 'type_variable(C#T)',
+                    operator: '+=',
+                    rhs: '42')),
+    const Test.clazz(
+        '''
+        class C<T> {
+          m() => ++T;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,
+                    element: 'type_variable(C#T)',
+                    operator: '++')),
+    const Test.clazz(
+        '''
+        class C<T> {
+          m() => T--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,
+                    element: 'type_variable(C#T)',
+                    operator: '--')),
+
+  ],
+  'Dynamic type literals': const [
+    // Dynamic type literals
+    const Test(
+        '''
+        m() => dynamic;
+        ''',
+        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_GET,
+                    constant: 'dynamic')),
+    // TODO(johnniwinther): Update these to expect the constant to be `dynamic`
+    // instead of `Type`. Currently the compile time constant evaluator cannot
+    // detect `dynamic` as a constant subexpression.
+    const Test(
+        '''
+        m() { dynamic(null, 42); }
+        ''',
+        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,
+                    constant: 'Type',
+                    arguments: '(null,42)')),
+    const Test(
+        '''
+        m() => dynamic += 42;
+        ''',
+        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,
+                    constant: 'Type',
+                    operator: '+=',
+                    rhs: '42')),
+    const Test(
+        '''
+        m() => ++dynamic;
+        ''',
+        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,
+                    constant: 'Type',
+                    operator: '++')),
+    const Test(
+        '''
+        m() => dynamic--;
+        ''',
+        const Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,
+                    constant: 'Type',
+                    operator: '--')),
+  ],
+  'Assert': const [
+    // Assert
+    const Test(
+        '''
+        m() { assert(false); }
+        ''',
+        const Visit(VisitKind.VISIT_ASSERT, expression: 'false')),
+    const Test(
+        '''
+        m() { assert(); }
+        ''',
+        const Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: '()')),
+    const Test(
+        '''
+        m() { assert(42, true); }
+        ''',
+        const Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: '(42,true)')),
+  ],
+  'Logical and': const [
+    // Logical and
+    const Test(
+        '''
+        m() => true && false;
+        ''',
+        const Visit(VisitKind.VISIT_LOGICAL_AND, left: 'true', right: 'false')),
+  ],
+  'Logical or': const [
+    // Logical or
+    const Test(
+        '''
+        m() => true || false;
+        ''',
+        const Visit(VisitKind.VISIT_LOGICAL_OR, left: 'true', right: 'false')),
+  ],
+  'Is test': const [
+    // Is test
+    const Test(
+        '''
+        class C {}
+        m() => 0 is C;
+        ''',
+        const Visit(VisitKind.VISIT_IS, expression: '0', type: 'C')),
+  ],
+  'Is not test': const [
+    // Is not test
+    const Test(
+        '''
+        class C {}
+        m() => 0 is! C;
+        ''',
+        const Visit(VisitKind.VISIT_IS_NOT, expression: '0', type: 'C')),
+  ],
+  'As test': const [
+    // As test
+    const Test(
+        '''
+        class C {}
+        m() => 0 as C;
+        ''',
+        const Visit(VisitKind.VISIT_AS, expression: '0', type: 'C')),
+  ],
+  'Binary operators': const [
+    // Binary operators
+    const Test(
+        '''
+        m() => 2 + 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '+', right: '3')),
+    const Test(
+        '''
+        m() => 2 - 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '-', right: '3')),
+    const Test(
+        '''
+        m() => 2 * 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '*', right: '3')),
+    const Test(
+        '''
+        m() => 2 / 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '/', right: '3')),
+    const Test(
+        '''
+        m() => 2 ~/ 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '~/', right: '3')),
+    const Test(
+        '''
+        m() => 2 % 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '%', right: '3')),
+    const Test(
+        '''
+        m() => 2 << 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '<<', right: '3')),
+    const Test(
+        '''
+        m() => 2 >> 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '>>', right: '3')),
+    const Test(
+        '''
+        m() => 2 <= 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '<=', right: '3')),
+    const Test(
+        '''
+        m() => 2 < 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '<', right: '3')),
+    const Test(
+        '''
+        m() => 2 >= 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '>=', right: '3')),
+    const Test(
+        '''
+        m() => 2 > 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '>', right: '3')),
+    const Test(
+        '''
+        m() => 2 & 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '&', right: '3')),
+    const Test(
+        '''
+        m() => 2 | 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '|', right: '3')),
+    const Test(
+        '''
+        m() => 2 ^ 3;
+        ''',
+        const Visit(VisitKind.VISIT_BINARY,
+                    left: '2', operator: '^', right: '3')),
+    const Test.clazz(
+        '''
+        class B {
+          operator +(_) => null;
+        }
+        class C extends B {
+          m() => super + 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_BINARY,
+                    element: 'function(B#+)',
+                    operator: '+',
+                    right: '42')),
+    const Test.clazz(
+        '''
+        class B {}
+        class C extends B {
+          m() => super + 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_BINARY,
+                    operator: '+',
+                    right: '42')),
+    const Test(
+        '''
+        m() => 2 === 3;
+        ''',
+        const Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,
+                    left: '2', operator: '===', right: '3')),
+    const Test(
+        '''
+        m() => 2 !== 3;
+        ''',
+        const Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,
+                    left: '2', operator: '!==', right: '3')),
+  ],
+  'Index': const [
+    // Index
+    const Test(
+        '''
+        m() => 2[3];
+        ''',
+        const Visit(VisitKind.VISIT_INDEX,
+                    receiver: '2', index: '3')),
+    const Test(
+        '''
+        m() => --2[3];
+        ''',
+        const Visit(VisitKind.VISIT_INDEX_PREFIX,
+                    receiver: '2', index: '3', operator: '--')),
+    const Test(
+        '''
+        m() => 2[3]++;
+        ''',
+        const Visit(VisitKind.VISIT_INDEX_POSTFIX,
+                    receiver: '2', index: '3', operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+          operator [](_) => null;
+        }
+        class C extends B {
+          m() => super[42];
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_INDEX,
+                    element: 'function(B#[])',
+                    index: '42')),
+    const Test.clazz(
+        '''
+        class B {
+        }
+        class C extends B {
+          m() => super[42];
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX,
+                    index: '42')),
+    const Test.clazz(
+        '''
+        class B {
+          operator [](_) => null;
+          operator []=(a, b) {}
+        }
+        class C extends B {
+          m() => ++super[42];
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_INDEX_PREFIX,
+                    getter: 'function(B#[])',
+                    setter: 'function(B#[]=)',
+                    index: '42',
+                    operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+          operator []=(a, b) {}
+        }
+        class C extends B {
+          m() => ++super[42];
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,
+                    setter: 'function(B#[]=)',
+                    index: '42',
+                    operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+        }
+        class C extends B {
+          m() => ++super[42];
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,
+                    index: '42',
+                    operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+          operator [](_) => null;
+        }
+        class C extends B {
+          m() => ++super[42];
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,
+                    getter: 'function(B#[])',
+                    index: '42',
+                    operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+          operator [](_) => null;
+          operator []=(a, b) {}
+        }
+        class C extends B {
+          m() => super[42]--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_INDEX_POSTFIX,
+                    getter: 'function(B#[])',
+                    setter: 'function(B#[]=)',
+                    index: '42',
+                    operator: '--')),
+    const Test.clazz(
+        '''
+        class B {
+          operator []=(a, b) {}
+        }
+        class C extends B {
+          m() => super[42]--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,
+                    setter: 'function(B#[]=)',
+                    index: '42',
+                    operator: '--')),
+    const Test.clazz(
+        '''
+        class B {
+        }
+        class C extends B {
+          m() => super[42]--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,
+                    index: '42',
+                    operator: '--')),
+    const Test.clazz(
+        '''
+        class B {
+          operator [](_) => null;
+        }
+        class C extends B {
+          m() => super[42]--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,
+                    getter: 'function(B#[])',
+                    index: '42',
+                    operator: '--')),
+  ],
+  'Equals': const [
+    // Equals
+    const Test(
+        '''
+        m() => 2 == 3;
+        ''',
+        const Visit(VisitKind.VISIT_EQUALS,
+                    left: '2', right: '3')),
+    const Test.clazz(
+        '''
+        class B {
+          operator ==(_) => null;
+        }
+        class C extends B {
+          m() => super == 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_EQUALS,
+                    element: 'function(B#==)',
+                    right: '42')),
+  ],
+  'Not equals': const [
+    // Not equals
+    const Test(
+        '''
+        m() => 2 != 3;
+        ''',
+        const Visit(VisitKind.VISIT_NOT_EQUALS,
+                    left: '2', right: '3')),
+    const Test.clazz(
+        '''
+        class B {
+          operator ==(_) => null;
+        }
+        class C extends B {
+          m() => super != 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_NOT_EQUALS,
+                    element: 'function(B#==)',
+                    right: '42')),
+  ],
+  'Unary expression': const [
+    // Unary expression
+    const Test(
+        '''
+        m() => -false;
+        ''',
+        const Visit(VisitKind.VISIT_UNARY,
+                    expression: 'false', operator: '-')),
+    const Test(
+        '''
+        m() => ~false;
+        ''',
+        const Visit(VisitKind.VISIT_UNARY,
+                    expression: 'false', operator: '~')),
+    const Test.clazz(
+        '''
+        class B {
+          operator -() => null;
+        }
+        class C extends B {
+          m() => -super;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_UNARY,
+                    element: 'function(B#unary-)', operator: '-')),
+    const Test.clazz(
+        '''
+        class B {
+        }
+        class C extends B {
+          m() => -super;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_UNARY,
+                    operator: '-')),
+    const Test.clazz(
+        '''
+        class B {
+          operator ~() => null;
+        }
+        class C extends B {
+          m() => ~super;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_UNARY,
+                    element: 'function(B#~)', operator: '~')),
+    const Test(
+        '''
+        m() => !0;
+        ''',
+        const Visit(VisitKind.VISIT_NOT, expression: '0')),
+    const Test(
+        '''
+        m() => +false;
+        ''',
+        // TODO(johnniwinther): Should this be an
+        // ERROR_UNDEFINED_UNARY_EXPRESSION? Currently the parser just skips
+        // the `+`.
+        const []),
+  ],
+  'Index set': const [
+    // Index set
+    const Test(
+        '''
+        m() => 0[1] = 2;
+        ''',
+        const Visit(VisitKind.VISIT_INDEX_SET,
+            receiver: '0', index: '1', rhs: '2')),
+    const Test.clazz(
+        '''
+        class B {
+          operator []=(a, b) {}
+        }
+        class C extends B {
+          m() => super[1] = 2;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_INDEX_SET,
+            element: 'function(B#[]=)', index: '1', rhs: '2')),
+    const Test.clazz(
+        '''
+        class B {
+        }
+        class C extends B {
+          m() => super[1] = 2;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_SET,
+            index: '1', rhs: '2')),
+  ],
+  'Compound assignment': const [
+    // Compound assignment
+    const Test(
+        '''
+        m(a) => a.b += 42;
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_COMPOUND,
+              receiver: 'a', operator: '+=', rhs: '42',
+              getter: 'Selector(getter, b, arity=0)',
+              setter: 'Selector(setter, b, arity=1)'),
+          const Visit(VisitKind.VISIT_PARAMETER_GET,
+              element: 'parameter(m#a)')
+        ]),
+    const Test(
+        '''
+        m(a) => a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_PARAMETER_COMPOUND,
+            element: 'parameter(m#a)', operator: '+=', rhs: '42')),
+    const Test(
+        '''
+        m(final a) => a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_FINAL_PARAMETER_COMPOUND,
+            element: 'parameter(m#a)', operator: '+=', rhs: '42')),
+    const Test(
+        '''
+        m() {
+          var a;
+          a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_COMPOUND,
+            element: 'variable(m#a)', operator: '+=', rhs: '42')),
+    const Test(
+        '''
+        m() {
+          final a = 0;
+          a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,
+            element: 'variable(m#a)', operator: '+=', rhs: '42')),
+    const Test(
+        '''
+        m() {
+          a() {}
+          a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_COMPOUND,
+            element: 'function(m#a)', operator: '+=', rhs: '42')),
+    const Test(
+        '''
+        var a;
+        m() => a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_COMPOUND,
+            element: 'field(a)', operator: '+=', rhs: '42')),
+    const Test(
+        '''
+        get a => 0;
+        set a(_) {}
+        m() => a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,
+            getter: 'getter(a)', setter: 'setter(a)',
+            operator: '+=', rhs: '42')),
+    const Test(
+        '''
+        class C {
+          static var a;
+        }
+        m() => C.a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
+            element: 'field(C#a)', operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static var a;
+          m() => C.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
+            element: 'field(C#a)', operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static var a;
+          m() => a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
+            element: 'field(C#a)', operator: '+=', rhs: '42')),
+    const Test.prefix(
+        '''
+        class C {
+          static var a;
+        }
+        ''',
+        '''
+        m() => p.C.a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
+            element: 'field(C#a)', operator: '+=', rhs: '42')),
+    const Test(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+        }
+        m() => C.a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+          m() => C.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+          m() => a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '+=', rhs: '42')),
+    const Test.prefix(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+        }
+        ''',
+        '''
+        m() => p.C.a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '+=', rhs: '42')),
+    // TODO(johnniwinther): Enable these when dart2js supports method and setter
+    // with the same name.
+    /*const Test(
+        '''
+        class C {
+          static a() {}
+          static set a(_) {}
+        }
+        m() => C.a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+            getter: 'function(C#a)', setter: 'setter(C#a)',
+            operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static a() {}
+          static set a(_) {}
+          m() => C.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+            getter: 'function(C#a)', setter: 'setter(C#a)',
+            operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class C {
+          static a() {}
+          static set a(_) {}
+          m() => a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+            getter: 'function(C#a)', setter: 'setter(C#a)',
+            operator: '+=', rhs: '42')),
+    const Test.prefix(
+        '''
+        class C {
+          static a() {}
+          static set a(_) {}
+        }
+        ''',
+        '''
+        m() => p.C.a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+            getter: 'function(C#a)', setter: 'setter(C#a)',
+            operator: '+=', rhs: '42')),*/
+    const Test.clazz(
+        '''
+        class C {
+          var a;
+          m() => a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,
+            operator: '+=', rhs: '42',
+            getter: 'Selector(getter, a, arity=0)',
+            setter: 'Selector(setter, a, arity=1)')),
+    const Test.clazz(
+        '''
+        class C {
+          var a = 0;
+          m() => this.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,
+            operator: '+=', rhs: '42',
+            getter: 'Selector(getter, a, arity=0)',
+            setter: 'Selector(setter, a, arity=1)')),
+    const Test.clazz(
+        '''
+        class B {
+          var a = 0;
+        }
+        class C extends B {
+          m() => super.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FIELD_COMPOUND,
+            element: 'field(B#a)', operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+          final a = 0;
+        }
+        class C extends B {
+          m() => super.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_COMPOUND,
+            element: 'field(B#a)', operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+          get a => 0;
+          set a (_) {}
+        }
+        class C extends B {
+          m() => super.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,
+            getter: 'getter(B#a)', setter: 'setter(B#a)',
+            operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class A {
+          get a => 0;
+        }
+        class B extends A {
+          set a (_) {}
+        }
+        class C extends B {
+          m() => super.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,
+            getter: 'getter(A#a)', setter: 'setter(B#a)',
+            operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class A {
+          var a;
+        }
+        class B extends A {
+          get a => 0;
+        }
+
+        class C extends B {
+          m() => super.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_COMPOUND,
+            getter: 'getter(B#a)', setter: 'field(A#a)',
+            operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class A {
+          var a;
+        }
+        class B extends A {
+          set a(_) {}
+        }
+
+        class C extends B {
+          m() => super.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_COMPOUND,
+            getter: 'field(A#a)', setter: 'setter(B#a)',
+            operator: '+=', rhs: '42')),
+    // TODO(johnniwinther): Enable this when dart2js supports shadow setters.
+    /*const Test.clazz(
+        '''
+        class A {
+          var a;
+        }
+        class B extends A {
+          final a = 0;
+        }
+
+        class C extends B {
+          m() => super.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,
+            getter: 'field(B#a)', setter: 'field(A#a)',
+            operator: '+=', rhs: '42')),*/
+    const Test.clazz(
+        '''
+        class B {
+          a() {}
+        }
+        class C extends B {
+          m() => super.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_METHOD_COMPOUND,
+            element: 'function(B#a)',
+            operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+        }
+        class C extends B {
+          m() => super.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND,
+            operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+          set a(_) {}
+        }
+        class C extends B {
+          m() => super.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,
+            setter: 'setter(B#a)', operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+          get a => 42;
+        }
+        class C extends B {
+          m() => super.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,
+            getter: 'getter(B#a)', operator: '+=', rhs: '42')),
+
+    const Test.clazz(
+        '''
+        class C {
+          static set a(var value) { }
+          m() => a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,
+            setter: 'setter(C#a)', operator: '+=', rhs: '42')),
+
+    const Test.clazz(
+        '''
+        class C {
+          static get a => 42;
+          m() => C.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,
+            getter: 'getter(C#a)', operator: '+=', rhs: '42')),
+
+    const Test.clazz(
+        '''
+        class C {
+          static final a = 42;
+          m() => C.a += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_COMPOUND,
+            element: 'field(C#a)', operator: '+=', rhs: '42')),
+
+    const Test(
+        '''
+        class C {
+          static a(var value) { }
+        }
+        m() => C.a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_METHOD_COMPOUND,
+            element: 'function(C#a)', operator: '+=', rhs: '42')),
+
+    const Test(
+        '''
+        set a(var value) { }
+        m() => a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,
+            setter: 'setter(a)', operator: '+=', rhs: '42')),
+
+    const Test(
+        '''
+        get a => 42;
+        m() => a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,
+            getter: 'getter(a)', operator: '+=', rhs: '42')),
+
+    const Test(
+        '''
+        a(var value) { }
+        m() => a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_COMPOUND,
+            element: 'function(a)', operator: '+=', rhs: '42')),
+
+    const Test(
+        '''
+        final a = 42;
+        m() => a += 42;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,
+            element: 'field(a)', operator: '+=', rhs: '42')),
+
+    const Test(
+        '''
+        m() => unresolved += 42;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_COMPOUND,
+            operator: '+=', rhs: '42')),
+  ],
+  'Compound index assignment': const [
+    // Compound index assignment
+    const Test(
+        '''
+        m() => 0[1] += 42;
+        ''',
+        const Visit(VisitKind.VISIT_COMPOUND_INDEX_SET,
+            receiver: '0', index: '1', operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+          operator [](_) {}
+          operator []=(a, b) {}
+        }
+        class C extends B {
+          m() => super[1] += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_COMPOUND_INDEX_SET,
+            getter: 'function(B#[])', setter: 'function(B#[]=)',
+            index: '1', operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+          operator []=(a, b) {}
+        }
+        class C extends B {
+          m() => super[1] += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,
+            setter: 'function(B#[]=)',
+            index: '1', operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+        }
+        class C extends B {
+          m() => super[1] += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,
+            index: '1', operator: '+=', rhs: '42')),
+    const Test.clazz(
+        '''
+        class B {
+          operator [](_) {}
+        }
+        class C extends B {
+          m() => super[1] += 42;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,
+            getter: 'function(B#[])',
+            index: '1', operator: '+=', rhs: '42')),
+  ],
+  'Prefix expression': const [
+    // Prefix expression
+    const Test(
+        '''
+        m(a) => --a.b;
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_PREFIX,
+              receiver: 'a', operator: '--',
+              getter: 'Selector(getter, b, arity=0)',
+              setter: 'Selector(setter, b, arity=1)'),
+          const Visit(VisitKind.VISIT_PARAMETER_GET,
+              element: 'parameter(m#a)')
+        ]),
+    const Test(
+        '''
+        m(a) => ++a;
+        ''',
+        const Visit(VisitKind.VISIT_PARAMETER_PREFIX,
+            element: 'parameter(m#a)', operator: '++')),
+    const Test(
+        '''
+        m(final a) => ++a;
+        ''',
+        const Visit(VisitKind.VISIT_FINAL_PARAMETER_PREFIX,
+            element: 'parameter(m#a)', operator: '++')),
+    const Test(
+        '''
+        m() {
+          var a;
+          --a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_PREFIX,
+            element: 'variable(m#a)', operator: '--')),
+    const Test(
+        '''
+        m() {
+          final a = 42;
+          --a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_PREFIX,
+            element: 'variable(m#a)', operator: '--')),
+    const Test(
+        '''
+        m() {
+          a() {}
+          --a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_PREFIX,
+            element: 'function(m#a)', operator: '--')),
+    const Test(
+        '''
+        var a;
+        m() => ++a;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_PREFIX,
+            element: 'field(a)', operator: '++')),
+    const Test(
+        '''
+        get a => 0;
+        set a(_) {}
+        m() => --a;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,
+            getter: 'getter(a)', setter: 'setter(a)',
+            operator: '--')),
+    const Test(
+        '''
+        class C {
+          static var a;
+        }
+        m() => ++C.a;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
+            element: 'field(C#a)', operator: '++')),
+    const Test.clazz(
+        '''
+        class C {
+          static var a;
+          m() => ++C.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
+            element: 'field(C#a)', operator: '++')),
+    const Test.clazz(
+        '''
+        class C {
+          static var a;
+          m() => --a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
+            element: 'field(C#a)', operator: '--')),
+    const Test.prefix(
+        '''
+        class C {
+          static var a;
+        }
+        ''',
+        '''
+        m() => --p.C.a;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
+            element: 'field(C#a)', operator: '--')),
+    const Test(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+        }
+        m() => ++C.a;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+          m() => --C.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '--')),
+    const Test.clazz(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+          m() => --a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '--')),
+    const Test.prefix(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+        }
+        ''',
+        '''
+        m() => ++p.C.a;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class C {
+          var a;
+          m() => --a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,
+            operator: '--',
+            getter: 'Selector(getter, a, arity=0)',
+            setter: 'Selector(setter, a, arity=1)')),
+    const Test.clazz(
+        '''
+        class C {
+          var a = 0;
+          m() => ++this.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,
+            operator: '++',
+            getter: 'Selector(getter, a, arity=0)',
+            setter: 'Selector(setter, a, arity=1)')),
+    const Test.clazz(
+        '''
+        class B {
+          var a = 0;
+        }
+        class C extends B {
+          m() => --super.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FIELD_PREFIX,
+            element: 'field(B#a)', operator: '--')),
+    const Test.clazz(
+        '''
+        class B {
+          final a = 0;
+        }
+        class C extends B {
+          m() => --super.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_PREFIX,
+            element: 'field(B#a)', operator: '--')),
+    const Test.clazz(
+        '''
+        class B {
+          get a => 0;
+          set a (_) {}
+        }
+        class C extends B {
+          m() => --super.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,
+            getter: 'getter(B#a)', setter: 'setter(B#a)',
+            operator: '--')),
+    const Test.clazz(
+        '''
+        class A {
+          get a => 0;
+        }
+        class B extends A {
+          set a (_) {}
+        }
+        class C extends B {
+          m() => ++super.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,
+            getter: 'getter(A#a)', setter: 'setter(B#a)',
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class A {
+          var a;
+        }
+        class B extends A {
+          get a => 0;
+        }
+
+        class C extends B {
+          m() => --super.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_PREFIX,
+            getter: 'getter(B#a)', setter: 'field(A#a)',
+            operator: '--')),
+    const Test.clazz(
+        '''
+        class A {
+          var a;
+        }
+        class B extends A {
+          set a(_) {}
+        }
+
+        class C extends B {
+          m() => ++super.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_PREFIX,
+            getter: 'field(A#a)', setter: 'setter(B#a)',
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+          a() {}
+        }
+        class C extends B {
+          m() => ++super.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_METHOD_PREFIX,
+            element: 'function(B#a)',
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+        }
+        class C extends B {
+          m() => ++super.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_PREFIX,
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+          set a(_) {}
+        }
+        class C extends B {
+          m() => ++super.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,
+            setter: 'setter(B#a)', operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+          get a => 42;
+        }
+        class C extends B {
+          m() => ++super.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,
+            getter: 'getter(B#a)', operator: '++')),
+
+    const Test.clazz(
+        '''
+        class C {
+          static set a(var value) { }
+          m() => ++a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,
+            setter: 'setter(C#a)', operator: '++')),
+
+    const Test.clazz(
+        '''
+        class C {
+          static get a => 42;
+          m() => ++C.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,
+            getter: 'getter(C#a)', operator: '++')),
+
+    const Test.clazz(
+        '''
+        class C {
+          static final a = 42;
+          m() => ++C.a;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_PREFIX,
+            element: 'field(C#a)', operator: '++')),
+
+    const Test(
+        '''
+        class C {
+          static a(var value) { }
+        }
+        m() => ++C.a;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_METHOD_PREFIX,
+            element: 'function(C#a)', operator: '++')),
+
+    const Test(
+        '''
+        set a(var value) { }
+        m() => ++a;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,
+            setter: 'setter(a)', operator: '++')),
+
+    const Test(
+        '''
+        get a => 42;
+        m() => ++a;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,
+            getter: 'getter(a)', operator: '++')),
+
+    const Test(
+        '''
+        a(var value) { }
+        m() => ++a;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_PREFIX,
+            element: 'function(a)', operator: '++')),
+
+    const Test(
+        '''
+        final a = 42;
+        m() => ++a;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,
+            element: 'field(a)', operator: '++')),
+
+    const Test(
+        '''
+        m() => ++unresolved;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_PREFIX,
+            operator: '++')),
+  ],
+  'Postfix expression': const [
+    // Postfix expression
+    const Test(
+        '''
+        m(a) => a.b--;
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_POSTFIX,
+              receiver: 'a', operator: '--',
+              getter: 'Selector(getter, b, arity=0)',
+              setter: 'Selector(setter, b, arity=1)'),
+          const Visit(VisitKind.VISIT_PARAMETER_GET,
+              element: 'parameter(m#a)')
+        ]),
+    const Test(
+        '''
+        m(a) => a++;
+        ''',
+        const Visit(VisitKind.VISIT_PARAMETER_POSTFIX,
+            element: 'parameter(m#a)', operator: '++')),
+    const Test(
+        '''
+        m(final a) => a++;
+        ''',
+        const Visit(VisitKind.VISIT_FINAL_PARAMETER_POSTFIX,
+            element: 'parameter(m#a)', operator: '++')),
+    const Test(
+        '''
+        m() {
+          var a;
+          a--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_LOCAL_VARIABLE_POSTFIX,
+            element: 'variable(m#a)', operator: '--')),
+    const Test(
+        '''
+        m() {
+          final a = 42;
+          a--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,
+            element: 'variable(m#a)', operator: '--')),
+    const Test(
+        '''
+        m() {
+          a() {}
+          a--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_LOCAL_FUNCTION_POSTFIX,
+            element: 'function(m#a)', operator: '--')),
+    const Test(
+        '''
+        var a;
+        m() => a++;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_POSTFIX,
+            element: 'field(a)', operator: '++')),
+    const Test(
+        '''
+        get a => 0;
+        set a(_) {}
+        m() => a--;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,
+            getter: 'getter(a)', setter: 'setter(a)',
+            operator: '--')),
+    const Test(
+        '''
+        class C {
+          static var a;
+        }
+        m() => C.a++;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
+            element: 'field(C#a)', operator: '++')),
+    const Test.clazz(
+        '''
+        class C {
+          static var a;
+          m() => C.a++;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
+            element: 'field(C#a)', operator: '++')),
+    const Test.clazz(
+        '''
+        class C {
+          static var a;
+          m() => a--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
+            element: 'field(C#a)', operator: '--')),
+    const Test.prefix(
+        '''
+        class C {
+          static var a;
+        }
+        ''',
+        '''
+        m() => p.C.a--;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
+            element: 'field(C#a)', operator: '--')),
+    const Test(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+        }
+        m() => C.a++;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+          m() => C.a--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '--')),
+    const Test.clazz(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+          m() => a--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '--')),
+    const Test.prefix(
+        '''
+        class C {
+          static get a => 0;
+          static set a(_) {}
+        }
+        ''',
+        '''
+        m() => p.C.a++;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
+            getter: 'getter(C#a)', setter: 'setter(C#a)',
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class C {
+          var a;
+          m() => a--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,
+            operator: '--',
+            getter: 'Selector(getter, a, arity=0)',
+            setter: 'Selector(setter, a, arity=1)')),
+    const Test.clazz(
+        '''
+        class C {
+          var a = 0;
+          m() => this.a++;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,
+            operator: '++',
+            getter: 'Selector(getter, a, arity=0)',
+            setter: 'Selector(setter, a, arity=1)')),
+    const Test.clazz(
+        '''
+        class B {
+          var a = 0;
+        }
+        class C extends B {
+          m() => super.a--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FIELD_POSTFIX,
+            element: 'field(B#a)', operator: '--')),
+    const Test.clazz(
+        '''
+        class B {
+          final a = 0;
+        }
+        class C extends B {
+          m() => super.a--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_POSTFIX,
+            element: 'field(B#a)', operator: '--')),
+    const Test.clazz(
+        '''
+        class B {
+          get a => 0;
+          set a (_) {}
+        }
+        class C extends B {
+          m() => super.a--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,
+            getter: 'getter(B#a)', setter: 'setter(B#a)',
+            operator: '--')),
+    const Test.clazz(
+        '''
+        class A {
+          get a => 0;
+        }
+        class B extends A {
+          set a (_) {}
+        }
+        class C extends B {
+          m() => super.a++;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,
+            getter: 'getter(A#a)', setter: 'setter(B#a)',
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class A {
+          var a;
+        }
+        class B extends A {
+          get a => 0;
+        }
+
+        class C extends B {
+          m() => super.a--;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_POSTFIX,
+            getter: 'getter(B#a)', setter: 'field(A#a)',
+            operator: '--')),
+    const Test.clazz(
+        '''
+        class A {
+          var a;
+        }
+        class B extends A {
+          set a(_) {}
+        }
+
+        class C extends B {
+          m() => super.a++;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_POSTFIX,
+            getter: 'field(A#a)', setter: 'setter(B#a)',
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+          a() {}
+        }
+        class C extends B {
+          m() => super.a++;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_SUPER_METHOD_POSTFIX,
+            element: 'function(B#a)',
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+        }
+        class C extends B {
+          m() => super.a++;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_POSTFIX,
+            operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+          set a(_) {}
+        }
+        class C extends B {
+          m() => super.a++;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,
+            setter: 'setter(B#a)', operator: '++')),
+    const Test.clazz(
+        '''
+        class B {
+          get a => 42;
+        }
+        class C extends B {
+          m() => super.a++;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,
+            getter: 'getter(B#a)', operator: '++')),
+
+    const Test.clazz(
+        '''
+        class C {
+          static set a(var value) { }
+          m() => a++;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,
+            setter: 'setter(C#a)', operator: '++')),
+
+    const Test.clazz(
+        '''
+        class C {
+          static get a => 42;
+          m() => C.a++;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,
+            getter: 'getter(C#a)', operator: '++')),
+
+    const Test.clazz(
+        '''
+        class C {
+          static final a = 42;
+          m() => C.a++;
+        }
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_POSTFIX,
+            element: 'field(C#a)', operator: '++')),
+
+    const Test(
+        '''
+        class C {
+          static a(var value) { }
+        }
+        m() => C.a++;
+        ''',
+        const Visit(VisitKind.VISIT_STATIC_METHOD_POSTFIX,
+            element: 'function(C#a)', operator: '++')),
+
+    const Test(
+        '''
+        set a(var value) { }
+        m() => a++;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,
+            setter: 'setter(a)', operator: '++')),
+
+    const Test(
+        '''
+        get a => 42;
+        m() => a++;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,
+            getter: 'getter(a)', operator: '++')),
+
+    const Test(
+        '''
+        a(var value) { }
+        m() => a++;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_POSTFIX,
+            element: 'function(a)', operator: '++')),
+
+    const Test(
+        '''
+        final a = 42;
+        m() => a++;
+        ''',
+        const Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,
+            element: 'field(a)', operator: '++')),
+
+    const Test(
+        '''
+        m() => unresolved++;
+        ''',
+        const Visit(VisitKind.VISIT_UNRESOLVED_POSTFIX,
+            operator: '++')),
+  ],
+  'Constructor invocations': const [
+    const Test(
+        '''
+        class Class {
+          const Class(a, b);
+        }
+        m() => const Class(true, 42);
+        ''',
+        const Visit(VisitKind.VISIT_CONST_CONSTRUCTOR_INVOKE,
+            constant: 'const Class(true, 42)')),
+    const Test(
+        '''
+        m() => const bool.fromEnvironment('foo');
+        ''',
+        const Visit(VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+            constant:
+                'const bool.fromEnvironment("foo")')),
+    const Test(
+        '''
+        m() => const bool.fromEnvironment('foo', defaultValue: true);
+        ''',
+        const Visit(VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+            constant: 'const bool.fromEnvironment("foo", defaultValue: true)')),
+    const Test(
+        '''
+        m() => const int.fromEnvironment('foo');
+        ''',
+        const Visit(VisitKind.VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+            constant: 'const int.fromEnvironment("foo")')),
+    const Test(
+        '''
+        m() => const String.fromEnvironment('foo');
+        ''',
+        const Visit(VisitKind.VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+            constant:
+                'const String.fromEnvironment("foo")')),
+    const Test(
+        '''
+        class Class {
+          Class(a, b);
+        }
+        m() => const Class(true, 42);
+        ''',
+        const Visit(VisitKind.ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,
+            element: 'generative_constructor(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class {}
+        m() => new Class();
+        ''',
+        const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+            element: 'generative_constructor(Class#)',
+            arguments: '()',
+            type: 'Class',
+            selector: 'CallStructure(arity=0)')),
+    const Test(
+        '''
+        class Class {
+          Class(a, b);
+        }
+        m() => new Class(true, 42);
+        ''',
+        const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+            element: 'generative_constructor(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class {
+          Class.named(a, b);
+        }
+        m() => new Class.named(true, 42);
+        ''',
+        const Visit(VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+            element: 'generative_constructor(Class#named)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class {}
+        m() => new Class(true, 42);
+        ''',
+        const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
+            element: 'generative_constructor(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class {
+          Class(a, b) : this._(a, b);
+          Class._(a, b);
+        }
+        m() => new Class(true, 42);
+        ''',
+        const Visit(VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
+            element: 'generative_constructor(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class {
+          Class() : this._(true, 42);
+          Class._(a, b);
+        }
+        m() => new Class(true, 42);
+        ''',
+        const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
+            element: 'generative_constructor(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class {
+          factory Class(a, b) => new Class._(a, b);
+          Class._(a, b);
+        }
+        m() => new Class(true, 42);
+        ''',
+        const Visit(VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,
+            element: 'function(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class {
+          factory Class() => new Class._(true, 42);
+          Class._(a, b);
+        }
+        m() => new Class(true, 42);
+        ''',
+        const Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
+            element: 'function(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class<T> {
+          factory Class(a, b) = Class<int>.a;
+          factory Class.a(a, b) = Class<Class<T>>.b;
+          Class.b(a, b);
+        }
+        m() => new Class<double>(true, 42);
+        ''',
+        const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+            element: 'function(Class#)',
+            arguments: '(true,42)',
+            type: 'Class<double>',
+            target: 'generative_constructor(Class#b)',
+            targetType: 'Class<Class<int>>',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class<T> {
+          factory Class(a) = Class<int>.a;
+          factory Class.a(a, [b]) = Class<Class<T>>.b;
+          Class.b(a, [b]);
+        }
+        m() => new Class<double>(true, 42);
+        ''',
+        const Visit(VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+            element: 'function(Class#)',
+            arguments: '(true,42)',
+            type: 'Class<double>',
+            target: 'generative_constructor(Class#b)',
+            targetType: 'Class<Class<int>>',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class {
+          factory Class() = Class._;
+          Class._();
+        }
+        m() => new Class(true, 42);
+        ''',
+        const Visit(
+            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+            element: 'function(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class<T> {
+          factory Class(a, b) = Class<int>.a;
+          factory Class.a(a, b) = Class<Class<T>>.b;
+          Class.b(a);
+        }
+        m() => new Class<double>(true, 42);
+        ''',
+        const Visit(
+            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+            element: 'function(Class#)',
+            arguments: '(true,42)',
+            type: 'Class<double>',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class {
+          Class(a, b);
+        }
+        m() => new Class.unresolved(true, 42);
+        ''',
+        const Visit(
+            VisitKind.VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,
+            arguments: '(true,42)')),
+    const Test(
+        '''
+        m() => new Unresolved(true, 42);
+        ''',
+        const Visit(
+            VisitKind.VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,
+            arguments: '(true,42)')),
+    const Test(
+        '''
+        abstract class AbstractClass {}
+        m() => new AbstractClass();
+        ''',
+        const Visit(
+            VisitKind.VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
+            element: 'generative_constructor(AbstractClass#)',
+            type: 'AbstractClass',
+            arguments: '()',
+            selector: 'CallStructure(arity=0)')),
+    const Test(
+        '''
+        class Class {
+          factory Class(a, b) = Unresolved;
+        }
+        m() => new Class(true, 42);
+        ''',
+        const Visit(
+            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+            element: 'function(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class {
+          factory Class(a, b) = Class.named;
+        }
+        m() => new Class(true, 42);
+        ''',
+        const Visit(
+            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+            element: 'function(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        class Class {
+          factory Class(a, b) = Class.named;
+          factory Class.named(a, b) = Class.unresolved;
+        }
+        m() => new Class(true, 42);
+        ''',
+        const Visit(
+            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+            element: 'function(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+    const Test(
+        '''
+        abstract class AbstractClass {
+          AbstractClass(a, b);
+        }
+        class Class {
+          factory Class(a, b) = AbstractClass;
+        }
+        m() => new Class(true, 42);
+        ''',
+        const Visit(
+            VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+            element: 'function(Class#)',
+            arguments: '(true,42)',
+            type: 'Class',
+            selector: 'CallStructure(arity=2)')),
+  ],
+  'If not null expressions': const [
+    const Test(
+        '''
+        m(a) => a?.b;
+        ''',
+        const [
+          const Visit(
+              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
+              receiver: 'a',
+              name: 'b'),
+          const Visit(
+              VisitKind.VISIT_PARAMETER_GET,
+              element: 'parameter(m#a)'),
+        ]),
+    const Test(
+        '''
+        class C {
+          static var b;
+        }
+        m(a) => C?.b;
+        ''',
+        const [
+          const Visit(
+              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
+              receiver: 'C',
+              name: 'b'),
+          const Visit(
+              VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
+              constant: 'C'),
+        ]),
+    const Test(
+        '''
+        m(a) => a?.b = 42;
+        ''',
+        const [
+          const Visit(
+              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,
+              receiver: 'a',
+              name: 'b',
+              rhs: '42'),
+          const Visit(
+              VisitKind.VISIT_PARAMETER_GET,
+              element: 'parameter(m#a)'),
+        ]),
+    const Test(
+        '''
+        m(a) => a?.b(42, true);
+        ''',
+        const [
+          const Visit(
+              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,
+              receiver: 'a',
+              arguments: '(42,true)',
+              selector: 'Selector(call, b, arity=2)'),
+          const Visit(
+              VisitKind.VISIT_PARAMETER_GET,
+              element: 'parameter(m#a)'),
+        ]),
+    const Test(
+        '''
+        m(a) => ++a?.b;
+        ''',
+        const [
+          const Visit(
+              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,
+              receiver: 'a',
+              getter: 'Selector(getter, b, arity=0)',
+              setter: 'Selector(setter, b, arity=1)',
+              operator: '++'),
+          const Visit(
+              VisitKind.VISIT_PARAMETER_GET,
+              element: 'parameter(m#a)'),
+        ]),
+    const Test(
+        '''
+        m(a) => a?.b--;
+        ''',
+        const [
+          const Visit(
+              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,
+              receiver: 'a',
+              getter: 'Selector(getter, b, arity=0)',
+              setter: 'Selector(setter, b, arity=1)',
+              operator: '--'),
+          const Visit(
+              VisitKind.VISIT_PARAMETER_GET,
+              element: 'parameter(m#a)'),
+        ]),
+    const Test(
+        '''
+        m(a) => a?.b *= 42;
+        ''',
+        const [
+          const Visit(
+              VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,
+              receiver: 'a',
+              getter: 'Selector(getter, b, arity=0)',
+              setter: 'Selector(setter, b, arity=1)',
+              operator: '*=',
+              rhs: '42'),
+          const Visit(
+              VisitKind.VISIT_PARAMETER_GET,
+              element: 'parameter(m#a)'),
+        ]),
+    const Test(
+        '''
+        m(a, b) => a ?? b;
+        ''',
+        const [
+          const Visit(VisitKind.VISIT_IF_NULL,
+                      left: 'a', right: 'b'),
+          const Visit(
+              VisitKind.VISIT_PARAMETER_GET,
+              element: 'parameter(m#a)'),
+          const Visit(
+              VisitKind.VISIT_PARAMETER_GET,
+              element: 'parameter(m#b)'),
+       ]),
+    const Test(
+        '''
+        m(a) => a ??= 42;
+        ''',
+        const Visit(
+            VisitKind.VISIT_PARAMETER_COMPOUND,
+            element: 'parameter(m#a)',
+            operator: '??=',
+            rhs: '42')),
+  ],
+};
diff --git a/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart b/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
index 511b1f7..a602e2e 100644
--- a/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
+++ b/tests/compiler/dart2js/semantic_visitor_test_send_visitor.dart
@@ -1,2943 +1,2943 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file

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

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

-

-part of dart2js.semantics_visitor_test;

-

-class SemanticSendTestVisitor extends SemanticTestVisitor {

-

-  SemanticSendTestVisitor(TreeElements elements) : super(elements);

-

-  @override

-  visitAs(

-      Send node,

-      Node expression,

-      DartType type,

-      arg) {

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

-        expression: expression, type: type));

-    apply(expression, arg);

-  }

-

-  @override

-  visitAssert(

-      Send node,

-      Node expression,

-      arg) {

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

-    super.visitAssert(node, expression, arg);

-  }

-

-  @override

-  errorInvalidAssert(

-      Send node,

-      NodeList arguments,

-      arg) {

-    visits.add(new Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: arguments));

-    super.errorInvalidAssert(node, arguments, arg);

-  }

-

-  @override

-  visitBinary(

-      Send node,

-      Node left,

-      BinaryOperator operator,

-      Node right,

-      arg) {

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

-        left: left, operator: operator, right: right));

-    super.visitBinary(node, left, operator, right, arg);

-  }

-

-  @override

-  errorUndefinedBinaryExpression(

-      Send node,

-      Node left,

-      Operator operator,

-      Node right,

-      arg) {

-    visits.add(new Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,

-        left: left, operator: operator, right: right));

-    super.errorUndefinedBinaryExpression(node, left, operator, right, arg);

-  }

-

-  @override

-  visitIndex(

-      Send node,

-      Node receiver,

-      Node index,

-      arg) {

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

-        receiver: receiver, index: index));

-    apply(receiver, arg);

-    apply(index, arg);

-  }

-

-  @override

-  visitClassTypeLiteralGet(

-      Send node,

-      ConstantExpression constant,

-      arg) {

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

-        constant: constant.getText()));

-  }

-

-  @override

-  visitClassTypeLiteralInvoke(

-      Send node,

-      ConstantExpression constant,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

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

-    apply(arguments, arg);

-  }

-

-  @override

-  visitClassTypeLiteralSet(

-      SendSet node,

-      ConstantExpression constant,

-      Node rhs,

-      arg) {

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

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

-    super.visitClassTypeLiteralSet(node, constant, rhs, arg);

-  }

-

-  @override

-  visitNotEquals(

-      Send node,

-      Node left,

-      Node right,

-      arg) {

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

-        left: left, right: right));

-    apply(left, arg);

-    apply(right, arg);

-  }

-

-  @override

-  visitDynamicPropertyPrefix(

-      Send node,

-      Node receiver,

-      IncDecOperator operator,

-      Selector getterSelector,

-      Selector setterSelector,

-      arg) {

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

-        receiver: receiver, operator: operator,

-        getter: getterSelector, setter: setterSelector));

-    apply(receiver, arg);

-  }

-

-  @override

-  visitDynamicPropertyPostfix(

-      Send node,

-      Node receiver,

-      IncDecOperator operator,

-      Selector getterSelector,

-      Selector setterSelector,

-      arg) {

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

-        receiver: receiver, operator: operator,

-        getter: getterSelector, setter: setterSelector));

-    apply(receiver, arg);

-  }

-

-  @override

-  visitDynamicPropertyGet(

-      Send node,

-      Node receiver,

-      Selector selector,

-      arg) {

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

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

-    apply(receiver, arg);

-  }

-

-  @override

-  visitDynamicPropertyInvoke(

-      Send node,

-      Node receiver,

-      NodeList arguments,

-      Selector selector,

-      arg) {

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

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

-    apply(receiver, arg);

-    apply(arguments, arg);

-  }

-

-  @override

-  visitDynamicPropertySet(

-      SendSet node,

-      Node receiver,

-      Selector selector,

-      Node rhs,

-      arg) {

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

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

-    super.visitDynamicPropertySet(node, receiver, selector, rhs, arg);

-  }

-

-  @override

-  visitDynamicTypeLiteralGet(

-      Send node,

-      ConstantExpression constant,

-      arg) {

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

-        constant: constant.getText()));

-  }

-

-  @override

-  visitDynamicTypeLiteralInvoke(

-      Send node,

-      ConstantExpression constant,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

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

-  }

-

-  @override

-  visitDynamicTypeLiteralSet(

-      Send node,

-      ConstantExpression constant,

-      Node rhs,

-      arg) {

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

-        rhs: rhs));

-    super.visitDynamicTypeLiteralSet(node, constant, rhs, arg);

-  }

-

-  @override

-  visitExpressionInvoke(

-      Send node,

-      Node expression,

-      NodeList arguments,

-      Selector selector,

-      arg) {

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

-        receiver: expression, arguments: arguments));

-  }

-

-  @override

-  visitIs(

-      Send node,

-      Node expression,

-      DartType type,

-      arg) {

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

-        expression: expression, type: type));

-    apply(expression, arg);

-  }

-

-  @override

-  visitIsNot(

-      Send node,

-      Node expression,

-      DartType type,

-      arg) {

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

-        expression: expression, type: type));

-    apply(expression, arg);

-  }

-

-  @override

-  visitLogicalAnd(

-      Send node,

-      Node left,

-      Node right,

-      arg) {

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

-        left: left, right: right));

-    apply(left, arg);

-    apply(right, arg);

-  }

-

-  @override

-  visitLogicalOr(

-      Send node,

-      Node left,

-      Node right,

-      arg) {

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

-        left: left, right: right));

-    apply(left, arg);

-    apply(right, arg);

-  }

-

-  @override

-  visitLocalFunctionGet(

-      Send node,

-      LocalFunctionElement function,

-      arg) {

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

-                         element: function));

-  }

-

-  @override

-  visitLocalFunctionSet(

-      SendSet node,

-      LocalFunctionElement function,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_SET,

-        element: function, rhs: rhs));

-    super.visitLocalFunctionSet(node, function, rhs, arg);

-  }

-

-  @override

-  visitLocalFunctionInvoke(

-      Send node,

-      LocalFunctionElement function,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: function, arguments: arguments, selector: callStructure));

-    super.visitLocalFunctionInvoke(

-        node, function, arguments, callStructure, arg);

-  }

-

-  @override

-  visitLocalFunctionIncompatibleInvoke(

-      Send node,

-      LocalFunctionElement function,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,

-        element: function, arguments: arguments, selector: callStructure));

-    super.visitLocalFunctionInvoke(

-        node, function, arguments, callStructure, arg);

-  }

-

-  @override

-  visitLocalVariableGet(

-      Send node,

-      LocalVariableElement variable,

-      arg) {

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

-                         element: variable));

-  }

-

-  @override

-  visitLocalVariableInvoke(

-      Send node,

-      LocalVariableElement variable,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: variable, arguments: arguments, selector: callStructure));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitLocalVariableSet(

-      SendSet node,

-      LocalVariableElement variable,

-      Node rhs,

-      arg) {

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

-        element: variable, rhs: rhs));

-    super.visitLocalVariableSet(node, variable, rhs, arg);

-  }

-

-  @override

-  visitFinalLocalVariableSet(

-      SendSet node,

-      LocalVariableElement variable,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_SET,

-        element: variable, rhs: rhs));

-    super.visitFinalLocalVariableSet(node, variable, rhs, arg);

-  }

-

-  @override

-  visitParameterGet(

-      Send node,

-      ParameterElement parameter,

-      arg) {

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

-  }

-

-  @override

-  visitParameterInvoke(

-      Send node,

-      ParameterElement parameter,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: parameter, arguments: arguments, selector: callStructure));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitParameterSet(

-      SendSet node,

-      ParameterElement parameter,

-      Node rhs,

-      arg) {

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

-                         element: parameter, rhs: rhs));

-    super.visitParameterSet(node, parameter, rhs, arg);

-  }

-

-  @override

-  visitFinalParameterSet(

-      SendSet node,

-      ParameterElement parameter,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_SET,

-                         element: parameter, rhs: rhs));

-    super.visitFinalParameterSet(node, parameter, rhs, arg);

-  }

-

-  @override

-  visitStaticFieldGet(

-      Send node,

-      FieldElement field,

-      arg) {

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

-  }

-

-  @override

-  visitStaticFieldInvoke(

-      Send node,

-      FieldElement field,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: field, arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitStaticFieldSet(

-      SendSet node,

-      FieldElement field,

-      Node rhs,

-      arg) {

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

-        element: field, rhs: rhs));

-    super.visitStaticFieldSet(node, field, rhs, arg);

-  }

-

-  @override

-  visitFinalStaticFieldSet(

-      SendSet node,

-      FieldElement field,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FINAL_STATIC_FIELD_SET,

-        element: field, rhs: rhs));

-    super.visitFinalStaticFieldSet(node, field, rhs, arg);

-  }

-

-  @override

-  visitStaticFunctionGet(

-      Send node,

-      MethodElement function,

-      arg) {

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

-        element: function));

-  }

-

-  @override

-  visitStaticFunctionSet(

-      SendSet node,

-      MethodElement function,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_SET,

-        element: function, rhs: rhs));

-    super.visitStaticFunctionSet(node, function, rhs, arg);

-  }

-

-  @override

-  visitStaticFunctionInvoke(

-      Send node,

-      MethodElement function,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: function, arguments: arguments));

-    super.visitStaticFunctionInvoke(

-        node, function, arguments, callStructure, arg);

-  }

-

-  @override

-  visitStaticFunctionIncompatibleInvoke(

-      Send node,

-      MethodElement function,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,

-        element: function, arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitStaticGetterGet(

-      Send node,

-      FunctionElement getter,

-      arg) {

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

-        element: getter));

-    super.visitStaticGetterGet(node, getter, arg);

-  }

-

-  @override

-  visitStaticGetterSet(

-      SendSet node,

-      MethodElement getter,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SET,

-        element: getter, rhs: rhs));

-    super.visitStaticGetterSet(node, getter, rhs, arg);

-  }

-

-  @override

-  visitStaticGetterInvoke(

-      Send node,

-      FunctionElement getter,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: getter, arguments: arguments));

-    super.visitStaticGetterInvoke(node, getter, arguments, callStructure, arg);

-  }

-

-  @override

-  visitStaticSetterInvoke(

-      Send node,

-      FunctionElement setter,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,

-        element: setter, arguments: arguments));

-    super.visitStaticSetterInvoke(node, setter, arguments, callStructure, arg);

-  }

-

-  @override

-  visitStaticSetterGet(

-      Send node,

-      FunctionElement getter,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_GET,

-        element: getter));

-    super.visitStaticSetterGet(node, getter, arg);

-  }

-

-  @override

-  visitStaticSetterSet(

-      SendSet node,

-      FunctionElement setter,

-      Node rhs,

-      arg) {

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

-        element: setter, rhs: rhs));

-    super.visitStaticSetterSet(node, setter, rhs, arg);

-  }

-

-  @override

-  visitSuperBinary(

-      Send node,

-      FunctionElement function,

-      BinaryOperator operator,

-      Node argument,

-      arg) {

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

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

-    apply(argument, arg);

-  }

-

-  @override

-  visitUnresolvedSuperBinary(

-      Send node,

-      Element element,

-      BinaryOperator operator,

-      Node argument,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_BINARY,

-        operator: operator, right: argument));

-    apply(argument, arg);

-  }

-

-  @override

-  visitSuperIndex(

-      Send node,

-      FunctionElement function,

-      Node index,

-      arg) {

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

-            element: function, index: index));

-    apply(index, arg);

-  }

-

-  @override

-  visitUnresolvedSuperIndex(

-      Send node,

-      Element element,

-      Node index,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX,

-        index: index));

-    apply(index, arg);

-  }

-

-  @override

-  visitSuperNotEquals(

-      Send node,

-      FunctionElement function,

-      Node argument,

-      arg) {

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

-            element: function, right: argument));

-    apply(argument, arg);

-  }

-

-  @override

-  visitThisGet(Identifier node, arg) {

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

-  }

-

-  @override

-  visitThisInvoke(

-      Send node,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-    apply(arguments, arg);

-  }

-

-  @override

-  visitThisPropertyGet(

-      Send node,

-      Selector selector,

-      arg) {

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

-                         name: selector.name));

-  }

-

-  @override

-  visitThisPropertyInvoke(

-      Send node,

-      NodeList arguments,

-      Selector selector,

-      arg) {

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

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

-    apply(arguments, arg);

-  }

-

-  @override

-  visitThisPropertySet(

-      SendSet node,

-      Selector selector,

-      Node rhs,

-      arg) {

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

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitTopLevelFieldGet(

-      Send node,

-      FieldElement field,

-      arg) {

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

-  }

-

-  @override

-  visitTopLevelFieldInvoke(

-      Send node,

-      FieldElement field,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: field, arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitTopLevelFieldSet(

-      SendSet node,

-      FieldElement field,

-      Node rhs,

-      arg) {

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

-        element: field, rhs: rhs));

-    super.visitTopLevelFieldSet(node, field, rhs, arg);

-  }

-

-  @override

-  visitFinalTopLevelFieldSet(

-      SendSet node,

-      FieldElement field,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FINAL_TOP_LEVEL_FIELD_SET,

-        element: field, rhs: rhs));

-    super.visitFinalTopLevelFieldSet(node, field, rhs, arg);

-  }

-

-  @override

-  visitTopLevelFunctionGet(

-      Send node,

-      MethodElement function,

-      arg) {

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

-        element: function));

-  }

-

-  @override

-  visitTopLevelFunctionSet(

-      SendSet node,

-      MethodElement function,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_SET,

-        element: function, rhs: rhs));

-    super.visitTopLevelFunctionSet(node, function, rhs, arg);

-  }

-

-  @override

-  visitTopLevelFunctionInvoke(

-      Send node,

-      MethodElement function,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: function, arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitTopLevelFunctionIncompatibleInvoke(

-      Send node,

-      MethodElement function,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,

-        element: function, arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitTopLevelGetterGet(

-      Send node,

-      FunctionElement getter,

-      arg) {

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

-        element: getter));

-    super.visitTopLevelGetterGet(node, getter, arg);

-  }

-

-  @override

-  visitTopLevelSetterGet(

-      Send node,

-      FunctionElement setter,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_GET,

-        element: setter));

-    super.visitTopLevelSetterGet(node, setter, arg);

-  }

-

-  @override

-  visitTopLevelGetterInvoke(

-      Send node,

-      FunctionElement getter,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: getter, arguments: arguments));

-    super.visitTopLevelGetterInvoke(

-        node, getter, arguments, callStructure, arg);

-  }

-

-  @override

-  visitTopLevelSetterInvoke(

-      Send node,

-      FunctionElement setter,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_INVOKE,

-        element: setter, arguments: arguments));

-    super.visitTopLevelSetterInvoke(

-        node, setter, arguments, callStructure, arg);

-  }

-

-  @override

-  visitTopLevelGetterSet(

-      SendSet node,

-      FunctionElement getter,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SET,

-        element: getter, rhs: rhs));

-    super.visitTopLevelGetterSet(node, getter, rhs, arg);

-  }

-

-  @override

-  visitTopLevelSetterSet(

-      SendSet node,

-      FunctionElement setter,

-      Node rhs,

-      arg) {

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

-        element: setter, rhs: rhs));

-    super.visitTopLevelSetterSet(node, setter, rhs, arg);

-  }

-

-  @override

-  visitTypeVariableTypeLiteralGet(

-      Send node,

-      TypeVariableElement element,

-      arg) {

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

-        element: element));

-  }

-

-  @override

-  visitTypeVariableTypeLiteralInvoke(

-      Send node,

-      TypeVariableElement element,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: element, arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitTypeVariableTypeLiteralSet(

-      SendSet node,

-      TypeVariableElement element,

-      Node rhs,

-      arg) {

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

-        element: element, rhs: rhs));

-    super.visitTypeVariableTypeLiteralSet(node, element, rhs, arg);

-  }

-

-  @override

-  visitTypedefTypeLiteralGet(

-      Send node,

-      ConstantExpression constant,

-      arg) {

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

-        constant: constant.getText()));

-  }

-

-  @override

-  visitTypedefTypeLiteralInvoke(

-      Send node,

-      ConstantExpression constant,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

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

-    apply(arguments, arg);

-  }

-

-  @override

-  visitTypedefTypeLiteralSet(

-      SendSet node,

-      ConstantExpression constant,

-      Node rhs,

-      arg) {

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

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

-    super.visitTypedefTypeLiteralSet(node, constant, rhs, arg);

-  }

-

-  @override

-  visitUnary(

-      Send node,

-      UnaryOperator operator,

-      Node expression,

-      arg) {

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

-        expression: expression, operator: operator));

-    super.visitUnary(node, operator, expression, arg);

-  }

-

-  @override

-  errorUndefinedUnaryExpression(

-      Send node,

-      Operator operator,

-      Node expression,

-      arg) {

-    visits.add(new Visit(VisitKind.ERROR_UNDEFINED_UNARY_EXPRESSION,

-        expression: expression, operator: operator));

-    super.errorUndefinedUnaryExpression(node, operator, expression, arg);

-  }

-

-  @override

-  visitNot(

-      Send node,

-      Node expression,

-      arg) {

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

-    apply(expression, arg);

-  }

-

-  @override

-  visitSuperFieldGet(

-      Send node,

-      FieldElement field,

-      arg) {

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

-  }

-

-  @override

-  visitUnresolvedSuperGet(

-      Send node,

-      Element element,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GET));

-  }

-

-  @override

-  visitSuperFieldInvoke(

-      Send node,

-      FieldElement field,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: field, arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitUnresolvedSuperInvoke(

-      Send node,

-      Element element,

-      NodeList arguments,

-      Selector selector,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INVOKE,

-        arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitSuperFieldSet(

-      SendSet node,

-      FieldElement field,

-      Node rhs,

-      arg) {

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

-        element: field, rhs: rhs));

-    super.visitSuperFieldSet(node, field, rhs, arg);

-  }

-

-  @override

-  visitFinalSuperFieldSet(

-      SendSet node,

-      FieldElement field,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FINAL_SUPER_FIELD_SET,

-        element: field, rhs: rhs));

-    super.visitFinalSuperFieldSet(node, field, rhs, arg);

-  }

-

-  @override

-  visitSuperMethodGet(

-      Send node,

-      MethodElement method,

-      arg) {

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

-  }

-

-  @override

-  visitSuperMethodSet(

-      SendSet node,

-      MethodElement method,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SET,

-        element: method, rhs: rhs));

-    super.visitSuperMethodSet(node, method, rhs, arg);

-  }

-

-  @override

-  visitSuperMethodInvoke(

-      Send node,

-      MethodElement method,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: method, arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitSuperMethodIncompatibleInvoke(

-      Send node,

-      MethodElement method,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,

-        element: method, arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitSuperGetterGet(

-      Send node,

-      FunctionElement getter,

-      arg) {

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

-    super.visitSuperGetterGet(node, getter, arg);

-  }

-

-  @override

-  visitSuperSetterGet(

-      Send node,

-      FunctionElement setter,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_GET, element: setter));

-    super.visitSuperSetterGet(node, setter, arg);

-  }

-

-  @override

-  visitSuperGetterInvoke(

-      Send node,

-      FunctionElement getter,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

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

-        element: getter, arguments: arguments));

-    super.visitSuperGetterInvoke(node, getter, arguments, callStructure, arg);

-  }

-

-  @override

-  visitSuperSetterInvoke(

-      Send node,

-      FunctionElement setter,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_INVOKE,

-        element: setter, arguments: arguments));

-    super.visitSuperSetterInvoke(node, setter, arguments, callStructure, arg);

-  }

-

-  @override

-  visitSuperGetterSet(

-      SendSet node,

-      FunctionElement getter,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SET,

-        element: getter, rhs: rhs));

-    super.visitSuperGetterSet(node, getter, rhs, arg);

-  }

-

-  @override

-  visitSuperSetterSet(

-      SendSet node,

-      FunctionElement setter,

-      Node rhs,

-      arg) {

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

-        element: setter, rhs: rhs));

-    super.visitSuperSetterSet(node, setter, rhs, arg);

-  }

-

-  @override

-  visitSuperUnary(

-      Send node,

-      UnaryOperator operator,

-      FunctionElement function,

-      arg) {

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

-        element: function, operator: operator));

-  }

-

-  @override

-  visitUnresolvedSuperUnary(

-      Send node,

-      UnaryOperator operator,

-      Element element,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_UNARY,

-        operator: operator));

-  }

-

-  @override

-  visitEquals(

-      Send node,

-      Node left,

-      Node right,

-      arg) {

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

-    apply(left, arg);

-    apply(right, arg);

-  }

-

-  @override

-  visitSuperEquals(

-      Send node,

-      FunctionElement function,

-      Node argument,

-      arg) {

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

-        element: function, right: argument));

-    apply(argument, arg);

-  }

-

-  @override

-  visitIndexSet(

-      Send node,

-      Node receiver,

-      Node index,

-      Node rhs,

-      arg) {

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

-        receiver: receiver, index: index, rhs: rhs));

-    apply(receiver, arg);

-    apply(index, arg);

-    apply(rhs, arg);

-  }

-

-  @override

-  visitSuperIndexSet(

-      Send node,

-      FunctionElement function,

-      Node index,

-      Node rhs,

-      arg) {

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

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

-    apply(index, arg);

-    apply(rhs, arg);

-  }

-

-  @override

-  visitDynamicPropertyCompound(

-      Send node,

-      Node receiver,

-      AssignmentOperator operator,

-      Node rhs,

-      Selector getterSelector,

-      Selector setterSelector,

-      arg) {

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

-        receiver: receiver, operator: operator, rhs: rhs,

-        getter: getterSelector, setter: setterSelector));

-    apply(receiver, arg);

-    apply(rhs, arg);

-  }

-

-  @override

-  visitFinalLocalVariableCompound(

-      Send node,

-      LocalVariableElement variable,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitFinalLocalVariablePrefix(

-      Send node,

-      LocalVariableElement variable,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_PREFIX,

-        element: variable, operator: operator));

-  }

-

-  @override

-  visitFinalLocalVariablePostfix(

-      Send node,

-      LocalVariableElement variable,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,

-        element: variable, operator: operator));

-  }

-

-  @override

-  visitFinalParameterCompound(

-      Send node,

-      ParameterElement parameter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_COMPOUND,

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitFinalParameterPrefix(

-      Send node,

-      ParameterElement parameter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_PREFIX,

-        element: parameter, operator: operator));

-  }

-

-  @override

-  visitFinalParameterPostfix(

-      Send node,

-      ParameterElement parameter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_POSTFIX,

-        element: parameter, operator: operator));

-  }

-

-  @override

-  visitFinalStaticFieldCompound(

-      Send node,

-      FieldElement field,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_COMPOUND,

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitFinalStaticFieldPostfix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_POSTFIX,

-        element: field, operator: operator));

-  }

-

-  @override

-  visitFinalStaticFieldPrefix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_PREFIX,

-        element: field, operator: operator));

-  }

-

-  @override

-  visitFinalSuperFieldCompound(

-      Send node,

-      FieldElement field,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_COMPOUND,

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitFinalTopLevelFieldCompound(

-      Send node,

-      FieldElement field,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitFinalTopLevelFieldPostfix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,

-        element: field, operator: operator));

-  }

-

-  @override

-  visitFinalTopLevelFieldPrefix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,

-        element: field, operator: operator));

-  }

-

-  @override

-  visitLocalFunctionCompound(

-      Send node,

-      LocalFunctionElement function,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_COMPOUND,

-        element: function, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitLocalVariableCompound(

-      Send node,

-      LocalVariableElement variable,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitParameterCompound(

-      Send node,

-      ParameterElement parameter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitStaticFieldCompound(

-      Send node,

-      FieldElement field,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitStaticGetterSetterCompound(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

-        operator: operator, rhs: rhs,

-        getter: getter, setter: setter));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitSuperFieldCompound(

-      Send node,

-      FieldElement field,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitSuperGetterSetterCompound(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

-        operator: operator, rhs: rhs,

-        getter: getter, setter: setter));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitThisPropertyCompound(

-      Send node,

-      AssignmentOperator operator,

-      Node rhs,

-      Selector getterSelector,

-      Selector setterSelector,

-      arg) {

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

-        operator: operator, rhs: rhs,

-        getter: getterSelector, setter: setterSelector));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitTopLevelFieldCompound(

-      Send node,

-      FieldElement field,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitTopLevelGetterSetterCompound(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

-        operator: operator, rhs: rhs,

-        getter: getter, setter: setter));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitStaticMethodSetterCompound(

-      Send node,

-      FunctionElement method,

-      FunctionElement setter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

-        operator: operator, rhs: rhs,

-        getter: method, setter: setter));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitSuperFieldSetterCompound(

-      Send node,

-      FieldElement field,

-      FunctionElement setter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

-        operator: operator, rhs: rhs,

-        getter: field, setter: setter));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitSuperGetterFieldCompound(

-      Send node,

-      FunctionElement getter,

-      FieldElement field,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

-        operator: operator, rhs: rhs,

-        getter: getter, setter: field));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitSuperMethodSetterCompound(

-      Send node,

-      FunctionElement method,

-      FunctionElement setter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_COMPOUND,

-        getter: method, setter: setter, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitSuperMethodCompound(

-      Send node,

-      FunctionElement method,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_COMPOUND,

-        element: method, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitSuperMethodPrefix(

-      Send node,

-      FunctionElement method,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_PREFIX,

-        element: method, operator: operator));

-  }

-

-  @override

-  visitSuperMethodPostfix(

-      Send node,

-      FunctionElement method,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_POSTFIX,

-        element: method, operator: operator));

-  }

-

-  @override

-  visitUnresolvedSuperCompound(

-      Send node,

-      Element element,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND,

-        operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedSuperPrefix(

-      Send node,

-      Element element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_PREFIX,

-        operator: operator));

-  }

-

-  @override

-  visitUnresolvedSuperPostfix(

-      Send node,

-      Element element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_POSTFIX,

-        operator: operator));

-  }

-

-  @override

-  visitTopLevelMethodSetterCompound(

-      Send node,

-      FunctionElement method,

-      FunctionElement setter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,

-        getter: method, setter: setter, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitCompoundIndexSet(

-      Send node,

-      Node receiver,

-      Node index,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

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

-    apply(receiver, arg);

-    apply(index, arg);

-    apply(rhs, arg);

-  }

-

-  @override

-  visitSuperCompoundIndexSet(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      Node index,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

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

-        getter: getter, setter: setter,

-        index: index, rhs: rhs, operator: operator));

-    apply(index, arg);

-    apply(rhs, arg);

-  }

-

-  @override

-  visitClassTypeLiteralCompound(

-      Send node,

-      ConstantExpression constant,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitDynamicTypeLiteralCompound(

-      Send node,

-      ConstantExpression constant,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitTypeVariableTypeLiteralCompound(

-      Send node,

-      TypeVariableElement element,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,

-        element: element, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitTypedefTypeLiteralCompound(

-      Send node,

-      ConstantExpression constant,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,

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

-    apply(rhs, arg);

-  }

-

-  @override

-  visitLocalFunctionPrefix(

-      Send node,

-      LocalFunctionElement function,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_PREFIX,

-        element: function, operator: operator));

-  }

-

-  @override

-  visitClassTypeLiteralPrefix(

-      Send node,

-      ConstantExpression constant,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,

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

-  }

-

-  @override

-  visitDynamicTypeLiteralPrefix(

-      Send node,

-      ConstantExpression constant,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,

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

-  }

-

-  @override

-  visitLocalVariablePrefix(

-      Send node,

-      LocalVariableElement variable,

-      IncDecOperator operator,

-      arg) {

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

-        element: variable, operator: operator));

-  }

-

-  @override

-  visitParameterPrefix(

-      Send node,

-      ParameterElement parameter,

-      IncDecOperator operator,

-      arg) {

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

-        element: parameter, operator: operator));

-  }

-

-  @override

-  visitStaticFieldPrefix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

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

-        element: field, operator: operator));

-  }

-

-  @override

-  visitStaticGetterSetterPrefix(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

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

-        getter: getter, setter: setter, operator: operator));

-  }

-

-  @override

-  visitStaticMethodSetterPrefix(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_PREFIX,

-        getter: getter, setter: setter, operator: operator));

-  }

-

-  @override

-  visitSuperFieldFieldCompound(

-      Send node,

-      FieldElement readField,

-      FieldElement writtenField,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,

-        getter: readField, setter: writtenField, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitSuperFieldFieldPrefix(

-      Send node,

-      FieldElement readField,

-      FieldElement writtenField,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_PREFIX,

-        getter: readField, setter: writtenField, operator: operator));

-  }

-

-  @override

-  visitSuperFieldPrefix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

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

-        element: field, operator: operator));

-  }

-

-  @override

-  visitFinalSuperFieldPrefix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_PREFIX,

-        element: field, operator: operator));

-  }

-

-  @override

-  visitSuperFieldSetterPrefix(

-      Send node,

-      FieldElement field,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

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

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

-  }

-

-  @override

-  visitSuperGetterFieldPrefix(

-      Send node,

-      FunctionElement getter,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

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

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

-  }

-

-  @override

-  visitSuperGetterSetterPrefix(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

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

-        getter: getter, setter: setter, operator: operator));

-  }

-

-  @override

-  visitSuperMethodSetterPrefix(

-      Send node,

-      FunctionElement method,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_PREFIX,

-        getter: method, setter: setter, operator: operator));

-  }

-

-  @override

-  visitThisPropertyPrefix(

-      Send node,

-      IncDecOperator operator,

-      Selector getterSelector,

-      Selector setterSelector,

-      arg) {

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

-        operator: operator,

-        getter: getterSelector, setter: setterSelector));

-  }

-

-  @override

-  visitTopLevelFieldPrefix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

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

-        element: field, operator: operator));

-  }

-

-  @override

-  visitTopLevelGetterSetterPrefix(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

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

-        getter: getter, setter: setter, operator: operator));

-  }

-

-  @override

-  visitTopLevelMethodSetterPrefix(

-      Send node,

-      FunctionElement method,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,

-        getter: method, setter: setter, operator: operator));

-  }

-

-  @override

-  visitTypeVariableTypeLiteralPrefix(

-      Send node,

-      TypeVariableElement element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,

-        element: element, operator: operator));

-  }

-

-  @override

-  visitTypedefTypeLiteralPrefix(

-      Send node,

-      ConstantExpression constant,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,

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

-  }

-

-  @override

-  visitLocalFunctionPostfix(

-      Send node,

-      LocalFunctionElement function,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_POSTFIX,

-        element: function, operator: operator));

-  }

-

-  @override

-  visitClassTypeLiteralPostfix(

-      Send node,

-      ConstantExpression constant,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_POSTFIX,

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

-  }

-

-  @override

-  visitDynamicTypeLiteralPostfix(

-      Send node,

-      ConstantExpression constant,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,

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

-  }

-

-  @override

-  visitLocalVariablePostfix(

-      Send node,

-      LocalVariableElement variable,

-      IncDecOperator operator,

-      arg) {

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

-        element: variable, operator: operator));

-  }

-

-  @override

-  visitParameterPostfix(

-      Send node,

-      ParameterElement parameter,

-      IncDecOperator operator,

-      arg) {

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

-        element: parameter, operator: operator));

-  }

-

-  @override

-  visitStaticFieldPostfix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

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

-        element: field, operator: operator));

-  }

-

-  @override

-  visitStaticGetterSetterPostfix(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

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

-        getter: getter, setter: setter, operator: operator));

-  }

-

-  @override

-  visitStaticMethodSetterPostfix(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_POSTFIX,

-        getter: getter, setter: setter, operator: operator));

-  }

-

-  @override

-  visitSuperFieldFieldPostfix(

-      Send node,

-      FieldElement readField,

-      FieldElement writtenField,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_POSTFIX,

-        getter: readField, setter: writtenField, operator: operator));

-  }

-

-  @override

-  visitSuperFieldPostfix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

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

-        element: field, operator: operator));

-  }

-

-  @override

-  visitFinalSuperFieldPostfix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_POSTFIX,

-        element: field, operator: operator));

-  }

-

-  @override

-  visitSuperFieldSetterPostfix(

-      Send node,

-      FieldElement field,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

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

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

-  }

-

-  @override

-  visitSuperGetterFieldPostfix(

-      Send node,

-      FunctionElement getter,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

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

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

-  }

-

-  @override

-  visitSuperGetterSetterPostfix(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

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

-        getter: getter, setter: setter, operator: operator));

-  }

-

-  @override

-  visitSuperMethodSetterPostfix(

-      Send node,

-      FunctionElement method,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_POSTFIX,

-        getter: method, setter: setter, operator: operator));

-  }

-

-  @override

-  visitThisPropertyPostfix(

-      Send node,

-      IncDecOperator operator,

-      Selector getterSelector,

-      Selector setterSelector,

-      arg) {

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

-        operator: operator,

-        getter: getterSelector, setter: setterSelector));

-  }

-

-  @override

-  visitTopLevelFieldPostfix(

-      Send node,

-      FieldElement field,

-      IncDecOperator operator,

-      arg) {

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

-        element: field, operator: operator));

-  }

-

-  @override

-  visitTopLevelGetterSetterPostfix(

-      Send node,

-      FunctionElement getter,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

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

-        getter: getter, setter: setter, operator: operator));

-  }

-

-  @override

-  visitTopLevelMethodSetterPostfix(

-      Send node,

-      FunctionElement method,

-      FunctionElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,

-        getter: method, setter: setter, operator: operator));

-  }

-

-  @override

-  visitTypeVariableTypeLiteralPostfix(

-      Send node,

-      TypeVariableElement element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,

-        element: element, operator: operator));

-  }

-

-  @override

-  visitTypedefTypeLiteralPostfix(

-      Send node,

-      ConstantExpression constant,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,

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

-  }

-

-  @override

-  visitUnresolvedCompound(

-      Send node,

-      ErroneousElement element,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_COMPOUND,

-        operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedGet(

-      Send node,

-      Element element,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_GET, name: element.name));

-  }

-

-  @override

-  visitUnresolvedSet(

-      Send node,

-      Element element,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SET,

-                         name: element.name, rhs: rhs));

-    super.visitUnresolvedSet(node, element, rhs, arg);

-  }

-

-  @override

-  visitUnresolvedInvoke(

-      Send node,

-      Element element,

-      NodeList arguments,

-      Selector selector,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,

-                         name: element.name, arguments: arguments));

-    super.visitUnresolvedInvoke(node, element, arguments, selector, arg);

-  }

-

-  @override

-  visitUnresolvedPostfix(

-      Send node,

-      ErroneousElement element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_UNRESOLVED_POSTFIX, operator: operator));

-  }

-

-  @override

-  visitUnresolvedPrefix(

-      Send node,

-      ErroneousElement element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_UNRESOLVED_PREFIX, operator: operator));

-  }

-

-  @override

-  visitUnresolvedSuperCompoundIndexSet(

-      Send node,

-      Element element,

-      Node index,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,

-        index: index, operator: operator, rhs: rhs));

-    apply(index, arg);

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedSuperGetterCompoundIndexSet(

-      Send node,

-      Element element,

-      MethodElement setter,

-      Node index,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,

-        setter: setter, index: index, operator: operator, rhs: rhs));

-    apply(index, arg);

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedSuperSetterCompoundIndexSet(

-      Send node,

-      MethodElement getter,

-      Element element,

-      Node index,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,

-        getter: getter, index: index, operator: operator, rhs: rhs));

-    apply(index, arg);

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedSuperIndexSet(

-      Send node,

-      ErroneousElement element,

-      Node index,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_SET,

-               index: index, rhs: rhs));

-    apply(index, arg);

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedSuperIndexPostfix(

-      Send node,

-      Element element,

-      Node index,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,

-               index: index, operator: operator));

-    apply(index, arg);

-  }

-

-  @override

-  visitUnresolvedSuperGetterIndexPostfix(

-      Send node,

-      Element element,

-      MethodElement setter,

-      Node index,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,

-               setter: setter, index: index, operator: operator));

-    apply(index, arg);

-  }

-

-  @override

-  visitUnresolvedSuperSetterIndexPostfix(

-      Send node,

-      MethodElement getter,

-      Element element,

-      Node index,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,

-               getter: getter, index: index, operator: operator));

-    apply(index, arg);

-  }

-

-  @override

-  visitUnresolvedSuperIndexPrefix(

-      Send node,

-      Element element,

-      Node index,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,

-               index: index, operator: operator));

-    apply(index, arg);

-  }

-

-  @override

-  visitUnresolvedSuperGetterIndexPrefix(

-      Send node,

-      Element element,

-      MethodElement setter,

-      Node index,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,

-               setter: setter, index: index, operator: operator));

-    apply(index, arg);

-  }

-

-  @override

-  visitUnresolvedSuperSetterIndexPrefix(

-      Send node,

-      MethodElement getter,

-      Element element,

-      Node index,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,

-               getter: getter, index: index, operator: operator));

-    apply(index, arg);

-  }

-

-  @override

-  visitIndexPostfix(

-      Send node,

-      Node receiver,

-      Node index,

-      IncDecOperator operator,

-      arg) {

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

-        receiver: receiver, index: index, operator: operator));

-    apply(receiver, arg);

-    apply(index, arg);

-  }

-

-  @override

-  visitIndexPrefix(

-      Send node,

-      Node receiver,

-      Node index,

-      IncDecOperator operator,

-      arg) {

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

-        receiver: receiver, index: index, operator: operator));

-    apply(receiver, arg);

-    apply(index, arg);

-  }

-

-  @override

-  visitSuperIndexPostfix(

-      Send node,

-      FunctionElement indexFunction,

-      FunctionElement indexSetFunction,

-      Node index,

-      IncDecOperator operator,

-      arg) {

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

-        getter: indexFunction, setter: indexSetFunction,

-        index: index, operator: operator));

-    apply(index, arg);

-  }

-

-  @override

-  visitSuperIndexPrefix(

-      Send node,

-      FunctionElement indexFunction,

-      FunctionElement indexSetFunction,

-      Node index,

-      IncDecOperator operator,

-      arg) {

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

-        getter: indexFunction, setter: indexSetFunction,

-        index: index, operator: operator));

-    apply(index, arg);

-  }

-

-  @override

-  visitUnresolvedClassConstructorInvoke(

-      NewExpression node,

-      Element constructor,

-      DartType type,

-      NodeList arguments,

-      Selector selector,

-      arg) {

-    // TODO(johnniwinther): Test [type] when it is not `dynamic`.

-    visits.add(new Visit(

-        VisitKind.VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,

-        arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitUnresolvedConstructorInvoke(

-      NewExpression node,

-      Element constructor,

-      DartType type,

-      NodeList arguments,

-      Selector selector,

-      arg) {

-    // TODO(johnniwinther): Test [type] when it is not `dynamic`.

-    visits.add(new Visit(

-        VisitKind.VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,

-        arguments: arguments));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitConstConstructorInvoke(

-      NewExpression node,

-      ConstructedConstantExpression constant,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_CONST_CONSTRUCTOR_INVOKE,

-                         constant: constant.getText()));

-    super.visitConstConstructorInvoke(node, constant, arg);

-  }

-

-  @override

-  visitBoolFromEnvironmentConstructorInvoke(

-      NewExpression node,

-      BoolFromEnvironmentConstantExpression constant,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,

-        constant: constant.getText()));

-    super.visitBoolFromEnvironmentConstructorInvoke(node, constant, arg);

-  }

-

-  @override

-  visitIntFromEnvironmentConstructorInvoke(

-      NewExpression node,

-      IntFromEnvironmentConstantExpression constant,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,

-        constant: constant.getText()));

-    super.visitIntFromEnvironmentConstructorInvoke(node, constant, arg);

-  }

-

-  @override

-  visitStringFromEnvironmentConstructorInvoke(

-      NewExpression node,

-      StringFromEnvironmentConstantExpression constant,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,

-        constant: constant.getText()));

-    super.visitStringFromEnvironmentConstructorInvoke(node, constant, arg);

-  }

-

-  @override

-  errorNonConstantConstructorInvoke(

-        NewExpression node,

-        Element element,

-        DartType type,

-        NodeList arguments,

-        CallStructure callStructure,

-        arg) {

-    visits.add(new Visit(VisitKind.ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,

-        element: element, type: type,

-        arguments: arguments, selector: callStructure));

-    super.errorNonConstantConstructorInvoke(

-        node, element, type, arguments, callStructure, arg);

-  }

-

-  @override

-  visitConstructorIncompatibleInvoke(

-        NewExpression node,

-        ConstructorElement constructor,

-        InterfaceType type,

-        NodeList arguments,

-        CallStructure callStructure,

-        arg) {

-    visits.add(new Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,

-        element: constructor, type: type,

-        arguments: arguments, selector: callStructure));

-    super.visitConstructorIncompatibleInvoke(

-        node, constructor, type, arguments, callStructure, arg);

-  }

-

-  @override

-  visitFactoryConstructorInvoke(

-      NewExpression node,

-      ConstructorElement constructor,

-      InterfaceType type,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,

-        element: constructor,

-        type: type,

-        arguments: arguments,

-        selector: callStructure));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitGenerativeConstructorInvoke(

-      NewExpression node,

-      ConstructorElement constructor,

-      InterfaceType type,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,

-        element: constructor,

-        type: type,

-        arguments: arguments,

-        selector: callStructure));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitRedirectingFactoryConstructorInvoke(

-      NewExpression node,

-      ConstructorElement constructor,

-      InterfaceType type,

-      ConstructorElement effectiveTarget,

-      InterfaceType effectiveTargetType,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-        element: constructor,

-        type: type,

-        target: effectiveTarget,

-        targetType: effectiveTargetType,

-        arguments: arguments,

-        selector: callStructure));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitRedirectingGenerativeConstructorInvoke(

-      NewExpression node,

-      ConstructorElement constructor,

-      InterfaceType type,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,

-        element: constructor,

-        type: type,

-        arguments: arguments,

-        selector: callStructure));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitAbstractClassConstructorInvoke(

-      NewExpression node,

-      ConstructorElement constructor,

-      InterfaceType type,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,

-        element: constructor,

-        type: type,

-        arguments: arguments,

-        selector: callStructure));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitUnresolvedRedirectingFactoryConstructorInvoke(

-      NewExpression node,

-      ConstructorElement constructor,

-      InterfaceType type,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(

-        VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,

-        element: constructor,

-        type: type,

-        arguments: arguments,

-        selector: callStructure));

-    apply(arguments, arg);

-  }

-

-  @override

-  visitUnresolvedStaticGetterCompound(

-      Send node,

-      Element element,

-      MethodElement setter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,

-        setter: setter, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedTopLevelGetterCompound(

-      Send node,

-      Element element,

-      MethodElement setter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,

-        setter: setter, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedStaticSetterCompound(

-      Send node,

-      MethodElement getter,

-      Element element,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,

-        getter: getter, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedTopLevelSetterCompound(

-      Send node,

-      MethodElement getter,

-      Element element,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,

-        getter: getter, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitStaticMethodCompound(

-      Send node,

-      MethodElement method,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_COMPOUND,

-        element: method, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitTopLevelMethodCompound(

-      Send node,

-      MethodElement method,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_COMPOUND,

-        element: method, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedStaticGetterPrefix(

-      Send node,

-      Element element,

-      MethodElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,

-        setter: setter, operator: operator));

-  }

-

-  @override

-  visitUnresolvedTopLevelGetterPrefix(

-      Send node,

-      Element element,

-      MethodElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,

-        setter: setter, operator: operator));

-  }

-

-  @override

-  visitUnresolvedStaticSetterPrefix(

-      Send node,

-      MethodElement getter,

-      Element element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,

-        getter: getter, operator: operator));

-  }

-

-  @override

-  visitUnresolvedTopLevelSetterPrefix(

-      Send node,

-      MethodElement getter,

-      Element element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,

-        getter: getter, operator: operator));

-  }

-

-  @override

-  visitStaticMethodPrefix(

-      Send node,

-      MethodElement method,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_PREFIX,

-        element: method, operator: operator));

-  }

-

-  @override

-  visitTopLevelMethodPrefix(

-      Send node,

-      MethodElement method,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_PREFIX,

-        element: method, operator: operator));

-  }

-

-  @override

-  visitUnresolvedStaticGetterPostfix(

-      Send node,

-      Element element,

-      MethodElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,

-        setter: setter, operator: operator));

-  }

-

-  @override

-  visitUnresolvedTopLevelGetterPostfix(

-      Send node,

-      Element element,

-      MethodElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,

-        setter: setter, operator: operator));

-  }

-

-  @override

-  visitUnresolvedStaticSetterPostfix(

-      Send node,

-      MethodElement getter,

-      Element element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,

-        getter: getter, operator: operator));

-  }

-

-  @override

-  visitUnresolvedTopLevelSetterPostfix(

-      Send node,

-      MethodElement getter,

-      Element element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,

-        getter: getter, operator: operator));

-  }

-

-  @override

-  visitStaticMethodPostfix(

-      Send node,

-      MethodElement method,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_POSTFIX,

-        element: method, operator: operator));

-  }

-

-  @override

-  visitTopLevelMethodPostfix(

-      Send node,

-      MethodElement method,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_POSTFIX,

-        element: method, operator: operator));

-  }

-

-  @override

-  visitUnresolvedSuperGetterCompound(

-      Send node, Element element,

-      MethodElement setter,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,

-        setter: setter, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedSuperGetterPostfix(

-      Send node,

-      Element element,

-      MethodElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,

-        setter: setter, operator: operator));

-  }

-

-  @override

-  visitUnresolvedSuperGetterPrefix(

-      Send node,

-      Element element,

-      MethodElement setter,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,

-        setter: setter, operator: operator));

-  }

-

-  @override

-  visitUnresolvedSuperSetterCompound(

-      Send node, MethodElement getter,

-      Element element,

-      AssignmentOperator operator,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,

-        getter: getter, operator: operator, rhs: rhs));

-    apply(rhs, arg);

-  }

-

-  @override

-  visitUnresolvedSuperSetterPostfix(

-      Send node,

-      MethodElement getter,

-      Element element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,

-        getter: getter, operator: operator));

-  }

-

-  @override

-  visitUnresolvedSuperSetterPrefix(

-      Send node,

-      MethodElement getter,

-      Element element,

-      IncDecOperator operator,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,

-        getter: getter, operator: operator));

-  }

-

-  @override

-  visitIfNotNullDynamicPropertyGet(

-      Send node,

-      Node receiver,

-      Selector selector,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,

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

-    super.visitIfNotNullDynamicPropertyGet(node, receiver, selector, arg);

-  }

-

-  @override

-  visitIfNotNullDynamicPropertySet(

-      Send node,

-      Node receiver,

-      Selector selector,

-      Node rhs,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,

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

-    super.visitIfNotNullDynamicPropertySet(node, receiver, selector, rhs, arg);

-  }

-

-  @override

-  visitIfNotNullDynamicPropertyInvoke(

-      Send node,

-      Node receiver,

-      NodeList arguments,

-      Selector selector,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,

-        receiver: receiver, selector: selector, arguments: arguments));

-    super.visitIfNotNullDynamicPropertyInvoke(

-        node, receiver, arguments, selector, arg);

-  }

-

-  @override

-  visitIfNotNullDynamicPropertyPrefix(

-      Send node,

-      Node receiver,

-      IncDecOperator operator,

-      Selector getterSelector,

-      Selector setterSelector,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,

-        receiver: receiver, operator: operator,

-        getter: getterSelector, setter: setterSelector));

-    super.visitIfNotNullDynamicPropertyPrefix(

-        node, receiver, operator, getterSelector, setterSelector, arg);

-  }

-

-  @override

-  visitIfNotNullDynamicPropertyPostfix(

-      Send node,

-      Node receiver,

-      IncDecOperator operator,

-      Selector getterSelector,

-      Selector setterSelector,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,

-        receiver: receiver, operator: operator,

-        getter: getterSelector, setter: setterSelector));

-    super.visitIfNotNullDynamicPropertyPostfix(

-        node, receiver, operator, getterSelector, setterSelector, arg);

-  }

-

-  @override

-  visitIfNotNullDynamicPropertyCompound(

-      Send node,

-      Node receiver,

-      AssignmentOperator operator,

-      Node rhs,

-      Selector getterSelector,

-      Selector setterSelector,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,

-        receiver: receiver, operator: operator, rhs: rhs,

-        getter: getterSelector, setter: setterSelector));

-    super.visitIfNotNullDynamicPropertyCompound(

-        node, receiver, operator, rhs, getterSelector, setterSelector, arg);

-  }

-

-  @override

-  visitIfNull(

-      Send node,

-      Node left,

-      Node right,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_IF_NULL, left: left, right: right));

-    super.visitIfNull(node, left, right, arg);

-  }

-

-  @override

-  visitConstantGet(

-      Send node,

-      ConstantExpression constant,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_CONSTANT_GET,

-        constant: constant.getText()));

-    super.visitConstantGet(node, constant, arg);

-  }

-

-  @override

-  visitConstantInvoke(

-      Send node,

-      ConstantExpression constant,

-      NodeList arguments,

-      CallStructure callStructure,

-      arg) {

-    visits.add(new Visit(VisitKind.VISIT_CONSTANT_INVOKE,

-        constant: constant.getText()));

-    super.visitConstantInvoke(node, constant, arguments, callStructure, arg);

-  }

-}

+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart2js.semantics_visitor_test;
+
+class SemanticSendTestVisitor extends SemanticTestVisitor {
+
+  SemanticSendTestVisitor(TreeElements elements) : super(elements);
+
+  @override
+  visitAs(
+      Send node,
+      Node expression,
+      DartType type,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_AS,
+        expression: expression, type: type));
+    apply(expression, arg);
+  }
+
+  @override
+  visitAssert(
+      Send node,
+      Node expression,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_ASSERT, expression: expression));
+    super.visitAssert(node, expression, arg);
+  }
+
+  @override
+  errorInvalidAssert(
+      Send node,
+      NodeList arguments,
+      arg) {
+    visits.add(new Visit(VisitKind.ERROR_INVALID_ASSERT, arguments: arguments));
+    super.errorInvalidAssert(node, arguments, arg);
+  }
+
+  @override
+  visitBinary(
+      Send node,
+      Node left,
+      BinaryOperator operator,
+      Node right,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_BINARY,
+        left: left, operator: operator, right: right));
+    super.visitBinary(node, left, operator, right, arg);
+  }
+
+  @override
+  errorUndefinedBinaryExpression(
+      Send node,
+      Node left,
+      Operator operator,
+      Node right,
+      arg) {
+    visits.add(new Visit(VisitKind.ERROR_UNDEFINED_BINARY_EXPRESSION,
+        left: left, operator: operator, right: right));
+    super.errorUndefinedBinaryExpression(node, left, operator, right, arg);
+  }
+
+  @override
+  visitIndex(
+      Send node,
+      Node receiver,
+      Node index,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_INDEX,
+        receiver: receiver, index: index));
+    apply(receiver, arg);
+    apply(index, arg);
+  }
+
+  @override
+  visitClassTypeLiteralGet(
+      Send node,
+      ConstantExpression constant,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_GET,
+        constant: constant.getText()));
+  }
+
+  @override
+  visitClassTypeLiteralInvoke(
+      Send node,
+      ConstantExpression constant,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,
+        constant: constant.getText(), arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitClassTypeLiteralSet(
+      SendSet node,
+      ConstantExpression constant,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_INVOKE,
+        constant: constant.getText(), rhs: rhs));
+    super.visitClassTypeLiteralSet(node, constant, rhs, arg);
+  }
+
+  @override
+  visitNotEquals(
+      Send node,
+      Node left,
+      Node right,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_NOT_EQUALS,
+        left: left, right: right));
+    apply(left, arg);
+    apply(right, arg);
+  }
+
+  @override
+  visitDynamicPropertyPrefix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_PREFIX,
+        receiver: receiver, operator: operator,
+        getter: getterSelector, setter: setterSelector));
+    apply(receiver, arg);
+  }
+
+  @override
+  visitDynamicPropertyPostfix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_POSTFIX,
+        receiver: receiver, operator: operator,
+        getter: getterSelector, setter: setterSelector));
+    apply(receiver, arg);
+  }
+
+  @override
+  visitDynamicPropertyGet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_GET,
+        receiver: receiver, name: selector.name));
+    apply(receiver, arg);
+  }
+
+  @override
+  visitDynamicPropertyInvoke(
+      Send node,
+      Node receiver,
+      NodeList arguments,
+      Selector selector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_INVOKE,
+        receiver: receiver, name: selector.name, arguments: arguments));
+    apply(receiver, arg);
+    apply(arguments, arg);
+  }
+
+  @override
+  visitDynamicPropertySet(
+      SendSet node,
+      Node receiver,
+      Selector selector,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_SET,
+        receiver: receiver, name: selector.name, rhs: rhs));
+    super.visitDynamicPropertySet(node, receiver, selector, rhs, arg);
+  }
+
+  @override
+  visitDynamicTypeLiteralGet(
+      Send node,
+      ConstantExpression constant,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_GET,
+        constant: constant.getText()));
+  }
+
+  @override
+  visitDynamicTypeLiteralInvoke(
+      Send node,
+      ConstantExpression constant,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_INVOKE,
+        constant: constant.getText(), arguments: arguments));
+  }
+
+  @override
+  visitDynamicTypeLiteralSet(
+      Send node,
+      ConstantExpression constant,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_SET,
+        rhs: rhs));
+    super.visitDynamicTypeLiteralSet(node, constant, rhs, arg);
+  }
+
+  @override
+  visitExpressionInvoke(
+      Send node,
+      Node expression,
+      NodeList arguments,
+      Selector selector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_EXPRESSION_INVOKE,
+        receiver: expression, arguments: arguments));
+  }
+
+  @override
+  visitIs(
+      Send node,
+      Node expression,
+      DartType type,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_IS,
+        expression: expression, type: type));
+    apply(expression, arg);
+  }
+
+  @override
+  visitIsNot(
+      Send node,
+      Node expression,
+      DartType type,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_IS_NOT,
+        expression: expression, type: type));
+    apply(expression, arg);
+  }
+
+  @override
+  visitLogicalAnd(
+      Send node,
+      Node left,
+      Node right,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOGICAL_AND,
+        left: left, right: right));
+    apply(left, arg);
+    apply(right, arg);
+  }
+
+  @override
+  visitLogicalOr(
+      Send node,
+      Node left,
+      Node right,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOGICAL_OR,
+        left: left, right: right));
+    apply(left, arg);
+    apply(right, arg);
+  }
+
+  @override
+  visitLocalFunctionGet(
+      Send node,
+      LocalFunctionElement function,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_GET,
+                         element: function));
+  }
+
+  @override
+  visitLocalFunctionSet(
+      SendSet node,
+      LocalFunctionElement function,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_SET,
+        element: function, rhs: rhs));
+    super.visitLocalFunctionSet(node, function, rhs, arg);
+  }
+
+  @override
+  visitLocalFunctionInvoke(
+      Send node,
+      LocalFunctionElement function,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_INVOKE,
+        element: function, arguments: arguments, selector: callStructure));
+    super.visitLocalFunctionInvoke(
+        node, function, arguments, callStructure, arg);
+  }
+
+  @override
+  visitLocalFunctionIncompatibleInvoke(
+      Send node,
+      LocalFunctionElement function,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_INCOMPATIBLE_INVOKE,
+        element: function, arguments: arguments, selector: callStructure));
+    super.visitLocalFunctionInvoke(
+        node, function, arguments, callStructure, arg);
+  }
+
+  @override
+  visitLocalVariableGet(
+      Send node,
+      LocalVariableElement variable,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_GET,
+                         element: variable));
+  }
+
+  @override
+  visitLocalVariableInvoke(
+      Send node,
+      LocalVariableElement variable,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_INVOKE,
+        element: variable, arguments: arguments, selector: callStructure));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitLocalVariableSet(
+      SendSet node,
+      LocalVariableElement variable,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_SET,
+        element: variable, rhs: rhs));
+    super.visitLocalVariableSet(node, variable, rhs, arg);
+  }
+
+  @override
+  visitFinalLocalVariableSet(
+      SendSet node,
+      LocalVariableElement variable,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_SET,
+        element: variable, rhs: rhs));
+    super.visitFinalLocalVariableSet(node, variable, rhs, arg);
+  }
+
+  @override
+  visitParameterGet(
+      Send node,
+      ParameterElement parameter,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_GET, element: parameter));
+  }
+
+  @override
+  visitParameterInvoke(
+      Send node,
+      ParameterElement parameter,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_INVOKE,
+        element: parameter, arguments: arguments, selector: callStructure));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitParameterSet(
+      SendSet node,
+      ParameterElement parameter,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_SET,
+                         element: parameter, rhs: rhs));
+    super.visitParameterSet(node, parameter, rhs, arg);
+  }
+
+  @override
+  visitFinalParameterSet(
+      SendSet node,
+      ParameterElement parameter,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_SET,
+                         element: parameter, rhs: rhs));
+    super.visitFinalParameterSet(node, parameter, rhs, arg);
+  }
+
+  @override
+  visitStaticFieldGet(
+      Send node,
+      FieldElement field,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_GET, element: field));
+  }
+
+  @override
+  visitStaticFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_INVOKE,
+        element: field, arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitStaticFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_SET,
+        element: field, rhs: rhs));
+    super.visitStaticFieldSet(node, field, rhs, arg);
+  }
+
+  @override
+  visitFinalStaticFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FINAL_STATIC_FIELD_SET,
+        element: field, rhs: rhs));
+    super.visitFinalStaticFieldSet(node, field, rhs, arg);
+  }
+
+  @override
+  visitStaticFunctionGet(
+      Send node,
+      MethodElement function,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_GET,
+        element: function));
+  }
+
+  @override
+  visitStaticFunctionSet(
+      SendSet node,
+      MethodElement function,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_SET,
+        element: function, rhs: rhs));
+    super.visitStaticFunctionSet(node, function, rhs, arg);
+  }
+
+  @override
+  visitStaticFunctionInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_INVOKE,
+        element: function, arguments: arguments));
+    super.visitStaticFunctionInvoke(
+        node, function, arguments, callStructure, arg);
+  }
+
+  @override
+  visitStaticFunctionIncompatibleInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FUNCTION_INCOMPATIBLE_INVOKE,
+        element: function, arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitStaticGetterGet(
+      Send node,
+      FunctionElement getter,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_GET,
+        element: getter));
+    super.visitStaticGetterGet(node, getter, arg);
+  }
+
+  @override
+  visitStaticGetterSet(
+      SendSet node,
+      MethodElement getter,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SET,
+        element: getter, rhs: rhs));
+    super.visitStaticGetterSet(node, getter, rhs, arg);
+  }
+
+  @override
+  visitStaticGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_INVOKE,
+        element: getter, arguments: arguments));
+    super.visitStaticGetterInvoke(node, getter, arguments, callStructure, arg);
+  }
+
+  @override
+  visitStaticSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_INVOKE,
+        element: setter, arguments: arguments));
+    super.visitStaticSetterInvoke(node, setter, arguments, callStructure, arg);
+  }
+
+  @override
+  visitStaticSetterGet(
+      Send node,
+      FunctionElement getter,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_GET,
+        element: getter));
+    super.visitStaticSetterGet(node, getter, arg);
+  }
+
+  @override
+  visitStaticSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_SETTER_SET,
+        element: setter, rhs: rhs));
+    super.visitStaticSetterSet(node, setter, rhs, arg);
+  }
+
+  @override
+  visitSuperBinary(
+      Send node,
+      FunctionElement function,
+      BinaryOperator operator,
+      Node argument,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_BINARY,
+        element: function, operator: operator, right: argument));
+    apply(argument, arg);
+  }
+
+  @override
+  visitUnresolvedSuperBinary(
+      Send node,
+      Element element,
+      BinaryOperator operator,
+      Node argument,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_BINARY,
+        operator: operator, right: argument));
+    apply(argument, arg);
+  }
+
+  @override
+  visitSuperIndex(
+      Send node,
+      FunctionElement function,
+      Node index,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX,
+            element: function, index: index));
+    apply(index, arg);
+  }
+
+  @override
+  visitUnresolvedSuperIndex(
+      Send node,
+      Element element,
+      Node index,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX,
+        index: index));
+    apply(index, arg);
+  }
+
+  @override
+  visitSuperNotEquals(
+      Send node,
+      FunctionElement function,
+      Node argument,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_NOT_EQUALS,
+            element: function, right: argument));
+    apply(argument, arg);
+  }
+
+  @override
+  visitThisGet(Identifier node, arg) {
+    visits.add(new Visit(VisitKind.VISIT_THIS_GET));
+  }
+
+  @override
+  visitThisInvoke(
+      Send node,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_THIS_INVOKE, arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitThisPropertyGet(
+      Send node,
+      Selector selector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_GET,
+                         name: selector.name));
+  }
+
+  @override
+  visitThisPropertyInvoke(
+      Send node,
+      NodeList arguments,
+      Selector selector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_INVOKE,
+                         name: selector.name, arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitThisPropertySet(
+      SendSet node,
+      Selector selector,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_SET,
+                         name: selector.name, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitTopLevelFieldGet(
+      Send node,
+      FieldElement field,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_GET, element: field));
+  }
+
+  @override
+  visitTopLevelFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_INVOKE,
+        element: field, arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitTopLevelFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_SET,
+        element: field, rhs: rhs));
+    super.visitTopLevelFieldSet(node, field, rhs, arg);
+  }
+
+  @override
+  visitFinalTopLevelFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FINAL_TOP_LEVEL_FIELD_SET,
+        element: field, rhs: rhs));
+    super.visitFinalTopLevelFieldSet(node, field, rhs, arg);
+  }
+
+  @override
+  visitTopLevelFunctionGet(
+      Send node,
+      MethodElement function,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_GET,
+        element: function));
+  }
+
+  @override
+  visitTopLevelFunctionSet(
+      SendSet node,
+      MethodElement function,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_SET,
+        element: function, rhs: rhs));
+    super.visitTopLevelFunctionSet(node, function, rhs, arg);
+  }
+
+  @override
+  visitTopLevelFunctionInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INVOKE,
+        element: function, arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitTopLevelFunctionIncompatibleInvoke(
+      Send node,
+      MethodElement function,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FUNCTION_INCOMPATIBLE_INVOKE,
+        element: function, arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitTopLevelGetterGet(
+      Send node,
+      FunctionElement getter,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_GET,
+        element: getter));
+    super.visitTopLevelGetterGet(node, getter, arg);
+  }
+
+  @override
+  visitTopLevelSetterGet(
+      Send node,
+      FunctionElement setter,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_GET,
+        element: setter));
+    super.visitTopLevelSetterGet(node, setter, arg);
+  }
+
+  @override
+  visitTopLevelGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_INVOKE,
+        element: getter, arguments: arguments));
+    super.visitTopLevelGetterInvoke(
+        node, getter, arguments, callStructure, arg);
+  }
+
+  @override
+  visitTopLevelSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_INVOKE,
+        element: setter, arguments: arguments));
+    super.visitTopLevelSetterInvoke(
+        node, setter, arguments, callStructure, arg);
+  }
+
+  @override
+  visitTopLevelGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SET,
+        element: getter, rhs: rhs));
+    super.visitTopLevelGetterSet(node, getter, rhs, arg);
+  }
+
+  @override
+  visitTopLevelSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_SETTER_SET,
+        element: setter, rhs: rhs));
+    super.visitTopLevelSetterSet(node, setter, rhs, arg);
+  }
+
+  @override
+  visitTypeVariableTypeLiteralGet(
+      Send node,
+      TypeVariableElement element,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_GET,
+        element: element));
+  }
+
+  @override
+  visitTypeVariableTypeLiteralInvoke(
+      Send node,
+      TypeVariableElement element,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_INVOKE,
+        element: element, arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitTypeVariableTypeLiteralSet(
+      SendSet node,
+      TypeVariableElement element,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_SET,
+        element: element, rhs: rhs));
+    super.visitTypeVariableTypeLiteralSet(node, element, rhs, arg);
+  }
+
+  @override
+  visitTypedefTypeLiteralGet(
+      Send node,
+      ConstantExpression constant,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_GET,
+        constant: constant.getText()));
+  }
+
+  @override
+  visitTypedefTypeLiteralInvoke(
+      Send node,
+      ConstantExpression constant,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_INVOKE,
+        constant: constant.getText(), arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitTypedefTypeLiteralSet(
+      SendSet node,
+      ConstantExpression constant,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_SET,
+        constant: constant.getText(), rhs: rhs));
+    super.visitTypedefTypeLiteralSet(node, constant, rhs, arg);
+  }
+
+  @override
+  visitUnary(
+      Send node,
+      UnaryOperator operator,
+      Node expression,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNARY,
+        expression: expression, operator: operator));
+    super.visitUnary(node, operator, expression, arg);
+  }
+
+  @override
+  errorUndefinedUnaryExpression(
+      Send node,
+      Operator operator,
+      Node expression,
+      arg) {
+    visits.add(new Visit(VisitKind.ERROR_UNDEFINED_UNARY_EXPRESSION,
+        expression: expression, operator: operator));
+    super.errorUndefinedUnaryExpression(node, operator, expression, arg);
+  }
+
+  @override
+  visitNot(
+      Send node,
+      Node expression,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_NOT, expression: expression));
+    apply(expression, arg);
+  }
+
+  @override
+  visitSuperFieldGet(
+      Send node,
+      FieldElement field,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_GET, element: field));
+  }
+
+  @override
+  visitUnresolvedSuperGet(
+      Send node,
+      Element element,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GET));
+  }
+
+  @override
+  visitSuperFieldInvoke(
+      Send node,
+      FieldElement field,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_INVOKE,
+        element: field, arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitUnresolvedSuperInvoke(
+      Send node,
+      Element element,
+      NodeList arguments,
+      Selector selector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INVOKE,
+        arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitSuperFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SET,
+        element: field, rhs: rhs));
+    super.visitSuperFieldSet(node, field, rhs, arg);
+  }
+
+  @override
+  visitFinalSuperFieldSet(
+      SendSet node,
+      FieldElement field,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FINAL_SUPER_FIELD_SET,
+        element: field, rhs: rhs));
+    super.visitFinalSuperFieldSet(node, field, rhs, arg);
+  }
+
+  @override
+  visitSuperMethodGet(
+      Send node,
+      MethodElement method,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_GET, element: method));
+  }
+
+  @override
+  visitSuperMethodSet(
+      SendSet node,
+      MethodElement method,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SET,
+        element: method, rhs: rhs));
+    super.visitSuperMethodSet(node, method, rhs, arg);
+  }
+
+  @override
+  visitSuperMethodInvoke(
+      Send node,
+      MethodElement method,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_INVOKE,
+        element: method, arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitSuperMethodIncompatibleInvoke(
+      Send node,
+      MethodElement method,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_INCOMPATIBLE_INVOKE,
+        element: method, arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitSuperGetterGet(
+      Send node,
+      FunctionElement getter,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_GET, element: getter));
+    super.visitSuperGetterGet(node, getter, arg);
+  }
+
+  @override
+  visitSuperSetterGet(
+      Send node,
+      FunctionElement setter,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_GET, element: setter));
+    super.visitSuperSetterGet(node, setter, arg);
+  }
+
+  @override
+  visitSuperGetterInvoke(
+      Send node,
+      FunctionElement getter,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_INVOKE,
+        element: getter, arguments: arguments));
+    super.visitSuperGetterInvoke(node, getter, arguments, callStructure, arg);
+  }
+
+  @override
+  visitSuperSetterInvoke(
+      Send node,
+      FunctionElement setter,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_INVOKE,
+        element: setter, arguments: arguments));
+    super.visitSuperSetterInvoke(node, setter, arguments, callStructure, arg);
+  }
+
+  @override
+  visitSuperGetterSet(
+      SendSet node,
+      FunctionElement getter,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SET,
+        element: getter, rhs: rhs));
+    super.visitSuperGetterSet(node, getter, rhs, arg);
+  }
+
+  @override
+  visitSuperSetterSet(
+      SendSet node,
+      FunctionElement setter,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_SETTER_SET,
+        element: setter, rhs: rhs));
+    super.visitSuperSetterSet(node, setter, rhs, arg);
+  }
+
+  @override
+  visitSuperUnary(
+      Send node,
+      UnaryOperator operator,
+      FunctionElement function,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_UNARY,
+        element: function, operator: operator));
+  }
+
+  @override
+  visitUnresolvedSuperUnary(
+      Send node,
+      UnaryOperator operator,
+      Element element,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_UNARY,
+        operator: operator));
+  }
+
+  @override
+  visitEquals(
+      Send node,
+      Node left,
+      Node right,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_EQUALS, left: left, right: right));
+    apply(left, arg);
+    apply(right, arg);
+  }
+
+  @override
+  visitSuperEquals(
+      Send node,
+      FunctionElement function,
+      Node argument,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_EQUALS,
+        element: function, right: argument));
+    apply(argument, arg);
+  }
+
+  @override
+  visitIndexSet(
+      Send node,
+      Node receiver,
+      Node index,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_INDEX_SET,
+        receiver: receiver, index: index, rhs: rhs));
+    apply(receiver, arg);
+    apply(index, arg);
+    apply(rhs, arg);
+  }
+
+  @override
+  visitSuperIndexSet(
+      Send node,
+      FunctionElement function,
+      Node index,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_SET,
+        element: function, index: index, rhs: rhs));
+    apply(index, arg);
+    apply(rhs, arg);
+  }
+
+  @override
+  visitDynamicPropertyCompound(
+      Send node,
+      Node receiver,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_PROPERTY_COMPOUND,
+        receiver: receiver, operator: operator, rhs: rhs,
+        getter: getterSelector, setter: setterSelector));
+    apply(receiver, arg);
+    apply(rhs, arg);
+  }
+
+  @override
+  visitFinalLocalVariableCompound(
+      Send node,
+      LocalVariableElement variable,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_COMPOUND,
+        element: variable, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitFinalLocalVariablePrefix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_PREFIX,
+        element: variable, operator: operator));
+  }
+
+  @override
+  visitFinalLocalVariablePostfix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FINAL_LOCAL_VARIABLE_POSTFIX,
+        element: variable, operator: operator));
+  }
+
+  @override
+  visitFinalParameterCompound(
+      Send node,
+      ParameterElement parameter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_COMPOUND,
+        element: parameter, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitFinalParameterPrefix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_PREFIX,
+        element: parameter, operator: operator));
+  }
+
+  @override
+  visitFinalParameterPostfix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_FINAL_PARAMETER_POSTFIX,
+        element: parameter, operator: operator));
+  }
+
+  @override
+  visitFinalStaticFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_COMPOUND,
+        element: field, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitFinalStaticFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_POSTFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitFinalStaticFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FINAL_FIELD_PREFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitFinalSuperFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_COMPOUND,
+        element: field, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitFinalTopLevelFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_COMPOUND,
+        element: field, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitFinalTopLevelFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_POSTFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitFinalTopLevelFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FINAL_FIELD_PREFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitLocalFunctionCompound(
+      Send node,
+      LocalFunctionElement function,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_COMPOUND,
+        element: function, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitLocalVariableCompound(
+      Send node,
+      LocalVariableElement variable,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_COMPOUND,
+        element: variable, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitParameterCompound(
+      Send node,
+      ParameterElement parameter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_COMPOUND,
+        element: parameter, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitStaticFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_COMPOUND,
+        element: field, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitStaticGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_COMPOUND,
+        operator: operator, rhs: rhs,
+        getter: getter, setter: setter));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitSuperFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_COMPOUND,
+        element: field, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitSuperGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_COMPOUND,
+        operator: operator, rhs: rhs,
+        getter: getter, setter: setter));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitThisPropertyCompound(
+      Send node,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_COMPOUND,
+        operator: operator, rhs: rhs,
+        getter: getterSelector, setter: setterSelector));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitTopLevelFieldCompound(
+      Send node,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_COMPOUND,
+        element: field, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitTopLevelGetterSetterCompound(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_COMPOUND,
+        operator: operator, rhs: rhs,
+        getter: getter, setter: setter));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitStaticMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_COMPOUND,
+        operator: operator, rhs: rhs,
+        getter: method, setter: setter));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitSuperFieldSetterCompound(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_COMPOUND,
+        operator: operator, rhs: rhs,
+        getter: field, setter: setter));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitSuperGetterFieldCompound(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_COMPOUND,
+        operator: operator, rhs: rhs,
+        getter: getter, setter: field));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitSuperMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_COMPOUND,
+        getter: method, setter: setter, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitSuperMethodCompound(
+      Send node,
+      FunctionElement method,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_COMPOUND,
+        element: method, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitSuperMethodPrefix(
+      Send node,
+      FunctionElement method,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_PREFIX,
+        element: method, operator: operator));
+  }
+
+  @override
+  visitSuperMethodPostfix(
+      Send node,
+      FunctionElement method,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_POSTFIX,
+        element: method, operator: operator));
+  }
+
+  @override
+  visitUnresolvedSuperCompound(
+      Send node,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND,
+        operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedSuperPrefix(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_PREFIX,
+        operator: operator));
+  }
+
+  @override
+  visitUnresolvedSuperPostfix(
+      Send node,
+      Element element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_POSTFIX,
+        operator: operator));
+  }
+
+  @override
+  visitTopLevelMethodSetterCompound(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_COMPOUND,
+        getter: method, setter: setter, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitCompoundIndexSet(
+      Send node,
+      Node receiver,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_COMPOUND_INDEX_SET,
+        receiver: receiver, index: index, rhs: rhs, operator: operator));
+    apply(receiver, arg);
+    apply(index, arg);
+    apply(rhs, arg);
+  }
+
+  @override
+  visitSuperCompoundIndexSet(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_COMPOUND_INDEX_SET,
+        getter: getter, setter: setter,
+        index: index, rhs: rhs, operator: operator));
+    apply(index, arg);
+    apply(rhs, arg);
+  }
+
+  @override
+  visitClassTypeLiteralCompound(
+      Send node,
+      ConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_COMPOUND,
+        constant: constant.getText(), operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitDynamicTypeLiteralCompound(
+      Send node,
+      ConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_COMPOUND,
+        constant: constant.getText(), operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitTypeVariableTypeLiteralCompound(
+      Send node,
+      TypeVariableElement element,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_COMPOUND,
+        element: element, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitTypedefTypeLiteralCompound(
+      Send node,
+      ConstantExpression constant,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_COMPOUND,
+        constant: constant.getText(), operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitLocalFunctionPrefix(
+      Send node,
+      LocalFunctionElement function,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_PREFIX,
+        element: function, operator: operator));
+  }
+
+  @override
+  visitClassTypeLiteralPrefix(
+      Send node,
+      ConstantExpression constant,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_PREFIX,
+        constant: constant.getText(), operator: operator));
+  }
+
+  @override
+  visitDynamicTypeLiteralPrefix(
+      Send node,
+      ConstantExpression constant,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_PREFIX,
+        constant: constant.getText(), operator: operator));
+  }
+
+  @override
+  visitLocalVariablePrefix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_PREFIX,
+        element: variable, operator: operator));
+  }
+
+  @override
+  visitParameterPrefix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_PREFIX,
+        element: parameter, operator: operator));
+  }
+
+  @override
+  visitStaticFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_PREFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitStaticGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_PREFIX,
+        getter: getter, setter: setter, operator: operator));
+  }
+
+  @override
+  visitStaticMethodSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_PREFIX,
+        getter: getter, setter: setter, operator: operator));
+  }
+
+  @override
+  visitSuperFieldFieldCompound(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_COMPOUND,
+        getter: readField, setter: writtenField, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitSuperFieldFieldPrefix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_PREFIX,
+        getter: readField, setter: writtenField, operator: operator));
+  }
+
+  @override
+  visitSuperFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_PREFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitFinalSuperFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_PREFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitSuperFieldSetterPrefix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_PREFIX,
+        getter: field, setter: setter, operator: operator));
+  }
+
+  @override
+  visitSuperGetterFieldPrefix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_PREFIX,
+        getter: getter, setter: field, operator: operator));
+  }
+
+  @override
+  visitSuperGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_PREFIX,
+        getter: getter, setter: setter, operator: operator));
+  }
+
+  @override
+  visitSuperMethodSetterPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_PREFIX,
+        getter: method, setter: setter, operator: operator));
+  }
+
+  @override
+  visitThisPropertyPrefix(
+      Send node,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_PREFIX,
+        operator: operator,
+        getter: getterSelector, setter: setterSelector));
+  }
+
+  @override
+  visitTopLevelFieldPrefix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_PREFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitTopLevelGetterSetterPrefix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_PREFIX,
+        getter: getter, setter: setter, operator: operator));
+  }
+
+  @override
+  visitTopLevelMethodSetterPrefix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_PREFIX,
+        getter: method, setter: setter, operator: operator));
+  }
+
+  @override
+  visitTypeVariableTypeLiteralPrefix(
+      Send node,
+      TypeVariableElement element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_PREFIX,
+        element: element, operator: operator));
+  }
+
+  @override
+  visitTypedefTypeLiteralPrefix(
+      Send node,
+      ConstantExpression constant,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_PREFIX,
+        constant: constant.getText(), operator: operator));
+  }
+
+  @override
+  visitLocalFunctionPostfix(
+      Send node,
+      LocalFunctionElement function,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_FUNCTION_POSTFIX,
+        element: function, operator: operator));
+  }
+
+  @override
+  visitClassTypeLiteralPostfix(
+      Send node,
+      ConstantExpression constant,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_CLASS_TYPE_LITERAL_POSTFIX,
+        constant: constant.getText(), operator: operator));
+  }
+
+  @override
+  visitDynamicTypeLiteralPostfix(
+      Send node,
+      ConstantExpression constant,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_DYNAMIC_TYPE_LITERAL_POSTFIX,
+        constant: constant.getText(), operator: operator));
+  }
+
+  @override
+  visitLocalVariablePostfix(
+      Send node,
+      LocalVariableElement variable,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_LOCAL_VARIABLE_POSTFIX,
+        element: variable, operator: operator));
+  }
+
+  @override
+  visitParameterPostfix(
+      Send node,
+      ParameterElement parameter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_PARAMETER_POSTFIX,
+        element: parameter, operator: operator));
+  }
+
+  @override
+  visitStaticFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_FIELD_POSTFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitStaticGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_GETTER_SETTER_POSTFIX,
+        getter: getter, setter: setter, operator: operator));
+  }
+
+  @override
+  visitStaticMethodSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_SETTER_POSTFIX,
+        getter: getter, setter: setter, operator: operator));
+  }
+
+  @override
+  visitSuperFieldFieldPostfix(
+      Send node,
+      FieldElement readField,
+      FieldElement writtenField,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_FIELD_POSTFIX,
+        getter: readField, setter: writtenField, operator: operator));
+  }
+
+  @override
+  visitSuperFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_POSTFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitFinalSuperFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FINAL_FIELD_POSTFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitSuperFieldSetterPostfix(
+      Send node,
+      FieldElement field,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_FIELD_SETTER_POSTFIX,
+        getter: field, setter: setter, operator: operator));
+  }
+
+  @override
+  visitSuperGetterFieldPostfix(
+      Send node,
+      FunctionElement getter,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_FIELD_POSTFIX,
+        getter: getter, setter: field, operator: operator));
+  }
+
+  @override
+  visitSuperGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_GETTER_SETTER_POSTFIX,
+        getter: getter, setter: setter, operator: operator));
+  }
+
+  @override
+  visitSuperMethodSetterPostfix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_METHOD_SETTER_POSTFIX,
+        getter: method, setter: setter, operator: operator));
+  }
+
+  @override
+  visitThisPropertyPostfix(
+      Send node,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_THIS_PROPERTY_POSTFIX,
+        operator: operator,
+        getter: getterSelector, setter: setterSelector));
+  }
+
+  @override
+  visitTopLevelFieldPostfix(
+      Send node,
+      FieldElement field,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_FIELD_POSTFIX,
+        element: field, operator: operator));
+  }
+
+  @override
+  visitTopLevelGetterSetterPostfix(
+      Send node,
+      FunctionElement getter,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_GETTER_SETTER_POSTFIX,
+        getter: getter, setter: setter, operator: operator));
+  }
+
+  @override
+  visitTopLevelMethodSetterPostfix(
+      Send node,
+      FunctionElement method,
+      FunctionElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_SETTER_POSTFIX,
+        getter: method, setter: setter, operator: operator));
+  }
+
+  @override
+  visitTypeVariableTypeLiteralPostfix(
+      Send node,
+      TypeVariableElement element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPE_VARIABLE_TYPE_LITERAL_POSTFIX,
+        element: element, operator: operator));
+  }
+
+  @override
+  visitTypedefTypeLiteralPostfix(
+      Send node,
+      ConstantExpression constant,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TYPEDEF_TYPE_LITERAL_POSTFIX,
+        constant: constant.getText(), operator: operator));
+  }
+
+  @override
+  visitUnresolvedCompound(
+      Send node,
+      ErroneousElement element,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_COMPOUND,
+        operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedGet(
+      Send node,
+      Element element,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_GET, name: element.name));
+  }
+
+  @override
+  visitUnresolvedSet(
+      Send node,
+      Element element,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SET,
+                         name: element.name, rhs: rhs));
+    super.visitUnresolvedSet(node, element, rhs, arg);
+  }
+
+  @override
+  visitUnresolvedInvoke(
+      Send node,
+      Element element,
+      NodeList arguments,
+      Selector selector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_INVOKE,
+                         name: element.name, arguments: arguments));
+    super.visitUnresolvedInvoke(node, element, arguments, selector, arg);
+  }
+
+  @override
+  visitUnresolvedPostfix(
+      Send node,
+      ErroneousElement element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_UNRESOLVED_POSTFIX, operator: operator));
+  }
+
+  @override
+  visitUnresolvedPrefix(
+      Send node,
+      ErroneousElement element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_UNRESOLVED_PREFIX, operator: operator));
+  }
+
+  @override
+  visitUnresolvedSuperCompoundIndexSet(
+      Send node,
+      Element element,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_UNRESOLVED_SUPER_COMPOUND_INDEX_SET,
+        index: index, operator: operator, rhs: rhs));
+    apply(index, arg);
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedSuperGetterCompoundIndexSet(
+      Send node,
+      Element element,
+      MethodElement setter,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND_INDEX_SET,
+        setter: setter, index: index, operator: operator, rhs: rhs));
+    apply(index, arg);
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedSuperSetterCompoundIndexSet(
+      Send node,
+      MethodElement getter,
+      Element element,
+      Node index,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND_INDEX_SET,
+        getter: getter, index: index, operator: operator, rhs: rhs));
+    apply(index, arg);
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedSuperIndexSet(
+      Send node,
+      ErroneousElement element,
+      Node index,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_SET,
+               index: index, rhs: rhs));
+    apply(index, arg);
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedSuperIndexPostfix(
+      Send node,
+      Element element,
+      Node index,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_POSTFIX,
+               index: index, operator: operator));
+    apply(index, arg);
+  }
+
+  @override
+  visitUnresolvedSuperGetterIndexPostfix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      Node index,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_POSTFIX,
+               setter: setter, index: index, operator: operator));
+    apply(index, arg);
+  }
+
+  @override
+  visitUnresolvedSuperSetterIndexPostfix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      Node index,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_POSTFIX,
+               getter: getter, index: index, operator: operator));
+    apply(index, arg);
+  }
+
+  @override
+  visitUnresolvedSuperIndexPrefix(
+      Send node,
+      Element element,
+      Node index,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_INDEX_PREFIX,
+               index: index, operator: operator));
+    apply(index, arg);
+  }
+
+  @override
+  visitUnresolvedSuperGetterIndexPrefix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      Node index,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_INDEX_PREFIX,
+               setter: setter, index: index, operator: operator));
+    apply(index, arg);
+  }
+
+  @override
+  visitUnresolvedSuperSetterIndexPrefix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      Node index,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_INDEX_PREFIX,
+               getter: getter, index: index, operator: operator));
+    apply(index, arg);
+  }
+
+  @override
+  visitIndexPostfix(
+      Send node,
+      Node receiver,
+      Node index,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_INDEX_POSTFIX,
+        receiver: receiver, index: index, operator: operator));
+    apply(receiver, arg);
+    apply(index, arg);
+  }
+
+  @override
+  visitIndexPrefix(
+      Send node,
+      Node receiver,
+      Node index,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_INDEX_PREFIX,
+        receiver: receiver, index: index, operator: operator));
+    apply(receiver, arg);
+    apply(index, arg);
+  }
+
+  @override
+  visitSuperIndexPostfix(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_POSTFIX,
+        getter: indexFunction, setter: indexSetFunction,
+        index: index, operator: operator));
+    apply(index, arg);
+  }
+
+  @override
+  visitSuperIndexPrefix(
+      Send node,
+      FunctionElement indexFunction,
+      FunctionElement indexSetFunction,
+      Node index,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_SUPER_INDEX_PREFIX,
+        getter: indexFunction, setter: indexSetFunction,
+        index: index, operator: operator));
+    apply(index, arg);
+  }
+
+  @override
+  visitUnresolvedClassConstructorInvoke(
+      NewExpression node,
+      Element constructor,
+      DartType type,
+      NodeList arguments,
+      Selector selector,
+      arg) {
+    // TODO(johnniwinther): Test [type] when it is not `dynamic`.
+    visits.add(new Visit(
+        VisitKind.VISIT_UNRESOLVED_CLASS_CONSTRUCTOR_INVOKE,
+        arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitUnresolvedConstructorInvoke(
+      NewExpression node,
+      Element constructor,
+      DartType type,
+      NodeList arguments,
+      Selector selector,
+      arg) {
+    // TODO(johnniwinther): Test [type] when it is not `dynamic`.
+    visits.add(new Visit(
+        VisitKind.VISIT_UNRESOLVED_CONSTRUCTOR_INVOKE,
+        arguments: arguments));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitConstConstructorInvoke(
+      NewExpression node,
+      ConstructedConstantExpression constant,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_CONST_CONSTRUCTOR_INVOKE,
+                         constant: constant.getText()));
+    super.visitConstConstructorInvoke(node, constant, arg);
+  }
+
+  @override
+  visitBoolFromEnvironmentConstructorInvoke(
+      NewExpression node,
+      BoolFromEnvironmentConstantExpression constant,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_BOOL_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+        constant: constant.getText()));
+    super.visitBoolFromEnvironmentConstructorInvoke(node, constant, arg);
+  }
+
+  @override
+  visitIntFromEnvironmentConstructorInvoke(
+      NewExpression node,
+      IntFromEnvironmentConstantExpression constant,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_INT_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+        constant: constant.getText()));
+    super.visitIntFromEnvironmentConstructorInvoke(node, constant, arg);
+  }
+
+  @override
+  visitStringFromEnvironmentConstructorInvoke(
+      NewExpression node,
+      StringFromEnvironmentConstantExpression constant,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_STRING_FROM_ENVIRONMENT_CONSTRUCTOR_INVOKE,
+        constant: constant.getText()));
+    super.visitStringFromEnvironmentConstructorInvoke(node, constant, arg);
+  }
+
+  @override
+  errorNonConstantConstructorInvoke(
+        NewExpression node,
+        Element element,
+        DartType type,
+        NodeList arguments,
+        CallStructure callStructure,
+        arg) {
+    visits.add(new Visit(VisitKind.ERROR_NON_CONSTANT_CONSTRUCTOR_INVOKE,
+        element: element, type: type,
+        arguments: arguments, selector: callStructure));
+    super.errorNonConstantConstructorInvoke(
+        node, element, type, arguments, callStructure, arg);
+  }
+
+  @override
+  visitConstructorIncompatibleInvoke(
+        NewExpression node,
+        ConstructorElement constructor,
+        InterfaceType type,
+        NodeList arguments,
+        CallStructure callStructure,
+        arg) {
+    visits.add(new Visit(VisitKind.VISIT_CONSTRUCTOR_INCOMPATIBLE_INVOKE,
+        element: constructor, type: type,
+        arguments: arguments, selector: callStructure));
+    super.visitConstructorIncompatibleInvoke(
+        node, constructor, type, arguments, callStructure, arg);
+  }
+
+  @override
+  visitFactoryConstructorInvoke(
+      NewExpression node,
+      ConstructorElement constructor,
+      InterfaceType type,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_FACTORY_CONSTRUCTOR_INVOKE,
+        element: constructor,
+        type: type,
+        arguments: arguments,
+        selector: callStructure));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitGenerativeConstructorInvoke(
+      NewExpression node,
+      ConstructorElement constructor,
+      InterfaceType type,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_GENERATIVE_CONSTRUCTOR_INVOKE,
+        element: constructor,
+        type: type,
+        arguments: arguments,
+        selector: callStructure));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitRedirectingFactoryConstructorInvoke(
+      NewExpression node,
+      ConstructorElement constructor,
+      InterfaceType type,
+      ConstructorElement effectiveTarget,
+      InterfaceType effectiveTargetType,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+        element: constructor,
+        type: type,
+        target: effectiveTarget,
+        targetType: effectiveTargetType,
+        arguments: arguments,
+        selector: callStructure));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitRedirectingGenerativeConstructorInvoke(
+      NewExpression node,
+      ConstructorElement constructor,
+      InterfaceType type,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_REDIRECTING_GENERATIVE_CONSTRUCTOR_INVOKE,
+        element: constructor,
+        type: type,
+        arguments: arguments,
+        selector: callStructure));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitAbstractClassConstructorInvoke(
+      NewExpression node,
+      ConstructorElement constructor,
+      InterfaceType type,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_ABSTRACT_CLASS_CONSTRUCTOR_INVOKE,
+        element: constructor,
+        type: type,
+        arguments: arguments,
+        selector: callStructure));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitUnresolvedRedirectingFactoryConstructorInvoke(
+      NewExpression node,
+      ConstructorElement constructor,
+      InterfaceType type,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(
+        VisitKind.VISIT_UNRESOLVED_REDIRECTING_FACTORY_CONSTRUCTOR_INVOKE,
+        element: constructor,
+        type: type,
+        arguments: arguments,
+        selector: callStructure));
+    apply(arguments, arg);
+  }
+
+  @override
+  visitUnresolvedStaticGetterCompound(
+      Send node,
+      Element element,
+      MethodElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_COMPOUND,
+        setter: setter, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedTopLevelGetterCompound(
+      Send node,
+      Element element,
+      MethodElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_COMPOUND,
+        setter: setter, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedStaticSetterCompound(
+      Send node,
+      MethodElement getter,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_COMPOUND,
+        getter: getter, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedTopLevelSetterCompound(
+      Send node,
+      MethodElement getter,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_COMPOUND,
+        getter: getter, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitStaticMethodCompound(
+      Send node,
+      MethodElement method,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_COMPOUND,
+        element: method, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitTopLevelMethodCompound(
+      Send node,
+      MethodElement method,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_COMPOUND,
+        element: method, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedStaticGetterPrefix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_PREFIX,
+        setter: setter, operator: operator));
+  }
+
+  @override
+  visitUnresolvedTopLevelGetterPrefix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_PREFIX,
+        setter: setter, operator: operator));
+  }
+
+  @override
+  visitUnresolvedStaticSetterPrefix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_PREFIX,
+        getter: getter, operator: operator));
+  }
+
+  @override
+  visitUnresolvedTopLevelSetterPrefix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_PREFIX,
+        getter: getter, operator: operator));
+  }
+
+  @override
+  visitStaticMethodPrefix(
+      Send node,
+      MethodElement method,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_PREFIX,
+        element: method, operator: operator));
+  }
+
+  @override
+  visitTopLevelMethodPrefix(
+      Send node,
+      MethodElement method,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_PREFIX,
+        element: method, operator: operator));
+  }
+
+  @override
+  visitUnresolvedStaticGetterPostfix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_GETTER_POSTFIX,
+        setter: setter, operator: operator));
+  }
+
+  @override
+  visitUnresolvedTopLevelGetterPostfix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_GETTER_POSTFIX,
+        setter: setter, operator: operator));
+  }
+
+  @override
+  visitUnresolvedStaticSetterPostfix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_STATIC_SETTER_POSTFIX,
+        getter: getter, operator: operator));
+  }
+
+  @override
+  visitUnresolvedTopLevelSetterPostfix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_TOP_LEVEL_SETTER_POSTFIX,
+        getter: getter, operator: operator));
+  }
+
+  @override
+  visitStaticMethodPostfix(
+      Send node,
+      MethodElement method,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_STATIC_METHOD_POSTFIX,
+        element: method, operator: operator));
+  }
+
+  @override
+  visitTopLevelMethodPostfix(
+      Send node,
+      MethodElement method,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_TOP_LEVEL_METHOD_POSTFIX,
+        element: method, operator: operator));
+  }
+
+  @override
+  visitUnresolvedSuperGetterCompound(
+      Send node, Element element,
+      MethodElement setter,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_COMPOUND,
+        setter: setter, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedSuperGetterPostfix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_POSTFIX,
+        setter: setter, operator: operator));
+  }
+
+  @override
+  visitUnresolvedSuperGetterPrefix(
+      Send node,
+      Element element,
+      MethodElement setter,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_GETTER_PREFIX,
+        setter: setter, operator: operator));
+  }
+
+  @override
+  visitUnresolvedSuperSetterCompound(
+      Send node, MethodElement getter,
+      Element element,
+      AssignmentOperator operator,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_COMPOUND,
+        getter: getter, operator: operator, rhs: rhs));
+    apply(rhs, arg);
+  }
+
+  @override
+  visitUnresolvedSuperSetterPostfix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_POSTFIX,
+        getter: getter, operator: operator));
+  }
+
+  @override
+  visitUnresolvedSuperSetterPrefix(
+      Send node,
+      MethodElement getter,
+      Element element,
+      IncDecOperator operator,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_UNRESOLVED_SUPER_SETTER_PREFIX,
+        getter: getter, operator: operator));
+  }
+
+  @override
+  visitIfNotNullDynamicPropertyGet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_GET,
+        receiver: receiver, name: selector.name));
+    super.visitIfNotNullDynamicPropertyGet(node, receiver, selector, arg);
+  }
+
+  @override
+  visitIfNotNullDynamicPropertySet(
+      Send node,
+      Node receiver,
+      Selector selector,
+      Node rhs,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_SET,
+        receiver: receiver, name: selector.name, rhs: rhs));
+    super.visitIfNotNullDynamicPropertySet(node, receiver, selector, rhs, arg);
+  }
+
+  @override
+  visitIfNotNullDynamicPropertyInvoke(
+      Send node,
+      Node receiver,
+      NodeList arguments,
+      Selector selector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_INVOKE,
+        receiver: receiver, selector: selector, arguments: arguments));
+    super.visitIfNotNullDynamicPropertyInvoke(
+        node, receiver, arguments, selector, arg);
+  }
+
+  @override
+  visitIfNotNullDynamicPropertyPrefix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_PREFIX,
+        receiver: receiver, operator: operator,
+        getter: getterSelector, setter: setterSelector));
+    super.visitIfNotNullDynamicPropertyPrefix(
+        node, receiver, operator, getterSelector, setterSelector, arg);
+  }
+
+  @override
+  visitIfNotNullDynamicPropertyPostfix(
+      Send node,
+      Node receiver,
+      IncDecOperator operator,
+      Selector getterSelector,
+      Selector setterSelector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_POSTFIX,
+        receiver: receiver, operator: operator,
+        getter: getterSelector, setter: setterSelector));
+    super.visitIfNotNullDynamicPropertyPostfix(
+        node, receiver, operator, getterSelector, setterSelector, arg);
+  }
+
+  @override
+  visitIfNotNullDynamicPropertyCompound(
+      Send node,
+      Node receiver,
+      AssignmentOperator operator,
+      Node rhs,
+      Selector getterSelector,
+      Selector setterSelector,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_IF_NOT_NULL_DYNAMIC_PROPERTY_COMPOUND,
+        receiver: receiver, operator: operator, rhs: rhs,
+        getter: getterSelector, setter: setterSelector));
+    super.visitIfNotNullDynamicPropertyCompound(
+        node, receiver, operator, rhs, getterSelector, setterSelector, arg);
+  }
+
+  @override
+  visitIfNull(
+      Send node,
+      Node left,
+      Node right,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_IF_NULL, left: left, right: right));
+    super.visitIfNull(node, left, right, arg);
+  }
+
+  @override
+  visitConstantGet(
+      Send node,
+      ConstantExpression constant,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_CONSTANT_GET,
+        constant: constant.getText()));
+    super.visitConstantGet(node, constant, arg);
+  }
+
+  @override
+  visitConstantInvoke(
+      Send node,
+      ConstantExpression constant,
+      NodeList arguments,
+      CallStructure callStructure,
+      arg) {
+    visits.add(new Visit(VisitKind.VISIT_CONSTANT_INVOKE,
+        constant: constant.getText()));
+    super.visitConstantInvoke(node, constant, arguments, callStructure, arg);
+  }
+}
diff --git a/tests/compiler/dart2js/show_package_warnings_test.dart b/tests/compiler/dart2js/show_package_warnings_test.dart
index eb9a441..de518f9 100644
--- a/tests/compiler/dart2js/show_package_warnings_test.dart
+++ b/tests/compiler/dart2js/show_package_warnings_test.dart
@@ -69,14 +69,26 @@
                   'Unexpected errors: ${collector.errors}');
     Expect.equals(warnings, collector.warnings.length,
                   'Unexpected warnings: ${collector.warnings}');
+    checkUriSchemes(collector.warnings);
     Expect.equals(hints, collector.hints.length,
                   'Unexpected hints: ${collector.hints}');
+    checkUriSchemes(collector.hints);
     Expect.equals(infos, collector.infos.length,
                   'Unexpected infos: ${collector.infos}');
+    checkUriSchemes(collector.infos);
     print('==================================================================');
   }));
 }
 
+void checkUriSchemes(Iterable<DiagnosticMessage> messages) {
+  for (DiagnosticMessage message in messages) {
+    if (message.uri != null) {
+      Expect.notEquals('package', message.uri.scheme,
+          "Unexpected package uri `${message.uri}` in message: $message");
+    }
+  }
+}
+
 void main() {
   test([Uri.parse('memory:main.dart')],
        showPackageWarnings: true,
diff --git a/tests/compiler/dart2js/top_level_closure_tree_shake_test.dart b/tests/compiler/dart2js/top_level_closure_tree_shake_test.dart
new file mode 100644
index 0000000..6c3ae37
--- /dev/null
+++ b/tests/compiler/dart2js/top_level_closure_tree_shake_test.dart
@@ -0,0 +1,38 @@
+// 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 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'compiler_helper.dart';
+
+const String TEST_ONE = r"""
+main() {
+  var f = use;
+  if (false) {
+    // This statement and the use of 'foo' should be optimized away, causing
+    // 'foo' to be absent from the final code.
+    f(foo);
+  }
+  f(bar);
+}
+
+foo() => 'Tarantula!';
+bar() => 'Coelacanth!';
+
+use(x) {
+  print(x());
+}
+""";
+
+
+main() {
+  asyncTest(() => Future.wait([
+      compileAll(TEST_ONE).then((String generated) {
+        Expect.isFalse(generated.contains('Tarantula!'),
+            "failed to remove 'foo'");
+        Expect.isTrue(generated.contains('Coelacanth!'));
+      }),
+  ]));
+}
diff --git a/tests/compiler/dart2js/type_order_test.dart b/tests/compiler/dart2js/type_order_test.dart
index a3337f3..e4faa01 100644
--- a/tests/compiler/dart2js/type_order_test.dart
+++ b/tests/compiler/dart2js/type_order_test.dart
@@ -1,72 +1,72 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file

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

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

-

-library subtype_test;

-

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

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

-import 'type_test_helper.dart';

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

-import "package:compiler/src/elements/elements.dart"

-       show Element, ClassElement, TypedefElement;

-

-void main() {

-  asyncTest(() => TypeEnvironment.create(r"""

-      class A<AT, AS> {}

-      typedef BS B<BT, BS>(BT t);

-      class C<CT, CS> extends A<CS, CT> {}

-      class X {}

-      class Y {}

-      class Z {}

-      """).then((env) {

-

-    List types = [];

-    DartType add(DartType type) {

-      types.add(type);

-      return type;

-    }

-

-    DartType dynamic_ = add(env['dynamic']);

-    DartType void_ = add(env['void']);

-

-    ClassElement A = env.getElement('A');

-    TypedefElement B = env.getElement('B');

-    ClassElement C = env.getElement('C');

-    DartType X = add(env['X']);

-    DartType Y = add(env['Y']);

-    DartType Z = add(env['Z']);

-

-    InterfaceType A_this = add(A.thisType);

-    InterfaceType A_raw = add(A.rawType);

-    TypeVariableType AT = add(A_this.typeArguments[0]);

-    TypeVariableType AS = add(A_this.typeArguments[1]);

-    InterfaceType A_X_Y = add(instantiate(A, [X, Y]));

-    InterfaceType A_Y_X = add(instantiate(A, [Y, X]));

-

-    TypedefType B_this = add(B.computeType(env.compiler));

-    TypedefType B_raw = add(B.rawType);

-    TypeVariableType BT = add(B_this.typeArguments[0]);

-    TypeVariableType BS = add(B_this.typeArguments[1]);

-    FunctionType B_this_alias = add(B.alias);

-    TypedefType B_X_Y = add(instantiate(B, [X, Y]));

-    FunctionType B_X_Y_alias = add(B_X_Y.unalias(env.compiler));

-    TypedefType B_Y_X = add(instantiate(B, [Y, X]));

-    FunctionType B_Y_X_alias = add(B_Y_X.unalias(env.compiler));

-

-    InterfaceType C_this = add(C.thisType);

-    InterfaceType C_raw = add(C.rawType);

-    TypeVariableType CT = add(C_this.typeArguments[0]);

-    TypeVariableType CS = add(C_this.typeArguments[1]);

-

-    Expect.listEquals(

-        [void_, dynamic_,

-         A_raw, A_this, A_X_Y, A_Y_X, AT, AS,

-         B_raw, B_this, B_X_Y, B_Y_X, BT, BS,

-         C_raw, C_this, CT, CS,

-         X, Y, Z,

-         B_this_alias, B_Y_X_alias, B_X_Y_alias,

-        ],

-        Types.sorted(types));

-  }));

+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library subtype_test;
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'type_test_helper.dart';
+import 'package:compiler/src/dart_types.dart';
+import "package:compiler/src/elements/elements.dart"
+       show Element, ClassElement, TypedefElement;
+
+void main() {
+  asyncTest(() => TypeEnvironment.create(r"""
+      class A<AT, AS> {}
+      typedef BS B<BT, BS>(BT t);
+      class C<CT, CS> extends A<CS, CT> {}
+      class X {}
+      class Y {}
+      class Z {}
+      """).then((env) {
+
+    List types = [];
+    DartType add(DartType type) {
+      types.add(type);
+      return type;
+    }
+
+    DartType dynamic_ = add(env['dynamic']);
+    DartType void_ = add(env['void']);
+
+    ClassElement A = env.getElement('A');
+    TypedefElement B = env.getElement('B');
+    ClassElement C = env.getElement('C');
+    DartType X = add(env['X']);
+    DartType Y = add(env['Y']);
+    DartType Z = add(env['Z']);
+
+    InterfaceType A_this = add(A.thisType);
+    InterfaceType A_raw = add(A.rawType);
+    TypeVariableType AT = add(A_this.typeArguments[0]);
+    TypeVariableType AS = add(A_this.typeArguments[1]);
+    InterfaceType A_X_Y = add(instantiate(A, [X, Y]));
+    InterfaceType A_Y_X = add(instantiate(A, [Y, X]));
+
+    TypedefType B_this = add(B.computeType(env.compiler));
+    TypedefType B_raw = add(B.rawType);
+    TypeVariableType BT = add(B_this.typeArguments[0]);
+    TypeVariableType BS = add(B_this.typeArguments[1]);
+    FunctionType B_this_alias = add(B.alias);
+    TypedefType B_X_Y = add(instantiate(B, [X, Y]));
+    FunctionType B_X_Y_alias = add(B_X_Y.unalias(env.compiler));
+    TypedefType B_Y_X = add(instantiate(B, [Y, X]));
+    FunctionType B_Y_X_alias = add(B_Y_X.unalias(env.compiler));
+
+    InterfaceType C_this = add(C.thisType);
+    InterfaceType C_raw = add(C.rawType);
+    TypeVariableType CT = add(C_this.typeArguments[0]);
+    TypeVariableType CS = add(C_this.typeArguments[1]);
+
+    Expect.listEquals(
+        [void_, dynamic_,
+         A_raw, A_this, A_X_Y, A_Y_X, AT, AS,
+         B_raw, B_this, B_X_Y, B_Y_X, BT, BS,
+         C_raw, C_this, CT, CS,
+         X, Y, Z,
+         B_this_alias, B_Y_X_alias, B_X_Y_alias,
+        ],
+        Types.sorted(types));
+  }));
 }
\ No newline at end of file
diff --git a/tests/compiler/dart2js/type_promotion_test.dart b/tests/compiler/dart2js/type_promotion_test.dart
index 8739394..b391cf9 100644
--- a/tests/compiler/dart2js/type_promotion_test.dart
+++ b/tests/compiler/dart2js/type_promotion_test.dart
@@ -1,29 +1,29 @@
-// 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.

-

-// Test that dart2js produces the expected static type warnings for type

-// promotion language tests. This ensures that the analyzer and dart2js agrees

-// on these tests.

-

-import 'warnings_checker.dart';

-

-/// Map from test files to a map of their expected status. If the status map is

-/// `null` no warnings must be missing or unexpected, otherwise the status map

-/// can contain a list of line numbers for keys 'missing' and 'unexpected' for

-/// the warnings of each category.

-const Map<String, dynamic> TESTS = const {

-    'language/type_promotion_assign_test.dart': null,

-    'language/type_promotion_closure_test.dart': null,

-    'language/type_promotion_functions_test.dart':

-        const {'missing': const [62, 63, 64]}, // Issue 14933.

-    'language/type_promotion_local_test.dart': null,

-    'language/type_promotion_logical_and_test.dart': null,

-    'language/type_promotion_more_specific_test.dart': null,

-    'language/type_promotion_multiple_test.dart': null,

-    'language/type_promotion_parameter_test.dart': null,

-};

-

-void main() {

-  checkWarnings(TESTS);

-}

+// 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.
+
+// Test that dart2js produces the expected static type warnings for type
+// promotion language tests. This ensures that the analyzer and dart2js agrees
+// on these tests.
+
+import 'warnings_checker.dart';
+
+/// Map from test files to a map of their expected status. If the status map is
+/// `null` no warnings must be missing or unexpected, otherwise the status map
+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
+/// the warnings of each category.
+const Map<String, dynamic> TESTS = const {
+    'language/type_promotion_assign_test.dart': null,
+    'language/type_promotion_closure_test.dart': null,
+    'language/type_promotion_functions_test.dart':
+        const {'missing': const [62, 63, 64]}, // Issue 14933.
+    'language/type_promotion_local_test.dart': null,
+    'language/type_promotion_logical_and_test.dart': null,
+    'language/type_promotion_more_specific_test.dart': null,
+    'language/type_promotion_multiple_test.dart': null,
+    'language/type_promotion_parameter_test.dart': null,
+};
+
+void main() {
+  checkWarnings(TESTS);
+}
diff --git a/tests/compiler/dart2js/warnings_checker.dart b/tests/compiler/dart2js/warnings_checker.dart
index e1dba07..daaa32d 100644
--- a/tests/compiler/dart2js/warnings_checker.dart
+++ b/tests/compiler/dart2js/warnings_checker.dart
@@ -1,83 +1,83 @@
-// 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.

-

-// Test that dart2js produces the expected static type warnings to ensures that

-// the analyzer and dart2js agrees on the tests.

-

-import 'dart:async';

-import 'dart:io';

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

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

-import 'memory_compiler.dart';

-import 'package:compiler/src/filenames.dart';

-import 'package:compiler/src/io/source_file.dart';

-import 'package:compiler/src/source_file_provider.dart';

-import 'package:compiler/src/util/uri_extras.dart';

-import 'dart:convert';

-

-void checkWarnings(Map<String, dynamic> tests, [List<String> arguments]) {

-  bool isWindows = Platform.isWindows;

-  Uri script = currentDirectory.resolveUri(Platform.script);

-  bool warningsMismatch = false;

-  bool verbose = arguments != null && arguments.contains('-v');

-  asyncTest(() => Future.forEach(tests.keys, (String test) {

-    Uri uri = script.resolve('../../$test');

-    String source = UTF8.decode(readAll(uriPathToNative(uri.path)));

-    SourceFile file = new StringSourceFile(

-        uri, relativize(currentDirectory, uri, isWindows), source);

-    Map<int,String> expectedWarnings = {};

-    int lineNo = 0;

-    for (String line in source.split('\n')) {

-      if (line.contains('///') &&

-          (line.contains('static type warning') ||

-           line.contains('static warning'))) {

-        expectedWarnings[lineNo] = line;

-      }

-      lineNo++;

-    }

-    Set<int> unseenWarnings = new Set<int>.from(expectedWarnings.keys);

-    DiagnosticCollector collector = new DiagnosticCollector();

-    var compiler = compilerFor(const {},

-         diagnosticHandler: collector,

-         options: ['--analyze-only'],

-         showDiagnostics: verbose);

-    return compiler.run(uri).then((_) {

-      Map<String, List<int>> statusMap = tests[test];

-      // Line numbers with known unexpected warnings.

-      List<int> unexpectedStatus = [];

-      if (statusMap != null && statusMap.containsKey('unexpected')) {

-        unexpectedStatus = statusMap['unexpected'];

-      }

-      // Line numbers with known missing warnings.

-      List<int> missingStatus = [];

-      if (statusMap != null && statusMap.containsKey('missing')) {

-        missingStatus = statusMap['missing'];

-      }

-      for (DiagnosticMessage message in collector.warnings) {

-        Expect.equals(uri, message.uri);

-        int lineNo = file.getLine(message.begin);

-        if (expectedWarnings.containsKey(lineNo)) {

-          unseenWarnings.remove(lineNo);

-        } else if (!unexpectedStatus.contains(lineNo+1)) {

-          warningsMismatch = true;

-          print(file.getLocationMessage(

-              'Unexpected warning: ${message.message}',

-              message.begin, message.end));

-        }

-      }

-      if (!unseenWarnings.isEmpty) {

-        for (int lineNo in unseenWarnings) {

-          if (!missingStatus.contains(lineNo+1)) {

-            warningsMismatch = true;

-            String line = expectedWarnings[lineNo];

-            print('$uri [${lineNo+1}]: Missing static type warning.');

-            print(line);

-          }

-        }

-      }

-    });

-  }).then((_) {

-    Expect.isFalse(warningsMismatch);

-  }));

-}

+// 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.
+
+// Test that dart2js produces the expected static type warnings to ensures that
+// the analyzer and dart2js agrees on the tests.
+
+import 'dart:async';
+import 'dart:io';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'memory_compiler.dart';
+import 'package:compiler/src/filenames.dart';
+import 'package:compiler/src/io/source_file.dart';
+import 'package:compiler/src/source_file_provider.dart';
+import 'package:compiler/src/util/uri_extras.dart';
+import 'dart:convert';
+
+void checkWarnings(Map<String, dynamic> tests, [List<String> arguments]) {
+  bool isWindows = Platform.isWindows;
+  Uri script = currentDirectory.resolveUri(Platform.script);
+  bool warningsMismatch = false;
+  bool verbose = arguments != null && arguments.contains('-v');
+  asyncTest(() => Future.forEach(tests.keys, (String test) {
+    Uri uri = script.resolve('../../$test');
+    String source = UTF8.decode(readAll(uriPathToNative(uri.path)));
+    SourceFile file = new StringSourceFile(
+        uri, relativize(currentDirectory, uri, isWindows), source);
+    Map<int,String> expectedWarnings = {};
+    int lineNo = 0;
+    for (String line in source.split('\n')) {
+      if (line.contains('///') &&
+          (line.contains('static type warning') ||
+           line.contains('static warning'))) {
+        expectedWarnings[lineNo] = line;
+      }
+      lineNo++;
+    }
+    Set<int> unseenWarnings = new Set<int>.from(expectedWarnings.keys);
+    DiagnosticCollector collector = new DiagnosticCollector();
+    var compiler = compilerFor(const {},
+         diagnosticHandler: collector,
+         options: ['--analyze-only'],
+         showDiagnostics: verbose);
+    return compiler.run(uri).then((_) {
+      Map<String, List<int>> statusMap = tests[test];
+      // Line numbers with known unexpected warnings.
+      List<int> unexpectedStatus = [];
+      if (statusMap != null && statusMap.containsKey('unexpected')) {
+        unexpectedStatus = statusMap['unexpected'];
+      }
+      // Line numbers with known missing warnings.
+      List<int> missingStatus = [];
+      if (statusMap != null && statusMap.containsKey('missing')) {
+        missingStatus = statusMap['missing'];
+      }
+      for (DiagnosticMessage message in collector.warnings) {
+        Expect.equals(uri, message.uri);
+        int lineNo = file.getLine(message.begin);
+        if (expectedWarnings.containsKey(lineNo)) {
+          unseenWarnings.remove(lineNo);
+        } else if (!unexpectedStatus.contains(lineNo+1)) {
+          warningsMismatch = true;
+          print(file.getLocationMessage(
+              'Unexpected warning: ${message.message}',
+              message.begin, message.end));
+        }
+      }
+      if (!unseenWarnings.isEmpty) {
+        for (int lineNo in unseenWarnings) {
+          if (!missingStatus.contains(lineNo+1)) {
+            warningsMismatch = true;
+            String line = expectedWarnings[lineNo];
+            print('$uri [${lineNo+1}]: Missing static type warning.');
+            print(line);
+          }
+        }
+      }
+    });
+  }).then((_) {
+    Expect.isFalse(warningsMismatch);
+  }));
+}
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 2399b15..c398750 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -67,48 +67,28 @@
 11673_test: RuntimeError # Cannot read property 'prototype' of undefined
 12320_test: RuntimeError # Cannot read property 'prototype' of undefined
 16407_test: Pass # Please triage this failure.
-17645_test: RuntimeError # Please triage this failure.
-19191_test: RuntimeError # Please triage this failure.
-21166_test: RuntimeError # Please triage this failure.
-21579_test: RuntimeError # Please triage this failure.
-21666_test: Crash # Internal Error: No default constructor available.
 22487_test: RuntimeError # Cannot read property 'prototype' of undefined
 22868_test: Crash # (main()async{var clo...  cannot handle async/sync*/async* functions
 22895_test: Crash # (main()async{var clo...  cannot handle async/sync*/async* functions
 23404_test: RuntimeError # Cannot read property 'prototype' of undefined
-23432_test: RuntimeError # Please triage this failure.
+23432_test : RuntimeError # 
 LayoutTests_fast_mediastream_getusermedia_t01_test/none: RuntimeError # Cannot read property 'prototype' of undefined
 async_stacktrace_test/asyncStar: Crash # (runTests()async{awa...  cannot handle async/sync*/async* functions
 async_stacktrace_test/none: Crash # (runTests()async{awa...  cannot handle async/sync*/async* functions
-bounds_check_test/none: RuntimeError # Please triage this failure.
 closure5_test: RuntimeError # Cannot read property 'prototype' of undefined
-closure_capture4_test: RuntimeError # Please triage this failure.
 closure_capture5_test: Crash # (i=0): For-loop variable captured in loop header
-closure_type_reflection2_test: Crash # Internal Error: No default constructor available.
-closure_type_reflection_test: Crash # Internal Error: No default constructor available.
-compound_operator_index_test: RuntimeError # Please triage this failure.
 conditional_send_test: RuntimeError # receiver.get$_collection$_nums is not a function
-conflict_index_test: RuntimeError # Please triage this failure.
 deferred/deferred_class_test: RuntimeError # receiver.get$_collection$_nums is not a function
 deferred/deferred_constant2_test: RuntimeError # receiver.get$_collection$_nums is not a function
 deferred/deferred_constant3_test: RuntimeError # receiver.get$_collection$_nums is not a function
 deferred/deferred_constant4_test: RuntimeError # receiver.get$_collection$_nums is not a function
 deferred/deferred_function_test: RuntimeError # receiver.get$_collection$_nums is not a function
 deferred/deferred_mirrors1_test: RuntimeError # receiver.get$_collection$_nums is not a function
-deferred/deferred_mirrors2_test: Crash # Internal Error: No default constructor available.
+deferred/deferred_mirrors2_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
 deferred/deferred_overlapping_test: RuntimeError # receiver.get$_collection$_nums is not a function
-deferred_fail_and_retry_test: Crash # Internal Error: No default constructor available.
-deferred_fail_and_retry_worker_test: Crash # Internal Error: No default constructor available.
 for_test: RuntimeError # Please triage this failure.
 if_null_test: RuntimeError # receiver.get$_collection$_nums is not a function
-index_test: RuntimeError # Please triage this failure.
-int_index_test/none: RuntimeError # Please triage this failure.
-invalid_length_negative_test: Fail # Please triage this failure.
-is_check_instanceof_test: RuntimeError # Please triage this failure.
-list_factory_test: RuntimeError # Please triage this failure.
-mirror_invalid_field_access2_test: RuntimeError # Please triage this failure.
 mirror_invalid_field_access3_test: Crash # Internal Error: No default constructor available.
-mirror_invalid_field_access4_test: RuntimeError # Please triage this failure.
 mirror_invalid_field_access_test: Crash # Internal Error: No default constructor available.
 mirror_invalid_invoke3_test: Crash # Internal Error: No default constructor available.
 mirror_invalid_invoke_test: Crash # Internal Error: No default constructor available.
@@ -117,14 +97,12 @@
 mirror_type_inference_field2_test: Crash # Internal Error: No default constructor available.
 mirror_type_inference_field_test: Crash # Internal Error: No default constructor available.
 mirror_type_inference_function_test: Crash # Internal Error: No default constructor available.
-mirrors_declarations_filtering_test: Crash # Internal Error: No default constructor available.
-mirrors_used_native_test: RuntimeError # Please triage this failure.
-mirrors_used_warning2_test: RuntimeError # receiver.get$_nums is not a function
-mirrors_used_warning_test/minif: RuntimeError # receiver.get$_nums is not a function
-mirrors_used_warning_test/none: RuntimeError # receiver.get$_nums is not a function
-no_such_method_mirrors_test: RuntimeError # Please triage this failure.
+mirrors_used_warning2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+mirrors_used_warning_test/minif : RuntimeError # TypeError: receiver.get$_nums is not a function
+mirrors_used_warning_test/none : RuntimeError # TypeError: receiver.get$_nums is not a function
 reflect_native_types_test: Crash # Internal Error: No default constructor available.
 runtime_type_test: RuntimeError # Cannot read property 'prototype' of undefined
-string_interpolation_opt1_test: RuntimeError # Please triage this failure.
 switch_test/none: Crash # (switch (val){foo:ba...  continue to a labeled switch case
 timer_test: RuntimeError # receiver.get$_collection$_nums is not a function
+no_such_method_test : Crash # Internal Error: No default constructor available.
+mirrors_used_closure_test : Crash # Internal Error: No default constructor available.
diff --git a/tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart b/tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart
index 03d4725..60702c4 100644
--- a/tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart
+++ b/tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// Note: This test relies on LF line endings in the source file.
+
 import "package:expect/expect.dart";
 
 main() {
diff --git a/tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart b/tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart
index 14ff9a5..461bcfe 100644
--- a/tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart
+++ b/tests/compiler/dart2js_extra/string_interpolation_dynamic_test.dart
Binary files differ
diff --git a/tests/compiler/dart2js_extra/string_interpolation_test.dart b/tests/compiler/dart2js_extra/string_interpolation_test.dart
index 7552214..b8350e1 100644
--- a/tests/compiler/dart2js_extra/string_interpolation_test.dart
+++ b/tests/compiler/dart2js_extra/string_interpolation_test.dart
Binary files differ
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index 9798091..bb3bb85 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -23,17 +23,14 @@
 [ $compiler == dart2js && $cps_ir ]
 compute_this_script_test: RuntimeError # receiver.get$_collection$_nums is not a function
 event_loop_test: RuntimeError # receiver.get$_collection$_nums is not a function
-inference_of_helper_methods_test: RuntimeError # Please triage this failure.
 internal_library_test: RuntimeError # receiver.get$_collection$_nums is not a function
 mirror_intercepted_field_test: Crash # Internal Error: No default constructor available.
 native_closure_identity_frog_test: RuntimeError # invoke is not a function
-native_exception2_test: RuntimeError # Please triage this failure.
 native_exception_test: RuntimeError # J.getInterceptor(...).toString$0 is not a function
 native_method_inlining_test: RuntimeError # Please triage this failure.
 native_mirror_test: Crash # Internal Error: No default constructor available.
 native_mixin_field_test: RuntimeError # Please triage this failure.
-native_mixin_with_plain_test: RuntimeError # Please triage this failure.
-native_no_such_method_exception3_frog_test: RuntimeError # Please triage this failure.
+native_no_such_method_exception3_frog_test : RuntimeError # 
 native_wrapping_function3_frog_test: RuntimeError # invoke is not a function
 native_wrapping_function_frog_test: RuntimeError # invoke is not a function
 optimization_hints_test: RuntimeError # Please triage this failure.
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index b9428c1..693a690 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -36,6 +36,9 @@
 int_parse_radix_test/02: Fail # No bigints.
 double_parse_test/01: Pass, Fail # JS implementations disagree on U+0085 being whitespace.
 integer_to_radix_string_test: RuntimeError # issue 22045
+int_modulo_arith_test/bignum: RuntimeError # No bigints.
+int_modulo_arith_test/modPow: RuntimeError # No bigints.
+
 
 # With the exception of 'void', const Symbol() should not accept reserved
 # words.
@@ -210,133 +213,47 @@
 big_integer_parsed_mul_div_vm_test: Pass, Slow
 
 [ $compiler == dart2js && $cps_ir ]
-apply2_test: RuntimeError # Please triage this failure.
-apply3_test: RuntimeError # Please triage this failure.
-apply4_test: RuntimeError # Please triage this failure.
-apply_test: RuntimeError # Please triage this failure.
-collection_from_test: RuntimeError # Please triage this failure.
-collection_length_test: RuntimeError # Please triage this failure.
-collection_removes_test: RuntimeError # Please triage this failure.
-collection_test: RuntimeError # Please triage this failure.
-collection_to_string_test: RuntimeError # Please triage this failure.
-core_runtime_types_test: RuntimeError # Please triage this failure.
 date_time2_test: RuntimeError # Cannot read property 'prototype' of undefined
 date_time3_test: RuntimeError # Cannot read property 'prototype' of undefined
 date_time4_test: RuntimeError # Cannot read property 'prototype' of undefined
 date_time7_test: RuntimeError # Cannot read property 'prototype' of undefined
 date_time_parse_test: RuntimeError # Cannot read property 'prototype' of undefined
 error_stack_trace1_test: Pass # H.unwrapException(...).get$stackTrace is not a function
-for_in_test: RuntimeError # Please triage this failure.
-hash_set_test/none: RuntimeError # Please triage this failure.
 hashcode_test: RuntimeError # Please triage this failure.
-indexed_list_access_test: RuntimeError # Please triage this failure.
 int_parse_radix_test/01: Crash # Invalid argument(s)
 int_parse_radix_test/02: Crash # Invalid argument(s)
-int_parse_radix_test/none: Crash # Invalid argument(s)
-iterable_contains_test: RuntimeError # Please triage this failure.
 iterable_empty_test: RuntimeError # Please triage this failure.
-iterable_fold_test: RuntimeError # Please triage this failure.
-iterable_join_test: RuntimeError # Please triage this failure.
-iterable_mapping_test: RuntimeError # Please triage this failure.
-iterable_reduce_test: RuntimeError # Please triage this failure.
 iterable_return_type_test/none: RuntimeError # Please triage this failure.
-iterable_skip_test: RuntimeError # Please triage this failure.
-iterable_test: RuntimeError # Please triage this failure.
 iterable_to_list_test: RuntimeError # Please triage this failure.
 iterable_to_set_test: RuntimeError # Please triage this failure.
-iterable_tostring_test: RuntimeError # Please triage this failure.
-json_map_test: Crash # Internal Error: No default constructor available.
-linked_hash_map_test: RuntimeError # Please triage this failure.
-list_as_map_test: RuntimeError # Please triage this failure.
-list_contains_argument_order_test: RuntimeError # Please triage this failure.
-list_fill_range_test: RuntimeError # Please triage this failure.
-list_for_each_test: RuntimeError # Please triage this failure.
-list_get_range_test: RuntimeError # Please triage this failure.
-list_growable_test: RuntimeError # Please triage this failure.
-list_index_of2_test: RuntimeError # Please triage this failure.
-list_index_of_test: RuntimeError # Please triage this failure.
-list_insert_all_test: RuntimeError # Please triage this failure.
-list_insert_test: RuntimeError # Please triage this failure.
-list_iterators_test: RuntimeError # Please triage this failure.
-list_literal_is_growable_test: RuntimeError # Please triage this failure.
-list_literal_test: RuntimeError # Please triage this failure.
-list_map_test: RuntimeError # Please triage this failure.
-list_remove_range_test: RuntimeError # Please triage this failure.
-list_removeat_test: RuntimeError # Please triage this failure.
-list_replace_range_test: RuntimeError # Please triage this failure.
-list_reversed_test: RuntimeError # Please triage this failure.
-list_set_all_test: RuntimeError # Please triage this failure.
-list_set_range_test: RuntimeError # Please triage this failure.
-list_sort_test: RuntimeError # Please triage this failure.
 list_test/01: RuntimeError # this.get$length is not a function
 list_test/none: RuntimeError # this.get$length is not a function
-list_to_string2_test: RuntimeError # Please triage this failure.
-list_unmodifiable_test: RuntimeError # Please triage this failure.
 main_test: RuntimeError # receiver.get$_collection$_nums is not a function
-map_test: Crash # Internal Error: No default constructor available.
 map_values2_test: RuntimeError # Please triage this failure.
 map_values3_test: RuntimeError # Please triage this failure.
 map_values4_test: RuntimeError # Please triage this failure.
 null_test: RuntimeError # Cannot read property 'prototype' of undefined
-queue_first_test: RuntimeError # Please triage this failure.
-queue_iterator_test: RuntimeError # Please triage this failure.
-queue_last_test: RuntimeError # Please triage this failure.
-queue_single_test: RuntimeError # Please triage this failure.
-queue_test: RuntimeError # Please triage this failure.
-range_error_test: RuntimeError # Please triage this failure.
 reg_exp_first_match_test: RuntimeError # Cannot read property 'prototype' of undefined
 reg_exp_group_test: RuntimeError # Cannot read property 'prototype' of undefined
-reg_exp_groups_test: RuntimeError # Please triage this failure.
 reg_exp_string_match_test: RuntimeError # Cannot read property 'prototype' of undefined
 regexp/capture-3_test: RuntimeError # Cannot read property 'prototype' of undefined
-regexp/capture_test: RuntimeError # Please triage this failure.
 regexp/extended-characters-match_test: RuntimeError # Cannot read property 'prototype' of undefined
-regexp/global_test: RuntimeError # Please triage this failure.
-regexp/many-brackets_test: RuntimeError # Please triage this failure.
 regexp/non-bmp_test: RuntimeError # Cannot read property 'prototype' of undefined
-regexp/non-capturing-groups_test: RuntimeError # Please triage this failure.
 regexp/pcre_test: Crash # Stack Overflow
-regexp/regexp_test: RuntimeError # Please triage this failure.
 regexp/regress-regexp-construct-result_test: RuntimeError # Cannot read property 'prototype' of undefined
 regexp/results-cache_test: RuntimeError # Cannot read property 'prototype' of undefined
-regexp/stack-overflow2_test: RuntimeError # Please triage this failure.
 regexp/stack-overflow_test: RuntimeError # Cannot read property 'prototype' of undefined
 regexp/unicode-handling_test: RuntimeError # Cannot read property 'prototype' of undefined
-regress_11099_test: RuntimeError # Please triage this failure.
-set_test: RuntimeError # Please triage this failure.
-set_to_string_test: RuntimeError # Please triage this failure.
 shuffle_test: RuntimeError # Please triage this failure.
-sort_test: RuntimeError # Please triage this failure.
-splay_tree_test: RuntimeError # Please triage this failure.
 stacktrace_fromstring_test: RuntimeError # receiver.get$_collection$_nums is not a function
 stopwatch2_test: RuntimeError # Cannot read property 'prototype' of undefined
 stopwatch_test: RuntimeError # Cannot read property 'prototype' of undefined
-string_codeunits_test: RuntimeError # Please triage this failure.
-string_from_list_test: RuntimeError # Please triage this failure.
 string_fromcharcodes_test: RuntimeError # Please triage this failure.
-string_pattern_test: RuntimeError # Please triage this failure.
 string_replace_all_test: RuntimeError # Cannot read property 'prototype' of undefined
-string_replace_test: RuntimeError # Please triage this failure.
-string_runes_test: RuntimeError # Please triage this failure.
-string_source_test: RuntimeError # Please triage this failure.
-string_split_test: RuntimeError # Please triage this failure.
-string_test: RuntimeError # Please triage this failure.
-string_to_lower_case_test: RuntimeError # Please triage this failure.
-strings_test: RuntimeError # Please triage this failure.
-symbol_operator_test/03: RuntimeError # Please triage this failure.
+symbol_operator_test/03 : RuntimeError # 
 symbol_reserved_word_test/03: Pass # Please triage this failure.
 symbol_reserved_word_test/06: RuntimeError # Please triage this failure.
 symbol_reserved_word_test/09: RuntimeError # Please triage this failure.
 symbol_reserved_word_test/12: RuntimeError # Please triage this failure.
 symbol_test/none: Crash # The null object does not have a getter '_element'.
-uri_base_test: Crash # Invalid argument(s)
-uri_file_test: Crash # Invalid argument(s)
-uri_http_test: Crash # Invalid argument(s)
-uri_ipv4_test: RuntimeError # Please triage this failure.
-uri_ipv6_test: Crash # Invalid argument(s)
-uri_normalize_path_test: RuntimeError # Please triage this failure.
-uri_parse_test: Crash # Invalid argument(s)
-uri_path_test: Crash # Invalid argument(s)
-uri_query_test: Crash # Internal Error: No default constructor available.
-uri_scheme_test: Crash # Invalid argument(s)
 uri_test: Crash # Invalid argument(s)
diff --git a/tests/corelib/int_modulo_arith_test.dart b/tests/corelib/int_modulo_arith_test.dart
new file mode 100644
index 0000000..87d253d
--- /dev/null
+++ b/tests/corelib/int_modulo_arith_test.dart
@@ -0,0 +1,207 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+import "dart:math" show pow;
+
+var smallNumber = 1234567890;   // is 31-bit integer.
+var mediumNumber = 1234567890123456;  // is 53-bit integer
+var bigNumber = 590295810358705600000;  // is > 64-bit integer, exact as double.
+
+testModPow() {
+  test(x, e, m, expectedResult) {
+    // Check that expected result is correct, using an unoptimized version.
+    assert(() {
+      if (1 is double) return true;  // Don't have bignums.
+      slowModPow(x, e, m) {
+        var r = 1;
+        while (e > 0) {
+          if (e.isOdd) r = (r * x) % m;
+          e >>= 1;
+          x = (x * x) % m;
+        }
+        return r;
+      }
+      return slowModPow(x, e, m) == expectedResult;
+    });
+    var result = x.modPow(e, m);
+    Expect.equals(expectedResult, result, "$x.modPow($e, $m)");
+  }
+
+  test(10, 20, 1, 0);
+  test(1234567890, 1000000001, 19, 11);
+  test(1234567890, 19, 1000000001, 122998977);
+  test(19, 1234567890, 1000000001, 619059596);
+  test(19, 1000000001, 1234567890, 84910879);
+  test(1000000001, 19, 1234567890, 872984351);
+  test(1000000001, 1234567890, 19, 0);
+  test(12345678901234567890, 10000000000000000001, 19, 2);
+  test(12345678901234567890, 19, 10000000000000000001, 3239137215315834625);
+  test(19, 12345678901234567890, 10000000000000000001, 4544207837373941034);
+  test(19, 10000000000000000001, 12345678901234567890, 11135411705397624859);
+  test(10000000000000000001, 19, 12345678901234567890, 2034013733189773841);
+  test(10000000000000000001, 12345678901234567890, 19, 1);
+  test(12345678901234567890, 19, 10000000000000000001, 3239137215315834625);
+  test(12345678901234567890, 10000000000000000001, 19, 2);
+  test(123456789012345678901234567890,
+       123456789012345678901234567891,
+       123456789012345678901234567899,
+       116401406051033429924651549616);
+  test(123456789012345678901234567890,
+       123456789012345678901234567899,
+       123456789012345678901234567891,
+       123456789012345678901234567890);
+  test(123456789012345678901234567899,
+       123456789012345678901234567890,
+       123456789012345678901234567891,
+       35088523091000351053091545070);
+  test(123456789012345678901234567899,
+       123456789012345678901234567891,
+       123456789012345678901234567890,
+       18310047270234132455316941949);
+  test(123456789012345678901234567891,
+       123456789012345678901234567899,
+       123456789012345678901234567890,
+       1);
+  test(123456789012345678901234567891,
+       123456789012345678901234567890,
+       123456789012345678901234567899,
+       40128068573873018143207285483);
+
+}
+
+testModInverse() {
+  test(x, m, expectedResult) {
+    //print("$x op $m == $expectedResult");
+    // Check that expectedResult is an inverse.
+    assert(expectedResult < m);
+    // The 1 % m handles the m = 1 special case.
+    // This test may overflow if we don't have bignums, so only run on VM.
+    assert(1 is double || (((x % m) * expectedResult) - 1) % m == 0);
+
+    var result = x.modInverse(m);
+    Expect.equals(expectedResult, result, "$x modinv $m");
+
+    if (x > m) {
+      x = x % m;
+      var result = x.modInverse(m);
+      Expect.equals(expectedResult, result, "$x modinv $m");
+    }
+  }
+
+  testThrows(x, m) {
+    // Throws if not co-prime, which is a symmetric property.
+    Expect.throws(() => x.modInverse(m), null, "$x modinv $m");
+    Expect.throws(() => m.modInverse(x), null, "$m modinv $x");
+  }
+
+  test(1, 1, 0);
+
+  testThrows(0, 1000000001);
+  testThrows(2, 4);
+  testThrows(99, 9);
+  testThrows(19, 1000000001);
+  testThrows(123456789012345678901234567890, 123456789012345678901234567899);
+
+  // Co-prime numbers
+  test(1234567890, 19, 11);
+  test(1234567890, 1000000001, 189108911);
+  test(19, 1234567890, 519818059);
+  test(1000000001, 1234567890, 1001100101);
+
+  test(12345, 12346, 12345);
+  test(12345, 12346, 12345);
+
+  test(smallNumber, 137, 42);
+  test(137, smallNumber, 856087223);
+  test(mediumNumber, 137, 77);
+  test(137, mediumNumber, 540686667207353);
+  test(bigNumber, 137, 128);                  /// bignum: ok
+  // Bigger numbers as modulo is tested in big_integer_arith_vm_test.dart.
+  // Big doubles are not co-prime, so there is nothing to test for dart2js.
+}
+
+testGcd() {
+  // Call testFunc with all combinations and orders of plus/minus
+  // value and other.
+  callCombos(value, other, testFunc) {
+    testFunc(value, other);
+    testFunc(value, -other);
+    testFunc(-value, other);
+    testFunc(-value, -other);
+    if (value == other) return;
+    testFunc(other, value);
+    testFunc(other, -value);
+    testFunc(-other, value);
+    testFunc(-other, -value);
+  }
+
+  // Test that gcd of value and other (non-negative) is expectedResult.
+  // Tests all combinations of positive and negative values and order of
+  // operands, so use positive values and order is not important.
+  test(value, other, [expectedResult]) {
+    assert(value % expectedResult == 0);  // Check for bug in test.
+    assert(other % expectedResult == 0);
+    callCombos(value, other, (a, b) {
+      var result = a.gcd(b);
+      /// Check that the result is a divisor.
+      Expect.equals(0, a % result, "$result | $a");
+      Expect.equals(0, b % result, "$result | $b");
+      // Check for bug in test. If assert fails, the expected value is too low,
+      // and the gcd call has found a greater common divisor.
+      assert(result >= expectedResult);
+      Expect.equals(expectedResult, result, "$a.gcd($b)");
+    });
+  }
+
+  // Test that gcd of value and other (non-negative) throws.
+  testThrows(value, other) {
+    callCombos(value, other, (a, b) {
+      Expect.throws(() => a.gcd(b), null, "$a.gcd($b)");
+    });
+  }
+
+  // Throws if either operand is zero, and if both operands are zero.
+  testThrows(0, 1000);
+  testThrows(0, 0);
+
+  // Format:
+  //  test(value1, value2, expectedResult);
+  test(1, 1, 1);     // both are 1
+  test(1, 2, 1);     // one is 1
+  test(3, 5, 1);     // coprime.
+  test(37, 37, 37);  // Same larger prime.
+
+  test(9999, 7272, 909);  // Larger numbers
+
+  // Multiplying both operands by a number multiplies result by same number.
+  test(693, 609, 21);
+  test(693 << 5, 609 << 5, 21 << 5);
+  test(693 * 937, 609 * 937, 21 * 937);
+  test(693 * pow(2, 32), 609 * pow(2, 32), 21 * pow(2, 32));
+  test(693 * pow(2, 52), 609 * pow(2, 52), 21 * pow(2, 52));
+  test(693 * pow(2, 53), 609 * pow(2, 53), 21 * pow(2, 53));  // Regression.
+  test(693 * pow(2, 99), 609 * pow(2, 99), 21 * pow(2, 99));
+
+  test(1234567890, 19, 1);
+  test(1234567890, 1000000001, 1);
+  test(19, 1000000001, 19);
+
+  test(0x3FFFFFFF, 0x3FFFFFFF, 0x3FFFFFFF);
+  test(0x3FFFFFFF, 0x40000000, 1);
+
+  test(pow(2, 54), pow(2, 53), pow(2, 53));
+
+  test((pow(2, 52) - 1) * pow(2, 14),
+       (pow(2, 26) - 1) * pow(2, 22),
+       (pow(2, 26) - 1) * pow(2, 14));
+}
+
+main() {
+  testModPow();  /// modPow: ok
+  testModInverse();
+  testGcd();
+}
+
diff --git a/tests/html/html.status b/tests/html/html.status
index 8814b56..1dd6339 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -6,6 +6,9 @@
 dromaeo_smoke_test: Skip # Issue 14521, 8257
 cross_frame_test: Skip # Test reloads itself. Issue 18558
 
+js_array_test: Skip # Issue 23676, 23677
+js_typed_interop_test: Skip # Issue 23676, 23677
+
 [ $compiler == none && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 custom/attribute_changed_callback_test/unsupported_on_polyfill: Fail # Issue 18931 (Disabled for Chrome 35 roll)
 form_data_test/functional: Skip # Issue 19726
@@ -414,150 +417,3 @@
 window_nosuchmethod_test: StaticWarning
 
 [ $compiler == dart2js && $cps_ir ]
-async_spawnuri_test: Crash # Invalid argument(s)
-async_test: Crash # Invalid argument(s)
-audiobuffersourcenode_test: Crash # Invalid argument(s)
-audiocontext_test: Crash # Invalid argument(s)
-audioelement_test: Crash # Invalid argument(s)
-b_element_test: Crash # Invalid argument(s)
-blob_constructor_test: Crash # Invalid argument(s)
-cache_test: Crash # Invalid argument(s)
-callbacks_test: Crash # Invalid argument(s)
-canvas_pixel_array_type_alias_test: Crash # Invalid argument(s)
-canvas_test: Crash # Invalid argument(s)
-canvasrenderingcontext2d_test: Crash # Invalid argument(s)
-cdata_test: Crash # Invalid argument(s)
-client_rect_test: Crash # Invalid argument(s)
-cross_domain_iframe_test: Crash # Invalid argument(s)
-crypto_test: Crash # Invalid argument(s)
-css_rule_list_test: Crash # Invalid argument(s)
-css_test: Crash # Invalid argument(s)
-cssstyledeclaration_test: Crash # Invalid argument(s)
-custom/attribute_changed_callback_test: Crash # Invalid argument(s)
-custom/constructor_calls_created_synchronously_test: Crash # Invalid argument(s)
-custom/created_callback_test: Crash # Invalid argument(s)
-custom/document_register_basic_test: Crash # Invalid argument(s)
-custom/document_register_type_extensions_test: Crash # Invalid argument(s)
-custom/element_upgrade_test: Crash # Invalid argument(s)
-custom/entered_left_view_test: Crash # Invalid argument(s)
-custom/js_custom_test: Crash # Invalid argument(s)
-custom/mirrors_test: Crash # Invalid argument(s)
-custom/regress_194523002_test: Crash # Internal Error: No default constructor available.
-custom_element_method_clash_test: Crash # Invalid argument(s)
-custom_element_name_clash_test: Crash # Invalid argument(s)
-custom_elements_23127_test: Crash # Invalid argument(s)
-custom_elements_test: Crash # Invalid argument(s)
-custom_tags_test: Crash # Invalid argument(s)
-dart_object_local_storage_test: Crash # Invalid argument(s)
-datalistelement_test: Crash # Invalid argument(s)
-document_test: Crash # Invalid argument(s)
-documentfragment_test: Crash # Invalid argument(s)
-dom_constructors_test: Crash # Invalid argument(s)
-domparser_test: Crash # Invalid argument(s)
-element_add_test: Crash # Invalid argument(s)
-element_animate_test: Crash # Invalid argument(s)
-element_classes_svg_test: Crash # Invalid argument(s)
-element_classes_test: Crash # Invalid argument(s)
-element_constructor_1_test: Crash # Invalid argument(s)
-element_dimensions_test: Crash # Invalid argument(s)
-element_offset_test: Crash # Invalid argument(s)
-element_test: Crash # Invalid argument(s)
-element_types_constructors1_test: Crash # Invalid argument(s)
-element_types_constructors2_test: Crash # Invalid argument(s)
-element_types_constructors3_test: Crash # Invalid argument(s)
-element_types_constructors4_test: Crash # Invalid argument(s)
-element_types_constructors5_test: Crash # Invalid argument(s)
-element_types_constructors6_test: Crash # Invalid argument(s)
-element_types_test: Crash # Invalid argument(s)
-event_customevent_test: Crash # Invalid argument(s)
-event_test: Crash # Invalid argument(s)
-events_test: Crash # Invalid argument(s)
-exceptions_test: Crash # Invalid argument(s)
-fileapi_test: Crash # Invalid argument(s)
-filereader_test: Crash # Invalid argument(s)
-fontface_loaded_test: Crash # Invalid argument(s)
-fontface_test: Crash # Invalid argument(s)
-form_data_test: Crash # Invalid argument(s)
-form_element_test: Crash # Invalid argument(s)
-geolocation_test: Crash # Invalid argument(s)
-hidden_dom_1_test: Crash # Invalid argument(s)
-hidden_dom_2_test: Crash # Invalid argument(s)
-history_test: Crash # Invalid argument(s)
-htmlcollection_test: Crash # Invalid argument(s)
-htmlelement_test: Crash # Invalid argument(s)
-htmloptionscollection_test: Crash # Invalid argument(s)
-indexeddb_1_test: Crash # Invalid argument(s)
-indexeddb_2_test: Crash # Invalid argument(s)
-indexeddb_3_test: Crash # Invalid argument(s)
-indexeddb_4_test: Crash # Invalid argument(s)
-indexeddb_5_test: Crash # Invalid argument(s)
-input_element_test: Crash # Invalid argument(s)
-instance_of_test: Crash # Invalid argument(s)
-isolates_test: Crash # Invalid argument(s)
-js_interop_1_test: Crash # Invalid argument(s)
-js_test: Crash # Invalid argument(s)
-keyboard_event_test: Crash # Invalid argument(s)
-localstorage_test: Crash # Invalid argument(s)
-location_test: Crash # Invalid argument(s)
-media_stream_test: Crash # Invalid argument(s)
-mediasource_test: Crash # Invalid argument(s)
-messageevent_test: Crash # Invalid argument(s)
-mouse_event_test: Crash # Invalid argument(s)
-mutationobserver_test: Crash # Invalid argument(s)
-native_gc_test: Crash # Invalid argument(s)
-navigator_test: Crash # Invalid argument(s)
-node_test: Crash # Invalid argument(s)
-node_validator_important_if_you_suppress_make_the_bug_critical_test: Crash # Invalid argument(s)
-non_instantiated_is_test: Crash # Invalid argument(s)
-notification_test: Crash # Invalid argument(s)
-performance_api_test: Crash # Invalid argument(s)
-postmessage_structured_test: Crash # Invalid argument(s)
-query_test: Crash # Invalid argument(s)
-queryall_test: Crash # Invalid argument(s)
-range_test: Crash # Invalid argument(s)
-request_animation_frame_test: Crash # Invalid argument(s)
-rtc_test: Crash # Invalid argument(s)
-selectelement_test: Crash # Invalid argument(s)
-serialized_script_value_test: Crash # Invalid argument(s)
-shadow_dom_test: Crash # Invalid argument(s)
-shadowroot_test: Crash # Invalid argument(s)
-speechrecognition_test: Crash # Invalid argument(s)
-storage_quota_test/missingenumcheck: Crash # Invalid argument(s)
-storage_quota_test/none: Crash # Invalid argument(s)
-storage_test: Crash # Invalid argument(s)
-streams_test: Crash # Invalid argument(s)
-svg_test: Crash # Invalid argument(s)
-svgelement_test: Crash # Invalid argument(s)
-table_test: Crash # Invalid argument(s)
-text_event_test: Crash # Invalid argument(s)
-touchevent_test: Crash # Invalid argument(s)
-track_element_constructor_test: Crash # Invalid argument(s)
-transferables_test: Crash # Invalid argument(s)
-transition_event_test: Crash # Invalid argument(s)
-trusted_html_tree_sanitizer_test: Crash # Invalid argument(s)
-typed_arrays_1_test: Crash # Invalid argument(s)
-typed_arrays_2_test: Crash # Invalid argument(s)
-typed_arrays_3_test: Crash # Invalid argument(s)
-typed_arrays_4_test: Crash # Invalid argument(s)
-typed_arrays_5_test: Crash # Invalid argument(s)
-typed_arrays_arraybuffer_test: Crash # Invalid argument(s)
-typed_arrays_dataview_test: Crash # Invalid argument(s)
-typed_arrays_range_checks_test: Crash # Invalid argument(s)
-typed_arrays_simd_test: Crash # Invalid argument(s)
-typing_test: Crash # Invalid argument(s)
-unknownelement_test: Crash # Invalid argument(s)
-uri_test: Crash # Invalid argument(s)
-url_test: Crash # Invalid argument(s)
-webgl_1_test: Crash # Invalid argument(s)
-websocket_test: Crash # Invalid argument(s)
-websql_test: Crash # Invalid argument(s)
-wheelevent_test: Crash # Invalid argument(s)
-window_eq_test: Crash # Invalid argument(s)
-window_mangling_test: Crash # Invalid argument(s)
-window_nosuchmethod_test: Crash # Invalid argument(s)
-window_test: Crash # Invalid argument(s)
-worker_api_test: Crash # Invalid argument(s)
-worker_test: Crash # Invalid argument(s)
-xhr_cross_origin_test: Crash # Invalid argument(s)
-xhr_test: Crash # Invalid argument(s)
-xsltprocessor_test: Crash # Invalid argument(s)
diff --git a/tests/html/js_array_test.dart b/tests/html/js_array_test.dart
new file mode 100644
index 0000000..4ede8ed
--- /dev/null
+++ b/tests/html/js_array_test.dart
@@ -0,0 +1,594 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library jsArrayTest;
+
+import 'dart:html';
+import 'dart:js';
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+
+_injectJs() {
+  document.body.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+function callJsMethod(jsObj, jsMethodName, args) {
+  return jsObj[jsMethodName].apply(jsObj, args);
+}
+
+function jsEnumerateIndices(obj) {
+  var ret = [];
+  for(var i in obj) {
+    ret.push(i);
+  }
+  return ret;
+}
+
+function setValue(obj, index, value) {
+  return obj[index] = value;
+}
+
+function getValue(obj, index) {
+  return obj[index];
+}
+
+function checkIsArray(obj) {
+  return Array.isArray(obj);
+}
+
+function concatValues(obj) {
+  return obj.concat("a", "b", ["c", "d"], 42, {foo: 10});
+}
+
+function concatOntoArray(obj) {
+  return [1,2,3].concat(obj, "foo");
+}
+
+function repeatedConcatOntoArray(obj) {
+  return [1,2,3].concat(obj, obj);
+}
+
+function everyGreaterThanZero(obj) {
+  return obj.every(function(currentValue, index, array) {
+    return currentValue > 0;
+  });
+}
+
+function everyGreaterThanZeroCheckThisArg(obj) {
+  var j = 0;
+  return obj.every(function(currentValue, index, array) {
+    if (j != index) {
+      throw "Unxpected index";
+    }
+    j++;
+    if (array !== obj) {
+      throw "Array argument doesn't match obj";
+    }
+    return currentValue > 0;
+  });
+}
+
+function filterGreater42(obj) {
+  return obj.filter(function(currentValue, index, array) {
+    return currentValue > 42;
+  });
+}
+
+function forEachCollectResult(array, callback) {
+  var result = [];
+  array.forEach(function(currentValue) {
+    result.push(currentValue * 2);
+  });
+  return result;
+}
+
+function someEqual42(array, callback) {
+  return array.some(function(currentValue) {
+    return currentValue == 42;
+  });
+}
+
+function sortNumbersBackwards(array) {
+  return array.sort(function(a, b) {
+    return b - a;
+  });
+}
+
+function spliceDummyItems(array) {
+  return array.splice(1, 2, "quick" ,"brown", "fox");
+}
+
+function spliceTestStringArgs(array) {
+  return array.splice("1.2", "2.01", "quick" ,"brown", "fox");
+}
+
+function splicePastEnd(array) {
+  return array.splice(1, 5332, "quick" ,"brown", "fox");
+}
+
+function callJsToString(array) {
+  return array.toString();
+}
+
+function mapAddIndexToEachElement(array) {
+  return array.map(function(currentValue, index) {
+    return currentValue + index;
+  });
+}
+
+function reduceSumDoubledElements(array) {
+  return array.reduce(function(previousValue, currentValue) {
+        return previousValue + currentValue*2;
+      },
+      0);
+}
+
+// TODO(jacobr): add a test that distinguishes reduce from reduceRight.
+function reduceRightSumDoubledElements(array) {
+  return array.reduceRight(function(previousValue, currentValue) {
+        return previousValue + currentValue*2;
+      },
+      0);
+}
+
+function identical(o1, o2) {
+  return o1 === o2;
+}
+
+function getOwnPropertyDescriptorJson(array, property) {
+  return JSON.stringify(Object.getOwnPropertyDescriptor(array, property));
+}
+
+function setLength(array, len) {
+  return array.length = len;
+}
+
+function jsonStringify(o) {
+  return JSON.stringify(o);
+}
+
+// Calling a method from Dart List on an arbitrary target object.
+function callListMethodOnTarget(dartArray, target, methodName, args) {
+  return dartArray[methodName].apply(target, args);
+}
+
+""");
+}
+
+class Foo {}
+
+callJsMethod(List array, String methodName, List args) =>
+    context.callMethod("callJsMethod", [array, methodName, args]);
+
+callIndexOf(List array, value) => callJsMethod(array, "indexOf", [value]);
+callLastIndexOf(List array, value) =>
+    callJsMethod(array, "lastIndexOf", [value]);
+
+callPop(List array) => callJsMethod(array, "pop", []);
+callPush(List array, element) => callJsMethod(array, "push", [element]);
+callShift(List array) => callJsMethod(array, "shift", []);
+callReverse(List array) => callJsMethod(array, "reverse", []);
+callSetLength(List array, length) =>
+    context.callMethod("setLength", [array, length]);
+
+callListMethodOnObject(JsObject object, String methodName, List args) => context
+    .callMethod("callListMethodOnTarget", [[], object, methodName, args]);
+
+jsonStringify(JsObject object) => context.callMethod("jsonStringify", [object]);
+
+main() {
+  _injectJs();
+  useHtmlConfiguration();
+
+  group('indexOf', () {
+    var div = new DivElement();
+    var list = [3, 42, "foo", 42, div];
+    test('found', () {
+      expect(callIndexOf(list, 3), equals(0));
+      expect(callIndexOf(list, 42), equals(1));
+      expect(callIndexOf(list, "foo"), equals(2));
+      expect(callIndexOf(list, div), equals(4));
+    });
+
+    test('missing', () {
+      expect(callIndexOf(list, 31), equals(-1));
+      expect(callIndexOf(list, "42"), equals(-1));
+      expect(callIndexOf(list, null), equals(-1));
+    });
+  });
+
+  group('set length', () {
+    test('larger', () {
+      var list = ["a", "b", "c", "d"];
+      expect(callSetLength(list, 10), equals(10));
+      expect(list.length, equals(10));
+      expect(list.last, equals(null));
+      expect(list[3], equals("d"));
+    });
+
+    test('smaller', () {
+      var list = ["a", "b", "c", "d"];
+      expect(callSetLength(list, 2), equals(2));
+      expect(list.first, equals("a"));
+      expect(list.last, equals("b"));
+      expect(list.length, equals(2));
+      expect(callSetLength(list, 0), equals(0));
+      expect(list.length, equals(0));
+      expect(callSetLength(list, 2), equals(2));
+      expect(list.first, equals(null));
+    });
+
+    test('invalid', () {
+      var list = ["a", "b", "c", "d"];
+      expect(() => callSetLength(list, 2.3), throws);
+      expect(list.length, equals(4));
+      expect(() => callSetLength(list, -1), throws);
+      expect(list.length, equals(4));
+      // Make sure we are coercing to a JS number.
+      expect(callSetLength(list, "2"), equals("2"));
+      expect(list.length, equals(2));
+    });
+  });
+
+  group('join', () {
+    var list = [3, 42, "foo"];
+    var listWithDartClasses = [3, new Foo(), 42, "foo", new Object()];
+    test('default', () {
+      expect(callJsMethod(list, "join", []), equals("3,42,foo"));
+      expect(callJsMethod(listWithDartClasses, "join", []),
+          equals("3,Instance of 'Foo',42,foo,Instance of 'Object'"));
+    });
+
+    test('custom separator', () {
+      expect(callJsMethod(list, "join", ["##"]), equals("3##42##foo"));
+    });
+  });
+
+  group('lastIndexOf', () {
+    var list = [3, 42, "foo", 42];
+    test('found', () {
+      expect(callLastIndexOf(list, 3), equals(0));
+      expect(callLastIndexOf(list, 42), equals(3));
+      expect(callLastIndexOf(list, "foo"), equals(2));
+    });
+
+    test('missing', () {
+      expect(callLastIndexOf(list, 31), equals(-1));
+      expect(callLastIndexOf(list, "42"), equals(-1));
+      expect(callLastIndexOf(list, null), equals(-1));
+    });
+  });
+
+  group('pop', () {
+    test('all', () {
+      var foo = new Foo();
+      var div = new DivElement();
+      var list = [3, 42, "foo", foo, div];
+      expect(callPop(list), equals(div));
+      expect(list.length, equals(4));
+      expect(callPop(list), equals(foo));
+      expect(list.length, equals(3));
+      expect(callPop(list), equals("foo"));
+      expect(list.length, equals(2));
+      expect(callPop(list), equals(42));
+      expect(list.length, equals(1));
+      expect(callPop(list), equals(3));
+      expect(list.length, equals(0));
+      expect(callPop(list), equals(null));
+      expect(list.length, equals(0));
+    });
+  });
+
+  group('push', () {
+    test('strings', () {
+      var list = [];
+      var div = new DivElement();
+      expect(callPush(list, "foo"), equals(1));
+      expect(callPush(list, "bar"), equals(2));
+      // Calling push with 0 elements should do nothing.
+      expect(callJsMethod(list, "push", []), equals(2));
+      expect(callPush(list, "baz"), equals(3));
+      expect(callPush(list, div), equals(4));
+      expect(callJsMethod(list, "push", ["a", "b"]), equals(6));
+      expect(list, equals(["foo", "bar", "baz", div, "a", "b"]));
+    });
+  });
+
+  group('shift', () {
+    test('all', () {
+      var foo = new Foo();
+      var div = new DivElement();
+      var list = [3, 42, "foo", foo, div];
+      expect(callShift(list), equals(3));
+      expect(list.length, equals(4));
+      expect(callShift(list), equals(42));
+      expect(list.length, equals(3));
+      expect(callShift(list), equals("foo"));
+      expect(list.length, equals(2));
+      expect(callShift(list), equals(foo));
+      expect(list.length, equals(1));
+      expect(callShift(list), equals(div));
+      expect(list.length, equals(0));
+      expect(callShift(list), equals(null));
+      expect(list.length, equals(0));
+    });
+  });
+
+  group('reverse', () {
+    test('simple', () {
+      var foo = new Foo();
+      var div = new DivElement();
+      var list = [div, 42, foo];
+      callReverse(list);
+      expect(list, equals([foo, 42, div]));
+      list = [3, 42];
+      callReverse(list);
+      expect(list, equals([42, 3]));
+    });
+  });
+
+  group('slice', () {
+    test('copy', () {
+      var foo = new Foo();
+      var div = new DivElement();
+      var list = [3, 42, "foo", foo, div];
+      var copy = callJsMethod(list, "slice", []);
+      expect(identical(list, copy), isFalse);
+      expect(copy.length, equals(list.length));
+      for (var i = 0; i < list.length; i++) {
+        expect(list[i], equals(copy[i]));
+      }
+      expect(identical(list[3], copy[3]), isTrue);
+      expect(identical(list[4], copy[4]), isTrue);
+
+      copy.add("dummy");
+      expect(list.length + 1, equals(copy.length));
+    });
+
+    test('specify start', () {
+      var list = [3, 42, "foo"];
+      var copy = callJsMethod(list, "slice", [1]);
+      expect(copy.first, equals(42));
+    });
+
+    test('specify start and end', () {
+      var list = [3, 42, 92, "foo"];
+      var copy = callJsMethod(list, "slice", [1, 3]);
+      expect(copy.first, equals(42));
+      expect(copy.last, equals(92));
+    });
+
+    test('from end', () {
+      var list = [3, 42, 92, "foo"];
+      expect(callJsMethod(list, "slice", [-2]), equals([92, "foo"]));
+
+      // Past the end of the front of the array.
+      expect(callJsMethod(list, "slice", [-2, 3]), equals([92]));
+
+      // Past the end of the front of the array.
+      expect(callJsMethod(list, "slice", [-10, 2]), equals([3, 42]));
+    });
+  });
+
+  group("js snippet tests", () {
+    test("enumerate indices", () {
+      var list = ["a", "b", "c", "d"];
+      var indices = context.callMethod('jsEnumerateIndices', [list]);
+      expect(indices.length, equals(4));
+      for (int i = 0; i < 4; i++) {
+        expect(indices[i], equals('$i'));
+      }
+    });
+
+    test("set element", () {
+      var list = ["a", "b", "c", "d"];
+      context.callMethod('setValue', [list, 0, 42]);
+      expect(list[0], equals(42));
+      context.callMethod('setValue', [list, 1, 84]);
+      expect(list[1], equals(84));
+      context.callMethod(
+          'setValue', [list, 6, 100]); // Off the end of the list.
+      expect(list.length, equals(7));
+      expect(list[4], equals(null));
+      expect(list[6], equals(100));
+
+      // These tests have to be commented out because we don't persist
+      // JS proxies for Dart objects like we could/should.
+      // context.callMethod('setValue', [list, -1, "foo"]); // Not a valid array index
+      // expect(context.callMethod('getValue', [list, -1]), equals("foo"));
+      // expect(context.callMethod('getValue', [list, "-1"]), equals("foo"));
+    });
+
+    test("get element", () {
+      var list = ["a", "b", "c", "d"];
+      expect(context.callMethod('getValue', [list, 0]), equals("a"));
+      expect(context.callMethod('getValue', [list, 1]), equals("b"));
+      expect(context.callMethod('getValue', [list, 6]), equals(null));
+      expect(context.callMethod('getValue', [list, -1]), equals(null));
+
+      expect(context.callMethod('getValue', [list, "0"]), equals("a"));
+      expect(context.callMethod('getValue', [list, "1"]), equals("b"));
+    });
+
+    test("is array", () {
+      var list = ["a", "b"];
+      expect(context.callMethod("checkIsArray", [list]), isTrue);
+    });
+
+    test("property descriptors", () {
+      // This test matters to make behavior consistent with JS native arrays
+      // and to make devtools integration work well.
+      var list = ["a", "b"];
+      expect(context.callMethod("getOwnPropertyDescriptorJson", [list, 0]),
+          equals('{"value":"a",'
+              '"writable":true,'
+              '"enumerable":true,'
+              '"configurable":true}'));
+
+      expect(
+          context.callMethod("getOwnPropertyDescriptorJson", [list, "length"]),
+          equals('{"value":2,'
+              '"writable":true,'
+              '"enumerable":false,'
+              '"configurable":false}'));
+    });
+
+    test("concat js arrays", () {
+      var list = ["1", "2"];
+      // Tests that calling the concat method from JS will flatten out JS arrays
+      // We concat the array with "a", "b", ["c", "d"], 42, {foo: 10}
+      // which should generate ["1", "2", "a", "b", ["c", "d"], 42, {foo: 10}]
+      var ret = context.callMethod("concatValues", [list]);
+      expect(list.length, equals(2));
+      expect(ret.length, equals(8));
+      expect(ret[0], equals("1"));
+      expect(ret[3], equals("b"));
+      expect(ret[5], equals("d"));
+      expect(ret[6], equals(42));
+      expect(ret[7]['foo'], equals(10));
+    });
+
+    test("concat onto arrays", () {
+      // This test only passes if we have monkey patched the core Array object
+      // prototype to handle Dart Lists.
+      var list = ["a", "b"];
+      var ret = context.callMethod("concatOntoArray", [list]);
+      expect(list.length, equals(2));
+      expect(ret, equals([1, 2, 3, "a", "b", "foo"]));
+    });
+
+    test("dart arrays on dart arrays", () {
+      // This test only passes if we have monkey patched the core Array object
+      // prototype to handle Dart Lists.
+      var list = ["a", "b"];
+      var ret = callJsMethod(list, "concat", [["c", "d"], "e", ["f", "g"]]);
+      expect(list.length, equals(2));
+      expect(ret, equals(["a", "b", "c", "d", "e", "f", "g"]));
+    });
+
+    test("every greater than zero", () {
+      expect(context.callMethod("everyGreaterThanZero", [[1, 5]]), isTrue);
+      expect(context.callMethod("everyGreaterThanZeroCheckThisArg", [[1, 5]]),
+          isTrue);
+      expect(context.callMethod("everyGreaterThanZero", [[1, 0]]), isFalse);
+      expect(context.callMethod("everyGreaterThanZero", [[]]), isTrue);
+    });
+
+    test("filter greater than 42", () {
+      expect(context.callMethod("filterGreater42", [[1, 5]]), equals([]));
+      expect(context.callMethod("filterGreater42", [[43, 5, 49]]),
+          equals([43, 49]));
+      expect(context.callMethod("filterGreater42", [["43", "5", "49"]]),
+          equals(["43", "49"]));
+    });
+
+    test("for each collect result", () {
+      expect(context.callMethod("forEachCollectResult", [[1, 5, 7]]),
+          equals([2, 10, 14]));
+    });
+
+    test("some", () {
+      expect(context.callMethod("someEqual42", [[1, 5, 9]]), isFalse);
+      expect(context.callMethod("someEqual42", [[1, 42, 9]]), isTrue);
+    });
+
+    test("sort backwards", () {
+      var arr = [1, 5, 9];
+      var ret = context.callMethod("sortNumbersBackwards", [arr]);
+      expect(identical(arr, ret), isTrue);
+      expect(ret, equals([9, 5, 1]));
+    });
+
+    test("splice dummy items", () {
+      var list = [1, 2, 3, 4];
+      var removed = context.callMethod("spliceDummyItems", [list]);
+      expect(removed.length, equals(2));
+      expect(removed[0], equals(2));
+      expect(removed[1], equals(3));
+      expect(list.first, equals(1));
+      expect(list[1], equals("quick"));
+      expect(list[2], equals("brown"));
+      expect(list[3], equals("fox"));
+      expect(list.last, equals(4));
+    });
+
+    test("splice string args", () {
+      var list = [1, 2, 3, 4];
+      var removed = context.callMethod("spliceTestStringArgs", [list]);
+      expect(removed.length, equals(2));
+      expect(removed[0], equals(2));
+      expect(removed[1], equals(3));
+      expect(list.first, equals(1));
+      expect(list[1], equals("quick"));
+      expect(list[2], equals("brown"));
+      expect(list[3], equals("fox"));
+      expect(list.last, equals(4));
+    });
+
+    test("splice pastEndOfArray", () {
+      var list = [1, 2, 3, 4];
+      var removed = context.callMethod("splicePastEnd", [list]);
+      expect(removed.length, equals(3));
+      expect(list.first, equals(1));
+      expect(list.length, equals(4));
+      expect(list[1], equals("quick"));
+      expect(list[2], equals("brown"));
+      expect(list[3], equals("fox"));
+    });
+
+    test("splice both bounds past end of array", () {
+      var list = [1];
+      var removed = context.callMethod("splicePastEnd", [list]);
+      expect(removed.length, equals(0));
+      expect(list.first, equals(1));
+      expect(list.length, equals(4));
+      expect(list[1], equals("quick"));
+      expect(list[2], equals("brown"));
+      expect(list[3], equals("fox"));
+    });
+
+    test("call List method on JavaScript object", () {
+      var jsObject = new JsObject.jsify({});
+      callListMethodOnObject(jsObject, 'push', ["a"]);
+      callListMethodOnObject(jsObject, 'push', ["b"]);
+      callListMethodOnObject(jsObject, 'push', ["c", "d"]);
+      callListMethodOnObject(jsObject, 'push', []);
+
+      expect(jsonStringify(jsObject),
+          equals('{"0":"a","1":"b","2":"c","3":"d","length":4}'));
+
+      expect(callListMethodOnObject(jsObject, 'pop', []), equals("d"));
+      expect(callListMethodOnObject(jsObject, 'join', ["#"]), equals("a#b#c"));
+
+      var jsArray = new JsObject.jsify([]);
+      callListMethodOnObject(jsArray, 'push', ["a"]);
+      callListMethodOnObject(jsArray, 'push', ["b"]);
+      callListMethodOnObject(jsArray, 'push', ["c", "d"]);
+      callListMethodOnObject(jsArray, 'push', []);
+
+      expect(jsonStringify(jsArray), equals('["a","b","c","d"]'));
+    });
+  });
+
+  // This test group is disabled until we figure out an efficient way to
+  // distinguish between "array" Dart List types and non-array Dart list types.
+  /*
+  group('Non-array Lists', () {
+    test('opaque proxy', () {
+      // Dartium could easily support making LinkedList and all other classes
+      // implementing List behave like a JavaScript array but that would
+      // be challenging to implement in dart2js until browsers support ES6.
+      var list = ["a", "b", "c", "d"];
+      var listView = new UnmodifiableListView(list.getRange(1,3));
+      expect(listView is List, isTrue);
+      expect(listView.length, equals(2));
+      expect(context.callMethod("checkIsArray", [listView]), isFalse);
+      expect(context.callMethod("checkIsArray", [listView.toList()]), isTrue);
+      expect(context.callMethod("getOwnPropertyDescriptorJson",
+          [listView, "length"]), equals("null"));
+    });
+  });
+  */
+}
diff --git a/tests/html/js_typed_interop_test.dart b/tests/html/js_typed_interop_test.dart
new file mode 100644
index 0000000..c8c0260
--- /dev/null
+++ b/tests/html/js_typed_interop_test.dart
@@ -0,0 +1,139 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library jsArrayTest;
+
+import 'dart:html';
+import 'dart:js';
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+
+_injectJs() {
+  document.body.append(new ScriptElement()
+    ..type = 'text/javascript'
+    ..innerHtml = r"""
+  var foo = {
+    x: 3,
+    z: 40, // Not specified in typed Dart API so should fail in checked mode.
+    multiplyByX: function(arg) { return arg * this.x; },
+    // This function can be torn off without having to bind this.
+    multiplyBy2: function(arg) { return arg * 2; }
+  };
+
+  var foob = {
+    x: 8,
+    y: "why",
+    multiplyByX: function(arg) { return arg * this.x; }
+  };
+
+  var bar = {
+    x: "foo",
+    multiplyByX: true
+  };
+
+  var selection = ["a", "b", "c", foo, bar];  
+  selection.doubleLength = function() { return this.length * 2; };
+""");
+}
+
+abstract class Foo {
+  int get x;
+  set x(int v);
+  num multiplyByX(num y);
+  num multiplyBy2(num y);
+}
+
+abstract class Foob extends Foo {
+  final String y;
+}
+
+abstract class Bar {
+  String get x;
+  bool get multiplyByX;
+}
+
+class Baz {}
+
+// This class shows the pattern used by APIs such as jQuery that add methods
+// to Arrays.
+abstract class Selection implements List {
+  num doubleLength();
+}
+
+Foo get foo => context['foo'];
+Foob get foob => context['foob'];
+Bar get bar => context['bar'];
+Selection get selection => context['selection'];
+
+main() {
+  // Call experimental API to register Dart interfaces implemented by
+  // JavaScript classes.
+  registerJsInterfaces([Foo, Foob, Bar, Selection]);
+
+  _injectJs();
+
+  useHtmlConfiguration();
+
+  group('property', () {
+    test('get', () {
+      expect(foo.x, equals(3));
+      expect(foob.x, equals(8));
+      expect(foob.y, equals("why"));
+
+      // Exists in JS but not in API.
+      expect(() => foo.z, throws);
+      expect(bar.multiplyByX, isTrue);
+    });
+    test('set', () {
+      foo.x = 42;
+      expect(foo.x, equals(42));
+      // Property tagged as read only in typed API.
+      expect(() => foob.y = "bla", throws);
+      expect(() => foo.unknownName = 42, throws);
+    });
+  });
+
+  group('method', () {
+    test('call', () {
+      foo.x = 100;
+      expect(foo.multiplyByX(4), equals(400));
+      foob.x = 10;
+      expect(foob.multiplyByX(4), equals(40));
+    });
+
+    test('tearoff', () {
+      foo.x = 10;
+      // TODO(jacobr): should we automatically bind "this" for tearoffs of JS
+      // objects?
+      JsFunction multiplyBy2 = foo.multiplyBy2;
+      expect(multiplyBy2(5), equals(10));
+    });
+  });
+
+  group('type check', () {
+    test('js interfaces', () {
+      expect(foo is JsObject, isTrue);
+      // Cross-casts are allowed.
+      expect(foo is Bar, isTrue);
+      expect(selection is JsArray, isTrue);
+
+      // We do know at runtime whether something is a JsArray or not.
+      expect(foo is JsArray, isFalse);
+    });
+
+    test('dart interfaces', () {
+      expect(foo is Function, isFalse);
+      expect(selection is List, isTrue);
+    });
+  });
+
+  group("registration", () {
+    test('repeated fails', () {
+      // The experimental registerJsInterfaces API has already been called so
+      // it cannot be called a second time.
+      expect(() => registerJsInterfaces([Baz]), throws);
+    });
+  });
+}
diff --git a/tests/html/svgelement_test.dart b/tests/html/svgelement_test.dart
index 2b573ca..5527dcd 100644
--- a/tests/html/svgelement_test.dart
+++ b/tests/html/svgelement_test.dart
@@ -40,11 +40,11 @@
   }
   group('additionalConstructors', () {
     test('valid', () {
-      final svgContent = """
-<svg version="1.1">
-  <circle></circle>
-  <path></path>
-</svg>""";
+      final svgContent =
+          "<svg version=\"1.1\">\n"
+          "  <circle></circle>\n"
+          "  <path></path>\n"
+          "</svg>";
       final el = new svg.SvgElement.svg(svgContent);
       expect(el, isSvgSvgElement);
       expect(el.innerHtml, anyOf("<circle></circle><path></path>", '<circle '
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 58a420a..e6b89b8 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -129,55 +129,54 @@
 bool_from_environment_default_value_test: RuntimeError # receiver.get$_collection$_nums is not a function
 capability_test: RuntimeError # receiver.get$_collection$_nums is not a function
 compile_time_error_test/none: RuntimeError # receiver.get$_collection$_nums is not a function
-count_test: Crash # Invalid argument(s)
-cross_isolate_message_test: Crash # Invalid argument(s)
-deferred_in_isolate2_test: Crash # Invalid argument(s)
+count_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+cross_isolate_message_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+deferred_in_isolate2_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
 deferred_in_isolate_test: RuntimeError # receiver.get$_collection$_nums is not a function
 function_send_test: RuntimeError # receiver.get$_nums is not a function
 handle_error2_test: RuntimeError # receiver.get$_collection$_nums is not a function
 handle_error3_test: RuntimeError # receiver.get$_collection$_nums is not a function
 handle_error_test: RuntimeError # receiver.get$_collection$_nums is not a function
-illegal_msg_function_test: Crash # Invalid argument(s)
-illegal_msg_mirror_test: Crash # Invalid argument(s)
+illegal_msg_function_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+illegal_msg_mirror_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 int_from_environment_default_value_test: RuntimeError # receiver.get$_collection$_nums is not a function
-isolate_complex_messages_test: Crash # Invalid argument(s)
+isolate_complex_messages_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 isolate_current_test: RuntimeError # receiver.get$_nums is not a function
 isolate_import_test/none: RuntimeError # receiver.get$_collection$_nums is not a function
 issue_22778_test: RuntimeError # receiver.get$_collection$_nums is not a function
 kill2_test: RuntimeError # receiver.get$_collection$_nums is not a function
 kill_self_test: RuntimeError # receiver.get$_collection$_nums is not a function
 kill_test: RuntimeError # receiver.get$_collection$_nums is not a function
-mandel_isolate_test: Crash # Invalid argument(s)
-message2_test: Crash # Invalid argument(s)
+mandel_isolate_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
+message2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 message3_test/byteBuffer: RuntimeError # receiver.get$_collection$_nums is not a function
 message3_test/constInstance: Crash # Invalid argument(s)
 message3_test/fun: RuntimeError # receiver.get$_collection$_nums is not a function
 message3_test/int32x4: RuntimeError # receiver.get$_collection$_nums is not a function
 message3_test/none: RuntimeError # receiver.get$_collection$_nums is not a function
 message_enum_test: RuntimeError # receiver.get$_collection$_nums is not a function
-message_test: Crash # Invalid argument(s)
-mint_maker_test: Crash # Invalid argument(s)
-nested_spawn2_test: Crash # Invalid argument(s)
-nested_spawn_test: Crash # Invalid argument(s)
+message_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+mint_maker_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+nested_spawn2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+nested_spawn_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 object_leak_test: RuntimeError # receiver.get$_collection$_nums is not a function
 ondone_test: RuntimeError # receiver.get$_nums is not a function
 pause_test: RuntimeError # receiver.get$_nums is not a function
 ping_pause_test: RuntimeError # receiver.get$_collection$_nums is not a function
 ping_test: RuntimeError # receiver.get$_collection$_nums is not a function
 port_test: RuntimeError # receiver.get$_collection$_nums is not a function
-raw_port_test: Crash # Invalid argument(s)
-request_reply_test: Crash # Invalid argument(s)
+raw_port_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+request_reply_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 simple_message_test/none: RuntimeError # receiver.get$_collection$_nums is not a function
-spawn_function_custom_class_test: Crash # Invalid argument(s)
-spawn_function_test: Crash # Invalid argument(s)
-spawn_uri_missing_from_isolate_test: Crash # Invalid argument(s)
-spawn_uri_missing_test: Crash # Invalid argument(s)
-spawn_uri_multi_test/01: Crash # Invalid argument(s)
+spawn_function_custom_class_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+spawn_function_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+spawn_uri_missing_from_isolate_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
+spawn_uri_missing_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
 spawn_uri_multi_test/none: Crash # Invalid argument(s)
-stacktrace_message_test: Crash # Invalid argument(s)
+stacktrace_message_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 start_paused_test: RuntimeError # receiver.get$_nums is not a function
-static_function_test: Crash # Invalid argument(s)
+static_function_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 string_from_environment_default_value_test: RuntimeError # receiver.get$_collection$_nums is not a function
-timer_isolate_test: Crash # Invalid argument(s)
+timer_isolate_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
 typed_message_test: RuntimeError # receiver.get$_nums is not a function
-unresolved_ports_test: Crash # Invalid argument(s)
+unresolved_ports_test : RuntimeError # TypeError: receiver.get$_nums is not a function
diff --git a/tests/language/async_await_syntax_test.dart b/tests/language/async_await_syntax_test.dart
index 2b28e47..aa73ff3 100644
--- a/tests/language/async_await_syntax_test.dart
+++ b/tests/language/async_await_syntax_test.dart
@@ -13,6 +13,7 @@
 a01a() async => null;                        /// a01a: ok
 a01b() async* => null;                       /// a01b: compile-time error
 a01c() sync* => null;                        /// a01c: compile-time error
+a01d() async => yield 5;                     /// a01d: compile-time error
 a02a() async {}                              /// a02a: ok
 a03a() async* {}                             /// a03a: ok
 a03b() async * {}                            /// a03b: ok
@@ -40,6 +41,12 @@
   var await = (a) {};                        /// a05f: continued
   await(0);                                  /// a05f: continued
 }                                            /// a05f: continued
+a05g() async {                               /// a05g: continued
+    yield 5;                                 /// a05g: compile-time error
+}                                            /// a05g: continued
+a05h() async {                               /// a05h: continued
+    yield* st;                               /// a05h: compile-time error
+}                                            /// a05h: continued
 a06a() async { await for (var o in st) {} }  /// a06a: ok
 a06b() sync* { await for (var o in st) {} }  /// a06b: compile-time error
 a07a() sync* { yield 0; }                    /// a07a: ok
@@ -116,6 +123,7 @@
   b08a() sync* { yield* []; }                  /// b08a: ok
   b09a() async* { yield 0; }                   /// b09a: ok
   b10a() async* { yield* []; }                 /// b10a: static type warning
+  b10b() async { yield 0; }                    /// b10b: compile-time error
 
   get sync sync {}                             /// b11a: compile-time error
   get sync sync* {}                            /// b11b: ok
@@ -160,6 +168,8 @@
   c08a() sync* { yield* []; } c08a();                  /// c08a: ok
   c09a() async* { yield 0; } c09a();                   /// c09a: ok
   c10a() async* { yield* []; } c10a();                 /// c10a: static type warning
+  c11a() async { yield -5; } c11a();                   /// c11a: compile-time error
+  c11b() async { yield* st; } c11b();                  /// c11b: compile-time error
 }
 
 method2() {
@@ -197,6 +207,7 @@
   a01a();     /// a01a: continued
   a01b();     /// a01b: continued
   a01c();     /// a01c: continued
+  a01d();     /// a01d: continued
   a02a();     /// a02a: continued
   a03a();     /// a03a: continued
   a03b();     /// a03b: continued
@@ -209,6 +220,8 @@
   a05d();     /// a05d: continued
   a05e();     /// a05e: continued
   a05f();     /// a05f: continued
+  a05g();     /// a05g: continued
+  a05h();     /// a05h: continued
   a06a();     /// a06a: continued
   a06b();     /// a06b: continued
   a07a();     /// a07a: continued
@@ -259,6 +272,7 @@
   c.b08a();   /// b08a: continued
   c.b09a();   /// b09a: continued
   c.b10a();   /// b10a: continued
+  c.b10b();   /// b10b: continued
   a = c.sync;   /// b11a: continued
   a = c.sync;   /// b11b: continued
   a = c.async;  /// b11c: continued
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 7209ad5..7b73b20 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -150,7 +150,11 @@
 mixin_mixin_bound2_test: RuntimeError # Issue 12605
 
 [ $compiler == dart2js ]
-malformed_test/none: Fail # Expect failure in lib/_internal/compiler/js_lib/preambles/d8.js
+async_await_syntax_test/a05h: Fail # 23716
+async_await_syntax_test/c11a: Fail # 23716
+async_await_syntax_test/c11b: Fail # 23716
+
+malformed_test/none: Fail # Expect failure in lib/_internal/js_runtime/lib/preambles/d8.js
 
 type_variable_conflict2_test/01: RuntimeError # Issue 19725
 
@@ -245,10 +249,6 @@
 generic_field_mixin5_test: Crash # Issue 18651
 
 [ $compiler == dart2js && $cps_ir ]
-abstract_object_method_test: RuntimeError # Please triage this failure.
-assert_assignable_type_test: RuntimeError # Please triage this failure.
-assign_op_test: RuntimeError # Please triage this failure.
-assignable_expression_test/none: RuntimeError # Please triage this failure.
 async_and_or_test: Crash # (test()async{await test1();await test2();}): cannot handle async/sync*/async* functions
 async_await_catch_regression_test: Crash # (test()async{var exc...  cannot handle async/sync*/async* functions
 async_await_syntax_test/a01a: Crash # (a01a()async=>null;): cannot handle async/sync*/async* functions
@@ -358,19 +358,11 @@
 await_regression_test: Crash # (main()async{testNes...  cannot handle async/sync*/async* functions
 await_test: Crash # (others()async{var a...  cannot handle async/sync*/async* functions
 bind_test: RuntimeError # Cannot read property 'prototype' of undefined
-bound_closure_primitives_test: RuntimeError # Please triage this failure.
-call_with_no_such_method_test: RuntimeError # Please triage this failure.
 canonical_const3_test: RuntimeError # Cannot read property 'prototype' of undefined
-cascade2_test: RuntimeError # Please triage this failure.
-cascade_2_test: RuntimeError # Please triage this failure.
 cascade_test/none: RuntimeError # Cannot read property 'prototype' of undefined
-cast_test/04: RuntimeError # Please triage this failure.
-cast_test/05: RuntimeError # Please triage this failure.
-cast_test/none: RuntimeError # Please triage this failure.
 cha_deopt1_test: RuntimeError # receiver.get$_collection$_nums is not a function
 cha_deopt2_test: RuntimeError # receiver.get$_collection$_nums is not a function
 cha_deopt3_test: RuntimeError # receiver.get$_collection$_nums is not a function
-char_escape_test: RuntimeError # Please triage this failure.
 closure7_test: RuntimeError # Cannot read property 'prototype' of undefined
 closure8_test: RuntimeError # Cannot read property 'prototype' of undefined
 closure_cycles_test: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -378,15 +370,8 @@
 closure_shared_state_test: RuntimeError # Cannot read property 'prototype' of undefined
 closure_type_variables_test: Crash # Invalid argument(s)
 closures_initializer2_test: RuntimeError # Cannot read property 'prototype' of undefined
-compile_time_constant_a_test: RuntimeError # Please triage this failure.
-compile_time_constant_b_test: RuntimeError # Please triage this failure.
-compound_assignment_operator_test: RuntimeError # Please triage this failure.
 const_evaluation_test/01: Crash # Internal Error: No default constructor available.
-const_list_test: RuntimeError # Please triage this failure.
-const_map_test: RuntimeError # Please triage this failure.
-const_nested_test: Crash # Invalid argument(s)
 constructor12_test: RuntimeError # Please triage this failure.
-constructor_with_mixin_test: Crash # Internal Error: No default constructor available.
 crash_6725_test/01: Crash # The null object does not have a getter '_element'.
 custom_await_stack_trace_test: Crash # (main()async{try {va...  cannot handle async/sync*/async* functions
 cyclic_type_test/00: RuntimeError # Cannot read property 'prototype' of undefined
@@ -423,7 +408,7 @@
 deferred_load_inval_code_test: RuntimeError # receiver.get$_collection$_nums is not a function
 deferred_load_library_wrong_args_test/none: RuntimeError # receiver.get$_collection$_nums is not a function
 deferred_mixin_test: RuntimeError # receiver.get$_collection$_nums is not a function
-deferred_no_such_method_test: RuntimeError # receiver.get$_collection$_nums is not a function
+deferred_no_such_method_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 deferred_not_loaded_check_test: RuntimeError # Please triage this failure.
 deferred_only_constant_test: RuntimeError # receiver.get$_collection$_nums is not a function
 deferred_optimized_test: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -432,20 +417,9 @@
 deferred_shadow_load_library_test: RuntimeError # receiver.get$_collection$_nums is not a function
 deferred_shared_and_unshared_classes_test: RuntimeError # receiver.get$_collection$_nums is not a function
 deferred_static_seperate_test: RuntimeError # receiver.get$_collection$_nums is not a function
-deopt_no_feedback_test: RuntimeError # Please triage this failure.
-enum_duplicate_test/01: RuntimeError # Please triage this failure.
-enum_duplicate_test/02: RuntimeError # Please triage this failure.
-enum_duplicate_test/none: RuntimeError # Please triage this failure.
 enum_mirror_test: Crash # Internal Error: No default constructor available.
-enum_private_test/01: RuntimeError # Please triage this failure.
-enum_private_test/02: RuntimeError # Please triage this failure.
-enum_private_test/none: RuntimeError # Please triage this failure.
-execute_finally7_test: RuntimeError # Cannot read property 'call$0' of null
 f_bounded_equality_test: RuntimeError # Cannot read property 'prototype' of undefined
-fannkuch_test: RuntimeError # Please triage this failure.
-field_increment_bailout_test: RuntimeError # Please triage this failure.
-final_super_field_set_test/01: RuntimeError # Please triage this failure.
-fixed_length_test: RuntimeError # Please triage this failure.
+final_super_field_set_test/01 : RuntimeError # 
 fixed_type_variable_test/02: RuntimeError # Cannot read property 'prototype' of undefined
 fixed_type_variable_test/04: RuntimeError # Cannot read property 'prototype' of undefined
 fixed_type_variable_test/06: RuntimeError # Cannot read property 'prototype' of undefined
@@ -480,53 +454,14 @@
 function_subtype_simple1_test: RuntimeError # Cannot read property 'prototype' of undefined
 function_subtype_simple2_test: RuntimeError # Cannot read property 'prototype' of undefined
 function_subtype_top_level0_test: RuntimeError # Cannot read property 'prototype' of undefined
-function_syntax_test/none: RuntimeError # Please triage this failure.
-function_test: RuntimeError # Please triage this failure.
 function_type_alias6_test/none: RuntimeError # Cannot read property 'prototype' of undefined
-gc_test: RuntimeError # Please triage this failure.
-generic_constructor_mixin2_test: Crash # Internal Error: No default constructor available.
-generic_constructor_mixin3_test: Crash # Internal Error: No default constructor available.
-generic_constructor_mixin_test: Crash # Internal Error: No default constructor available.
 generic_creation_test: RuntimeError # Cannot read property 'prototype' of undefined
 generic_field_mixin3_test: RuntimeError # Please triage this failure.
-getter_setter_interceptor_test: RuntimeError # Please triage this failure.
-getter_setter_order_test: RuntimeError # Please triage this failure.
-gvn_interceptor_test: RuntimeError # Please triage this failure.
 identical_closure_test: RuntimeError # Cannot read property 'prototype' of undefined
-if_null_assignment_behavior_test/01: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/02: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/04: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/05: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/06: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/07: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/08: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/09: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/10: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/12: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/16: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/17: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/18: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/19: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/20: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/21: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/22: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/23: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/24: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/25: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/26: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/27: RuntimeError # Please triage this failure.
-if_null_assignment_behavior_test/28: RuntimeError # Please triage this failure.
 if_null_assignment_static_test/01: RuntimeError # Issue 23669
 if_null_assignment_static_test/03: RuntimeError # Issue 23669
 if_null_assignment_static_test/04: RuntimeError # Issue 23669
 if_null_assignment_static_test/05: RuntimeError # Issue 23669
-if_null_assignment_static_test/29: RuntimeError # Issue 23669
-if_null_assignment_static_test/30: RuntimeError # Please triage this failure.
-if_null_assignment_static_test/31: RuntimeError # Issue 23669
-if_null_assignment_static_test/32: RuntimeError # Issue 23669
-if_null_assignment_static_test/33: RuntimeError # Issue 23669
-if_null_assignment_static_test/34: RuntimeError # Please triage this failure.
-if_null_assignment_static_test/35: RuntimeError # Please triage this failure.
 if_null_assignment_static_test/36: RuntimeError # Issue 23669
 if_null_assignment_static_test/38: RuntimeError # Issue 23669
 if_null_assignment_static_test/39: RuntimeError # Issue 23669
@@ -534,31 +469,17 @@
 implicit_closure1_test: RuntimeError # Cannot read property 'prototype' of undefined
 implicit_closure2_test: RuntimeError # Cannot read property 'prototype' of undefined
 implicit_closure_test: RuntimeError # Cannot read property 'prototype' of undefined
-incr_op_test: RuntimeError # Please triage this failure.
-index_test: RuntimeError # Please triage this failure.
-inference_mixin_field_test: Crash # Internal Error: No default constructor available.
 infinite_switch_label_test: Crash # (switch (target){l0:...  continue to a labeled switch case
 inlined_conditional_test: RuntimeError # Cannot read property 'prototype' of undefined
 instance_creation_in_function_annotation_test: Crash # Internal Error: No default constructor available.
 instanceof4_test/01: RuntimeError # Please triage this failure.
-interceptor7_test: RuntimeError # Please triage this failure.
-invocation_mirror_invoke_on2_test: RuntimeError # Please triage this failure.
-invocation_mirror_invoke_on_test: RuntimeError # Please triage this failure.
+invocation_mirror_invoke_on_test : RuntimeError # 
 invocation_mirror_test: Crash # (super[37]=42): visitUnresolvedSuperIndexSet
 is_function_test: RuntimeError # Cannot read property 'prototype' of undefined
-issue12288_test: RuntimeError # Please triage this failure.
 issue13179_test: RuntimeError # Cannot read property 'prototype' of undefined
-issue7513_test: RuntimeError # Please triage this failure.
 issue_1751477_test: RuntimeError # receiver.get$_collection$_nums is not a function
 large_class_declaration_test: Crash # Stack Overflow
-list_literal3_test: RuntimeError # Please triage this failure.
 list_test: RuntimeError # Please triage this failure.
-list_tracer_closure_test: RuntimeError # Please triage this failure.
-list_tracer_in_list_test: RuntimeError # Please triage this failure.
-list_tracer_in_map_test: RuntimeError # Please triage this failure.
-list_tracer_return_from_tearoff_closure_test: RuntimeError # Please triage this failure.
-local_function_test: RuntimeError # Please triage this failure.
-logical_expression_test: RuntimeError # Please triage this failure.
 main_test/01: RuntimeError # receiver.get$_collection$_nums is not a function
 main_test/02: RuntimeError # receiver.get$_collection$_nums is not a function
 main_test/04: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -571,65 +492,33 @@
 main_test/43: RuntimeError # receiver.get$_collection$_nums is not a function
 main_test/44: RuntimeError # receiver.get$_collection$_nums is not a function
 main_test/45: RuntimeError # receiver.get$_collection$_nums is not a function
-many_calls_test: RuntimeError # Please triage this failure.
-many_named_arguments_test: RuntimeError # Please triage this failure.
-many_overridden_no_such_method_test: RuntimeError # Please triage this failure.
-mega_load_test: RuntimeError # Please triage this failure.
+many_overridden_no_such_method_test : RuntimeError # 
 method_binding_test: RuntimeError # Cannot read property 'prototype' of undefined
 methods_as_constants2_test: RuntimeError # Cannot read property 'prototype' of undefined
-minify_closure_variable_collision_test: RuntimeError # Please triage this failure.
 mint_compares_test: RuntimeError # Cannot read property 'prototype' of undefined
-mixin_bound_test: Crash # Internal Error: No default constructor available.
-mixin_forwarding_constructor1_test: Crash # Internal Error: No default constructor available.
-mixin_forwarding_constructor3_test: Crash # Internal Error: No default constructor available.
-mixin_prefix_test: Crash # Internal Error: No default constructor available.
-mixin_super_constructor2_test: Crash # Internal Error: No default constructor available.
-mixin_super_constructor_default_test: Crash # Internal Error: No default constructor available.
-mixin_super_constructor_multiple_test: Crash # Internal Error: No default constructor available.
 mixin_super_constructor_named_test/01: Crash # Internal Error: No default constructor available.
-mixin_super_constructor_named_test/none: Crash # Internal Error: No default constructor available.
 mixin_super_constructor_positionals_test/01: Crash # Internal Error: No default constructor available.
-mixin_super_constructor_positionals_test/none: Crash # Internal Error: No default constructor available.
-mixin_super_constructor_test: Crash # Internal Error: No default constructor available.
-mixin_type_parameter2_test: Crash # Internal Error: No default constructor available.
-mixin_type_parameter3_test: Crash # Internal Error: No default constructor available.
 mixin_type_parameters_mixin_extends_test: Crash # The null object does not have a getter '_element'.
 mixin_type_parameters_mixin_test: Crash # The null object does not have a getter '_element'.
 mixin_type_parameters_super_extends_test: Crash # The null object does not have a getter '_element'.
 mixin_type_parameters_super_test: Crash # The null object does not have a getter '_element'.
-mixin_typedef_constructor_test: Crash # Internal Error: No default constructor available.
 named_parameters_with_conversions_test: RuntimeError # Cannot read property 'prototype' of undefined
-named_parameters_with_dollars_test: RuntimeError # Please triage this failure.
-nested_if_test: RuntimeError # Please triage this failure.
 nested_switch_label_test: Crash # (switch (target){out...  continue to a labeled switch case
-no_such_method_dispatcher_test: RuntimeError # Please triage this failure.
-no_such_method_empty_selector_test: RuntimeError # Please triage this failure.
-no_such_method_test: RuntimeError # Please triage this failure.
+no_such_method_test : RuntimeError # 
 null_test/none: Crash # Internal Error: No default constructor available.
 null_to_string2_test: RuntimeError # Cannot read property 'prototype' of undefined
 null_to_string_test: RuntimeError # Cannot read property 'prototype' of undefined
-operator_index_evaluation_order_test: RuntimeError # Please triage this failure.
-optimize_redundant_array_load_test: RuntimeError # Please triage this failure.
-optimized_lists_test: RuntimeError # Please triage this failure.
-osr_test: RuntimeError # Please triage this failure.
-overridden_no_such_method_test: RuntimeError # Please triage this failure.
+overridden_no_such_method_test : RuntimeError # 
 override_method_with_field_test/02: RuntimeError # Cannot read property 'prototype' of undefined
 override_method_with_field_test/none: RuntimeError # Cannot read property 'prototype' of undefined
-param2_test: RuntimeError # Please triage this failure.
 prefix14_test: RuntimeError # Cannot read property 'prototype' of undefined
 prefix15_test: RuntimeError # Cannot read property 'prototype' of undefined
 prefix21_test: RuntimeError # Cannot read property 'prototype' of undefined
-pure_function2_test: RuntimeError # Please triage this failure.
-pure_function_test: RuntimeError # Please triage this failure.
 range_analysis_test: RuntimeError # Cannot read property 'prototype' of undefined
 recursive_calls_test: RuntimeError # Cannot read property 'prototype' of undefined
 reg_ex2_test: RuntimeError # Cannot read property 'prototype' of undefined
 reg_exp2_test: RuntimeError # Cannot read property 'prototype' of undefined
-reg_exp_test: RuntimeError # Please triage this failure.
-regress_11800_test: RuntimeError # Please triage this failure.
-regress_18435_test: Crash # Invalid argument(s)
 regress_18535_test: Crash # Internal Error: No default constructor available.
-regress_21016_test: RuntimeError # Please triage this failure.
 regress_22438_test: Crash # (main()async{var err...  cannot handle async/sync*/async* functions
 regress_22443_test: RuntimeError # receiver.get$_collection$_nums is not a function
 regress_22445_test: Crash # (main()async{var err...  cannot handle async/sync*/async* functions
@@ -647,24 +536,17 @@
 static_implicit_closure_test: RuntimeError # Cannot read property 'prototype' of undefined
 string_interpolation_test/01: RuntimeError # Cannot read property 'prototype' of undefined
 string_interpolation_test/none: RuntimeError # Cannot read property 'prototype' of undefined
-string_join_test: RuntimeError # Please triage this failure.
-string_test: RuntimeError # Please triage this failure.
 super_bound_closure_test/01: RuntimeError # Cannot read property 'call' of undefined
 super_bound_closure_test/none: RuntimeError # Cannot read property 'call' of undefined
-super_call4_test: RuntimeError # Please triage this failure.
+super_call4_test : RuntimeError # 
 super_getter_setter_test: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
 super_implicit_closure_test: RuntimeError # Cannot read property 'prototype' of undefined
 super_operator_index2_test: RuntimeError # this.get$map is not a function
-super_operator_index3_test: RuntimeError # Please triage this failure.
-super_operator_index4_test: RuntimeError # Please triage this failure.
 super_operator_index5_test: Crash # (super[0]=42): visitUnresolvedSuperIndexSet
-super_operator_index6_test: RuntimeError # Please triage this failure.
 super_operator_index7_test: Crash # (super[0]=42): visitUnresolvedSuperIndexSet
 super_operator_index8_test: Crash # (super[f()]=g()): visitUnresolvedSuperIndexSet
 super_operator_index_test/03: Crash # (super[4]=42): visitUnresolvedSuperIndexSet
 super_operator_index_test/05: Crash # (super[4]=42): visitUnresolvedSuperIndexSet
-super_operator_index_test/06: Crash # The null object does not have a getter 'isParameter'.
-super_operator_test: RuntimeError # Please triage this failure.
 switch_label2_test: Crash # (switch (target){cas...  continue to a labeled switch case
 switch_label_test: Crash # (switch (animal){cas...  continue to a labeled switch case
 switch_try_catch_test: Crash # (switch (0){_0:case ...  continue to a labeled switch case
@@ -708,8 +590,9 @@
 type_promotion_functions_test/none: RuntimeError # Cannot read property 'prototype' of undefined
 type_variable_closure2_test: RuntimeError # Please triage this failure.
 type_variable_closure_test: Crash # Invalid argument(s)
-type_variable_conflict2_test/07: RuntimeError # Please triage this failure.
 typedef_is_test: RuntimeError # Cannot read property 'prototype' of undefined
-typevariable_substitution2_test/01: Crash # Internal Error: No default constructor available.
-typevariable_substitution2_test/02: Crash # Internal Error: No default constructor available.
-typevariable_substitution2_test/none: Crash # Internal Error: No default constructor available.
+invocation_mirror2_test : Crash # Internal Error: No default constructor available.
+type_variable_conflict2_test/01 : Crash # Internal Error: No default constructor available.
+async_await_syntax_test/a05h : Crash # bailout: (a05h()async{yield*st;}): cannot handle async/sync*/async* functions
+async_await_syntax_test/c11a : Crash # bailout: (c11a()async{yield-5;}): cannot handle async/sync*/async* functions
+async_await_syntax_test/c11b : Crash # bailout: (c11b()async{yield*st;}): cannot handle async/sync*/async* functions
diff --git a/tests/language/multiline_strings_test.dart b/tests/language/multiline_strings_test.dart
index d7f8f3e..8795014 100644
--- a/tests/language/multiline_strings_test.dart
+++ b/tests/language/multiline_strings_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// Note: This test relies on LF line endings in the source file.
+
 import "package:expect/expect.dart";
 
 main() {
diff --git a/tests/language/raw_string_test.dart b/tests/language/raw_string_test.dart
index ee5365b..b577747 100644
--- a/tests/language/raw_string_test.dart
+++ b/tests/language/raw_string_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// Note: This test relies on LF line endings in the source file.
+
 import "package:expect/expect.dart";
 
 class RawStringTest {
diff --git a/tests/lib/convert/json_pretty_test.dart b/tests/lib/convert/json_pretty_test.dart
index a0c3bc6..6238052 100644
--- a/tests/lib/convert/json_pretty_test.dart
+++ b/tests/lib/convert/json_pretty_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// Note: This test relies on LF line endings in the source file.
+
 library json_pretty_test;
 
 import 'dart:convert';
diff --git a/tests/lib/convert/utf84_test.dart b/tests/lib/convert/utf84_test.dart
index 37f0e2c..ddd1dc9 100755
--- a/tests/lib/convert/utf84_test.dart
+++ b/tests/lib/convert/utf84_test.dart
@@ -87,9 +87,8 @@
     0xbd, 0xb6, 0x20, 0xce, 0xbe, 0xce, 0xad, 0xcf,
     0x86, 0xcf, 0x89, 0xcf, 0x84, 0xce, 0xbf];
 
-const String testKatakanaPhrase = """
-イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム
-ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン""";
+const String testKatakanaPhrase = "イロハニホヘト チリヌルヲ ワカヨタレソ "
+    "ツネナラム ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン";
 
 const List<int> testKatakanaUtf8 = const<int>[
     0xe3, 0x82, 0xa4, 0xe3, 0x83, 0xad, 0xe3, 0x83,
@@ -101,7 +100,7 @@
     0x82, 0xbf, 0xe3, 0x83, 0xac, 0xe3, 0x82, 0xbd,
     0x20, 0xe3, 0x83, 0x84, 0xe3, 0x83, 0x8d, 0xe3,
     0x83, 0x8a, 0xe3, 0x83, 0xa9, 0xe3, 0x83, 0xa0,
-    0x0a, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xb0, 0xe3,
+    0x20, 0xe3, 0x82, 0xa6, 0xe3, 0x83, 0xb0, 0xe3,
     0x83, 0x8e, 0xe3, 0x82, 0xaa, 0xe3, 0x82, 0xaf,
     0xe3, 0x83, 0xa4, 0xe3, 0x83, 0x9e, 0x20, 0xe3,
     0x82, 0xb1, 0xe3, 0x83, 0x95, 0xe3, 0x82, 0xb3,
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 184c01d..015e3bd 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -354,13 +354,13 @@
 async/catch_errors7_test: RuntimeError # receiver.get$_nums is not a function
 async/catch_errors8_test: RuntimeError # receiver.get$_nums is not a function
 async/catch_errors_test: RuntimeError # receiver.get$_nums is not a function
-async/first_regression_test: Crash # Invalid argument(s)
+async/first_regression_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 async/future_constructor_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/future_delayed_error_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/future_microtask_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/future_test/01: Crash # (()async=>new Future.value(value)): cannot handle async/sync*/async* functions
 async/future_test/none: RuntimeError # receiver.get$_nums is not a function
-async/future_timeout_test: Crash # Invalid argument(s)
+async/future_timeout_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 async/future_value_chain2_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/future_value_chain3_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/future_value_chain4_test: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -373,7 +373,7 @@
 async/intercept_schedule_microtask4_test: RuntimeError # receiver.get$_nums is not a function
 async/intercept_schedule_microtask5_test: RuntimeError # receiver.get$_nums is not a function
 async/intercept_schedule_microtask6_test: RuntimeError # receiver.get$_nums is not a function
-async/multiple_timer_test: Crash # Invalid argument(s)
+async/multiple_timer_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 async/print_test/none: RuntimeError # receiver.get$_nums is not a function
 async/run_zoned1_test: RuntimeError # receiver.get$_nums is not a function
 async/run_zoned4_test: RuntimeError # receiver.get$_nums is not a function
@@ -382,10 +382,10 @@
 async/run_zoned7_test: RuntimeError # receiver.get$_nums is not a function
 async/run_zoned8_test: RuntimeError # receiver.get$_nums is not a function
 async/run_zoned9_test/none: RuntimeError # receiver.get$_nums is not a function
-async/schedule_microtask2_test: Crash # Invalid argument(s)
-async/schedule_microtask3_test: Crash # Invalid argument(s)
-async/schedule_microtask5_test: Crash # Invalid argument(s)
-async/schedule_microtask_test: Crash # Invalid argument(s)
+async/schedule_microtask2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/schedule_microtask3_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/schedule_microtask5_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/schedule_microtask_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 async/slow_consumer2_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/slow_consumer3_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/slow_consumer_test: RuntimeError # receiver.get$_collection$_nums is not a function
@@ -414,41 +414,41 @@
 async/stack_trace23_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/stack_trace24_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/stack_trace25_test: RuntimeError # receiver.get$_collection$_nums is not a function
-async/stream_controller_async_test: Crash # Invalid argument(s)
+async/stream_controller_async_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 async/stream_controller_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/stream_empty_test: Crash # (Future runTest()asy...  cannot handle async/sync*/async* functions
 async/stream_event_transformed_test: RuntimeError # receiver.get$_nums is not a function
-async/stream_first_where_test: Crash # Invalid argument(s)
-async/stream_from_iterable_test: Crash # Invalid argument(s)
+async/stream_first_where_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_from_iterable_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 async/stream_iterator_double_cancel_test: RuntimeError # receiver.get$_collection$_nums is not a function
-async/stream_iterator_test: Crash # Invalid argument(s)
-async/stream_join_test: Crash # Invalid argument(s)
-async/stream_last_where_test: Crash # Invalid argument(s)
+async/stream_iterator_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_join_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_last_where_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 async/stream_listen_zone_test: RuntimeError # receiver.get$_nums is not a function
-async/stream_periodic2_test: Crash # Invalid argument(s)
-async/stream_periodic3_test: Crash # Invalid argument(s)
-async/stream_periodic4_test: Crash # Invalid argument(s)
-async/stream_periodic5_test: Crash # Invalid argument(s)
-async/stream_periodic_test: Crash # Invalid argument(s)
-async/stream_single_test: Crash # Invalid argument(s)
-async/stream_single_to_multi_subscriber_test: Crash # Invalid argument(s)
-async/stream_state_nonzero_timer_test: Crash # Invalid argument(s)
-async/stream_state_test: Crash # Invalid argument(s)
-async/stream_subscription_as_future_test: Crash # Invalid argument(s)
-async/stream_subscription_cancel_test: Crash # Invalid argument(s)
-async/stream_timeout_test: Crash # Invalid argument(s)
-async/stream_transform_test: Crash # Invalid argument(s)
-async/stream_transformation_broadcast_test: Crash # Invalid argument(s)
+async/stream_periodic2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_periodic3_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_periodic4_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_periodic5_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_periodic_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_single_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_single_to_multi_subscriber_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_state_nonzero_timer_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_state_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_subscription_as_future_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_subscription_cancel_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_timeout_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_transform_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/stream_transformation_broadcast_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 async/stream_transformer_from_handlers_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/stream_transformer_test: RuntimeError # receiver.get$_collection$_nums is not a function
 async/stream_zones_test: RuntimeError # receiver.get$_nums is not a function
-async/timer_cancel1_test: Crash # Invalid argument(s)
-async/timer_cancel2_test: Crash # Invalid argument(s)
-async/timer_cancel_test: Crash # Invalid argument(s)
-async/timer_isActive_test: Crash # Invalid argument(s)
+async/timer_cancel1_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/timer_cancel2_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/timer_cancel_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/timer_isActive_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 async/timer_regress22626_test: RuntimeError # receiver.get$_collection$_nums is not a function
-async/timer_repeat_test: Crash # Invalid argument(s)
-async/timer_test: Crash # Invalid argument(s)
+async/timer_repeat_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+async/timer_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 async/zone_bind_callback_test: RuntimeError # receiver.get$_nums is not a function
 async/zone_bind_callback_unary_test: RuntimeError # receiver.get$_nums is not a function
 async/zone_bind_test: RuntimeError # receiver.get$_nums is not a function
@@ -469,47 +469,22 @@
 async/zone_run_unary_test: RuntimeError # receiver.get$_nums is not a function
 async/zone_value_test: RuntimeError # receiver.get$_collection$_nums is not a function
 convert/ascii_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion1_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion2_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_json_decode1_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_json_encode1_test: Crash # Internal Error: No default constructor available.
-convert/chunked_conversion_utf82_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf83_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf84_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf85_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf86_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf87_test: RuntimeError # Please triage this failure.
 convert/chunked_conversion_utf88_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf89_test: RuntimeError # Please triage this failure.
-convert/chunked_conversion_utf8_test: RuntimeError # Please triage this failure.
 convert/codec1_test: RuntimeError # Cannot read property 'prototype' of undefined
-convert/codec2_test: Crash # Internal Error: No default constructor available.
 convert/encoding_test: RuntimeError # receiver.get$_collection$_nums is not a function
 convert/html_escape_test: RuntimeError # receiver.get$_collection$_nums is not a function
-convert/json_chunk_test: RuntimeError # Please triage this failure.
-convert/json_lib_test: Crash # Invalid argument(s)
-convert/json_pretty_test: Crash # Internal Error: No default constructor available.
-convert/json_test: Crash # Internal Error: No default constructor available.
-convert/json_toEncodable_reviver_test: Crash # Internal Error: No default constructor available.
-convert/json_utf8_chunk_test: RuntimeError # Please triage this failure.
-convert/json_util_test: Crash # Internal Error: No default constructor available.
+convert/json_lib_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 convert/latin1_test: RuntimeError # Please triage this failure.
-convert/line_splitter_test: Crash # Invalid argument(s)
+convert/line_splitter_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 convert/streamed_conversion_json_decode1_test: RuntimeError # receiver.get$_collection$_nums is not a function
-convert/streamed_conversion_json_encode1_test: Crash # Internal Error: No default constructor available.
+convert/streamed_conversion_json_encode1_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
 convert/streamed_conversion_json_utf8_decode_test: RuntimeError # receiver.get$_collection$_nums is not a function
-convert/streamed_conversion_json_utf8_encode_test: Crash # Internal Error: No default constructor available.
+convert/streamed_conversion_json_utf8_encode_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
 convert/streamed_conversion_utf8_decode_test: RuntimeError # receiver.get$_collection$_nums is not a function
 convert/streamed_conversion_utf8_encode_test: RuntimeError # receiver.get$_collection$_nums is not a function
-convert/utf82_test: RuntimeError # Please triage this failure.
-convert/utf84_test: RuntimeError # Please triage this failure.
-convert/utf8_encode_test: RuntimeError # Please triage this failure.
-convert/utf8_test: RuntimeError # Please triage this failure.
-js/datetime_roundtrip_test: Crash # Internal Error: No default constructor available.
-js/null_test: Crash # Invalid argument(s)
 math/pi_test: RuntimeError # receiver.get$_collection$_nums is not a function
-math/point_test: Crash # Invalid argument(s)
-math/rectangle_test: Crash # Invalid argument(s)
+math/point_test : RuntimeError # TypeError: receiver.get$_nums is not a function
+math/rectangle_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 mirrors/abstract_class_test/00: Crash # Internal Error: No default constructor available.
 mirrors/abstract_class_test/none: Crash # Internal Error: No default constructor available.
 mirrors/abstract_test: Crash # Internal Error: No default constructor available.
@@ -532,10 +507,10 @@
 mirrors/declarations_type_test: Crash # Internal Error: No default constructor available.
 mirrors/deferred_mirrors_metadata_test: Crash # Internal Error: No default constructor available.
 mirrors/deferred_mirrors_metatarget_test: Crash # Internal Error: No default constructor available.
-mirrors/deferred_mirrors_update_test: Crash # Internal Error: No default constructor available.
+mirrors/deferred_mirrors_update_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
 mirrors/deferred_type_test: Crash # Internal Error: No default constructor available.
-mirrors/delegate_call_through_getter_test: RuntimeError # Please triage this failure.
-mirrors/delegate_test: RuntimeError # Please triage this failure.
+mirrors/delegate_call_through_getter_test : RuntimeError # 
+mirrors/delegate_test : RuntimeError # 
 mirrors/disable_tree_shaking_test: Crash # Internal Error: No default constructor available.
 mirrors/empty_test: Crash # Internal Error: No default constructor available.
 mirrors/enum_test: Crash # Internal Error: No default constructor available.
@@ -571,7 +546,6 @@
 mirrors/generics_substitution_test: Crash # Internal Error: No default constructor available.
 mirrors/generics_test/01: Crash # Internal Error: No default constructor available.
 mirrors/generics_test/none: Crash # Internal Error: No default constructor available.
-mirrors/get_field_cache_test: RuntimeError # Please triage this failure.
 mirrors/get_field_static_test/00: Crash # Internal Error: No default constructor available.
 mirrors/get_field_static_test/none: Crash # Internal Error: No default constructor available.
 mirrors/globalized_closures2_test/00: Crash # Internal Error: No default constructor available.
@@ -581,7 +555,6 @@
 mirrors/hierarchy_invariants_test: Crash # Internal Error: No default constructor available.
 mirrors/immutable_collections_test: Crash # Internal Error: No default constructor available.
 mirrors/inherit_field_test: Crash # Internal Error: No default constructor available.
-mirrors/inherited_metadata_test: Crash # Internal Error: No default constructor available.
 mirrors/initializing_formals_test/01: Crash # Internal Error: No default constructor available.
 mirrors/initializing_formals_test/none: Crash # Internal Error: No default constructor available.
 mirrors/instance_members_easier_test: Crash # Internal Error: No default constructor available.
@@ -593,7 +566,6 @@
 mirrors/intercepted_class_test: Crash # Internal Error: No default constructor available.
 mirrors/intercepted_object_test: Crash # Internal Error: No default constructor available.
 mirrors/intercepted_superclass_test: Crash # Internal Error: No default constructor available.
-mirrors/invocation_cache_test: RuntimeError # Please triage this failure.
 mirrors/invocation_fuzz_test/emptyarray: Crash # Internal Error: No default constructor available.
 mirrors/invocation_fuzz_test/false: Crash # Internal Error: No default constructor available.
 mirrors/invocation_fuzz_test/none: Crash # Internal Error: No default constructor available.
@@ -647,7 +619,6 @@
 mirrors/metadata_allowed_values_test/14: Crash # Internal Error: No default constructor available.
 mirrors/metadata_allowed_values_test/none: Crash # Internal Error: No default constructor available.
 mirrors/metadata_class_mirror_test: Crash # Internal Error: No default constructor available.
-mirrors/metadata_const_map_test: Crash # Internal Error: No default constructor available.
 mirrors/metadata_constructed_constant_test: Crash # Internal Error: No default constructor available.
 mirrors/metadata_constructor_arguments_test/none: Crash # Internal Error: No default constructor available.
 mirrors/metadata_nested_constructor_call_test/none: Crash # Internal Error: No default constructor available.
@@ -665,8 +636,6 @@
 mirrors/mirrors_reader_test: Crash # Internal Error: No default constructor available.
 mirrors/mirrors_resolve_fields_test: Crash # Internal Error: No default constructor available.
 mirrors/mirrors_test: Crash # Internal Error: No default constructor available.
-mirrors/mirrors_used_typedef_declaration_test/01: Crash # Internal Error: No default constructor available.
-mirrors/mirrors_used_typedef_declaration_test/none: Crash # Internal Error: No default constructor available.
 mirrors/mixin_application_test: Crash # Internal Error: No default constructor available.
 mirrors/mixin_members_test: Crash # Internal Error: No default constructor available.
 mirrors/mixin_test: Crash # Internal Error: No default constructor available.
@@ -677,11 +646,9 @@
 mirrors/null2_test: Crash # Internal Error: No default constructor available.
 mirrors/null_test: Crash # Invalid argument(s)
 mirrors/operator_test: Crash # Internal Error: No default constructor available.
-mirrors/parameter_annotation_mirror_test: Crash # Internal Error: No default constructor available.
 mirrors/parameter_is_const_test/none: Crash # Internal Error: No default constructor available.
 mirrors/parameter_metadata_test: Crash # Internal Error: No default constructor available.
 mirrors/parameter_of_mixin_app_constructor_test: Crash # Internal Error: No default constructor available.
-mirrors/parameter_test/01: Crash # Internal Error: No default constructor available.
 mirrors/parameter_test/none: Crash # Internal Error: No default constructor available.
 mirrors/private_symbol_mangling_test: Crash # Internal Error: No default constructor available.
 mirrors/private_types_test: Crash # Internal Error: No default constructor available.
@@ -719,8 +686,6 @@
 mirrors/relation_subtype_test: Crash # Internal Error: No default constructor available.
 mirrors/removed_api_test: Crash # Internal Error: No default constructor available.
 mirrors/repeated_private_anon_mixin_app_test: Crash # Internal Error: No default constructor available.
-mirrors/return_type_test: Crash # Internal Error: No default constructor available.
-mirrors/runtime_type_test: Crash # Internal Error: No default constructor available.
 mirrors/set_field_with_final_inheritance_test: Crash # Internal Error: No default constructor available.
 mirrors/set_field_with_final_test: Crash # Internal Error: No default constructor available.
 mirrors/spawn_function_root_library_test: Crash # Internal Error: No default constructor available.
@@ -736,22 +701,15 @@
 mirrors/to_string_test: Crash # Internal Error: No default constructor available.
 mirrors/top_level_accessors_test: Crash # Internal Error: No default constructor available.
 mirrors/type_argument_is_type_variable_test: Crash # Internal Error: No default constructor available.
-mirrors/type_mirror_for_type_test: Crash # Internal Error: No default constructor available.
 mirrors/type_variable_is_static_test: Crash # Internal Error: No default constructor available.
 mirrors/type_variable_owner_test/01: Crash # Internal Error: No default constructor available.
 mirrors/type_variable_owner_test/none: Crash # Internal Error: No default constructor available.
 mirrors/typearguments_mirror_test: Crash # Internal Error: No default constructor available.
-mirrors/typedef_deferred_library_test: Crash # Internal Error: No default constructor available.
-mirrors/typedef_in_signature_test: Crash # Internal Error: No default constructor available.
-mirrors/typedef_library_test: Crash # Internal Error: No default constructor available.
+mirrors/typedef_deferred_library_test : RuntimeError # TypeError: receiver.get$_collection$_nums is not a function
 mirrors/typedef_metadata_test: Crash # Internal Error: No default constructor available.
 mirrors/typedef_reflected_type_test/01: Crash # Internal Error: No default constructor available.
 mirrors/typedef_reflected_type_test/none: Crash # Internal Error: No default constructor available.
 mirrors/typedef_test: Crash # Internal Error: No default constructor available.
 mirrors/unnamed_library_test: Crash # Internal Error: No default constructor available.
-mirrors/unused_mirrors_used_test: RuntimeError # Please triage this failure.
 mirrors/variable_is_const_test/none: Crash # Internal Error: No default constructor available.
-typed_data/int32x4_test: RuntimeError # Please triage this failure.
-typed_data/typed_data_from_list_test: RuntimeError # Please triage this failure.
 typed_data/typed_data_list_test: RuntimeError # Please triage this failure.
-typed_data/typed_list_iterable_test: RuntimeError # Please triage this failure.
diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart b/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart
index 851c04c..45533d4 100755
--- a/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_cr.dart
Binary files differ
diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart b/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart
index bcf3e64..d93615c 100755
--- a/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_crlf.dart
@@ -2,8 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a

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

 

-// This file is marked executable so source control will preserve the type of

-// line ending.

+// Note: This test relies on CRLF line endings in the source file.

 

 library line_endings.crlf;

 

diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart b/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart
index 71a34c8..b805a75 100755
--- a/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_lf.dart
@@ -2,8 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// This file is marked executable so source control will preserve the type of
-// line ending.
+// Note: This test relies on LF line endings in the source file.
 
 library line_endings.lf;
 
diff --git a/tests/lib/mirrors/method_mirror_source_line_ending_test.dart b/tests/lib/mirrors/method_mirror_source_line_ending_test.dart
index e052cc1..c059397 100644
--- a/tests/lib/mirrors/method_mirror_source_line_ending_test.dart
+++ b/tests/lib/mirrors/method_mirror_source_line_ending_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// Note: These tests rely on specific line endings in the source files.
+
 import "dart:mirrors";
 import "package:expect/expect.dart";
 
diff --git a/tests/lib/mirrors/method_mirror_source_other.dart b/tests/lib/mirrors/method_mirror_source_other.dart
index 29adf5b..37151b6 100644
--- a/tests/lib/mirrors/method_mirror_source_other.dart
+++ b/tests/lib/mirrors/method_mirror_source_other.dart
@@ -3,4 +3,6 @@
 }
 // This function must be on the first line.
 
-class SomethingInOther {}
\ No newline at end of file
+class SomethingInOther {}
+
+// Note: This test relies on LF line endings in the source file.
diff --git a/tests/lib/mirrors/method_mirror_source_test.dart b/tests/lib/mirrors/method_mirror_source_test.dart
index 9b09452..cea4dc1 100644
--- a/tests/lib/mirrors/method_mirror_source_test.dart
+++ b/tests/lib/mirrors/method_mirror_source_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// Note: This test relies on LF line endings in the source file.
+
 import "dart:mirrors";
 import "package:expect/expect.dart";
 import "method_mirror_source_other.dart";
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 7036123..9edc6cc 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -170,120 +170,16 @@
 io/http_client_stays_alive_test: Skip  # Timeout.
 
 [ $compiler == dart2js && $cps_ir ]
-array_bounds_check_generalization_test: RuntimeError # Please triage this failure.
-coverage_test: Crash # Invalid argument(s)
-io/addlatexhash_test: Crash # Invalid argument(s)
-io/create_recursive_test: Crash # Invalid argument(s)
-io/directory_list_pause_test: Crash # Invalid argument(s)
-io/directory_uri_test: Crash # Invalid argument(s)
-io/file_lock_test: Crash # Invalid argument(s)
-io/file_stat_test: Crash # Invalid argument(s)
 io/file_test: Crash # Invalid argument(s)
-io/file_typed_data_test: Crash # Invalid argument(s)
-io/file_uri_test: Crash # Invalid argument(s)
 io/file_write_only_test: Crash # (main()async{asyncSt...  cannot handle async/sync*/async* functions
-io/http_10_test: Crash # Internal Error: No default constructor available.
-io/http_advanced_test: Crash # Internal Error: No default constructor available.
-io/http_auth_digest_test: Crash # Invalid argument(s)
-io/http_auth_test: Crash # Invalid argument(s)
-io/http_basic_test: Crash # Internal Error: No default constructor available.
 io/http_bind_test: Crash # (testBindShared(Stri...  cannot handle async/sync*/async* functions
-io/http_client_connect_test: Crash # Internal Error: No default constructor available.
-io/http_client_exception_test: Crash # Internal Error: No default constructor available.
-io/http_client_request_test: Crash # Internal Error: No default constructor available.
-io/http_client_stays_alive_test: Crash # Internal Error: No default constructor available.
-io/http_close_test: Crash # Internal Error: No default constructor available.
-io/http_compression_test: Crash # Internal Error: No default constructor available.
-io/http_connection_close_test: Crash # Invalid argument(s)
-io/http_connection_header_test: Crash # Internal Error: No default constructor available.
-io/http_connection_info_test: Crash # Internal Error: No default constructor available.
-io/http_content_length_test: Crash # Internal Error: No default constructor available.
-io/http_cookie_date_test: Crash # Invalid argument(s)
-io/http_cookie_test: Crash # Internal Error: No default constructor available.
-io/http_cross_process_test: Crash # Internal Error: No default constructor available.
-io/http_date_test: Crash # Invalid argument(s)
-io/http_detach_socket_test: Crash # Internal Error: No default constructor available.
-io/http_head_test: Crash # Internal Error: No default constructor available.
-io/http_headers_state_test: Crash # Internal Error: No default constructor available.
-io/http_headers_test: Crash # Internal Error: No default constructor available.
-io/http_ipv6_test: Crash # Invalid argument(s)
-io/http_keep_alive_test: Crash # Internal Error: No default constructor available.
-io/http_no_reason_phrase_test: Crash # Invalid argument(s)
-io/http_outgoing_size_test: Crash # Internal Error: No default constructor available.
-io/http_parser_test: Crash # Invalid argument(s)
-io/http_proxy_configuration_test: Crash # Internal Error: No default constructor available.
-io/http_proxy_test: Crash # Invalid argument(s)
-io/http_read_test: Crash # Internal Error: No default constructor available.
-io/http_redirect_test: Crash # Invalid argument(s)
-io/http_request_pipeling_test: Crash # Internal Error: No default constructor available.
-io/http_requested_uri_test: Crash # Internal Error: No default constructor available.
-io/http_response_deadline_test: Crash # Internal Error: No default constructor available.
-io/http_reuse_server_port_test: Crash # Internal Error: No default constructor available.
-io/http_server_close_response_after_error_test: Crash # Internal Error: No default constructor available.
-io/http_server_early_client_close2_test: Crash # Internal Error: No default constructor available.
-io/http_server_early_client_close_test: Crash # Internal Error: No default constructor available.
-io/http_server_idle_timeout_test: Crash # Internal Error: No default constructor available.
-io/http_server_response_test: Crash # Internal Error: No default constructor available.
-io/http_server_test: Crash # Internal Error: No default constructor available.
-io/http_session_test: Crash # Internal Error: No default constructor available.
-io/http_shutdown_test: Crash # Internal Error: No default constructor available.
-io/http_stream_close_test: Crash # Invalid argument(s)
+io/http_parser_test : RuntimeError # TypeError: receiver.get$_nums is not a function
 io/https_bad_certificate_test: Crash # (main()async{var cli...  cannot handle async/sync*/async* functions
-io/https_client_certificate_test: Crash # Invalid argument(s)
-io/https_client_exception_test: Crash # Invalid argument(s)
-io/https_server_test: Crash # Internal Error: No default constructor available.
-io/https_unauthorized_test: Crash # Internal Error: No default constructor available.
 io/issue_22636_test: Crash # (test()async{server=...  cannot handle async/sync*/async* functions
 io/issue_22637_test: Crash # (test()async{server=...  cannot handle async/sync*/async* functions
-io/link_async_test: Crash # Invalid argument(s)
-io/link_test: Crash # Invalid argument(s)
-io/link_uri_test: Crash # Invalid argument(s)
 io/observatory_test: Crash # Invalid argument(s)
-io/parent_test: Crash # Invalid argument(s)
-io/platform_resolved_executable_test/00: Crash # Internal Error: No default constructor available.
-io/platform_resolved_executable_test/01: Crash # Invalid argument(s)
-io/platform_resolved_executable_test/02: Crash # Invalid argument(s)
-io/platform_resolved_executable_test/03: Crash # Internal Error: No default constructor available.
-io/platform_resolved_executable_test/04: Crash # Invalid argument(s)
-io/platform_resolved_executable_test/05: Crash # Invalid argument(s)
-io/platform_resolved_executable_test/06: Crash # Internal Error: No default constructor available.
-io/platform_resolved_executable_test/none: Crash # Internal Error: No default constructor available.
-io/platform_test: Crash # Internal Error: No default constructor available.
-io/process_environment_test: Crash # Internal Error: No default constructor available.
-io/process_path_environment_test: Crash # Internal Error: No default constructor available.
-io/raw_secure_server_closing_test: Crash # Invalid argument(s)
-io/raw_secure_server_socket_test: Crash # Invalid argument(s)
-io/raw_secure_socket_pause_test: Crash # Internal Error: No default constructor available.
-io/raw_secure_socket_test: Crash # Internal Error: No default constructor available.
-io/raw_socket_test: Crash # Invalid argument(s)
-io/raw_socket_typed_data_test: Crash # Invalid argument(s)
-io/regress_8828_test: Crash # Internal Error: No default constructor available.
-io/regress_9194_test: Crash # Internal Error: No default constructor available.
-io/resolve_symbolic_links_test: Crash # Invalid argument(s)
-io/secure_builtin_roots_test: Crash # Invalid argument(s)
-io/secure_server_closing_test: Crash # Invalid argument(s)
-io/secure_server_socket_test: Crash # Invalid argument(s)
-io/secure_socket_test: Crash # Internal Error: No default constructor available.
-io/skipping_dart2js_compilations_test: Crash # Invalid argument(s)
 io/socket_bind_test: Crash # (testListenCloseList...  cannot handle async/sync*/async* functions
-io/socket_exception_test: Crash # Invalid argument(s)
 io/socket_source_address_test: Crash # (Future testConnect(...  cannot handle async/sync*/async* functions
-io/socket_upgrade_to_secure_test: Crash # Invalid argument(s)
-io/stdin_sync_test: Crash # Internal Error: No default constructor available.
-io/test_extension_fail_test: Crash # Invalid argument(s)
-io/test_extension_test: Crash # Invalid argument(s)
-io/test_runner_test: Crash # Internal Error: No default constructor available.
-io/uri_platform_test: Crash # Invalid argument(s)
-io/web_socket_error_test: Crash # Internal Error: No default constructor available.
-io/web_socket_ping_test: Crash # Internal Error: No default constructor available.
-io/web_socket_pipe_test: Crash # Internal Error: No default constructor available.
-io/web_socket_protocol_test: Crash # Internal Error: No default constructor available.
-io/web_socket_test: Crash # Internal Error: No default constructor available.
-io/web_socket_typed_data_test: Crash # Internal Error: No default constructor available.
-io/windows_environment_test: Crash # Invalid argument(s)
 priority_queue_stress_test: RuntimeError # receiver.get$_collection$_nums is not a function
 slowpath_safepoints_test: RuntimeError # Cannot read property 'prototype' of undefined
-status_expression_test: RuntimeError # Please triage this failure.
 typed_array_test: RuntimeError # receiver.get$_collection$_nums is not a function
-verbose_gc_to_bmu_test: Crash # Invalid argument(s)
-verified_mem_test: RuntimeError # Please triage this failure.
diff --git a/tests/try/poi/serialize_test.dart b/tests/try/poi/serialize_test.dart
index 8cc192d..87f4d7b 100644
--- a/tests/try/poi/serialize_test.dart
+++ b/tests/try/poi/serialize_test.dart
@@ -532,6 +532,10 @@
     "kind": "class"
   },
   {
+    "name": "Resource",
+    "kind": "class"
+  },
+  {
     "name": "Set",
     "kind": "class"
   },
diff --git a/tools/VERSION b/tools/VERSION
index d214ff1..11b57f2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 12
 PATCH 0
-PRERELEASE 0
+PRERELEASE 1
 PRERELEASE_PATCH 0
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 3a2b541..fefd0c6 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -204,7 +204,8 @@
 
   for library in [join('_blink', 'dartium'),
                   join('_chrome', 'dart2js'), join('_chrome', 'dartium'),
-                  join('_internal', 'compiler'),
+                  join('_internal', 'js_runtime'),
+                  join('_internal', 'sdk_library_metadata'),
                   'async', 'collection', 'convert', 'core', 'developer',
                   'internal', 'io', 'isolate',
                   join('html', 'dart2js'), join('html', 'dartium'),
@@ -219,10 +220,6 @@
              ignore=ignore_patterns('*.svn', 'doc', '*.py', '*.gypi', '*.sh',
                                     '.gitignore'))
 
-  # Copy lib/_internal/libraries.dart.
-  copyfile(join(HOME, 'sdk', 'lib', '_internal', 'libraries.dart'),
-           join(LIB, '_internal', 'libraries.dart'))
-
   # Create and copy tools.
   UTIL = join(SDK_tmp, 'util')
   os.makedirs(UTIL)
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 191a94c..f3d4784 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -13,7 +13,7 @@
   "dartium_chromium_commit": "62a7524d4f71c9e0858d24b0aa1bbff3a2d09bff",
   "chromium_base_revision": "297060",
   "dartium_webkit_branch": "/blink/branches/dart/dartium",
-  "dartium_webkit_revision": "197293",
+  "dartium_webkit_revision": "198020",
 
   "args_tag": "@0.13.0",
   "barback_rev" : "@29ee90dbcf77cfd64632fa2797a4c8a4f29a4b51",
diff --git a/tools/dom/templates/html/dartium/html_dartium.darttemplate b/tools/dom/templates/html/dartium/html_dartium.darttemplate
index 0934721..1d55826 100644
--- a/tools/dom/templates/html/dartium/html_dartium.darttemplate
+++ b/tools/dom/templates/html/dartium/html_dartium.darttemplate
@@ -146,9 +146,9 @@
   '_DOMWindowCrossFrame': () => _DOMWindowCrossFrame,
   // FIXME: Move these to better locations.
   'DateTime': () => DateTime,
-  'JsObject': () => js.JsObject,
-  'JsFunction': () => js.JsFunction,
-  'JsArray': () => js.JsArray,
+  'JsObject': () => js.JsObjectImpl,
+  'JsFunction': () => js.JsFunctionImpl,
+  'JsArray': () => js.JsArrayImpl,
 $!TYPE_MAP
 };
 
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index e2b0d18..fc1d536 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -279,7 +279,8 @@
     Uri sdk = useSdk ?
         nativeDirectoryToUri(buildDir).resolve('dart-sdk/') :
         nativeDirectoryToUri(TestUtils.dartDir.toNativePath()).resolve('sdk/');
-    Uri preambleDir = sdk.resolve('lib/_internal/compiler/js_lib/preambles/');
+    Uri preambleDir = sdk.resolve(
+        'lib/_internal/js_runtime/lib/preambles/');
     return runtimeConfiguration.dart2jsPreambles(preambleDir)
         ..add(artifact.filename);
   }
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 3c3116a..f09f283 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -1897,7 +1897,7 @@
     // NOTE: We exclude tests and patch files for now.
     return filename.endsWith(".dart") &&
         !filename.endsWith("_test.dart") &&
-        !filename.contains("_internal/compiler/js_lib");
+        !filename.contains("_internal/js_runtime/lib");
   }
 
   bool get listRecursively => true;
diff --git a/utils/analysis_server/analysis_server.gyp b/utils/analysis_server/analysis_server.gyp
index 99e059b..1708ad7 100644
--- a/utils/analysis_server/analysis_server.gyp
+++ b/utils/analysis_server/analysis_server.gyp
@@ -17,7 +17,7 @@
           'action_name': 'generate_analysis_server_snapshot',
           'inputs': [
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
-            '../../sdk/lib/_internal/libraries.dart',
+            '../../sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
             '<(SHARED_INTERMEDIATE_DIR)/packages.stamp',
             '<(SHARED_INTERMEDIATE_DIR)/pkg_files.stamp',
           ],
diff --git a/utils/apidoc/apidoc.dart b/utils/apidoc/apidoc.dart
index 1dcc495..db74d32 100644
--- a/utils/apidoc/apidoc.dart
+++ b/utils/apidoc/apidoc.dart
@@ -20,12 +20,11 @@
 
 import 'html_diff.dart';
 
-// TODO(rnystrom): Use "package:" URL (#4968).
-import '../../pkg/compiler/lib/src/mirrors/source_mirrors.dart';
-import '../../pkg/compiler/lib/src/mirrors/mirrors_util.dart';
-import '../../pkg/compiler/lib/src/filenames.dart';
-import '../../sdk/lib/_internal/dartdoc/lib/dartdoc.dart';
-import '../../sdk/lib/_internal/libraries.dart';
+import 'package:compiler/src/mirrors/source_mirrors.dart';
+import 'package:compiler/src/mirrors/mirrors_util.dart';
+import 'package:compiler/src/filenames.dart';
+import 'package:dartdoc/dartdoc.dart';
+import 'package:sdk_library_metadata/libraries.dart';
 import 'package:path/path.dart' as path;
 
 HtmlDiff _diff;
diff --git a/utils/compiler/compiler.gyp b/utils/compiler/compiler.gyp
index 61c4548..37d2074 100644
--- a/utils/compiler/compiler.gyp
+++ b/utils/compiler/compiler.gyp
@@ -20,7 +20,7 @@
           'action_name': 'generate_snapshots',
           'inputs': [
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
-            '../../sdk/lib/_internal/libraries.dart',
+            '../../sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
             '<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../runtime/lib", "../../sdk/lib/_internal/dartdoc"])',
             'create_snapshot.dart',
             '<(SHARED_INTERMEDIATE_DIR)/dart2js_files.stamp',
diff --git a/utils/dartfmt/dartfmt.gyp b/utils/dartfmt/dartfmt.gyp
index 2615f85..62b8906 100644
--- a/utils/dartfmt/dartfmt.gyp
+++ b/utils/dartfmt/dartfmt.gyp
@@ -16,7 +16,7 @@
           'action_name': 'generate_dartfmt_snapshot',
           'inputs': [
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
-            '../../sdk/lib/_internal/libraries.dart',
+            '../../sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
             '<(SHARED_INTERMEDIATE_DIR)/packages.stamp',
             '<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../third_party/pkg_tested/dart_style"])',
           ],
diff --git a/utils/pub/pub.gyp b/utils/pub/pub.gyp
index 81dcec7..146a505 100644
--- a/utils/pub/pub.gyp
+++ b/utils/pub/pub.gyp
@@ -18,7 +18,7 @@
           'action_name': 'generate_pub_snapshot',
           'inputs': [
             '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
-            '../../sdk/lib/_internal/libraries.dart',
+            '../../sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
             '<(SHARED_INTERMEDIATE_DIR)/dart2js_files.stamp',
             '<(SHARED_INTERMEDIATE_DIR)/pkg_files.stamp',
             '<(SHARED_INTERMEDIATE_DIR)/packages.stamp',