Version 2.0.0-dev.0.0

Merge commit '2aef206f3f754c2c396a7c81144d5902b15506e4' into dev
diff --git a/.gitattributes b/.gitattributes
index 30c6123..49b40f1 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -22,16 +22,32 @@
 tests/language/multiline_newline_cr.dart -text
 tests/language/multiline_newline_crlf.dart -text
 tests/language/multiline_newline_lf.dart -text
+tests/language_2/raw_string_test.dart -text
+tests/language_2/multiline_strings_test.dart -text
+tests/language_2/multiline_newline_cr.dart -text
+tests/language_2/multiline_newline_crlf.dart -text
+tests/language_2/multiline_newline_lf.dart -text
 tests/lib/convert/json_pretty_test.dart -text
+tests/lib_2/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
+tests/lib_2/mirrors/method_mirror_source_line_ending_test.dart -text
+tests/lib_2/mirrors/method_mirror_source_line_ending_cr.dart -text
+tests/lib_2/mirrors/method_mirror_source_line_ending_crlf.dart -text
+tests/lib_2/mirrors/method_mirror_source_line_ending_lf.dart -text
+tests/lib_2/mirrors/method_mirror_source_test.dart -text
+tests/lib_2/mirrors/method_mirror_source_other.dart -text
 tests/language_strong/multiline_newline_crlf.dart -text
-tests/lib_strong/mirrors/method_mirror_source_line_ending_cr.dart -text
-tests/lib_strong/mirrors/method_mirror_source_line_ending_crlf.dart -text
+tests/lib_2/mirrors/method_mirror_source_line_ending_test.dart -text
+tests/lib_2/mirrors/method_mirror_source_line_ending_cr.dart -text
+tests/lib_2/mirrors/method_mirror_source_line_ending_crlf.dart -text
+tests/lib_2/mirrors/method_mirror_source_line_ending_lf.dart -text
+tests/lib_2/mirrors/method_mirror_source_test.dart -text
+tests/lib_2/mirrors/method_mirror_source_other.dart -text
 
 # Files to leave alone and not diff.
 *.png binary
diff --git a/.packages b/.packages
index a034cb0..e2104d3 100644
--- a/.packages
+++ b/.packages
@@ -53,7 +53,6 @@
 kernel:pkg/kernel/lib
 linter:third_party/pkg/linter/lib
 logging:third_party/pkg/logging/lib
-lookup_map:pkg/lookup_map/lib
 markdown:third_party/pkg/markdown/lib
 matcher:third_party/pkg/matcher/lib
 meta:pkg/meta/lib
diff --git a/BUILD.gn b/BUILD.gn
index ccb5ff2..74c317e 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -166,22 +166,21 @@
     mkbootfs_gen = get_label_info("//packages/gn:mkbootfs", "target_gen_dir")
     boot_manifest = "$mkbootfs_gen/boot.bootfs.manifest"
 
-    # Compute path to magenta bootdata.bin
+    # Compute path to zircon bootdata.bin
     if (current_cpu == "arm64") {
-      magenta_bootdata =
-          "//out/build-magenta/build-magenta-qemu-arm64/bootdata.bin"
+      zircon_bootdata =
+          "//out/build-zircon/build-zircon-qemu-arm64/bootdata.bin"
     } else if (current_cpu == "x64") {
-      magenta_bootdata =
-          "//out/build-magenta/build-magenta-pc-x86-64/bootdata.bin"
+      zircon_bootdata = "//out/build-zircon/build-zircon-pc-x86-64/bootdata.bin"
     } else {
-      assert(false, "unable to determine path to magenta's bootdata.bin")
+      assert(false, "unable to determine path to zircon's bootdata.bin")
     }
 
     packages_file = "$mkbootfs_gen/packages"
 
     input = "$target_gen_dir/dart_test_tree.manifest"
     inputs = [
-      magenta_bootdata,
+      zircon_bootdata,
       input,
     ]
 
@@ -201,7 +200,7 @@
       "--build-id-map",
       rebase_path("$target_gen_dir/build_id_map"),
       "--pre-binaries",
-      rebase_path(magenta_bootdata),
+      rebase_path(zircon_bootdata),
     ]
     args += read_file(packages_file, "list lines")
   }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2f960c4..45a3af6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-## 1.25.0
+## 2.0.0
 
 ### Language
 * A string in a `part of` declaration may now be used to refer to the library
@@ -72,6 +72,33 @@
   * Removed require.js module loading timeout for dartdevc, which resolves an
     issue where the initial load of an app might give a timeout error.
 
+  * There is now a default SDK constraint of `<2.0.0` for any package with
+    no existing upper bound. This allows us to move more safely to 2.0.0.
+
+  * All new packages published on pub will now require an upper bound SDK
+    constraint so future major releases of Dart don't destabilize the package
+    ecosystem.
+
+  * When on a pre-release SDK build, all upper bounds matching exactly the
+    current SDK version but with no pre-release or build modifier will be
+    upgraded to be <= the current SDK version. This allows early adopters to
+    try out packages that don't explicitly declare support yet. You can disable
+    this functionality by setting the PUB_ALLOW_PRERELEASE_SDK system
+    environment variable to `false`.
+
+  * Added `--executables` option to `pub deps` command. This will list all
+    available executables that can be run with `pub run`.
+
+  * Fixed https://github.com/dart-lang/pub/issues/1684 so root package analysis
+    options are not enforced for dependencies when compiling with dartdevc.
+
+  * Fixed https://github.com/dart-lang/sdk/issues/30246 so you can include dart
+    scripts from subdirectories with dartdevc.
+
+  * Added a PUB_MAX_WORKERS_PER_TASK system environment variable which can be
+    set to configure the number of dartdevc/analyzer workers that are used
+    when compiling with --web-compiler=dartdevc.
+
 * dartfmt
 
     * Support assert in const constructor initializer lists.
diff --git a/DEPS b/DEPS
index e4bdb4c..54acd3c 100644
--- a/DEPS
+++ b/DEPS
@@ -36,7 +36,7 @@
 
   # Revisions of GN related dependencies. This should match the revision
   # pulled by Flutter.
-  "buildtools_revision": "@5b8eb38aaf523f0124756454276cd0a5b720c17e",
+  "buildtools_revision": "@057ef89874e3c622248cf99259434fdc683c4e30",
 
   # Scripts that make 'git cl format' work.
   "clang_format_scripts_rev": "@c09c8deeac31f05bd801995c475e7c8070f9ecda",
@@ -77,7 +77,7 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
   "dart_style_tag": "@1.0.7",  # Please see the note above before updating.
 
-  "dartdoc_tag" : "@v0.13.0+2",
+  "dartdoc_tag" : "@v0.13.0+3",
   "fixnum_tag": "@0.10.5",
   "func_tag": "@1.0.0",
   "glob_tag": "@1.1.3",
@@ -94,7 +94,7 @@
   "linter_tag": "@0.1.35",
   "logging_tag": "@0.11.3+1",
   "markdown_tag": "@0.11.3",
-  "matcher_tag": "@0.12.0+2",
+  "matcher_tag": "@0.12.1+3",
   "mime_rev": "@75890811d4af5af080351ba8a2853ad4c8df98dd",
   "mockito_tag": "@2.0.2",
   "mustache4dart_tag" : "@v1.1.0",
@@ -107,7 +107,7 @@
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_tag": "@1.3.0",
   "protobuf_tag": "@0.5.4",
-  "pub_rev": "@0f122625f8e607842afe156b9b23a9709e4ce39a",
+  "pub_rev": "@cde958f157d3662bf968bcbed05580d5c0355e89",
   "pub_semver_tag": "@1.3.2",
   "quiver_tag": "@0.22.0",
   "resource_rev":"@a49101ba2deb29c728acba6fb86000a8f730f4b1",
@@ -127,7 +127,7 @@
   "sunflower_rev": "@879b704933413414679396b129f5dfa96f7a0b1e",
   "term_glyph_tag": "@1.0.0",
   "test_reflective_loader_tag": "@0.1.0",
-  "test_tag": "@0.12.18+1",
+  "test_tag": "@0.12.24+2",
   "tuple_tag": "@v1.0.1",
   "typed_data_tag": "@1.1.3",
   "usage_tag": "@3.3.0",
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 2572c86..744f0b2 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -86,10 +86,14 @@
           unformatted_files.append(filename)
 
   if unformatted_files:
+    lineSep = " \\\n"
+    if windows:
+      lineSep = " ^\n";
     return [output_api.PresubmitError(
         'File output does not match dartfmt.\n'
         'Fix these issues with:\n'
-        '%s -w \\\n%s' % (prebuilt_dartfmt, ' \\\n'.join(unformatted_files)))]
+        '%s -w%s%s' % (prebuilt_dartfmt, lineSep,
+            lineSep.join(unformatted_files)))]
 
   return []
 
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index b999f2b..b7543a6 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -335,9 +335,9 @@
   # define into the compile line.
   if (is_clang && (is_linux || is_mac)) {
     if (is_linux) {
-      toolchain_stamp_file = "//buildtools/linux64/clang.stamp"
+      toolchain_stamp_file = "//buildtools/linux64/toolchain.stamp"
     } else {
-      toolchain_stamp_file = "//buildtools/mac/clang.stamp"
+      toolchain_stamp_file = "//buildtools/mac/toolchain.stamp"
     }
     toolchain_version = read_file(toolchain_stamp_file, "trim string")
     defines = [ "TOOLCHAIN_VERSION=$toolchain_version" ]
diff --git a/build/toolchain/android/BUILD.gn b/build/toolchain/android/BUILD.gn
index 2560e4c..f680609 100644
--- a/build/toolchain/android/BUILD.gn
+++ b/build/toolchain/android/BUILD.gn
@@ -47,8 +47,17 @@
 
     is_clang = invoker.is_clang
     if (is_clang) {
-      prefix =
-          rebase_path("//buildtools/${host_os}-x64/clang/bin", root_build_dir)
+      host_suffix = ""
+      if (host_os == "linux") {
+        host_suffix = "x86_64-linux"
+      } else if (host_os == "mac") {
+        host_suffix = "x86_64-darwin"
+      } else {
+        assert(false, "Unknown host")
+      }
+
+      prefix = rebase_path("//buildtools/toolchain/clang+llvm-$host_suffix/bin",
+                           root_build_dir)
 
       cc = compiler_prefix + prefix + "/clang"
       cxx = compiler_prefix + prefix + "/clang++"
diff --git a/build/toolchain/linux/BUILD.gn b/build/toolchain/linux/BUILD.gn
index 13dbfc1..7ad72ac 100644
--- a/build/toolchain/linux/BUILD.gn
+++ b/build/toolchain/linux/BUILD.gn
@@ -63,7 +63,8 @@
 }
 
 gcc_toolchain("clang_x86") {
-  prefix = rebase_path("//buildtools/linux-x64/clang/bin", root_build_dir)
+  prefix = rebase_path("//buildtools/toolchain/clang+llvm-x86_64-linux/bin",
+                       root_build_dir)
   cc = "${compiler_prefix}${prefix}/clang"
   cxx = "${compiler_prefix}${prefix}/clang++"
   readelf = "readelf"
@@ -94,7 +95,8 @@
 }
 
 gcc_toolchain("clang_x64") {
-  prefix = rebase_path("//buildtools/linux-x64/clang/bin", root_build_dir)
+  prefix = rebase_path("//buildtools/toolchain/clang+llvm-x86_64-linux/bin",
+                       root_build_dir)
   cc = "${compiler_prefix}${prefix}/clang"
   cxx = "${compiler_prefix}${prefix}/clang++"
 
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn
index 1dab179..b520efd 100644
--- a/build/toolchain/mac/BUILD.gn
+++ b/build/toolchain/mac/BUILD.gn
@@ -223,7 +223,8 @@
 mac_toolchain("clang_x64") {
   toolchain_cpu = "x64"
   toolchain_os = "mac"
-  prefix = rebase_path("//buildtools/mac-x64/clang/bin", root_build_dir)
+  prefix = rebase_path("//buildtools/toolchain/clang+llvm-x86_64-darwin/bin",
+                       root_build_dir)
   cc = "${goma_prefix}$prefix/clang"
   cxx = "${goma_prefix}$prefix/clang++"
   ar = "${prefix}/llvm-ar"
@@ -237,7 +238,8 @@
 mac_toolchain("clang_x86") {
   toolchain_cpu = "i386"
   toolchain_os = "mac"
-  prefix = rebase_path("//buildtools/mac-x64/clang/bin", root_build_dir)
+  prefix = rebase_path("//buildtools/toolchain/clang+llvm-x86_64-darwin/bin",
+                       root_build_dir)
   cc = "${goma_prefix}$prefix/clang"
   cxx = "${goma_prefix}$prefix/clang++"
   ar = "${prefix}/llvm-ar"
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index ae82899..63ce0a7 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -25,6 +25,9 @@
 % - It is a static warning and dynamic error to assign to a final local.
 % - Specify what "is equivalent to" means.
 % - Remove @proxy.
+% - Don't specify the exact object used for empty positionalArguments and
+%   namedArguments on Invocation.
+% - Remove the, now unnecessary, handling of invalid overrides of noSuchMethod.
 %
 % 1.15
 % - Change how language specification describes control flow.
@@ -4111,26 +4114,12 @@
 \end{itemize}
 
 \LMHash{}
-Then the method \code{noSuchMethod()} is looked up in $v_o$ and invoked with argument $im$, and the result of this invocation is the result of evaluating $i$. However, if the implementation found cannot be invoked with a single positional argument, the implementation  of \code{noSuchMethod()} in class \code{Object} is invoked on $v_o$ with argument $im'$, where $im'$ is an instance of \code{Invocation} such that :
-\begin{itemize}
-\item  \code{im'.isMethod} evaluates to \code{\TRUE{}}.
-\item  \code{im'.memberName} evaluates to \code{\#noSuchMethod}.
-\item \code{im'.positionalArguments} evaluates to an immutable list whose sole element is  $im$.
-\item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}.
-\end{itemize}
+Then the method \code{noSuchMethod()} is looked up in $v_o$ and invoked with argument $im$, and the result of this invocation is the result of evaluating $i$.
 
-and the result of the latter invocation is the result of evaluating $i$.
-
-\rationale {
-It is possible to bring about such a situation by overriding \code{noSuchMethod()} with the wrong number of arguments:}
-
-\begin{code}
-\CLASS{} Perverse \{
-    noSuchMethod(x,y) => x + y;
-\}
-
-\NEW{} Perverse.unknownMethod();
-\end{code}
+\commentary {
+It is not possible to override the \code{noSuchMethod} if class \code{Object}
+in such a way that it cannot be invoked with one argument of type \code{Invocation}.
+}
 
 \commentary{Notice that the wording carefully avoids re-evaluating the receiver $o$ and the arguments $a_i$. }
 
@@ -4206,23 +4195,14 @@
 the static method \code{Function.apply()} with arguments $v_g, [o_1, \ldots , o_n], \{x_{n+1} = o_{n+1}, \ldots , x_{n+k} = o_{n+k}\}$.
 
 \LMHash{}
-If  getter lookup has also failed, then a new instance $im$  of the predefined class  \code{Invocation}  is created, such that :
+If  getter lookup has also failed, then a new instance $im$  of the predefined class \code{Invocation} is created, such that:
 \begin{itemize}
-\item  \code{im.isMethod} evaluates to \code{\TRUE{}}.
-\item  \code{im.memberName} evaluates to the symbol \code{m}.
+\item \code{im.isMethod} evaluates to \code{\TRUE{}}.
+\item \code{im.memberName} evaluates to the symbol \code{m}.
 \item \code{im.positionalArguments} evaluates to an immutable list with the same  values as  \code{[$o_1, \ldots, o_n$]}.
 \item \code{im.namedArguments} evaluates to an immutable map with the same keys and values as \code{\{$\#x_{n+1}: o_{n+1}, \ldots, \#x_{n+k} : o_{n+k}$\}}.
 \end{itemize}
-Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked on \THIS{} with argument $im$, and the result of this invocation is the result of evaluating $i$. However, if the implementation found cannot be invoked with a single positional argument, the implementation  of \code{noSuchMethod()} in class \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \code{Invocation} such that :
-\begin{itemize}
-\item  \code{im'.isMethod} evaluates to \code{\TRUE{}}.
-\item  \code{im'.memberName} evaluates to \code{\#noSuchMethod}.
-\item \code{im'.positionalArguments} evaluates to an immutable list whose sole element is  $im$.
-\item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}.
-\end{itemize}
-
-and the result of this latter invocation is the result of evaluating $i$.
-
+Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked on \THIS{} with argument $im$, and the result of this invocation is the result of evaluating $i$.
 
 \LMHash{}
 It is a compile-time error if a super method invocation occurs in a top-level function or variable initializer, in an instance variable initializer or initializer list, in class \code{Object}, in a factory constructor or in a static method or variable initializer.
@@ -4300,22 +4280,14 @@
 (\ref{getterAndSetterLookup}) getter (\ref{getters}) $m$ in $o$  with respect to $L$. If $o$ is an instance of \code{Type} but $e$ is not a constant type literal, then if $f$ is a getter that forwards  to a static getter,  getter lookup fails. Otherwise, the body of $f$ is executed with \THIS{} bound to $o$.  The value of $i$ is the result returned by the call to the getter function.
 
 \LMHash{}
-If the getter lookup has failed, then a new instance $im$  of the predefined class  \code{Invocation}  is created, such that :
+If the getter lookup has failed, then a new instance $im$  of the predefined class \code{Invocation} is created, such that :
 \begin{itemize}
-\item  \code{im.isGetter} evaluates to \code{\TRUE{}}.
-\item  \code{im.memberName} evaluates to the symbol \code{m}.
-\item \code{im.positionalArguments} evaluates to the value of \code{\CONST{} []}.
-\item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}.
+\item \code{im.isGetter} evaluates to \code{\TRUE{}}.
+\item \code{im.memberName} evaluates to the symbol \code{m}.
+\item \code{im.positionalArguments} evaluates to an empty unmodifiable instance of \code{List<Object>}.
+\item \code{im.namedArguments} evaluates to an empty unmodifiable instance of \code{Map<Symbol, Object>}.
 \end{itemize}
-Then the method \code{noSuchMethod()} is looked up in $o$ and invoked  with argument $im$, and the result of this invocation is the result of evaluating $i$. However, if the implementation found cannot be invoked with a single positional argument, the implementation  of \code{noSuchMethod()} in class \code{Object} is invoked on $o$ with argument $im'$, where $im'$ is an instance of \code{Invocation} such that :
-\begin{itemize}
-\item  \code{im'.isMethod} evaluates to \code{\TRUE{}}.
-\item  \code{im'.memberName} evaluates to \code{\#noSuchMethod}.
-\item \code{im'.positionalArguments} evaluates to an immutable list whose sole element is  $im$.
-\item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}.
-\end{itemize}
-
-and the result of this latter invocation is the result of evaluating $i$.
+Then the method \code{noSuchMethod()} is looked up in $o$ and invoked with argument $im$, and the result of this invocation is the result of evaluating $i$.
 
 \LMHash{}
 It is a compile-time error if $m$ is a member of class \cd{Object} and $e$ is either a prefix object (\ref{imports}) or a constant type literal.
@@ -4351,21 +4323,14 @@
  Otherwise, $i$ is a getter invocation.  Let $f$ be the result of  looking up getter $m$ in $S_{dynamic}$  with respect to $L$.  The body of $f$  is executed with \THIS{} bound to the current value of  \THIS{}.  The value of $i$ is the result returned by the call to the getter function.
 
 \LMHash{}
-If the getter lookup has failed, then a new instance $im$  of the predefined class  \code{Invocation}  is created, such that :
+If the getter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
 \begin{itemize}
 \item  \code{im.isGetter} evaluates to \code{\TRUE{}}.
 \item  \code{im.memberName} evaluates to the symbol \code{m}.
-\item \code{im.positionalArguments} evaluates to the value of \code{\CONST{} []}.
-\item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}.
+\item \code{im.positionalArguments} evaluates to an empty unmodifiable instance of \code{List<Object>}.
+\item \code{im.namedArguments} evaluates to an empty unmodifiable instance of \code{Map<Symbol, Object>}.
 \end{itemize}
-Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked  with argument $im$, and the result of this invocation is the result of evaluating $i$. However, if the implementation found cannot be invoked with a single positional argument, the implementation  of \code{noSuchMethod()} in class \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \code{Invocation} such that :
-\begin{itemize}
-\item  \code{im'.isMethod} evaluates to \code{\TRUE{}}.
-\item  \code{im'.memberName} evaluates to \code{\#noSuchMethod}.
-\item \code{im'.positionalArguments} evaluates to an immutable list whose sole element is  $im$.
-\item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}.
-\end{itemize}
-and the result of this latter invocation is the result of evaluating $i$.
+Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked  with argument $im$, and the result of this invocation is the result of evaluating $i$.
 
 \LMHash{}
 Let $S_{static}$ be the superclass of the immediately enclosing class. It is a static type warning if $S_{static}$ does not have an accessible instance method or getter named $m$.
@@ -4373,8 +4338,8 @@
 The static type of $i$ is:
 \begin{itemize}
 \item The declared return type of $S_{static}.m$, if $S_{static}$ has an accessible instance getter named $m$.
-\item The static type of function $S_{static}.m$ if $S_{static}$ has an accessible instance method named $m$.
-\item The type  \DYNAMIC{} otherwise.
+\item The static type of function $S_{static}.m$, if $S_{static}$ has an accessible instance method named $m$.
+\item The type \DYNAMIC{} otherwise.
 \end{itemize}
 
 
@@ -4526,23 +4491,16 @@
 The expression $e_1$ is evaluated to an object $o_1$. Then, the expression $e_2$  is evaluated to an object $o_2$. Then, the setter $v=$ is looked up (\ref{getterAndSetterLookup}) in $o_1$ with respect to the current library.  If $o_1$ is an instance of \code{Type} but $e_1$ is not a constant type literal, then if $v=$ is a setter that forwards (\ref{functionDeclarations}) to a static setter, setter lookup fails. Otherwise, the body  of $v=$ is executed with its formal parameter bound to $o_2$ and \THIS{} bound to $o_1$.
 
 \LMHash{}
-If the setter lookup has failed, then a new instance $im$  of the predefined class  \code{Invocation}  is created, such that :
+If the setter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
 \begin{itemize}
-\item  \code{im.isSetter} evaluates to \code{\TRUE{}}.
-\item  \code{im.memberName} evaluates to the symbol \code{v=}.
+\item \code{im.isSetter} evaluates to \code{\TRUE{}}.
+\item \code{im.memberName} evaluates to the symbol \code{v=}.
 \item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o_2$]}.
-\item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}.
+\item \code{im.namedArguments} evaluates to an empty unmodifiable instance of \code{Map<Symbol, Object>}.
 \end{itemize}
 
 \LMHash{}
 Then the method \code{noSuchMethod()} is looked up in $o_1$ and invoked  with argument $im$.
-However, if the implementation found cannot be invoked with a single positional argument, the implementation  of \code{noSuchMethod()} in class \code{Object} is invoked on $o_1$ with argument $im'$, where $im'$ is an instance of \code{Invocation} such that :
-\begin{itemize}
-\item  \code{im'.isMethod} evaluates to \code{\TRUE{}}.
-\item  \code{im'.memberName} evaluates to \code{\#noSuchMethod}.
-\item \code{im'.positionalArguments} evaluates to an immutable list whose sole element is  $im$.
-\item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}.
-\end{itemize}
 
 \LMHash{}
 The value of the assignment expression is $o_2$ irrespective of whether setter lookup has failed or succeeded.
@@ -4565,23 +4523,16 @@
 The expression $e$ is evaluated to an object $o$.  Then, the setter $v=$ is looked up (\ref{getterAndSetterLookup}) in $S_{dynamic}$ with respect to the current library.  The body  of $v=$ is executed with its formal parameter bound to $o$ and \THIS{} bound to \THIS{}.
 
 \LMHash{}
-If the setter lookup has failed, then a new instance $im$  of the predefined class  \code{Invocation}  is created, such that :
+If the setter lookup has failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
 \begin{itemize}
-\item  \code{im.isSetter} evaluates to \code{\TRUE{}}.
-\item  \code{im.memberName} evaluates to the symbol \code{v=}.
+\item \code{im.isSetter} evaluates to \code{\TRUE{}}.
+\item \code{im.memberName} evaluates to the symbol \code{v=}.
 \item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o$]}.
-\item \code{im.namedArguments} evaluates to the value of \code{\CONST{} \{\}}.
+\item \code{im.namedArguments} evaluates to an empty unmodifiable instance of \code{Map<Symbol, Object>}.
 \end{itemize}
 
 \LMHash{}
-Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked  with argument $im$.
-However, if the implementation found cannot be invoked with a single positional argument, the implementation  of \code{noSuchMethod()} in class \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \code{Invocation} such that :
-\begin{itemize}
-\item  \code{im'.isMethod} evaluates to \code{\TRUE{}}.
-\item  \code{im'.memberName} evaluates to \code{\#noSuchMethod}.
-\item \code{im'.positionalArguments} evaluates to an immutable list whose sole element is  $im$.
-\item \code{im'.namedArguments} evaluates to the value of \code{\CONST{} \{\}}.
-\end{itemize}
+Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked with argument $im$.
 
 \LMHash{}
 The value of the assignment expression is $o$ irrespective of whether setter lookup has failed or succeeded.
diff --git a/docs/language/informal/generic-function-type-alias.md b/docs/language/informal/generic-function-type-alias.md
index 9dd6681..f03c5cc 100644
--- a/docs/language/informal/generic-function-type-alias.md
+++ b/docs/language/informal/generic-function-type-alias.md
@@ -132,13 +132,15 @@
 normalParameterTypes: // NEW
   normalParameterType (',' normalParameterType)*
 normalParameterType: // NEW
-  type | typedIdentifier
+  metadata (type | typedIdentifier)
 optionalParameterTypes: // NEW
   optionalPositionalParameterTypes | namedParameterTypes
 optionalPositionalParameterTypes: // NEW
   '[' normalParameterTypes ','? ']'
 namedParameterTypes: // NEW
-  '{' typedIdentifier (',' typedIdentifier)* ','? '}'
+  '{' namedParameterType (',' namedParameterType)* ','? '}'
+namedParameterType: // NEW
+  metadata typedIdentifier
 typedIdentifier: // NEW
   type identifier
 type: // CHANGED
diff --git a/docs/newsletter/20170908.md b/docs/newsletter/20170908.md
new file mode 100644
index 0000000..702eb4e
--- /dev/null
+++ b/docs/newsletter/20170908.md
@@ -0,0 +1,145 @@
+# Dart Language and Library Newsletter
+2017-09-08
+@floitschG
+
+Welcome to the Dart Language and Library Newsletter.
+
+## Follow-Up - Call
+Last newsletter we announced our desire to remove the `call` operator from the language. We got some feedback that showed some uses in the wild. Please keep them coming. It will definitely influence our decision whether (or when) we are going to remove the operator.
+
+We also forgot an additional benefit of removing the operator: since users wouldn't be able to implement functions by themselves we could extend the `Function` interface with useful properties. For example, we could add getters that return the arity / signature of the receiver closure:
+
+``` dart
+void onError(Function errorHandler) {
+  // positionalArgumentCount includes optional positional parameters.
+  if (errorHandler.positionalParameterCount >= 2) {
+    errorHandler(error, stackTrace);
+  } else {
+    errorHandler.positionalParameterCount == 1);
+    errorHandler(error);
+  }
+}
+```
+
+## Fuzzy Arrow
+In Dart 1.x `dynamic` was used for both the *top* and *bottom* of the typing hierarchy. Depending on the context, `dynamic` could either mean `Object` (top) or `Null` (bottom). For the remainder of the section remember that every type is a subtype of `Object` (which is why it's called "top"), and every type is a supertype of `Null`.
+
+This schizophrenic interpretation of `dynamic` can be observed easily with generic types:
+
+``` dart
+void main() {
+  print(<int>[1, 2, 3] is List<dynamic>);  // Use `dynamic` as bottom. => true.
+  print(<dynamic>[1, 2, 3] is List<int>);  // Use `dynamic` as top. => true.
+}
+```
+In the first statement, `List<dynamic>` is used as a supertype of `List<int>`, whereas in the second statement, `List<dynamic>` is used as subtype of `List<int>`. This works for every type and not just `int`. As such, `dynamic` clearly is top and bottom at the same time.
+
+With strong mode, this dual-view of `dynamic` became an issue, and, for the sake of soundness, `dynamic` was downgraded to `Object`. It still supports dynamic calls, but can't be used as bottom anymore. In strong mode, the second statement thus prints "false". However, strong mode kept one small exception: *fuzzy arrows*.
+
+The fuzzy arrow exception allows `dynamic` to be used as if it was `bottom` when it is used in function types. Take the following example:
+``` dart
+/// Fills [list2] with the result of applying [f] to every element of
+/// [list1] (if [f] is of arity 1), or of applying [f] to every
+/// element of [list1] and [list2] (otherwise).
+void map1or2(Function f, List list1, List list2) {
+  for (int i = 0; i < list1.length; i++) {
+    var x = list1[i];
+    if (f is Function(dynamic)) {
+      list2[i] = f(x);
+    } else {
+      var y = list2[i];
+      list2[i] = f(x, y);
+    }
+  }
+}
+
+int square(int x) => x * x;
+
+void main() {
+  var list1 = <int>[1, 2, 3];
+  var list2 = new List(3);
+  map1or2(square, list1, list2);
+  print(list2);
+}
+```
+This code is relatively dynamic and avoids lots of types (and in particular generic arguments to `map1or2`), but it is a correct strong mode program. In DDC it prints `[1, 4, 9]`.
+
+There are some implicit `dynamic`s in the program, but we are really interested in the one explicit `dynamic` in the function-type test: `if (f is Function(dynamic))`. Intuitively, that test looks good: we don't mind which type the function takes and thus wrote `dynamic` for the parameter type. However, that wouldn't work if `dynamic` was interpreted as `Object`. In that case, the `is` check asks whether the provided `f` could be invoked with *any* `Object`. That's not what we want. We don't want to invoke it with a random object value that we found somewhere, but invoke it with the values from `list1`. It's the caller's responsibility to make sure that the types match. In fact, we don't care for the type at all. The `is` check is just here to test for the arity.
+
+Since checking for arity is a common pattern, strong mode still treats `dynamic` as bottom in this context. This function types is thus equivalent to an arity check.
+
+For a long time, the fuzzy arrow exception was necessary. Dart didn't have any other way to do arity checking. Only with the move of the `Null` type to the bottom of the typing hierarchy, was it possible to explicitly use the bottom type instead of just dynamic. A sounder way of asking for a function's arity is thus:
+
+``` dart
+if (f is Function(Null)) {
+```
+
+This can be read as: "is `f` a function that takes at least `null`?". Without non-nullable types *every* 1-arity function takes `null` and this test is equivalent to asking whether the function takes one argument.
+
+`<footnote>`
+With non-nullable types, the bottom type would need to change, since there are types that wouldn't accept `null` anymore. At that point we would need to introduce a `Nothing` type, and the `is`-check would need to be rewritten to `if (f is Function(Nothing))`. Admittedly, the spoken interpretation doesn't sound as logical anymore: "is `f` a function that takes at least Nothing?"
+`</footnote>`
+
+Since there is now a "correct" way of testing for the arity of functions, the language team recently started to investigate whether we could drop the fuzzy arrow exception from strong mode (and thus Dart 2.0).
+
+Although the removal of fuzzy errors leads to breakages, our experience is pretty positive so far. The biggest problems arise in cases where the current type system is too weak to provide a correct replacement. Among those, `Map.fromIterables` clearly makes the biggest problems. The old signature of that constructor is `Map.fromIterable(Iterable iterable, {K key(element), V value(element)})`. Implicitly, both functions for `key` and `value` take `dynamic` arguments and use the fuzzy arrow exceptions to support iterables of any kind.
+
+Without the fuzzy arrow exception the implicit `dynamic` in those types is read similar to `Object`, thus requiring users to provide functions that can deal with *any* object (and not just the ones from the `iterable`).
+
+Unfortunately, our trick of replacing the `dynamic` with `Null` doesn't work here:
+
+``` dart
+Map.fromIterable(Iterable iterable,
+    {K key(Null element), V value(Null element)}) {
+  ...
+}
+
+// Works when the argument is not a function literal:
+new Map<int, String>.fromIterable(["1", "2"], keys: int.parse);
+
+// Doesn't work, with function literal:
+new Map<int, String>.fromIterable([1, 2], values: (x) => x.toString());
+```
+
+The reason the second instantiation doesn't work is that Dart uses the context of a function literal to infer the parameter type. In this case the literal `(x) => x.toString()` is used in a context where a `V Function(Null)` is expected, and the literal is thus automatically adapted to satisfy this signature: `String Function(Null)`. However, that means that any invocation of this function with a value that is not `null` yields to a dynamic error.
+
+The correct way to fix this constructor is to allow generic arguments for constructors:
+
+``` dart
+Map.fromIterable<T>(Iterable<T> iterable,
+    {K key(T element), V value(T element)}) {
+  ...
+}
+```
+Supporting generic arguments for constructors is on our roadmap, but will not make it for Dart 2.0. In the meantime we either have to live with requiring functions that take objects, or we will have to change the `key` and `value` type annotation to `Function`, thus losing the arity and type information:
+
+``` dart
+Map.fromIterable(Iterable iterable, {Function key, Function value}) {
+  ...
+}
+```
+
+## Enhanced Type Promotion
+As mentioned in a previous newsletter: one of our goals is to improve Dart's type promotion. We want to make better use of `is` and `is!` checks. For example, promote `x` to `int` after the `if` in the following code: `if (x is! int) throw x;`.
+
+When the language team discussed this topic we looked at the conditions under which type promotion would be useful and intuitive. One of the current restrictions is that promoted variables may not be assigned again:
+
+``` dart
+void foo(Object x) {
+  if (x is String) {
+    x = x.subString(1);  // Error: subString is not defined for Object.
+    print(x + "suffix");
+  }
+}
+
+void bar(Object x) {
+  if (x is WrappedInt) {
+    x = x.value;   // Error: `value` is not defined for Object.
+  }
+  assert(x is int);
+}
+```
+
+As can be seen in these two examples, assignments would require an analysis that deals with flow-control, and that assigns potentially different types to the same variable. Inside `foo` the user wants to continue using `x` as `String`, whereas in `bar` the user wants to use `x` as an `Object` after the assignment.
+
+We have discussed multiple approaches to provide the correct, intuitive behavior in these cases, and we are confident that we can provide a solution that will work in most cases. However, we don't want to delay or block the "easy" improvements, and therefore decided to exclude assignments from the current proposal. We will come back to assignments of promoted variables in the future.
diff --git a/docs/newsletter/20170915.md b/docs/newsletter/20170915.md
new file mode 100644
index 0000000..a425c60
--- /dev/null
+++ b/docs/newsletter/20170915.md
@@ -0,0 +1,327 @@
+# Dart Language and Library Newsletter
+2017-09-15
+@floitschG
+
+Welcome to the Dart Language and Library Newsletter.
+
+## Did You Know
+In this (hopefully) recurring section, we will show some of the lesser known features of Dart.
+
+### Labels
+Dart's semantics introduces labels as follows:
+
+> A label is an identifier followed by a colon. A labeled statement is a statement prefixed by a label L. A labeled case clause is a case clause within a switch statement (17.9) prefixed by a label L.
+> The sole role of labels is to provide targets for the `break` (17.14) and `continue` (17.15) statements.
+
+Most of this functionality is similar to other languages, so most of the following sections might look familiar to readers. I believe, Dart's handling of `continue` in `switch` statements is relatively unique, so make sure you read that section.
+
+#### Loops
+Labels are most often used as targets for `break` and `continue` inside loops.
+
+Say you have nested loops, and want to jump to `break` or `continue` to the outer loop. Without labels this wouldn't (easily) possible.
+
+The following example uses `continue label` to jump from the inner loop directly to the next iteration of the outer loop:
+``` dart
+/// Returns the inner list (of positive integers) with the smallest sum.
+List<int> smallestSumList(List<List<int>> lists) {
+  var smallestSum =0xFFFFFFFF;  // The lists are known to have smaller sums.
+  var smallestList = null;
+  outer:
+  for (var innerList in lists) {
+    var sum = 0;
+    for (var element in innerList) {
+      assert(element >= 0);
+      sum += element;
+      // No need to continue iterating over the inner list. Its sum is already
+      // too high.
+      if (sum > smallestSum) continue outer; // <===== continue to label.
+    }
+    smallestSum = sum;
+    smallestList = innerList;
+  }
+  return smallestList;
+}
+```
+This function runs through all lists, but stops adding up variables, as soon as the sum is too high.
+
+The same technique can be used to break out of an outer loop:
+
+``` dart
+var firstListWithNullValues = null;
+outer:
+for (var innerList in lists) {
+  for (var element in innerList) {
+    if (element == null) {
+      firstListWithNullValues = innerList;
+      break outer;  // <====== break to label.
+    }
+  }
+}
+// Now continue the normal work-flow.
+if (firstListWithNullValues != null) {
+  ...
+}
+```
+
+#### Breaking out of Blocks
+Labels can also be used to break out of blocks. Say we want to treat an error condition uniformly, but have multiple conditions (potentially deeply nested) that reveal the error. Labels can help structure this code.
+
+``` dart
+void doSomethingWithA(A a) {
+  errorChecks:
+  {
+    if (a.hasEntries) {
+      for (var entry in a.entries) {
+        if (entry is Bad) break errorChecks;  // <===== break out of block.
+      }
+    }
+    if (a.hasB) {
+      var b = a.b;
+      if (b.inSomeBadState) break errorChecks;  // <===== break out of block.
+    }
+    // All looks good.
+    use(a);
+    return;
+  }
+  // Error case:
+  print("something bad happened");
+}
+```
+A break to a block makes Dart continue with the statement just after the block. From a certain point of view, it's a structured `goto`, that is only allowed to jump to less-nested places that are after the current instruction.
+
+While statement labels are most useful on blocks, they are allowed on every statement. For example, `foo: break foo;` is a valid statement.
+
+Note that the loop `continue`s from above can be implemented by wrapping the loop body into a labeled block and breaking out of it. That is, the following two loops are equivalent:
+
+``` dart
+// With continue.
+for (int i = 0; i < 10; i++) {
+  if (i.isEven) continue;
+  print(i);
+}
+
+// With break.
+for (int i = 0; i < 10; i++) {
+  stmtLabel: {
+    if (i.isEven) break stmtLabel;
+    print(i);
+  }
+}
+```
+
+#### Labels in Switch
+Labels can also be used inside switches. They allow programs to `continue` with another `case` clause. In its simplest form this can be used as a way to fall through to the next clause:
+
+``` dart
+void switchExample(int foo) {
+  switch (foo) {
+    case 0:
+      print("foo is 0");
+      break;
+    case 1:
+      print("foo is 1");
+      continue shared; // Continue at the clause that is marked `shared`.
+    shared:
+    case 2:
+      print("foo is either 1 or 2");
+      break;
+  }
+}
+```
+
+Interestingly, Dart does *not* require the target of the `continue` to be the clause that follows the current `case` clause. Any `case` clause with a label is a valid target. This means, that Dart's `switch` statements are effectively state machines.
+
+The following example demonstrates such an abuse, where the whole `switch` is really just used as a state machine.
+
+``` dart
+void runDog() {
+  int age = 0;
+  int hungry = 0;
+  int tired = 0;
+
+  bool seesSquirrel() => new Random().nextDouble() < 0.1;
+  bool seesMailman() => new Random().nextDouble() < 0.1;
+
+  switch (0) {
+    start:
+    case 0:
+      print("dog has started");
+      continue doDogThings;
+
+    sleep:
+    case 1: // Never used.
+      print("sleeping");
+      tired = 0;
+      age++;
+      // The inevitable... :(
+      if (age > 20) break;
+      // Wake up and do dog things.
+      continue doDogThings;
+
+    doDogThings:
+    case 2: // Never used.
+      if (hungry > 2) continue eat;
+      if (tired > 3) continue sleep;
+      if (seesSquirrel()) continue chase;
+      if (seesMailman()) continue bark;
+      continue play;
+
+    chase:
+    case 3: // Never used.
+      print("chasing");
+      hungry++;
+      tired++;
+      continue doDogThings;
+
+    eat:
+    case 4: // Never used.
+      print("eating");
+      hungry = 0;
+      continue doDogThings;
+
+    bark:
+    case 5: // Never used.
+      print("barking");
+      tired++;
+      continue doDogThings;
+
+    play:
+    case 6: // Never used.
+      print("playing");
+      tired++;
+      hungry++;
+      continue doDogThings;
+  }
+}
+```
+This function jumps from one `switch` clause to the next simulating the life of a dog. In Dart, labels are only allowed on `case` clauses, so I had to add some `case` lines that will never be reached.
+
+This feature is pretty cool, but it has been used extremely rarely. Because of the added complexity for our compilers, we have frequently discussed its removal. So far it has survived our scrutiny, but we might eventually simplify our specification and make users add a `while(true)` loop (with a label!) themselves. The `dog` example could be rewritten as follows:
+
+``` dart
+var state = 0;
+loop:
+while (true)
+  switch (state) {
+    case 0:
+      print("dog has started");
+      state = 2; continue;
+
+    case 1:  // sleep.
+      print("sleeping");
+      tired = 0;
+      age++;
+      // The inevitable... :(
+      if (age > 20) break loop;  // <===== break out of loop.
+      // Wake up and do dog things.
+      state = 2; continue;
+
+    case 2:  // doDogThings.
+      if (hungry > 2) { state = 4; continue; }
+      if (tired > 3) { state = 1; continue; }
+      if (seesSquirrel()) { state = 3; continue; }
+      ...
+```
+If the state values were named constants this would be as readable as the original version, but wouldn't require the `switch` statement to support state machines.
+
+## Synchronous Async Start
+This section discusses our plans to make `async` functions start synchronously. This change is planned for Dart 2.0.
+
+### Motivation
+The current Dart specification requires that `async` functions are delayed:
+
+> If f is marked async (9), then a fresh instance (10.6.1) o implementing the built-in class Future is associated with the invocation and immediately returned to the caller. The body of f is scheduled for execution at some future time.
+
+For example:
+``` dart
+Future<int> foo(x) async {
+  print(x);
+  return x + 1;
+}
+
+main() {
+  foo(499).then(print);
+  print("after foo call");
+}
+```
+
+When this program is run, it emits the following output:
+```
+after foo call
+499
+500
+```
+
+The specification doesn't explain what precisely "at some future time" means, but in practice `async` functions use `scheduleMicrotask` to start their body.
+
+There are some benefits to delaying the execution of `async` function bodies:
+* It ensures that other code has the time to run. This helps to avoid some race conditions: by delaying the execution of the body, it's harder to accidentally interfere with the caller.
+* Seeing an `async` keyword made it easy to detect that a function would yield. This way `async` is mostly similar to `await`.
+
+However, this approach also comes with drawbacks:
+* Users tend to avoid `async` because it introduces latency.
+* Users of APIs start to rely on the `async` modifier, which is an implementation detail and should not be seen as part of the signature.
+* Many users don't expect that the function is delayed.
+* `async` functions cannot be used in many use-cases.
+
+#### Latency Issues
+When programs need to fetch data from the server they often use `async`. This makes sense: XMLHttpRequests are asynchronous, and waiting for them in an `async` function is the easiest way to deal with the corresponding futures. Often, programs start by fetching their resources as early as possible, so that work is done in parallel with the request.
+
+Some Googlers noticed big latency issues when using this approach. Because of the immediate yield of `async` functions, these requests weren't sent immediately, but the function was just bumped back in the microtask queue. Only later, when the microtask queue was finally executing the body, did it do the request. Often this delay was significant and noticeable.
+
+#### Relying on `async`
+Dart considers `async` an implementation detail. That is, as a user of an API it doesn't matter if a function body is implemented with `async` or without. As long as the function returns a `Future` it doesn't matter how the body of the function is implemented. This is the reason for having the `async` keyword after the function's signature, and not as part of it. Since `async` is not part of the type / signature, users may override `async` functions with synchronous functions, use closures of either implementation approach interchangeably, or refactor functions from one `async` to non-`async` or the inverse. In general, Dart wants our users to see `async` functions similar to non-`async` functions (from a user's point of view).
+
+Despite these efforts, we see users that take the `async` as part of the signature. Specifically, knowing that `async` immediately returns, is used as a part of the contract of a function. This is counter to how we envision `async` to be used: since `async` is not part of the signature / type, a user should be allowed to change the body from `async` to non-`async`.
+
+#### Expected Behavior is Not to Yield
+During readability reviews we have seen code where the authors clearly didn't expect the async function to yield. For example, we saw code like the following:
+
+``` dart
+class A {
+  bool isDoingRequest = false;
+
+  Future<String> doRequest(Uri link) async {
+    isDoingRequest = true;
+    return (await rpcCall()).data;
+  }
+
+  Future foo() async {
+    if (!isDoingRequest) {
+      var str = await doRequest(...);
+    }
+  }
+}
+```
+
+In this example, some other function is testing for the value of the `isDoingRequest`. If that field is set to false, it invokes `doRequest`, which, in the first line, sets the value to `true`. However, because of the asynchronous start, the field is not set immediately, but only in the next microtask. This means that other calls to foo might still see the `isDoingRequest` as `false` and initiate more requests.
+
+This mistake can happen easily when switching from synchronous functions to `async` functions. The code is much easier to read, but the additional delay could introduce substle bugs.
+
+Running synchronously also brings Dart in line with other languages, like Ecmascript. `<footnote>`C# also executes the body of async functions synchronously. However, C# doesn't guarantee, that `await` always yields. If a `Task` (the equivalent class for `Future`) is already completed, C# code may immediately continue running at the `await` point.`</footnote>
+
+### Required Changes
+Switching to synchronous starts of `async` functions requires changes in the specification and in our tools.
+
+The tool changes are relatively small, since few code touches the `async`/`await` functionality. A prototype CL for the VM and dart2js can be found here: https://dart-review.googlesource.com/c/sdk/+/5263
+
+The specification has already been updated with https://github.com/dart-lang/sdk/commit/2170830a9e41fa5b4067fde7bd44b76f5128c502
+
+### Migration
+Running `async` functions synchronously is a subtle change that might break programs in unexpected ways. Most programs don't depend on the additional `yield` on purpose, but some may depend on it by accident. We are aware that this change has the potential to cause big headaches.
+
+Once the patch is complete we intend to roll it out behind a flag. This way, users can start experimenting without being forced to switch in one go. With a bit of luck, most programs just continue working (or the reason for failures is obvious).
+
+If necessary, a full program search-and-replace can also bring back the old behavior:
+``` dart
+// Before:
+Future foo() async { doSomething(); }
+Future bar() async => doSomething();
+// After:
+Future foo() async { await null; doSomething(); }
+Future bar() async { await null; return doSomething(); }
+```
+This transformation is purely syntactic, and preserves the old behavior if done at the same time as the switch to the new semantics.
+Note that a slightly more advanced transformation would pay attention not to return a void value in the bar case above. However, it would be probably easier to just fix those by hand.
+
+Depending on the feedback and our own experience of migrating Google's whole codebase, we could also add a temporary flag to our tools that maintains the old behavior.
diff --git a/pkg/analysis_server/benchmark/integration/driver.dart b/pkg/analysis_server/benchmark/integration/driver.dart
index 505b573..da92839 100644
--- a/pkg/analysis_server/benchmark/integration/driver.dart
+++ b/pkg/analysis_server/benchmark/integration/driver.dart
@@ -91,7 +91,8 @@
    * field from the response.  If the server acknowledges the command with an
    * error response, the future will be completed with an error.
    */
-  Future send(String method, Map<String, dynamic> params) {
+  Future<Map<String, dynamic>> send(
+      String method, Map<String, dynamic> params) {
     return server.send(method, params);
   }
 
diff --git a/pkg/analysis_server/benchmark/integration/input_converter.dart b/pkg/analysis_server/benchmark/integration/input_converter.dart
index 99d2ec3..70999d5 100644
--- a/pkg/analysis_server/benchmark/integration/input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/input_converter.dart
@@ -257,7 +257,7 @@
     }
     if (json is Map) {
       Map<String, dynamic> result = new Map<String, dynamic>();
-      json.forEach((String origKey, value) {
+      json.forEach((origKey, value) {
         result[translateSrcPaths(origKey)] = translateSrcPaths(value);
       });
       return result;
diff --git a/pkg/analysis_server/benchmark/integration/operation.dart b/pkg/analysis_server/benchmark/integration/operation.dart
index bacb55e..75cf2a7 100644
--- a/pkg/analysis_server/benchmark/integration/operation.dart
+++ b/pkg/analysis_server/benchmark/integration/operation.dart
@@ -131,7 +131,7 @@
   bool _equal(expectedResult, actualResult) {
     if (expectedResult is Map && actualResult is Map) {
       if (expectedResult.length == actualResult.length) {
-        return expectedResult.keys.every((String key) {
+        return expectedResult.keys.every((key) {
           return key ==
                   'fileStamp' || // fileStamp values will not be the same across runs
               _equal(expectedResult[key], actualResult[key]);
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 42b0dbf..36dd89d 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -65,9 +65,8 @@
 import 'package:analyzer/src/util/glob.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
-import 'package:front_end/src/byte_store/file_byte_store.dart';
 import 'package:telemetry/crash_reporting.dart';
 import 'package:telemetry/telemetry.dart' as telemetry;
 import 'package:watcher/watcher.dart';
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 7a6c0b9..5199ef5 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -899,6 +899,12 @@
       String path, ContextInfo info, ChangeType changeType) {
     if (AnalysisEngine.isAnalysisOptionsFileName(path, pathContext)) {
       AnalysisDriver driver = info.analysisDriver;
+      if (driver == null) {
+        // I suspect that this happens as a result of a race condition: server
+        // has determined that the file (at [path]) is in a context, but hasn't
+        // yet created a driver for that context.
+        return;
+      }
       String contextRoot = info.folder.path;
       ContextBuilder builder =
           callbacks.createContextBuilder(info.folder, defaultContextOptions);
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
index 559316c..13027dd 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
@@ -59,17 +59,19 @@
       //
       Source source =
           driver.sourceFactory.forUri('package:$package/$package.dart');
-      Context context = resourceProvider.pathContext;
-      String packageRoot = context.dirname(context.dirname(source.fullName));
-      String pluginPath = _locator.findPlugin(packageRoot);
-      if (pluginPath != null) {
-        //
-        // Add the plugin to the context root.
-        //
-        // TODO(brianwilkerson) Do we need to wait for the plugin to be added?
-        // If we don't, then tests don't have any way to know when to expect
-        // that the list of plugins has been updated.
-        manager.addPluginToContextRoot(contextRoot, pluginPath);
+      if (source != null) {
+        Context context = resourceProvider.pathContext;
+        String packageRoot = context.dirname(context.dirname(source.fullName));
+        String pluginPath = _locator.findPlugin(packageRoot);
+        if (pluginPath != null) {
+          //
+          // Add the plugin to the context root.
+          //
+          // TODO(brianwilkerson) Do we need to wait for the plugin to be added?
+          // If we don't, then tests don't have any way to know when to expect
+          // that the list of plugins has been updated.
+          manager.addPluginToContextRoot(contextRoot, pluginPath);
+        }
       }
     }
   }
diff --git a/pkg/analysis_server/lib/src/protocol/protocol_internal.dart b/pkg/analysis_server/lib/src/protocol/protocol_internal.dart
index 1212a59..4fe3031 100644
--- a/pkg/analysis_server/lib/src/protocol/protocol_internal.dart
+++ b/pkg/analysis_server/lib/src/protocol/protocol_internal.dart
@@ -89,7 +89,8 @@
  * Compare the lists [listA] and [listB], using [itemEqual] to compare
  * list elements.
  */
-bool listEqual(List listA, List listB, bool itemEqual(a, b)) {
+bool listEqual<T1, T2>(
+    List<T1> listA, List<T2> listB, bool itemEqual(T1 a, T2 b)) {
   if (listA == null) {
     return listB == null;
   }
@@ -111,7 +112,7 @@
  * Compare the maps [mapA] and [mapB], using [valueEqual] to compare map
  * values.
  */
-bool mapEqual(Map mapA, Map mapB, bool valueEqual(a, b)) {
+bool mapEqual<K, V>(Map<K, V> mapA, Map<K, V> mapB, bool valueEqual(V a, V b)) {
   if (mapA == null) {
     return mapB == null;
   }
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 5f8f079..c6105cf 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -17,8 +17,8 @@
 import 'package:analyzer/src/generated/engine.dart' as engine;
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 
 import 'mock_sdk.dart';
 
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test.dart b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
index ccd8350..ceabbce 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
@@ -955,6 +955,6 @@
   void test_valueOf_unknown() {
     expect(() {
       new HighlightRegionType('no-such-type');
-    }, throws);
+    }, throwsException);
   }
 }
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart b/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
index a522793..df9b59d 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
@@ -1106,6 +1106,6 @@
   void test_valueOf_unknown() {
     expect(() {
       new HighlightRegionType('no-such-type');
-    }, throws);
+    }, throwsException);
   }
 }
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index ddabf0e..3fe95f9 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -26,8 +26,8 @@
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/summary/summary_file_builder.dart';
 import 'package:analyzer/src/util/glob.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:linter/src/rules.dart';
 import 'package:linter/src/rules/avoid_as.dart';
 import 'package:path/path.dart' as path;
diff --git a/pkg/analysis_server/test/integration/support/integration_tests.dart b/pkg/analysis_server/test/integration/support/integration_tests.dart
index 972e27e..fedc353 100644
--- a/pkg/analysis_server/test/integration/support/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/support/integration_tests.dart
@@ -459,7 +459,8 @@
    * the [Completer] objects which should be completed when acknowledgement is
    * received.
    */
-  final Map<String, Completer> _pendingCommands = <String, Completer>{};
+  final Map<String, Completer<Map<String, dynamic>>> _pendingCommands =
+      <String, Completer<Map<String, dynamic>>>{};
 
   /**
    * Number which should be used to compute the 'id' to send in the next command
@@ -580,7 +581,7 @@
       if (messageAsMap.containsKey('id')) {
         outOfTestExpect(messageAsMap['id'], isString);
         String id = message['id'];
-        Completer completer = _pendingCommands[id];
+        Completer<Map<String, dynamic>> completer = _pendingCommands[id];
         if (completer == null) {
           fail('Unexpected response from server: id=$id');
         } else {
@@ -625,7 +626,8 @@
    * field from the response.  If the server acknowledges the command with an
    * error response, the future will be completed with an error.
    */
-  Future send(String method, Map<String, dynamic> params) {
+  Future<Map<String, dynamic>> send(
+      String method, Map<String, dynamic> params) {
     String id = '${_nextId++}';
     Map<String, dynamic> command = <String, dynamic>{
       'id': id,
@@ -634,7 +636,8 @@
     if (params != null) {
       command['params'] = params;
     }
-    Completer completer = new Completer();
+    Completer<Map<String, dynamic>> completer =
+        new Completer<Map<String, dynamic>>();
     _pendingCommands[id] = completer;
     String line = JSON.encode(command);
     _recordStdio('SEND: $line');
@@ -916,7 +919,7 @@
    * substructure did not match.
    */
   checkSubstructure(item, Matcher matcher, List<MismatchDescriber> mismatches,
-      Description describeSubstructure(Description)) {
+      Description describeSubstructure(Description description)) {
     Map subState = {};
     if (!matcher.matches(item, subState)) {
       mismatches.add((Description mismatchDescription) {
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index b4e10a5..9a1717a 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
@@ -84,7 +84,7 @@
     expect(new ElementKind(ElementKind.UNKNOWN.name), ElementKind.UNKNOWN);
     expect(() {
       new ElementKind('no-such-kind');
-    }, throws);
+    }, throwsException);
   }
 
   void test_toString() {
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 1edb624..df05a2b 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -182,7 +182,7 @@
         if (expectedResult == null) {
           expect(() {
             convert(engineValue);
-          }, throws);
+          }, throwsException);
         } else {
           ApiEnum apiValue = convert(engineValue);
           expect(apiValue, equals(expectedResult));
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index b597269..a1edf8e 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -2433,6 +2433,7 @@
 ''');
   }
 
+  @failingTest
   test_createLocalVariable_functionType_synthetic() async {
     await resolveTestUnit('''
 foo(f(int p)) {}
@@ -2647,6 +2648,7 @@
 ''');
   }
 
+  @failingTest
   test_createMissingOverrides_functionTypedParameter() async {
     await resolveTestUnit('''
 abstract class A {
diff --git a/pkg/analysis_server/test/services/correction/levenshtein_test.dart b/pkg/analysis_server/test/services/correction/levenshtein_test.dart
index e398f83..c344a4c 100644
--- a/pkg/analysis_server/test/services/correction/levenshtein_test.dart
+++ b/pkg/analysis_server/test/services/correction/levenshtein_test.dart
@@ -43,16 +43,16 @@
   void test_negativeThreshold() {
     expect(() {
       levenshtein('', '', -5);
-    }, throws);
+    }, throwsArgumentError);
   }
 
   void test_null() {
     expect(() {
       levenshtein('', null, 5);
-    }, throws);
+    }, throwsArgumentError);
     expect(() {
       levenshtein(null, '', 5);
-    }, throws);
+    }, throwsArgumentError);
   }
 
   void test_same() {
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 3838ba7..aa75cad 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -14,8 +14,8 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index 2f7f6e7..c9665cd 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -88,7 +88,7 @@
   }
 
   test_stop_notRunning() {
-    expect(() => plugin.stop(), throwsA(new isInstanceOf<StateError>()));
+    expect(() => plugin.stop(), throwsStateError);
   }
 
   test_stop_running() async {
@@ -174,7 +174,7 @@
   }
 
   test_stop_notRunning() {
-    expect(() => plugin.stop(), throwsA(new isInstanceOf<StateError>()));
+    expect(() => plugin.stop(), throwsStateError);
   }
 
   test_stop_running() async {
@@ -631,7 +631,7 @@
   }
 
   test_stop_notRunning() {
-    expect(() => session.stop(), throwsA(new isInstanceOf<StateError>()));
+    expect(() => session.stop(), throwsStateError);
   }
 
   test_stop_running() async {
diff --git a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
index 0849ca5..db7dc41 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
@@ -17,8 +17,8 @@
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -81,6 +81,25 @@
     expect(manager.addedContextRoots, hasLength(1));
   }
 
+  test_addedDriver_missingPackage() async {
+    String pkg1Path = resourceProvider.convertPath('/pkg1');
+    resourceProvider.newFile(
+        resourceProvider.convertPath('/pkg1/lib/test1.dart'), '');
+
+    ContextRoot contextRoot = new ContextRoot(pkg1Path, []);
+    TestDriver driver = new TestDriver(resourceProvider, contextRoot);
+    driver.analysisOptions.enabledPluginNames = ['pkg3'];
+    watcher.addedDriver(driver, contextRoot);
+    expect(manager.addedContextRoots, isEmpty);
+    //
+    // Wait until the timer associated with the driver's FileSystemState is
+    // guaranteed to have expired and the list of changed files will have been
+    // delivered.
+    //
+    await new Future.delayed(new Duration(seconds: 1));
+    expect(manager.addedContextRoots, isEmpty);
+  }
+
   void test_creation() {
     expect(watcher.resourceProvider, resourceProvider);
     expect(watcher.manager, manager);
diff --git a/pkg/analysis_server/tool/spec/from_html.dart b/pkg/analysis_server/tool/spec/from_html.dart
index 1323da9..26c6eb9 100644
--- a/pkg/analysis_server/tool/spec/from_html.dart
+++ b/pkg/analysis_server/tool/spec/from_html.dart
@@ -121,7 +121,7 @@
       dom.Element element, List<String> requiredAttributes, String context,
       {List<String> optionalAttributes: const []}) {
     Set<String> attributesFound = new Set<String>();
-    element.attributes.forEach((String name, String value) {
+    element.attributes.forEach((name, value) {
       if (!requiredAttributes.contains(name) &&
           !optionalAttributes.contains(name)) {
         throw new Exception(
diff --git a/pkg/analyzer/lib/context/context_root.dart b/pkg/analyzer/lib/context/context_root.dart
index 2596ced..a728860 100644
--- a/pkg/analyzer/lib/context/context_root.dart
+++ b/pkg/analyzer/lib/context/context_root.dart
@@ -74,7 +74,7 @@
    * Compare the lists [listA] and [listB], using [itemEqual] to compare
    * list elements.
    */
-  bool _listEqual(List listA, List listB, bool itemEqual(a, b)) {
+  bool _listEqual<T>(List<T> listA, List<T> listB, bool itemEqual(T a, T b)) {
     if (listA == null) {
       return listB == null;
     }
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 6e7ab64..d91dbd3 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -558,6 +558,9 @@
 
   @override
   Folder resolveSymbolicLinksSync() => this;
+
+  @override
+  Uri toUri() => _provider.pathContext.toUri(path + '/');
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 68133b8..4845685 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -33,8 +33,8 @@
 import 'package:analyzer/src/summary/summary_sdk.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:args/args.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:package_config/packages.dart';
 import 'package:package_config/packages_file.dart';
 import 'package:package_config/src/packages_impl.dart';
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 73e8165..8036241 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -279,6 +279,7 @@
         _notEqual(this._options.lintRules, options.lintRules) ||
         this._options.preserveComments != options.preserveComments ||
         this._options.strongMode != options.strongMode ||
+        this._options.useFastaParser != options.useFastaParser ||
         this._options.enableAssertInitializer !=
             options.enableAssertInitializer ||
         this._options.enableLazyAssignmentOperators !=
@@ -324,6 +325,7 @@
       _typeSystem = null;
     }
     this._options.strongMode = options.strongMode;
+    this._options.useFastaParser = options.useFastaParser;
     this._options.trackCacheDependencies = options.trackCacheDependencies;
     this._options.disableCacheFlushing = options.disableCacheFlushing;
     this._options.patchPaths = options.patchPaths;
diff --git a/pkg/analyzer/lib/src/dart/analysis/byte_store.dart b/pkg/analyzer/lib/src/dart/analysis/byte_store.dart
index 1b04134..1ad08cc 100644
--- a/pkg/analyzer/lib/src/dart/analysis/byte_store.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/byte_store.dart
@@ -5,5 +5,5 @@
 // This library re-exports the parts of front_end's byte_store.dart whose API is
 // stable enough to be relied upon by clients.
 
-export 'package:front_end/src/byte_store/byte_store.dart'
+export 'package:front_end/byte_store.dart'
     show ByteStore, MemoryByteStore, MemoryCachingByteStore;
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index be8792e..36f43661 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -20,6 +20,7 @@
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/analysis/file_tracker.dart';
 import 'package:analyzer/src/dart/analysis/index.dart';
+import 'package:analyzer/src/dart/analysis/kernel_context.dart';
 import 'package:analyzer/src/dart/analysis/library_analyzer.dart';
 import 'package:analyzer/src/dart/analysis/library_context.dart';
 import 'package:analyzer/src/dart/analysis/search.dart';
@@ -39,9 +40,9 @@
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/api_signature.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:meta/meta.dart';
 
 /**
@@ -101,6 +102,11 @@
   static int allowedNumberOfContextsToWrite = 10;
 
   /**
+   * Whether kernel should be used to resynthesize elements.
+   */
+  final bool enableKernelDriver;
+
+  /**
    * The scheduler that schedules analysis work in this, and possibly other
    * analysis drivers.
    */
@@ -311,7 +317,8 @@
       this.contextRoot,
       SourceFactory sourceFactory,
       this._analysisOptions,
-      {PackageBundle sdkBundle,
+      {this.enableKernelDriver: false,
+      PackageBundle sdkBundle,
       this.disableChangesAndCacheAllResults: false,
       SummaryDataStore externalSummaries})
       : _logger = logger,
@@ -1087,16 +1094,41 @@
     // We need the fully resolved unit, or the result is not cached.
     return _logger.runAsync('Compute analysis result for $path', () async {
       try {
-        LibraryContext libraryContext = await _createLibraryContext(library);
+        LibraryContext libraryContext;
+        KernelContext kernelContext;
         try {
           _testView.numOfAnalyzedLibraries++;
-          LibraryAnalyzer analyzer = new LibraryAnalyzer(
-              analysisOptions,
-              declaredVariables,
-              sourceFactory,
-              _fsState,
-              libraryContext.store,
-              library);
+
+          LibraryAnalyzer analyzer;
+          if (enableKernelDriver) {
+            kernelContext = await KernelContext.forSingleLibrary(
+                library,
+                _logger,
+                _byteStore,
+                _analysisOptions,
+                declaredVariables,
+                _sourceFactory,
+                fsState);
+            analyzer = new LibraryAnalyzer(
+                analysisOptions,
+                declaredVariables,
+                sourceFactory,
+                kernelContext.isLibraryUri,
+                kernelContext.analysisContext,
+                kernelContext.resynthesizer,
+                library);
+          } else {
+            libraryContext = await _createLibraryContext(library);
+            analyzer = new LibraryAnalyzer(
+                analysisOptions,
+                declaredVariables,
+                sourceFactory,
+                libraryContext.isLibraryUri,
+                libraryContext.analysisContext,
+                libraryContext.resynthesizer,
+                library);
+          }
+
           Map<FileState, UnitAnalysisResult> results = analyzer.analyze();
 
           List<int> bytes;
@@ -1131,7 +1163,8 @@
           }
           return result;
         } finally {
-          libraryContext.dispose();
+          libraryContext?.dispose();
+          kernelContext?.dispose();
         }
       } catch (exception, stackTrace) {
         String contextKey =
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart b/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart
index ab41432..84090be 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_byte_store.dart
@@ -5,5 +5,4 @@
 // This library re-exports the parts of front_end's file_byte_store.dart whose
 // API is stable enough to be relied upon by clients.
 
-export 'package:front_end/src/byte_store/file_byte_store.dart'
-    show FileByteStore;
+export 'package:front_end/byte_store.dart' show FileByteStore;
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 43a9900..1b197c8 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -14,8 +14,6 @@
 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
-import 'package:analyzer/src/fasta/ast_builder.dart' as fasta;
-import 'package:analyzer/src/fasta/mock_element.dart' as fasta;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -28,12 +26,9 @@
 import 'package:analyzer/src/summary/summarize_ast.dart';
 import 'package:convert/convert.dart';
 import 'package:crypto/crypto.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/api_signature.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
-import 'package:front_end/src/fasta/builder/builder.dart' as fasta;
-import 'package:front_end/src/fasta/parser/parser.dart' as fasta;
-import 'package:front_end/src/fasta/scanner.dart' as fasta;
 import 'package:front_end/src/fasta/scanner/token.dart';
 import 'package:meta/meta.dart';
 
@@ -80,8 +75,6 @@
  * should be called.
  */
 class FileState {
-  static const bool USE_FASTA_PARSER = false;
-
   final FileSystemState _fsState;
 
   /**
@@ -108,7 +101,6 @@
   final bool isInExternalSummaries;
 
   bool _exists;
-  List<int> _contentBytes;
   String _content;
   String _contentHash;
   LineInfo _lineInfo;
@@ -413,13 +405,6 @@
       _exists = false;
     }
 
-    if (USE_FASTA_PARSER) {
-      var bytes = UTF8.encode(_content);
-      _contentBytes = new Uint8List(bytes.length + 1);
-      _contentBytes.setRange(0, bytes.length, bytes);
-      _contentBytes[_contentBytes.length - 1] = 0;
-    }
-
     // Compute the content hash.
     List<int> contentBytes = UTF8.encode(_content);
     {
@@ -571,61 +556,26 @@
 
   CompilationUnit _parse(AnalysisErrorListener errorListener) {
     AnalysisOptions analysisOptions = _fsState._analysisOptions;
+    CharSequenceReader reader = new CharSequenceReader(content);
+    Scanner scanner = new Scanner(source, reader, errorListener);
+    scanner.scanGenericMethodComments = analysisOptions.strongMode;
+    Token token = PerformanceStatistics.scan.makeCurrentWhile(() {
+      return scanner.tokenize();
+    });
+    LineInfo lineInfo = new LineInfo(scanner.lineStarts);
 
-    if (USE_FASTA_PARSER) {
-      try {
-        fasta.ScannerResult scanResult =
-            PerformanceStatistics.scan.makeCurrentWhile(() {
-          return fasta.scan(
-            _contentBytes,
-            includeComments: true,
-            scanGenericMethodComments: analysisOptions.strongMode,
-          );
-        });
+    bool useFasta = analysisOptions.useFastaParser;
+    Parser parser = new Parser(source, errorListener, useFasta: useFasta);
+    parser.enableAssertInitializer = analysisOptions.enableAssertInitializer;
+    parser.parseGenericMethodComments = analysisOptions.strongMode;
+    CompilationUnit unit = parser.parseCompilationUnit(token);
+    unit.lineInfo = lineInfo;
 
-        var astBuilder = new fasta.AstBuilder(
-            new ErrorReporter(errorListener, source),
-            null,
-            null,
-            new fasta.Scope.top(isModifiable: true),
-            true,
-            uri);
-        astBuilder.parseGenericMethodComments = analysisOptions.strongMode;
+    // StringToken uses a static instance of StringCanonicalizer, so we need
+    // to clear it explicitly once we are done using it for this file.
+    StringToken.canonicalizer.clear();
 
-        var parser = new fasta.Parser(astBuilder);
-        astBuilder.parser = parser;
-        parser.parseUnit(scanResult.tokens);
-        var unit = astBuilder.pop() as CompilationUnit;
-
-        LineInfo lineInfo = new LineInfo(scanResult.lineStarts);
-        unit.lineInfo = lineInfo;
-        return unit;
-      } catch (e, st) {
-        print(e);
-        print(st);
-        rethrow;
-      }
-    } else {
-      CharSequenceReader reader = new CharSequenceReader(content);
-      Scanner scanner = new Scanner(source, reader, errorListener);
-      scanner.scanGenericMethodComments = analysisOptions.strongMode;
-      Token token = PerformanceStatistics.scan.makeCurrentWhile(() {
-        return scanner.tokenize();
-      });
-      LineInfo lineInfo = new LineInfo(scanner.lineStarts);
-
-      Parser parser = new Parser(source, errorListener);
-      parser.enableAssertInitializer = analysisOptions.enableAssertInitializer;
-      parser.parseGenericMethodComments = analysisOptions.strongMode;
-      CompilationUnit unit = parser.parseCompilationUnit(token);
-      unit.lineInfo = lineInfo;
-
-      // StringToken uses a static instance of StringCanonicalizer, so we need
-      // to clear it explicitly once we are done using it for this file.
-      StringToken.canonicalizer.clear();
-
-      return unit;
-    }
+    return unit;
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/analysis/kernel_context.dart b/pkg/analyzer/lib/src/dart/analysis/kernel_context.dart
new file mode 100644
index 0000000..2aaccca8
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/kernel_context.dart
@@ -0,0 +1,206 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:analyzer/context/declared_variables.dart';
+import 'package:analyzer/dart/element/element.dart' show CompilationUnitElement;
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisContext, AnalysisEngine, AnalysisOptions;
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/kernel/resynthesize.dart';
+import 'package:analyzer/src/summary/summary_sdk.dart';
+import 'package:front_end/byte_store.dart';
+import 'package:front_end/compiler_options.dart';
+import 'package:front_end/file_system.dart';
+import 'package:front_end/src/base/libraries_specification.dart';
+import 'package:front_end/src/base/performace_logger.dart';
+import 'package:front_end/src/base/processed_options.dart';
+import 'package:front_end/src/fasta/uri_translator_impl.dart';
+import 'package:front_end/src/incremental/kernel_driver.dart';
+import 'package:kernel/ast.dart' as kernel;
+import 'package:kernel/target/targets.dart';
+import 'package:package_config/packages.dart';
+import 'package:package_config/src/packages_impl.dart';
+
+/**
+ * Support for resynthesizing element model from Kernel.
+ */
+class KernelContext {
+  /**
+   * The [AnalysisContext] which is used to do the analysis.
+   */
+  final AnalysisContext analysisContext;
+
+  /**
+   * The resynthesizer that resynthesizes elements in [analysisContext].
+   */
+  final ElementResynthesizer resynthesizer;
+
+  KernelContext._(this.analysisContext, this.resynthesizer);
+
+  /**
+   * Computes a [CompilationUnitElement] for the given library/unit pair.
+   */
+  CompilationUnitElement computeUnitElement(
+      Source librarySource, Source unitSource) {
+    String libraryUri = librarySource.uri.toString();
+    String unitUri = unitSource.uri.toString();
+    return resynthesizer.getElement(
+        new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
+  }
+
+  /**
+   * Cleans up any persistent resources used by this [KernelContext].
+   *
+   * Should be called once the [KernelContext] is no longer needed.
+   */
+  void dispose() {
+    analysisContext.dispose();
+  }
+
+  /**
+   * Return `true` if the given [uri] is known to be a library.
+   */
+  bool isLibraryUri(Uri uri) {
+    // TODO(scheglov) implement
+    return true;
+//    String uriStr = uri.toString();
+//    return store.unlinkedMap[uriStr]?.isPartOf == false;
+  }
+
+  /**
+   * Create a [KernelContext] which is prepared to analyze [targetLibrary].
+   */
+  static Future<KernelContext> forSingleLibrary(
+      FileState targetLibrary,
+      PerformanceLog logger,
+      ByteStore byteStore,
+      AnalysisOptions analysisOptions,
+      DeclaredVariables declaredVariables,
+      SourceFactory sourceFactory,
+      FileSystemState fsState) async {
+    return logger.runAsync('Create kernel context', () async {
+      // Prepare SDK libraries.
+      Map<String, LibraryInfo> dartLibraries = {};
+      {
+        DartSdk dartSdk = sourceFactory.dartSdk;
+        dartSdk.sdkLibraries.forEach((sdkLibrary) {
+          var name = Uri.parse(sdkLibrary.shortName).path;
+          var path = dartSdk.mapDartUri(sdkLibrary.shortName).fullName;
+          dartLibraries[name] =
+              new LibraryInfo(name, Uri.parse('file://$path'), const []);
+        });
+      }
+
+      // Prepare packages.
+      Packages packages = Packages.noPackages;
+      {
+        Map<String, List<Folder>> packageMap = sourceFactory.packageMap;
+        if (packageMap != null) {
+          var map = <String, Uri>{};
+          for (var name in packageMap.keys) {
+            map[name] = packageMap[name].first.toUri();
+          }
+          packages = new MapPackages(map);
+        }
+      }
+
+      var uriTranslator = new UriTranslatorImpl(
+          new TargetLibrariesSpecification('none', dartLibraries), packages);
+      var options = new ProcessedOptions(new CompilerOptions()
+        ..target = new NoneTarget(
+            new TargetFlags(strongMode: analysisOptions.strongMode))
+        ..reportMessages = false
+        ..logger = logger
+        ..fileSystem = new _FileSystemAdaptor(fsState)
+        ..byteStore = byteStore);
+      var driver = new KernelDriver(options, uriTranslator);
+
+      Uri targetUri = targetLibrary.uri;
+      KernelResult kernelResult = await driver.getKernel(targetUri);
+
+      // Remember Kernel libraries required to resynthesize the target.
+      var libraryMap = <String, kernel.Library>{};
+      for (var cycleResult in kernelResult.results) {
+        for (var library in cycleResult.kernelLibraries) {
+          String uriStr = library.importUri.toString();
+          libraryMap[uriStr] = library;
+        }
+      }
+
+      // Create and configure a new context.
+      AnalysisContextImpl analysisContext =
+          AnalysisEngine.instance.createAnalysisContext();
+      analysisContext.useSdkCachePartition = false;
+      analysisContext.analysisOptions = analysisOptions;
+      analysisContext.declaredVariables.addAll(declaredVariables);
+      analysisContext.sourceFactory = sourceFactory.clone();
+
+      // Create the resynthesizer bound to the analysis context.
+      var resynthesizer = new KernelResynthesizer(
+          analysisContext, kernelResult.types, libraryMap);
+
+      analysisContext.typeProvider = _buildTypeProvider(resynthesizer);
+      return new KernelContext._(analysisContext, resynthesizer);
+    });
+  }
+
+  static SummaryTypeProvider _buildTypeProvider(
+      KernelResynthesizer resynthesizer) {
+    var coreLibrary = resynthesizer.getLibrary('dart:core');
+    var asyncLibrary = resynthesizer.getLibrary('dart:async');
+    SummaryTypeProvider summaryTypeProvider = new SummaryTypeProvider();
+    summaryTypeProvider.initializeCore(coreLibrary);
+    summaryTypeProvider.initializeAsync(asyncLibrary);
+    return summaryTypeProvider;
+  }
+}
+
+class _FileSystemAdaptor implements FileSystem {
+  final FileSystemState fsState;
+
+  _FileSystemAdaptor(this.fsState);
+
+  @override
+  FileSystemEntity entityForUri(Uri uri) {
+    if (uri.isScheme('file')) {
+      var file = fsState.getFileForPath(uri.path);
+      return new _FileSystemEntityAdaptor(uri, file);
+    } else {
+      throw new ArgumentError(
+          'Only file:// URIs are supported, but $uri is given.');
+    }
+  }
+}
+
+class _FileSystemEntityAdaptor implements FileSystemEntity {
+  final Uri uri;
+  final FileState file;
+
+  _FileSystemEntityAdaptor(this.uri, this.file);
+
+  @override
+  Future<bool> exists() async {
+    return file.exists;
+  }
+
+  @override
+  Future<List<int>> readAsBytes() async {
+    // TODO(scheglov) Optimize.
+    return UTF8.encode(file.content);
+  }
+
+  @override
+  Future<String> readAsString() async {
+    return file.content;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 8550184..7be083f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -14,6 +14,8 @@
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/constant/evaluation.dart';
 import 'package:analyzer/src/dart/constant/utilities.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/error/pending_error.dart';
 import 'package:analyzer/src/generated/declaration_resolver.dart';
@@ -22,7 +24,6 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
 import 'package:front_end/src/dependency_walker.dart';
@@ -34,13 +35,13 @@
   final AnalysisOptions _analysisOptions;
   final DeclaredVariables _declaredVariables;
   final SourceFactory _sourceFactory;
-  final FileSystemState _fsState;
-  final SummaryDataStore _store;
   final FileState _library;
 
-  TypeProvider _typeProvider;
-  AnalysisContextImpl _context;
-  StoreBasedSummaryResynthesizer _resynthesizer;
+  final bool Function(Uri) _isLibraryUri;
+  final AnalysisContextImpl _context;
+  final ElementResynthesizer _resynthesizer;
+  final TypeProvider _typeProvider;
+
   LibraryElement _libraryElement;
 
   final Map<FileState, LineInfo> _fileToLineInfo = {};
@@ -53,8 +54,15 @@
   final Map<FileState, List<PendingError>> _fileToPendingErrors = {};
   final List<ConstantEvaluationTarget> _constants = [];
 
-  LibraryAnalyzer(this._analysisOptions, this._declaredVariables,
-      this._sourceFactory, this._fsState, this._store, this._library);
+  LibraryAnalyzer(
+      this._analysisOptions,
+      this._declaredVariables,
+      this._sourceFactory,
+      this._isLibraryUri,
+      this._context,
+      this._resynthesizer,
+      this._library)
+      : _typeProvider = _context.typeProvider;
 
   /**
    * Compute analysis results for all units of the library.
@@ -79,16 +87,9 @@
       _resolveUriBasedDirectives(file, unit);
     });
 
-    _createAnalysisContext();
-
     try {
-      _resynthesizer = new StoreBasedSummaryResynthesizer(
-          _context, _sourceFactory, _analysisOptions.strongMode, _store);
-      _typeProvider = _resynthesizer.typeProvider;
-      _context.typeProvider = _typeProvider;
-      _resynthesizer.finishCoreAsyncLibraries();
-
-      _libraryElement = _resynthesizer.getLibraryElement(_library.uriStr);
+      _libraryElement = _resynthesizer
+          .getElement(new ElementLocationImpl.con3([_library.uriStr]));
 
       _resolveDirectives(units);
 
@@ -305,16 +306,6 @@
     unit.accept(errorVerifier);
   }
 
-  void _createAnalysisContext() {
-    AnalysisContextImpl analysisContext =
-        AnalysisEngine.instance.createAnalysisContext();
-    analysisContext.analysisOptions = _analysisOptions;
-    analysisContext.declaredVariables.addAll(_declaredVariables);
-    analysisContext.sourceFactory = _sourceFactory.clone();
-    analysisContext.contentCache = new _ContentCacheWrapper(_fsState);
-    this._context = analysisContext;
-  }
-
   /**
    * Return a subset of the given [errors] that are not marked as ignored in
    * the [file].
@@ -382,8 +373,7 @@
    * Return `true` if the given [source] is a library.
    */
   bool _isLibrarySource(Source source) {
-    String uriStr = source.uri.toString();
-    return _store.unlinkedMap[uriStr]?.isPartOf == false;
+    return _isLibraryUri(source.uri);
   }
 
   /**
@@ -756,51 +746,6 @@
 }
 
 /**
- * [ContentCache] wrapper around [FileContentOverlay].
- */
-class _ContentCacheWrapper implements ContentCache {
-  final FileSystemState fsState;
-
-  _ContentCacheWrapper(this.fsState);
-
-  @override
-  void accept(ContentCacheVisitor visitor) {
-    throw new UnimplementedError();
-  }
-
-  @override
-  String getContents(Source source) {
-    return _getFileForSource(source).content;
-  }
-
-  @override
-  bool getExists(Source source) {
-    if (fsState.externalSummaries != null) {
-      String uriStr = source.uri.toString();
-      if (fsState.externalSummaries.hasUnlinkedUnit(uriStr)) {
-        return true;
-      }
-    }
-    return _getFileForSource(source).exists;
-  }
-
-  @override
-  int getModificationStamp(Source source) {
-    return _getFileForSource(source).exists ? 0 : -1;
-  }
-
-  @override
-  String setContents(Source source, String contents) {
-    throw new UnimplementedError();
-  }
-
-  FileState _getFileForSource(Source source) {
-    String path = source.fullName;
-    return fsState.getFileForPath(path);
-  }
-}
-
-/**
  * Either the name or the source associated with a part-of directive.
  */
 class _NameOrSource {
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index f9fa980..77e7370 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -3,10 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/context/declared_variables.dart';
-import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart'
     show CompilationUnitElement, LibraryElement;
-import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
@@ -19,8 +17,8 @@
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/link.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 
 /**
  * Context information necessary to analyze one or more libraries within an
@@ -35,12 +33,12 @@
   /**
    * The [AnalysisContext] which is used to do the analysis.
    */
-  final AnalysisContext _analysisContext;
+  final AnalysisContext analysisContext;
 
   /**
-   * The resynthesizer that resynthesizes elements in [_analysisContext].
+   * The resynthesizer that resynthesizes elements in [analysisContext].
    */
-  final ElementResynthesizer _resynthesizer;
+  final ElementResynthesizer resynthesizer;
 
   /**
    * Create a [LibraryContext] which is prepared to analyze [targetLibrary].
@@ -147,7 +145,7 @@
     });
   }
 
-  LibraryContext._(this.store, this._analysisContext, this._resynthesizer);
+  LibraryContext._(this.store, this.analysisContext, this.resynthesizer);
 
   /**
    * Computes a [CompilationUnitElement] for the given library/unit pair.
@@ -156,7 +154,7 @@
       Source librarySource, Source unitSource) {
     String libraryUri = librarySource.uri.toString();
     String unitUri = unitSource.uri.toString();
-    return _resynthesizer.getElement(
+    return resynthesizer.getElement(
         new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
   }
 
@@ -166,7 +164,15 @@
    * Should be called once the [LibraryContext] is no longer needed.
    */
   void dispose() {
-    _analysisContext.dispose();
+    analysisContext.dispose();
+  }
+
+  /**
+   * Return `true` if the given [uri] is known to be a library.
+   */
+  bool isLibraryUri(Uri uri) {
+    String uriStr = uri.toString();
+    return store.unlinkedMap[uriStr]?.isPartOf == false;
   }
 
   /**
@@ -207,17 +213,6 @@
 }
 
 /**
- * Container object holding the result of a call to
- * [LibraryContext.resolveUnit].
- */
-class ResolutionResult {
-  final CompilationUnit resolvedUnit;
-  final List<AnalysisError> errors;
-
-  ResolutionResult(this.resolvedUnit, this.errors);
-}
-
-/**
  * [ContentCache] wrapper around [FileContentOverlay].
  */
 class _ContentCacheWrapper implements ContentCache {
@@ -241,7 +236,8 @@
       return true;
     }
     String uriStr = source.uri.toString();
-    if (fsState.externalSummaries.hasUnlinkedUnit(uriStr)) {
+    if (fsState.externalSummaries != null &&
+        fsState.externalSummaries.hasUnlinkedUnit(uriStr)) {
       return true;
     }
     return _getFileForSource(source).exists;
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 1a01875..fb2b433 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -9199,7 +9199,7 @@
     } else if (_type != null) {
       return _type.beginToken;
     }
-    return identifier.beginToken;
+    return identifier?.beginToken;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index 8c5e1b1..01fa6e2 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -1447,8 +1447,9 @@
     _visitChildren(holder, node);
     ParameterElementImpl element = node.element;
     element.metadata = _createElementAnnotations(node.metadata);
-    element.parameters = holder.parameters;
-    element.typeParameters = holder.typeParameters;
+    if (node.parameters != null) {
+      _createGenericFunctionType(element, holder);
+    }
     holder.validate();
     return null;
   }
@@ -1476,8 +1477,7 @@
     _visitChildren(holder, node);
     ParameterElementImpl element = node.element;
     element.metadata = _createElementAnnotations(node.metadata);
-    element.parameters = holder.parameters;
-    element.typeParameters = holder.typeParameters;
+    _createGenericFunctionType(element, holder);
     holder.validate();
     return null;
   }
@@ -1556,6 +1556,22 @@
   }
 
   /**
+   * If the [holder] has type parameters or formal parameters for the
+   * given [parameter], wrap them into a new [GenericFunctionTypeElementImpl]
+   * and set [FunctionTypeImpl] for the [parameter].
+   */
+  void _createGenericFunctionType(
+      ParameterElementImpl parameter, ElementHolder holder) {
+    var typeElement = new GenericFunctionTypeElementImpl.forOffset(-1);
+    typeElement.enclosingElement = parameter;
+    typeElement.typeParameters = holder.typeParameters;
+    typeElement.parameters = holder.parameters;
+    var type = new FunctionTypeImpl(typeElement);
+    typeElement.type = type;
+    parameter.type = type;
+  }
+
+  /**
    * Return the body of the function that contains the given [parameter], or
    * `null` if no function body could be found.
    */
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 7b8572d..f1c68d5 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -615,7 +615,7 @@
       return _kernel.documentationComment;
     }
     if (_unlinkedClass != null) {
-      return _unlinkedClass?.documentationComment?.text;
+      return _unlinkedClass.documentationComment?.text;
     }
     return super.documentationComment;
   }
@@ -2037,7 +2037,7 @@
       return _kernelEnumValue.documentationComment;
     }
     if (_unlinkedEnumValue != null) {
-      return _unlinkedEnumValue?.documentationComment?.text;
+      return _unlinkedEnumValue.documentationComment?.text;
     }
     return super.documentationComment;
   }
@@ -3756,7 +3756,7 @@
       return _kernel.documentationComment;
     }
     if (_unlinkedEnum != null) {
-      return _unlinkedEnum?.documentationComment?.text;
+      return _unlinkedEnum.documentationComment?.text;
     }
     return super.documentationComment;
   }
@@ -3809,6 +3809,10 @@
 
   @override
   List<ElementAnnotation> get metadata {
+    if (_kernel != null) {
+      _metadata ??=
+          enclosingUnit._kernelContext.buildAnnotations(_kernel.annotations);
+    }
     if (_unlinkedEnum != null) {
       return _metadata ??=
           _buildAnnotations(enclosingUnit, _unlinkedEnum.annotations);
@@ -4043,7 +4047,7 @@
       return _kernel.documentationComment;
     }
     if (serializedExecutable != null) {
-      return serializedExecutable?.documentationComment?.text;
+      return serializedExecutable.documentationComment?.text;
     }
     return super.documentationComment;
   }
@@ -4738,7 +4742,9 @@
 
   @override
   DartType get type {
-    if (_unlinkedParam != null && _unlinkedParam.type == null) {
+    if (_unlinkedParam != null &&
+        _unlinkedParam.type == null &&
+        field != null) {
       _type ??= field?.type ?? DynamicTypeImpl.instance;
     }
     return super.type;
@@ -5085,7 +5091,7 @@
   @override
   String get documentationComment {
     if (_unlinkedTypedef != null) {
-      return _unlinkedTypedef?.documentationComment?.text;
+      return _unlinkedTypedef.documentationComment?.text;
     }
     return super.documentationComment;
   }
@@ -5531,7 +5537,7 @@
   @override
   String get documentationComment {
     if (_unlinkedTypedef != null) {
-      return _unlinkedTypedef?.documentationComment?.text;
+      return _unlinkedTypedef.documentationComment?.text;
     }
     return super.documentationComment;
   }
@@ -5928,6 +5934,9 @@
 
   @override
   bool get isDeferred {
+    if (_kernel != null) {
+      return _kernel.isDeferred;
+    }
     if (_unlinkedImport != null) {
       return _unlinkedImport.isDeferred;
     }
@@ -6452,8 +6461,11 @@
 
   @override
   String get documentationComment {
+    if (_kernelContext != null) {
+      return _kernelContext.library.documentationComment;
+    }
     if (_unlinkedDefiningUnit != null) {
-      return _unlinkedDefiningUnit?.libraryDocumentationComment?.text;
+      return _unlinkedDefiningUnit.libraryDocumentationComment?.text;
     }
     return super.documentationComment;
   }
@@ -7842,7 +7854,7 @@
       return _kernel.documentationComment;
     }
     if (_unlinkedVariable != null) {
-      return _unlinkedVariable?.documentationComment?.text;
+      return _unlinkedVariable.documentationComment?.text;
     }
     return super.documentationComment;
   }
@@ -8010,20 +8022,6 @@
   final kernel.VariableDeclaration _kernel;
 
   /**
-   * A list containing all of the parameters defined by this parameter element.
-   * There will only be parameters if this parameter is a function typed
-   * parameter.
-   */
-  List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
-
-  /**
-   * A list containing all of the type parameters defined for this parameter
-   * element. There will only be parameters if this parameter is a function
-   * typed parameter.
-   */
-  List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
-
-  /**
    * The kind of this parameter.
    */
   ParameterKind _parameterKind;
@@ -8354,19 +8352,7 @@
 
   @override
   List<ParameterElement> get parameters {
-    _resynthesizeTypeAndParameters();
-    return _parameters;
-  }
-
-  /**
-   * Set the parameters defined by this executable element to the given
-   * [parameters].
-   */
-  void set parameters(List<ParameterElement> parameters) {
-    for (ParameterElement parameter in parameters) {
-      (parameter as ParameterElementImpl).enclosingElement = this;
-    }
-    this._parameters = parameters;
+    return const <ParameterElement>[];
   }
 
   @override
@@ -8386,17 +8372,8 @@
   }
 
   @override
-  List<TypeParameterElement> get typeParameters => _typeParameters;
-
-  /**
-   * Set the type parameters defined by this parameter element to the given
-   * [typeParameters].
-   */
-  void set typeParameters(List<TypeParameterElement> typeParameters) {
-    for (TypeParameterElement parameter in typeParameters) {
-      (parameter as TypeParameterElementImpl).enclosingElement = this;
-    }
-    this._typeParameters = typeParameters;
+  List<TypeParameterElement> get typeParameters {
+    return const <TypeParameterElement>[];
   }
 
   @override
@@ -8450,17 +8427,6 @@
   FormalParameter computeNode() =>
       getNodeMatching((node) => node is FormalParameter);
 
-  @override
-  ElementImpl getChild(String identifier) {
-    for (ParameterElement parameter in _parameters) {
-      ParameterElementImpl parameterImpl = parameter;
-      if (parameterImpl.identifier == identifier) {
-        return parameterImpl;
-      }
-    }
-    return null;
-  }
-
   /**
    * Set the visible range for this element to the range starting at the given
    * [offset] with the given [length].
@@ -8482,61 +8448,27 @@
    * been build yet, build them and remember in the corresponding fields.
    */
   void _resynthesizeTypeAndParameters() {
+    // TODO(scheglov) Don't resynthesize parameters.
     if (_kernel != null && _type == null) {
       kernel.DartType type = _kernel.type;
       _type = enclosingUnit._kernelContext.getType(this, type);
-      if (type is kernel.FunctionType && type.typedefReference == null) {
-        _parameters = new List<ParameterElement>(
-            type.positionalParameters.length + type.namedParameters.length);
-        int index = 0;
-        for (int i = 0; i < type.positionalParameters.length; i++) {
-          String name = i < type.positionalParameterNames.length
-              ? type.positionalParameterNames[i]
-              : null;
-          _parameters[index++] = new ParameterElementImpl.forKernel(
-              enclosingElement,
-              new kernel.VariableDeclaration(name,
-                  type: type.positionalParameters[i]),
-              i < type.requiredParameterCount
-                  ? ParameterKind.REQUIRED
-                  : ParameterKind.POSITIONAL);
-        }
-        for (int i = 0; i < type.namedParameters.length; i++) {
-          _parameters[index++] = new ParameterElementImpl.forKernel(
-              enclosingElement,
-              new kernel.VariableDeclaration(type.namedParameters[i].name,
-                  type: type.namedParameters[i].type),
-              ParameterKind.NAMED);
-        }
-      } else {
-        _parameters = const <ParameterElement>[];
-      }
     }
     if (_unlinkedParam != null && _declaredType == null && _type == null) {
       if (_unlinkedParam.isFunctionTyped) {
         CompilationUnitElementImpl enclosingUnit = this.enclosingUnit;
-        FunctionElementImpl parameterTypeElement =
-            new FunctionElementImpl_forFunctionTypedParameter(
-                enclosingUnit, this);
-        if (!isSynthetic) {
-          parameterTypeElement.enclosingElement = this;
-        }
-        List<ParameterElement> subParameters = ParameterElementImpl
-            .resynthesizeList(_unlinkedParam.parameters, this,
-                synthetic: isSynthetic);
-        if (isSynthetic) {
-          parameterTypeElement.parameters = subParameters;
-        } else {
-          _parameters = subParameters;
-          parameterTypeElement.shareParameters(subParameters);
-        }
-        parameterTypeElement.returnType = enclosingUnit.resynthesizerContext
+
+        var typeElement = new GenericFunctionTypeElementImpl.forOffset(-1);
+        typeElement.enclosingElement = this;
+
+        typeElement.parameters = ParameterElementImpl.resynthesizeList(
+            _unlinkedParam.parameters, typeElement,
+            synthetic: isSynthetic);
+
+        typeElement.returnType = enclosingUnit.resynthesizerContext
             .resolveTypeRef(this, _unlinkedParam.type);
-        FunctionTypeImpl parameterType =
-            new FunctionTypeImpl.elementWithNameAndArgs(parameterTypeElement,
-                null, typeParameterContext.allTypeParameterTypes, false);
-        parameterTypeElement.type = parameterType;
-        _type = parameterType;
+
+        _type = new FunctionTypeImpl(typeElement);
+        typeElement.type = _type;
       } else {
         _type = enclosingUnit.resynthesizerContext
             .resolveLinkedType(this, _unlinkedParam.inferredTypeSlot);
@@ -9666,7 +9598,7 @@
    * Find out how many type parameters are in scope in this context.
    */
   int get typeParameterNestingLevel =>
-      _nestingLevel ??= unlinkedTypeParams.length +
+      _nestingLevel ??= (unlinkedTypeParams?.length ?? 0) +
           (enclosingTypeParameterContext?.typeParameterNestingLevel ?? 0);
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 9d09ba4..2c9f5e8 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -92,7 +92,7 @@
       TypeParameterElement.EMPTY_LIST;
 
   @override
-  FunctionTypedElement get element => super.element;
+  FunctionTypedElement get element => null;
 
   @override
   bool get isInstantiated => false;
@@ -1132,7 +1132,7 @@
    * parameter from [tParams] and `s` is a parameter from [sParams], and both
    * `t` and `s` are at the same position (for positional parameters)
    * or have the same name (for named parameters).
-   * 
+   *
    * Used for the various relations on function types which have the same
    * structural rules for handling optional parameters and arity, but use their
    * own relation for comparing the parameters.
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 60a0af1..2c1c729 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -307,7 +307,7 @@
   static const ParserErrorCode EXTERNAL_METHOD_WITH_BODY =
       const ParserErrorCode(
           'EXTERNAL_METHOD_WITH_BODY',
-          "External methods can't have a body.",
+          "An external or native method can't have a body.",
           "Try removing the body of the method, or "
           "removing the keyword 'external'.");
 
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 15f0cd4..97423bd 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -22,7 +22,12 @@
 
 import 'package:front_end/src/fasta/problems.dart' show unhandled;
 import 'package:front_end/src/fasta/messages.dart'
-    show Code, Message, codeExpectedExpression, codeExpectedFunctionBody;
+    show
+        Code,
+        Message,
+        codeExpectedExpression,
+        codeExpectedFunctionBody,
+        messageNativeClauseShouldBeAnnotation;
 import 'package:front_end/src/fasta/kernel/kernel_builder.dart'
     show Builder, KernelLibraryBuilder, Scope;
 import 'package:front_end/src/fasta/quote.dart';
@@ -71,6 +76,8 @@
   // * The current library has an import that uses the scheme "dart-ext".
   bool allowNativeClause = false;
 
+  StringLiteral nativeName;
+
   AstBuilder(this.errorReporter, this.library, this.member, Scope scope,
       this.isFullAst,
       [Uri uri])
@@ -183,6 +190,16 @@
     }
   }
 
+  @override
+  void handleNativeClause(Token nativeToken, bool hasName) {
+    debugEvent("NativeClause");
+    if (hasName) {
+      nativeName = pop(); // StringLiteral
+    } else {
+      nativeName = null;
+    }
+  }
+
   void handleScript(Token token) {
     debugEvent("Script");
     scriptTag = ast.scriptTag(token);
@@ -263,6 +280,15 @@
   }
 
   @override
+  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
+    debugEvent("NativeFunctionBody");
+    // TODO(danrubel) Change the parser to not produce these modifiers.
+    pop(); // star
+    pop(); // async
+    push(ast.nativeFunctionBody(nativeToken, nativeName, semicolon));
+  }
+
+  @override
   void handleEmptyFunctionBody(Token semicolon) {
     debugEvent("EmptyFunctionBody");
     // TODO(scheglov) Change the parser to not produce these modifiers.
@@ -294,6 +320,8 @@
     Statement bodyStatement;
     if (body is EmptyFunctionBody) {
       bodyStatement = ast.emptyStatement(body.semicolon);
+    } else if (body is NativeFunctionBody) {
+      // TODO(danrubel): what do we need to do with NativeFunctionBody?
     } else if (body is ExpressionFunctionBody) {
       bodyStatement = ast.returnStatement(null, body.expression, null);
     } else {
@@ -334,7 +362,8 @@
     push(token);
   }
 
-  void handleBinaryExpression(Token token) {
+  @override
+  void endBinaryExpression(Token token) {
     debugEvent("BinaryExpression");
     if (identical(".", token.stringValue) ||
         identical("?.", token.stringValue) ||
@@ -393,11 +422,9 @@
   void endIfStatement(Token ifToken, Token elseToken) {
     Statement elsePart = popIfNotNull(elseToken);
     Statement thenPart = pop();
-    Expression condition = pop();
-    analyzer.BeginToken leftParenthesis =
-        unsafeToken(ifToken.next, TokenType.OPEN_PAREN);
-    push(ast.ifStatement(ifToken, ifToken.next, condition,
-        leftParenthesis.endGroup, thenPart, elseToken, elsePart));
+    ParenthesizedExpression condition = pop();
+    push(ast.ifStatement(ifToken, condition.leftParenthesis, condition,
+        condition.rightParenthesis, thenPart, elseToken, elsePart));
   }
 
   void handleNoInitializers() {
@@ -462,6 +489,8 @@
             fieldName,
             initializerObject.operator,
             initializerObject.rightHandSide));
+      } else if (initializerObject is AssertInitializer) {
+        initializers.add(initializerObject);
       }
     }
 
@@ -674,8 +703,20 @@
     debugEvent("Assert");
     Expression message = popIfNotNull(comma);
     Expression condition = pop();
-    push(ast.assertStatement(assertKeyword, leftParenthesis, condition, comma,
-        message, rightParenthesis, semicolon));
+    switch (kind) {
+      case Assert.Expression:
+        throw new UnimplementedError(
+            'assert expressions are not yet supported');
+        break;
+      case Assert.Initializer:
+        push(ast.assertInitializer(assertKeyword, leftParenthesis, condition,
+            comma, message, rightParenthesis));
+        break;
+      case Assert.Statement:
+        push(ast.assertStatement(assertKeyword, leftParenthesis, condition,
+            comma, message, rightParenthesis, semicolon));
+        break;
+    }
   }
 
   void handleAsOperator(Token operator, Token endToken) {
@@ -972,7 +1013,7 @@
         rightBracket));
   }
 
-  void handleCatchBlock(Token onKeyword, Token catchKeyword) {
+  void handleCatchBlock(Token onKeyword, Token catchKeyword, Token comma) {
     debugEvent("CatchBlock");
     Block body = pop();
     FormalParameterList catchParameterList = popIfNotNull(catchKeyword);
@@ -995,7 +1036,7 @@
         catchKeyword,
         catchParameterList?.leftParenthesis,
         exception,
-        stackTrace == null ? null : stackTrace.token.previous,
+        comma,
         stackTrace,
         catchParameterList?.rightParenthesis,
         body));
@@ -1226,22 +1267,14 @@
         semicolon));
   }
 
-  void endConditionalUri(Token ifKeyword, Token equalitySign) {
+  void endConditionalUri(
+      Token ifKeyword, Token leftParen, Token equalSign, Token rightParen) {
     debugEvent("ConditionalUri");
     StringLiteral libraryUri = pop();
-    StringLiteral value = popIfNotNull(equalitySign);
+    StringLiteral value = popIfNotNull(equalSign);
     DottedName name = pop();
-    // TODO(paulberry,ahe): what if there is no `(` token due to an error in the
-    // file being parsed?  It seems like we need the parser to do adequate error
-    // recovery and then report both the ifKeyword and leftParen tokens to the
-    // listener.
-    Token leftParen = unsafeToken(ifKeyword.next, TokenType.OPEN_PAREN);
-    // TODO(paulberry,ahe): the parser should report the right paren token to
-    // the listener.
-    Token lastToken = value?.endToken ?? equalitySign ?? name?.endToken;
-    Token rightParen = unsafeToken(lastToken.next, TokenType.CLOSE_PAREN);
-    push(ast.configuration(ifKeyword, leftParen, name, equalitySign, value,
-        rightParen, libraryUri));
+    push(ast.configuration(
+        ifKeyword, leftParen, name, equalSign, value, rightParen, libraryUri));
   }
 
   @override
@@ -1290,11 +1323,6 @@
   }
 
   @override
-  void handleNativeClause(Token nativeToken, bool hasName) {
-    push(ast.nativeClause(nativeToken, hasName ? pop() : null));
-  }
-
-  @override
   void endClassDeclaration(
       int interfacesCount,
       Token beginToken,
@@ -1305,7 +1333,10 @@
       Token endToken) {
     debugEvent("ClassDeclaration");
     _ClassBody body = pop();
-    NativeClause nativeClause = nativeToken != null ? pop() : null;
+    NativeClause nativeClause;
+    if (nativeToken != null) {
+      nativeClause = ast.nativeClause(nativeToken, nativeName);
+    }
     ImplementsClause implementsClause;
     if (implementsKeyword != null) {
       List<TypeName> interfaces = popList(interfacesCount);
@@ -1412,6 +1443,16 @@
   }
 
   @override
+  void handleRecoverableError(Token token, Message message) {
+    /// TODO(danrubel): Ignore this error until we deprecate `native` support.
+    if (message == messageNativeClauseShouldBeAnnotation && allowNativeClause) {
+      return;
+    }
+    debugEvent("Error: ${message.message}");
+    addCompileTimeError(message, token.offset);
+  }
+
+  @override
   void handleQualified(Token period) {
     SimpleIdentifier identifier = pop();
     var prefix = pop();
@@ -1440,7 +1481,8 @@
   }
 
   @override
-  void endPartOf(Token partKeyword, Token semicolon, bool hasName) {
+  void endPartOf(
+      Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
     debugEvent("PartOf");
     var libraryNameOrUri = pop();
     LibraryIdentifier name;
@@ -1450,9 +1492,6 @@
     } else {
       name = ast.libraryIdentifier(libraryNameOrUri);
     }
-    // TODO(paulberry,ahe): seems hacky.  It would be nice if the parser passed
-    // in a reference to the "of" keyword.
-    var ofKeyword = unsafeToken(partKeyword.next, analyzer.Keyword.OF);
     List<Annotation> metadata = pop();
     Comment comment = pop();
     directives.add(ast.partOfDirective(
@@ -1545,7 +1584,11 @@
 
   @override
   void endNamedFunctionExpression(Token endToken) {
-    logEvent("NamedFunctionExpression");
+    // TODO(scheglov): The logEvent() invocation is commented because it
+    // spams to the console. We already know that these test fail, uncomment
+    // when you are working on fixing them.
+//    logEvent("NamedFunctionExpression");
+    unhandled("NamedFunctionExpression", "$runtimeType", -1, uri);
   }
 
   @override
@@ -1794,7 +1837,7 @@
   }
 
   @override
-  void endMetadataStar(int count, bool forParameter) {
+  void endMetadataStar(int count) {
     debugEvent("MetadataStar");
     push(popList(count) ?? NullValue.Metadata);
   }
@@ -1824,7 +1867,7 @@
 
   @override
   void debugEvent(String name) {
-    // printEvent(name);
+    // printEvent('AstBuilder: $name');
   }
 
   @override
@@ -1922,9 +1965,9 @@
     }
 
     switch (code.analyzerCode) {
-      case "EXPECTED_TYPE_NAME":
+      case "ABSTRACT_CLASS_MEMBER":
         errorReporter?.reportErrorForOffset(
-            ParserErrorCode.EXPECTED_TYPE_NAME, charOffset, 1);
+            ParserErrorCode.ABSTRACT_CLASS_MEMBER, charOffset, 1);
         return;
       case "CONST_CLASS":
         errorReporter?.reportErrorForOffset(
@@ -1934,18 +1977,22 @@
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.EXPECTED_STRING_LITERAL, charOffset, 1);
         return;
+      case "EXPECTED_TYPE_NAME":
+        errorReporter?.reportErrorForOffset(
+            ParserErrorCode.EXPECTED_TYPE_NAME, charOffset, 1);
+        return;
+      case "EXTERNAL_METHOD_WITH_BODY":
+        errorReporter?.reportErrorForOffset(
+            ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, charOffset, 1);
+        return;
       case "EXTRANEOUS_MODIFIER":
         String text = stringOrTokenLexeme();
         errorReporter?.reportErrorForOffset(ParserErrorCode.EXTRANEOUS_MODIFIER,
             charOffset, text.length, [text]);
         return;
       case "NATIVE_CLAUSE_SHOULD_BE_ANNOTATION":
-        if (!allowNativeClause) {
-          errorReporter?.reportErrorForOffset(
-              ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION,
-              charOffset,
-              1);
-        }
+        errorReporter?.reportErrorForOffset(
+            ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION, charOffset, 1);
         return;
       case "UNEXPECTED_TOKEN":
         String text = stringOrTokenLexeme();
diff --git a/pkg/analyzer/lib/src/fasta/resolution_applier.dart b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
index 6ee190c..66117ac 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_applier.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
@@ -46,6 +46,11 @@
   }
 
   @override
+  void visitNativeFunctionBody(NativeFunctionBody node) {
+    // nothing to resolve
+  }
+
+  @override
   void visitParenthesizedExpression(ParenthesizedExpression node) {
     node.visitChildren(this);
     node.staticType = node.expression.staticType;
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index 9ef1fb8..7c63b5c 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -131,6 +131,7 @@
       normalParameter.element = element;
       _setGenericFunctionType(normalParameter.type, element.type);
     }
+
     Expression defaultValue = node.defaultValue;
     if (defaultValue != null) {
       _walk(
@@ -139,9 +140,14 @@
         defaultValue.accept(this);
       });
     }
-    _walk(new ElementWalker.forParameter(element), () {
+
+    bool isFunctionTyped = normalParameter is FunctionTypedFormalParameter ||
+        normalParameter is FieldFormalParameter &&
+            normalParameter.parameters != null;
+    _walk(new ElementWalker.forParameter(element, isFunctionTyped), () {
       normalParameter.accept(this);
     });
+
     _resolveMetadata(node, node.metadata, element);
     return null;
   }
@@ -199,7 +205,8 @@
     if (node.parent is! DefaultFormalParameter) {
       ParameterElement element =
           _match(node.identifier, _walker.getParameter());
-      _walk(new ElementWalker.forParameter(element), () {
+      bool isFunctionTyped = node.parameters != null;
+      _walk(new ElementWalker.forParameter(element, isFunctionTyped), () {
         super.visitFieldFormalParameter(node);
       });
       _resolveMetadata(node, node.metadata, element);
@@ -268,7 +275,7 @@
     if (node.parent is! DefaultFormalParameter) {
       ParameterElement element =
           _match(node.identifier, _walker.getParameter());
-      _walk(new ElementWalker.forParameter(element), () {
+      _walk(new ElementWalker.forParameter(element, true), () {
         super.visitFunctionTypedFormalParameter(node);
       });
       _resolveMetadata(node, node.metadata, element);
@@ -407,7 +414,7 @@
           _match(node.identifier, _walker.getParameter());
       (node as SimpleFormalParameterImpl).element = element;
       _setGenericFunctionType(node.type, element.type);
-      _walk(new ElementWalker.forParameter(element), () {
+      _walk(new ElementWalker.forParameter(element, false), () {
         super.visitSimpleFormalParameter(node);
       });
       _resolveMetadata(node, node.metadata, element);
@@ -509,7 +516,7 @@
   }
 
   void _matchOffset(Element element, int offset) {
-    if (element.nameOffset != 0 && element.nameOffset != offset) {
+    if (element.nameOffset > 0 && element.nameOffset != offset) {
       throw new StateError('Element offset mismatch');
     } else {
       (element as ElementImpl).nameOffset = offset;
@@ -695,10 +702,18 @@
    * Creates an [ElementWalker] which walks the child elements of a parameter
    * element.
    */
-  ElementWalker.forParameter(ParameterElement element)
+  ElementWalker.forParameter(ParameterElement element, bool functionTyped)
       : element = element,
         _parameters = element.parameters,
-        _typeParameters = element.typeParameters;
+        _typeParameters = element.typeParameters {
+    // If the parameter node is function typed, extract type parameters and
+    // formal parameters from its generic function type element.
+    if (functionTyped) {
+      GenericFunctionTypeElement typeElement = element.type.element;
+      _typeParameters = typeElement.typeParameters;
+      _parameters = typeElement.parameters;
+    }
+  }
 
   /**
    * Creates an [ElementWalker] which walks the child elements of a typedef
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 3220f6f..15c3050 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1311,6 +1311,11 @@
   bool get trackCacheDependencies;
 
   /**
+   * Return `true` if analyzer should use the Dart 2.0 Front End parser.
+   */
+  bool get useFastaParser;
+
+  /**
    * Reset the state of this set of analysis options to its original state.
    */
   void resetToDefaults();
@@ -1455,6 +1460,9 @@
   bool trackCacheDependencies = true;
 
   @override
+  bool useFastaParser = false;
+
+  @override
   bool disableCacheFlushing = false;
 
   /**
@@ -1511,6 +1519,7 @@
     lintRules = options.lintRules;
     preserveComments = options.preserveComments;
     strongMode = options.strongMode;
+    useFastaParser = options.useFastaParser;
     if (options is AnalysisOptionsImpl) {
       declarationCasts = options.declarationCasts;
       strongModeHints = options.strongModeHints;
@@ -1692,6 +1701,7 @@
     strongMode = false;
     strongModeHints = false;
     trackCacheDependencies = true;
+    useFastaParser = false;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 374313c..1c76358 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -296,11 +296,16 @@
    */
   final bool enableSuperMixins;
 
+  final _UninstantiatedBoundChecker _uninstantiatedBoundChecker;
+
   /**
    * Initialize a newly created error verifier.
    */
-  ErrorVerifier(this._errorReporter, this._currentLibrary, this._typeProvider,
-      this._inheritanceManager, this.enableSuperMixins) {
+  ErrorVerifier(ErrorReporter errorReporter, this._currentLibrary,
+      this._typeProvider, this._inheritanceManager, this.enableSuperMixins)
+      : _errorReporter = errorReporter,
+        _uninstantiatedBoundChecker =
+            new _UninstantiatedBoundChecker(errorReporter) {
     this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
     this._hasExtUri = _currentLibrary.hasExtUri;
     _isEnclosingConstructorConst = false;
@@ -1189,7 +1194,7 @@
     _checkForTypeParameterSupertypeOfItsBound(node);
     _checkForTypeAnnotationDeferredClass(node.bound);
     _checkForImplicitDynamicType(node.bound);
-    _checkForNotInstantiatedBound(node.bound);
+    if (_options.strongMode) node.bound?.accept(_uninstantiatedBoundChecker);
     return super.visitTypeParameter(node);
   }
 
@@ -5312,30 +5317,6 @@
     }
   }
 
-  void _checkForNotInstantiatedBound(TypeAnnotation node) {
-    if (!_options.strongMode || node == null) {
-      return;
-    }
-
-    if (node is TypeName) {
-      if (node.typeArguments == null) {
-        DartType type = node.type;
-        if (type is ParameterizedType) {
-          Element element = type.element;
-          if (element is TypeParameterizedElement &&
-              element.typeParameters.any((p) => p.bound != null)) {
-            _errorReporter.reportErrorForNode(
-                StrongModeCode.NOT_INSTANTIATED_BOUND, node, [type]);
-          }
-        }
-      } else {
-        node.typeArguments.arguments.forEach(_checkForNotInstantiatedBound);
-      }
-    } else {
-      throw new UnimplementedError('${node.runtimeType}');
-    }
-  }
-
   /**
    * Verify the given operator-method [declaration], does not have an optional
    * parameter. This method assumes that the method declaration was tested to be
@@ -6528,40 +6509,9 @@
    * itself from anywhere except a class element or type parameter bounds.
    */
   bool _hasTypedefSelfReference(Element element) {
-    Set<Element> checked = new HashSet<Element>();
-    List<Element> toCheck = new List<Element>();
-    GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference
-        elementVisitor =
-        new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(
-            toCheck);
-    toCheck.add(element);
-    bool firstIteration = true;
-    while (true) {
-      Element current;
-      // get next element
-      while (true) {
-        // may be no more elements to check
-        if (toCheck.isEmpty) {
-          return false;
-        }
-        // try to get next element
-        current = toCheck.removeAt(toCheck.length - 1);
-        if (element == current) {
-          if (firstIteration) {
-            firstIteration = false;
-            break;
-          } else {
-            return true;
-          }
-        }
-        if (current != null && !checked.contains(current)) {
-          break;
-        }
-      }
-      // check current element
-      current.accept(elementVisitor);
-      checked.add(current);
-    }
+    var visitor = new _HasTypedefSelfReferenceVisitor(element);
+    element.accept(visitor);
+    return visitor.hasSelfReference;
   }
 
   bool _isFunctionType(DartType type) {
@@ -6919,58 +6869,6 @@
   }
 }
 
-class GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference
-    extends GeneralizingElementVisitor<Object> {
-  List<Element> toCheck;
-
-  GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference(this.toCheck)
-      : super();
-
-  @override
-  Object visitClassElement(ClassElement element) {
-    // Typedefs are allowed to reference themselves via classes.
-    return null;
-  }
-
-  @override
-  Object visitFunctionElement(FunctionElement element) {
-    _addTypeToCheck(element.returnType);
-    return super.visitFunctionElement(element);
-  }
-
-  @override
-  Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
-    _addTypeToCheck(element.returnType);
-    return super.visitFunctionTypeAliasElement(element);
-  }
-
-  @override
-  Object visitParameterElement(ParameterElement element) {
-    _addTypeToCheck(element.type);
-    return super.visitParameterElement(element);
-  }
-
-  @override
-  Object visitTypeParameterElement(TypeParameterElement element) {
-    _addTypeToCheck(element.bound);
-    return super.visitTypeParameterElement(element);
-  }
-
-  void _addTypeToCheck(DartType type) {
-    if (type == null) {
-      return;
-    }
-    // schedule for checking
-    toCheck.add(type.element);
-    // type arguments
-    if (type is InterfaceType) {
-      for (DartType typeArgument in type.typeArguments) {
-        _addTypeToCheck(typeArgument);
-      }
-    }
-  }
-}
-
 /**
  * A record of the elements that will be declared in some scope (block), but are
  * not yet declared.
@@ -7138,6 +7036,69 @@
       .firstWhere((ElementAnnotation e) => e.isRequired, orElse: () => null);
 }
 
+class _HasTypedefSelfReferenceVisitor
+    extends GeneralizingElementVisitor<Object> {
+  final FunctionTypeAliasElement element;
+  bool hasSelfReference = false;
+
+  _HasTypedefSelfReferenceVisitor(this.element);
+
+  @override
+  Object visitClassElement(ClassElement element) {
+    // Typedefs are allowed to reference themselves via classes.
+    return null;
+  }
+
+  @override
+  Object visitFunctionElement(FunctionElement element) {
+    _addTypeToCheck(element.returnType);
+    return super.visitFunctionElement(element);
+  }
+
+  @override
+  Object visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
+    _addTypeToCheck(element.returnType);
+    return super.visitFunctionTypeAliasElement(element);
+  }
+
+  @override
+  Object visitParameterElement(ParameterElement element) {
+    _addTypeToCheck(element.type);
+    return super.visitParameterElement(element);
+  }
+
+  @override
+  Object visitTypeParameterElement(TypeParameterElement element) {
+    _addTypeToCheck(element.bound);
+    return super.visitTypeParameterElement(element);
+  }
+
+  void _addTypeToCheck(DartType type) {
+    if (hasSelfReference) {
+      return;
+    }
+    if (type == null) {
+      return;
+    }
+    if (type.element == element) {
+      hasSelfReference = true;
+      return;
+    }
+    if (type is FunctionType) {
+      _addTypeToCheck(type.returnType);
+      for (ParameterElement parameter in type.parameters) {
+        _addTypeToCheck(parameter.type);
+      }
+    }
+    // type arguments
+    if (type is InterfaceType) {
+      for (DartType typeArgument in type.typeArguments) {
+        _addTypeToCheck(typeArgument);
+      }
+    }
+  }
+}
+
 /**
  * Recursively visits an AST, looking for method invocations.
  */
@@ -7152,3 +7113,27 @@
     super.visitMethodInvocation(node);
   }
 }
+
+/**
+ * Recursively visits a type annotation, looking uninstantiated bounds.
+ */
+class _UninstantiatedBoundChecker extends RecursiveAstVisitor {
+  final ErrorReporter _errorReporter;
+  _UninstantiatedBoundChecker(this._errorReporter);
+
+  @override
+  visitTypeName(node) {
+    var typeArgs = node.typeArguments;
+    if (typeArgs != null) {
+      typeArgs.accept(this);
+      return;
+    }
+
+    var element = node.type.element;
+    if (element is TypeParameterizedElement &&
+        element.typeParameters.any((p) => p.bound != null)) {
+      _errorReporter.reportErrorForNode(
+          StrongModeCode.NOT_INSTANTIATED_BOUND, node, [node.type]);
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/parser_fasta.dart b/pkg/analyzer/lib/src/generated/parser_fasta.dart
index d530528..3dc9892 100644
--- a/pkg/analyzer/lib/src/generated/parser_fasta.dart
+++ b/pkg/analyzer/lib/src/generated/parser_fasta.dart
@@ -67,6 +67,15 @@
   }
 
   @override
+  bool enableAssertInitializer = true;
+
+  @override
+  bool enableUriInPartOf = true;
+
+  @override
+  bool enableNnbd = false;
+
+  @override
   CompilationUnit parseCompilationUnit(Token token) {
     currentToken = token;
     return parseCompilationUnit2();
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index aed62ae..5cd67f2 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -7391,8 +7391,8 @@
             new CaughtException(new AnalysisException(), null));
       } else {
         nameScope = new EnclosedScope(nameScope);
-        List<TypeParameterElement> typeParameters =
-            parameterElement.typeParameters;
+        GenericFunctionTypeElement typeElement = parameterElement.type.element;
+        List<TypeParameterElement> typeParameters = typeElement.typeParameters;
         int length = typeParameters.length;
         for (int i = 0; i < length; i++) {
           nameScope.define(typeParameters[i]);
@@ -8622,9 +8622,28 @@
       type.typeArguments?.arguments?.forEach(_resolveTypeName);
       typeNameResolver.resolveTypeName(type);
       // TODO(scheglov) report error when don't apply type bounds for type bounds
-    } else {
-      // TODO(brianwilkerson) Add resolution of GenericFunctionType
-      throw new ArgumentError('Cannot resolve a ${type.runtimeType}');
+    } else if (type is GenericFunctionType) {
+      void resolveTypeParameter(TypeParameter t) {
+        _resolveTypeName(t.bound);
+      }
+
+      void resolveParameter(FormalParameter p) {
+        if (p is SimpleFormalParameter) {
+          _resolveTypeName(p.type);
+        } else if (p is DefaultFormalParameter) {
+          resolveParameter(p.parameter);
+        } else if (p is FieldFormalParameter) {
+          _resolveTypeName(p.type);
+        } else if (p is FunctionTypedFormalParameter) {
+          _resolveTypeName(p.returnType);
+          p.typeParameters?.typeParameters?.forEach(resolveTypeParameter);
+          p.parameters?.parameters?.forEach(resolveParameter);
+        }
+      }
+
+      _resolveTypeName(type.returnType);
+      type.typeParameters?.typeParameters?.forEach(resolveTypeParameter);
+      type.parameters?.parameters?.forEach(resolveParameter);
     }
   }
 
@@ -8641,10 +8660,8 @@
                 library, LibraryResolutionCapability.resolvedTypeNames)) {
               if (bound is TypeName) {
                 bound.type = typeParameterElement.bound;
-              } else {
-                // TODO(brianwilkerson) Add resolution of GenericFunctionType
-                throw new ArgumentError(
-                    'Cannot resolve a ${bound.runtimeType}');
+              } else if (bound is GenericFunctionTypeImpl) {
+                bound.type = typeParameterElement.bound;
               }
             } else {
               libraryScope ??= new LibraryScope(library);
@@ -9941,26 +9958,6 @@
   }
 
   /**
-   * Return an array containing all of the elements associated with the parameters in the given
-   * list.
-   *
-   * @param parameterList the list of parameters whose elements are to be returned
-   * @return the elements associated with the parameters
-   */
-  List<ParameterElement> _getElements(FormalParameterList parameterList) {
-    List<ParameterElement> elements = new List<ParameterElement>();
-    for (FormalParameter parameter in parameterList.parameters) {
-      ParameterElement element =
-          parameter.identifier.staticElement as ParameterElement;
-      // TODO(brianwilkerson) Understand why the element would be null.
-      if (element != null) {
-        elements.add(element);
-      }
-    }
-    return elements;
-  }
-
-  /**
    * In strong mode we infer "void" as the setter return type (as void is the
    * only legal return type for a setter). This allows us to give better
    * errors later if an invalid type is returned.
@@ -10100,21 +10097,15 @@
   }
 
   /**
-   * Given a parameter [element], create a function type based on the given
-   * [returnType] and [parameterList] and associate the created type with the
-   * element.
+   * Given a function typed [parameter] with [FunctionType] based on a
+   * [GenericFunctionTypeElementImpl], compute and set the return type for the
+   * function element.
    */
-  void _setFunctionTypedParameterType(ParameterElementImpl element,
+  void _setFunctionTypedParameterType(ParameterElementImpl parameter,
       TypeAnnotation returnType, FormalParameterList parameterList) {
-    List<ParameterElement> parameters = _getElements(parameterList);
-    FunctionElementImpl functionElement = new FunctionElementImpl.forNode(null);
-    functionElement.isSynthetic = true;
-    functionElement.shareParameters(parameters);
-    functionElement.declaredReturnType = _computeReturnType(returnType);
-    functionElement.enclosingElement = element;
-    functionElement.shareTypeParameters(element.typeParameters);
-    element.type = new FunctionTypeImpl(functionElement);
-    functionElement.type = element.type;
+    DartType type = parameter.type;
+    GenericFunctionTypeElementImpl typeElement = type.element;
+    typeElement.returnType = _computeReturnType(returnType);
   }
 }
 
diff --git a/pkg/analyzer/lib/src/kernel/resynthesize.dart b/pkg/analyzer/lib/src/kernel/resynthesize.dart
index d1bdb1d..626c335 100644
--- a/pkg/analyzer/lib/src/kernel/resynthesize.dart
+++ b/pkg/analyzer/lib/src/kernel/resynthesize.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/handle.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
@@ -19,7 +20,7 @@
 /**
  * Object that can resynthesize analyzer [LibraryElement] from Kernel.
  */
-class KernelResynthesizer {
+class KernelResynthesizer implements ElementResynthesizer {
   final AnalysisContext _analysisContext;
   final kernel.TypeEnvironment _types;
   final Map<String, kernel.Library> _kernelMap;
@@ -32,11 +33,23 @@
 
   KernelResynthesizer(this._analysisContext, this._types, this._kernelMap);
 
+  @override
+  AnalysisContext get context => _analysisContext;
+
   /**
    * Return the `Type` type.
    */
   DartType get typeType => getLibrary('dart:core').getType('Type').type;
 
+  @override
+  Element getElement(ElementLocation location) {
+    List<String> components = location.components;
+    if (components.length != 1) {
+      throw new ArgumentError('Only library access is implemented.');
+    }
+    return getLibrary(components[0]);
+  }
+
   /**
    * Return the [LibraryElementImpl] for the given [uriStr], or `null` if
    * the library is not part of the Kernel libraries bundle.
@@ -793,6 +806,7 @@
 
   DartType getType(ElementImpl context, kernel.DartType kernelType) {
     if (kernelType is kernel.DynamicType) return DynamicTypeImpl.instance;
+    if (kernelType is kernel.InvalidType) return DynamicTypeImpl.instance;
     if (kernelType is kernel.VoidType) return VoidTypeImpl.instance;
 
     if (kernelType is kernel.InterfaceType) {
diff --git a/pkg/analyzer/lib/src/lint/analysis.dart b/pkg/analyzer/lib/src/lint/analysis.dart
index 2f139a9..42199ed 100644
--- a/pkg/analyzer/lib/src/lint/analysis.dart
+++ b/pkg/analyzer/lib/src/lint/analysis.dart
@@ -24,8 +24,8 @@
 import 'package:analyzer/src/lint/registry.dart';
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/util/sdk.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:package_config/packages.dart' show Packages;
 import 'package:package_config/packages_file.dart' as pkgfile show parse;
 import 'package:package_config/src/packages_impl.dart' show MapPackages;
diff --git a/pkg/analyzer/lib/src/summary/summary_file_builder.dart b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
index 11434ed..7cabe97 100644
--- a/pkg/analyzer/lib/src/summary/summary_file_builder.dart
+++ b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
@@ -138,7 +138,8 @@
     scanner.scanGenericMethodComments = strong;
     Token token = scanner.tokenize();
     LineInfo lineInfo = new LineInfo(scanner.lineStarts);
-    Parser parser = new Parser(source, errorListener);
+    Parser parser = new Parser(source, errorListener,
+        useFasta: context.analysisOptions.useFastaParser);
     parser.parseGenericMethodComments = strong;
     CompilationUnit unit = parser.parseCompilationUnit(token);
     unit.lineInfo = lineInfo;
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index b731a57..1e00142 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -3769,8 +3769,9 @@
     RecordingErrorListener errorListener = new RecordingErrorListener();
     _errorReporter = new ErrorReporter(errorListener, _source);
 
-    Parser parser = new Parser(_source, errorListener);
     AnalysisOptions options = context.analysisOptions;
+    Parser parser =
+        new Parser(_source, errorListener, useFasta: options.useFastaParser);
     parser.enableAssertInitializer = options.enableAssertInitializer;
     parser.parseFunctionBodies =
         options.analyzeFunctionBodiesPredicate(_source);
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 505f549..8af0cf7 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -1455,8 +1455,8 @@
   Set<Element> _findSuperclassCovariantChecks(ClassElement element,
       Set<ClassElement> allCovariant, HashSet<String> seenConcreteMembers) {
     var visited = new HashSet<ClassElement>()..add(element);
-    var superChecks = new Set<Element>();
-    var existingChecks = new HashSet<Element>();
+    var superChecks = _createCovariantCheckSet();
+    var existingChecks = _createCovariantCheckSet();
 
     void visitImmediateSuper(InterfaceType type) {
       // For members of mixins/supertypes, check them against new interfaces,
@@ -1521,7 +1521,7 @@
   Set<Element> _findCovariantChecks(Iterable<ExecutableElement> members,
       Iterable<ClassElement> covariantInterfaces,
       [Set<Element> covariantChecks]) {
-    covariantChecks ??= new Set();
+    covariantChecks ??= _createCovariantCheckSet();
     if (members.isEmpty) return covariantChecks;
 
     for (var iface in covariantInterfaces) {
@@ -1595,12 +1595,8 @@
     //
     // The static type system allows this subtyping, but it is not sound without
     // these runtime checks.
-    void addCheck(Element e) {
-      covariantChecks.add(e is Member ? e.baseElement : e);
-    }
-
     var fresh = FunctionTypeImpl.relateTypeFormals(f1, f2, (b2, b1, p2, p1) {
-      if (!rules.isSubtypeOf(b2, b1)) addCheck(p1);
+      if (!rules.isSubtypeOf(b2, b1)) covariantChecks.add(p1);
       return true;
     });
     if (fresh != null) {
@@ -1608,11 +1604,31 @@
       f2 = f2.instantiate(fresh);
     }
     FunctionTypeImpl.relateParameters(f1.parameters, f2.parameters, (p1, p2) {
-      if (!rules.isOverrideSubtypeOfParameter(p1, p2)) addCheck(p1);
+      if (!rules.isOverrideSubtypeOfParameter(p1, p2)) covariantChecks.add(p1);
       return true;
     });
   }
 
+  static Set<Element> _createCovariantCheckSet() {
+    return new LinkedHashSet(
+        equals: _equalMemberElements, hashCode: _hashCodeMemberElements);
+  }
+
+  /// When finding superclass covariance checks, we need to track the
+  /// substituted member/parameter type, but we don't want this type to break
+  /// equality, because [Member] does not implement equality/hashCode, so
+  /// instead we jump to the declaring element.
+  static bool _equalMemberElements(Element x, Element y) {
+    x = x is Member ? x.baseElement : x;
+    y = y is Member ? y.baseElement : y;
+    return x == y;
+  }
+
+  static int _hashCodeMemberElements(Element x) {
+    x = x is Member ? x.baseElement : x;
+    return x.hashCode;
+  }
+
   /// Find all generic interfaces that are implemented by [type], including
   /// [type] itself if it is generic.
   ///
diff --git a/pkg/analyzer/lib/src/util/lru_map.dart b/pkg/analyzer/lib/src/util/lru_map.dart
index 716f7ab..46d61d5 100644
--- a/pkg/analyzer/lib/src/util/lru_map.dart
+++ b/pkg/analyzer/lib/src/util/lru_map.dart
@@ -20,7 +20,7 @@
 class LRUMap<K, V> {
   final LinkedHashMap<K, V> _map = new LinkedHashMap<K, V>();
   final int _maxSize;
-  final EvictionHandler _handler;
+  final EvictionHandler<K, V> _handler;
 
   LRUMap(this._maxSize, [this._handler]);
 
diff --git a/pkg/analyzer/test/cancelable_future_test.dart b/pkg/analyzer/test/cancelable_future_test.dart
index 8f38b6a..a578c8b 100644
--- a/pkg/analyzer/test/cancelable_future_test.dart
+++ b/pkg/analyzer/test/cancelable_future_test.dart
@@ -179,10 +179,10 @@
     completer.complete();
     expect(() {
       completer.complete();
-    }, throws);
+    }, throwsStateError);
     expect(() {
       completer.completeError(new Object());
-    }, throws);
+    }, throwsStateError);
   }
 
   void test_complete_after_completeError() {
@@ -191,10 +191,10 @@
     completer.completeError(new Object());
     expect(() {
       completer.complete();
-    }, throws);
+    }, throwsStateError);
     expect(() {
       completer.completeError(new Object());
-    }, throws);
+    }, throwsStateError);
     // Now absorb the error that's in the completer's future.
     completer.future.catchError((_) => null);
   }
diff --git a/pkg/analyzer/test/dart/element/builder_test.dart b/pkg/analyzer/test/dart/element/builder_test.dart
index 0ca09cd..d682314 100644
--- a/pkg/analyzer/test/dart/element/builder_test.dart
+++ b/pkg/analyzer/test/dart/element/builder_test.dart
@@ -145,8 +145,9 @@
       ParameterElement b = parameters[1];
       expect(b.displayName, 'b');
       expect(b.initializer, isNull);
-      expect(b.parameters, hasLength(1));
-      expect(b.parameters[0].displayName, 'b2');
+      var bTypeElement = b.type.element as GenericFunctionTypeElementImpl;
+      expect(bTypeElement.parameters, hasLength(1));
+      expect(bTypeElement.parameters[0].displayName, 'b2');
     }
     {
       var c = parameters[2] as DefaultParameterElementImpl;
@@ -499,7 +500,9 @@
     formalParameter.accept(builder);
     List<ParameterElement> parameters = holder.parameters;
     expect(parameters, hasLength(1));
+
     ParameterElement parameter = parameters[0];
+    var typeElement = parameter.type.element as GenericFunctionTypeElementImpl;
     expect(parameter, isNotNull);
     expect(parameter.name, parameterName);
     expect(parameter.initializer, isNull);
@@ -507,7 +510,7 @@
     expect(parameter.isFinal, isFalse);
     expect(parameter.isSynthetic, isFalse);
     expect(parameter.parameterKind, ParameterKind.REQUIRED);
-    expect(parameter.typeParameters, hasLength(1));
+    expect(typeElement.typeParameters, hasLength(1));
     _assertVisibleRange(parameter, 100, 110);
   }
 
@@ -1852,7 +1855,9 @@
     ElementHolder holder = buildElementsForAst(formalParameter);
     List<ParameterElement> parameters = holder.parameters;
     expect(parameters, hasLength(1));
+
     ParameterElement parameter = parameters[0];
+    var typeElement = parameter.type.element as GenericFunctionTypeElementImpl;
     expect(parameter, isNotNull);
     expect(parameter.name, parameterName);
     expect(parameter.initializer, isNull);
@@ -1860,7 +1865,7 @@
     expect(parameter.isFinal, isFalse);
     expect(parameter.isSynthetic, isFalse);
     expect(parameter.parameterKind, ParameterKind.REQUIRED);
-    expect(parameter.parameters, hasLength(1));
+    expect(typeElement.parameters, hasLength(1));
   }
 
   void test_visitFormalParameterList() {
diff --git a/pkg/analyzer/test/error/error_test.dart b/pkg/analyzer/test/error/error_test.dart
index b8d81de..a33f0f2 100644
--- a/pkg/analyzer/test/error/error_test.dart
+++ b/pkg/analyzer/test/error/error_test.dart
@@ -6,6 +6,7 @@
 import 'dart:io';
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:front_end/src/testing/package_root.dart' as package_root;
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -24,9 +25,9 @@
 
   List<String> get rootComponents {
     if (_rootComponents == null) {
-      List<String> components = path.split(Platform.script.toFilePath());
-      _rootComponents =
-          components.sublist(0, components.indexOf('analyzer') + 1);
+      List<String> components = path.split(package_root.packageRoot);
+      components.add('analyzer');
+      _rootComponents = components;
     }
     return _rootComponents;
   }
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 3c3ac72..205f1c1 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -484,7 +484,7 @@
   void test_toUri() {
     String path = provider.convertPath('/foo/directory');
     Folder folder = provider.newFolder(path);
-    expect(folder.toUri(), provider.pathContext.toUri(path));
+    expect(folder.toUri(), provider.pathContext.toUri(path + '/'));
   }
 
   /**
@@ -681,7 +681,7 @@
     provider.newFolder(path);
     expect(() {
       provider.deleteFile(path);
-    }, throwsA(new isInstanceOf<ArgumentError>()));
+    }, throwsArgumentError);
     expect(provider.getResource(path), new isInstanceOf<Folder>());
   }
 
@@ -689,7 +689,7 @@
     String path = provider.convertPath('/my/file');
     expect(() {
       provider.deleteFile(path);
-    }, throwsA(new isInstanceOf<ArgumentError>()));
+    }, throwsArgumentError);
     Resource file = provider.getResource(path);
     expect(file, isNotNull);
     expect(file.exists, isFalse);
@@ -745,7 +745,7 @@
     provider.newFolder(path);
     expect(() {
       provider.modifyFile(path, 'contents');
-    }, throwsA(new isInstanceOf<ArgumentError>()));
+    }, throwsArgumentError);
     expect(provider.getResource(path), new isInstanceOf<Folder>());
   }
 
@@ -753,7 +753,7 @@
     String path = provider.convertPath('/my/file');
     expect(() {
       provider.modifyFile(path, 'contents');
-    }, throwsA(new isInstanceOf<ArgumentError>()));
+    }, throwsArgumentError);
     Resource file = provider.getResource(path);
     expect(file, isNotNull);
     expect(file.exists, isFalse);
@@ -784,7 +784,7 @@
     provider.newFile(provider.convertPath('/my/file'), 'qwerty');
     expect(() {
       provider.newFolder(provider.convertPath('/my/file'));
-    }, throwsA(new isInstanceOf<ArgumentError>()));
+    }, throwsArgumentError);
   }
 
   void test_newFolder_alreadyExists_asFolder() {
@@ -797,13 +797,13 @@
   void test_newFolder_emptyPath() {
     expect(() {
       provider.newFolder('');
-    }, throwsA(new isInstanceOf<ArgumentError>()));
+    }, throwsArgumentError);
   }
 
   void test_newFolder_notAbsolute() {
     expect(() {
       provider.newFolder('not/absolute');
-    }, throwsA(new isInstanceOf<ArgumentError>()));
+    }, throwsArgumentError);
   }
 
   test_watch_createFile() {
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 5158c90..47fa637 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -6113,6 +6113,18 @@
     verify([source]);
   }
 
+  test_test_fieldInitializerOutsideConstructor_topLevelFunction() async {
+    Source source = addSource(r'''
+f(this.x(y)) {}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR,
+      CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+    ]);
+    verify([source]);
+  }
+
   test_typeAliasCannotReferenceItself_11987() async {
     Source source = addSource(r'''
 typedef void F(List<G> l);
@@ -6144,6 +6156,14 @@
     verify([source]);
   }
 
+  test_typeAliasCannotReferenceItself_functionTypedParameter_returnType() async {
+    Source source = addSource("typedef A(A b());");
+    await computeAnalysisResult(source);
+    assertErrors(
+        source, [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]);
+    verify([source]);
+  }
+
   test_typeAliasCannotReferenceItself_parameterType_named() async {
     Source source = addSource("typedef A({A a});");
     await computeAnalysisResult(source);
diff --git a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
new file mode 100644
index 0000000..8f59f00
--- /dev/null
+++ b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
@@ -0,0 +1,1025 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'non_error_resolver_driver_test.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(NonErrorResolverTest_Kernel);
+  });
+}
+
+@reflectiveTest
+class NonErrorResolverTest_Kernel extends NonErrorResolverTest_Driver {
+  @override
+  bool get enableKernelDriver => true;
+
+  @override
+  @failingTest
+  test_ambiguousExport() async {
+    return super.test_ambiguousExport();
+  }
+
+  @override
+  @failingTest
+  test_ambiguousExport_combinators_hide() async {
+    return super.test_ambiguousExport_combinators_hide();
+  }
+
+  @override
+  @failingTest
+  test_ambiguousExport_combinators_show() async {
+    return super.test_ambiguousExport_combinators_show();
+  }
+
+  @override
+  @failingTest
+  test_ambiguousExport_sameDeclaration() async {
+    return super.test_ambiguousExport_sameDeclaration();
+  }
+
+  @override
+  @failingTest
+  test_ambiguousImport_showCombinator() async {
+    return super.test_ambiguousImport_showCombinator();
+  }
+
+  @override
+  @failingTest
+  test_argumentTypeNotAssignable_classWithCall_Function() async {
+    return super.test_argumentTypeNotAssignable_classWithCall_Function();
+  }
+
+  @override
+  @failingTest
+  test_argumentTypeNotAssignable_fieldFormalParameterElement_member() async {
+    return super
+        .test_argumentTypeNotAssignable_fieldFormalParameterElement_member();
+  }
+
+  @override
+  @failingTest
+  test_argumentTypeNotAssignable_invocation_functionParameter_generic() async {
+    fail('This test fails only in checked mode.');
+    return super
+        .test_argumentTypeNotAssignable_invocation_functionParameter_generic();
+  }
+
+  @override
+  @failingTest
+  test_assignmentToFinals_importWithPrefix() async {
+    return super.test_assignmentToFinals_importWithPrefix();
+  }
+
+  @override
+  @failingTest
+  test_async_flattened() async {
+    return super.test_async_flattened();
+  }
+
+  @override
+  @failingTest
+  test_async_future_int_with_return_future_int() async {
+    return super.test_async_future_int_with_return_future_int();
+  }
+
+  @override
+  @failingTest
+  test_caseExpressionTypeImplementsEquals() async {
+    return super.test_caseExpressionTypeImplementsEquals();
+  }
+
+  @override
+  @failingTest
+  test_caseExpressionTypeImplementsEquals_Object() async {
+    return super.test_caseExpressionTypeImplementsEquals_Object();
+  }
+
+  @override
+  @failingTest
+  test_commentReference_beforeMethod() async {
+    fail('This test fails only in checked mode.');
+    return super.test_commentReference_beforeMethod();
+  }
+
+  @override
+  @failingTest
+  test_conflictingConstructorNameAndMember_setter() async {
+    return super.test_conflictingConstructorNameAndMember_setter();
+  }
+
+  @override
+  @failingTest
+  test_const_constructor_with_named_generic_parameter() async {
+    return super.test_const_constructor_with_named_generic_parameter();
+  }
+
+  @override
+  @failingTest
+  test_const_dynamic() async {
+    return super.test_const_dynamic();
+  }
+
+  @override
+  @failingTest
+  test_const_imported_defaultParameterValue_withImportPrefix() async {
+    return super.test_const_imported_defaultParameterValue_withImportPrefix();
+  }
+
+  @override
+  @failingTest
+  test_constConstructorWithNonConstSuper_unresolved() async {
+    return super.test_constConstructorWithNonConstSuper_unresolved();
+  }
+
+  @override
+  @failingTest
+  test_constConstructorWithNonFinalField_finalInstanceVar() async {
+    return super.test_constConstructorWithNonFinalField_finalInstanceVar();
+  }
+
+  @override
+  @failingTest
+  test_constDeferredClass_new() async {
+    return super.test_constDeferredClass_new();
+  }
+
+  @override
+  @failingTest
+  test_constEval_functionTypeLiteral() async {
+    return super.test_constEval_functionTypeLiteral();
+  }
+
+  @override
+  @failingTest
+  test_constEval_propertyExtraction_fieldStatic_targetType() async {
+    return super.test_constEval_propertyExtraction_fieldStatic_targetType();
+  }
+
+  @override
+  @failingTest
+  test_constEval_propertyExtraction_methodStatic_targetType() async {
+    return super.test_constEval_propertyExtraction_methodStatic_targetType();
+  }
+
+  @override
+  @failingTest
+  test_constEval_symbol() async {
+    return super.test_constEval_symbol();
+  }
+
+  @override
+  @failingTest
+  test_constEvalTypeBoolNumString_equal() async {
+    return super.test_constEvalTypeBoolNumString_equal();
+  }
+
+  @override
+  @failingTest
+  test_constEvalTypeBoolNumString_notEqual() async {
+    return super.test_constEvalTypeBoolNumString_notEqual();
+  }
+
+  @override
+  @failingTest
+  test_constEvelTypeNum_String() async {
+    return super.test_constEvelTypeNum_String();
+  }
+
+  @override
+  @failingTest
+  test_constMapKeyExpressionTypeImplementsEquals_abstract() async {
+    return super.test_constMapKeyExpressionTypeImplementsEquals_abstract();
+  }
+
+  @override
+  @failingTest
+  test_constNotInitialized_field() async {
+    return super.test_constNotInitialized_field();
+  }
+
+  @override
+  @failingTest
+  test_constRedirectSkipsSupertype() async {
+    return super.test_constRedirectSkipsSupertype();
+  }
+
+  @override
+  @failingTest
+  test_constructorDeclaration_scope_signature() async {
+    return super.test_constructorDeclaration_scope_signature();
+  }
+
+  @override
+  @failingTest
+  test_constWithNonConstantArgument_constField() async {
+    return super.test_constWithNonConstantArgument_constField();
+  }
+
+  @override
+  @failingTest
+  test_constWithTypeParameters_direct() async {
+    return super.test_constWithTypeParameters_direct();
+  }
+
+  @override
+  @failingTest
+  test_constWithUndefinedConstructor() async {
+    return super.test_constWithUndefinedConstructor();
+  }
+
+  @override
+  @failingTest
+  test_defaultValueInFunctionTypedParameter_named() async {
+    fail('This test fails only in checked mode.');
+    return super.test_defaultValueInFunctionTypedParameter_named();
+  }
+
+  @override
+  @failingTest
+  test_defaultValueInFunctionTypedParameter_optional() async {
+    fail('This test fails only in checked mode.');
+    return super.test_defaultValueInFunctionTypedParameter_optional();
+  }
+
+  @override
+  @failingTest
+  test_deprecatedMemberUse_hide() async {
+    return super.test_deprecatedMemberUse_hide();
+  }
+
+  @override
+  @failingTest
+  test_duplicateDefinition_emptyName() async {
+    return super.test_duplicateDefinition_emptyName();
+  }
+
+  @override
+  @failingTest
+  test_exportDuplicatedLibraryUnnamed() async {
+    return super.test_exportDuplicatedLibraryUnnamed();
+  }
+
+  @override
+  @failingTest
+  test_exportOfNonLibrary_libraryDeclared() async {
+    return super.test_exportOfNonLibrary_libraryDeclared();
+  }
+
+  @override
+  @failingTest
+  test_exportOfNonLibrary_libraryNotDeclared() async {
+    return super.test_exportOfNonLibrary_libraryNotDeclared();
+  }
+
+  @override
+  @failingTest
+  test_fieldFormalParameter_functionTyped_named() async {
+    return super.test_fieldFormalParameter_functionTyped_named();
+  }
+
+  @override
+  @failingTest
+  test_fieldInitializedInInitializerAndDeclaration_fieldNotFinal() async {
+    return super
+        .test_fieldInitializedInInitializerAndDeclaration_fieldNotFinal();
+  }
+
+  @override
+  @failingTest
+  test_fieldInitializerOutsideConstructor() async {
+    return super.test_fieldInitializerOutsideConstructor();
+  }
+
+  @override
+  @failingTest
+  test_fieldInitializerOutsideConstructor_defaultParameters() async {
+    return super.test_fieldInitializerOutsideConstructor_defaultParameters();
+  }
+
+  @override
+  @failingTest
+  test_fieldInitializerRedirectingConstructor_super() async {
+    return super.test_fieldInitializerRedirectingConstructor_super();
+  }
+
+  @override
+  @failingTest
+  test_finalInitializedInDeclarationAndConstructor_initializingFormal() async {
+    return super
+        .test_finalInitializedInDeclarationAndConstructor_initializingFormal();
+  }
+
+  @override
+  @failingTest
+  test_finalNotInitialized_atDeclaration() async {
+    return super.test_finalNotInitialized_atDeclaration();
+  }
+
+  @override
+  @failingTest
+  test_finalNotInitialized_fieldFormal() async {
+    return super.test_finalNotInitialized_fieldFormal();
+  }
+
+  @override
+  @failingTest
+  test_finalNotInitialized_functionTypedFieldFormal() async {
+    return super.test_finalNotInitialized_functionTypedFieldFormal();
+  }
+
+  @override
+  @failingTest
+  test_finalNotInitialized_hasNativeClause_hasConstructor() async {
+    return super.test_finalNotInitialized_hasNativeClause_hasConstructor();
+  }
+
+  @override
+  @failingTest
+  test_finalNotInitialized_hasNativeClause_noConstructor() async {
+    fail('This test fails only in checked mode.');
+    return super.test_finalNotInitialized_hasNativeClause_noConstructor();
+  }
+
+  @override
+  @failingTest
+  test_finalNotInitialized_redirectingConstructor() async {
+    return super.test_finalNotInitialized_redirectingConstructor();
+  }
+
+  @override
+  @failingTest
+  test_functionDeclaration_scope_signature() async {
+    return super.test_functionDeclaration_scope_signature();
+  }
+
+  @override
+  @failingTest
+  test_functionTypeAlias_scope_signature() async {
+    return super.test_functionTypeAlias_scope_signature();
+  }
+
+  @override
+  @failingTest
+  test_genericTypeAlias_castsAndTypeChecks_hasTypeParameters() async {
+    return super.test_genericTypeAlias_castsAndTypeChecks_hasTypeParameters();
+  }
+
+  @override
+  @failingTest
+  test_genericTypeAlias_castsAndTypeChecks_noTypeParameters() async {
+    return super.test_genericTypeAlias_castsAndTypeChecks_noTypeParameters();
+  }
+
+  @override
+  @failingTest
+  test_genericTypeAlias_fieldAndReturnType_noTypeParameters() async {
+    return super.test_genericTypeAlias_fieldAndReturnType_noTypeParameters();
+  }
+
+  @override
+  @failingTest
+  test_genericTypeAlias_fieldAndReturnType_typeParameters_arguments() async {
+    return super
+        .test_genericTypeAlias_fieldAndReturnType_typeParameters_arguments();
+  }
+
+  @override
+  @failingTest
+  test_genericTypeAlias_fieldAndReturnType_typeParameters_noArguments() async {
+    return super
+        .test_genericTypeAlias_fieldAndReturnType_typeParameters_noArguments();
+  }
+
+  @override
+  @failingTest
+  test_genericTypeAlias_invalidGenericFunctionType() async {
+    return super.test_genericTypeAlias_invalidGenericFunctionType();
+  }
+
+  @override
+  @failingTest
+  test_genericTypeAlias_noTypeParameters() async {
+    return super.test_genericTypeAlias_noTypeParameters();
+  }
+
+  @override
+  @failingTest
+  test_genericTypeAlias_typeParameters() async {
+    return super.test_genericTypeAlias_typeParameters();
+  }
+
+  @override
+  @failingTest
+  test_implicitThisReferenceInInitializer_constructorName() async {
+    return super.test_implicitThisReferenceInInitializer_constructorName();
+  }
+
+  @override
+  @failingTest
+  test_implicitThisReferenceInInitializer_topLevelField() async {
+    return super.test_implicitThisReferenceInInitializer_topLevelField();
+  }
+
+  @override
+  @failingTest
+  test_importDuplicatedLibraryName() async {
+    return super.test_importDuplicatedLibraryName();
+  }
+
+  @override
+  @failingTest
+  test_importDuplicatedLibraryUnnamed() async {
+    return super.test_importDuplicatedLibraryUnnamed();
+  }
+
+  @override
+  @failingTest
+  test_importOfNonLibrary_libraryDeclared() async {
+    return super.test_importOfNonLibrary_libraryDeclared();
+  }
+
+  @override
+  @failingTest
+  test_importOfNonLibrary_libraryNotDeclared() async {
+    return super.test_importOfNonLibrary_libraryNotDeclared();
+  }
+
+  @override
+  @failingTest
+  test_importPrefixes_withFirstLetterDifference() async {
+    return super.test_importPrefixes_withFirstLetterDifference();
+  }
+
+  @override
+  @failingTest
+  test_inconsistentMethodInheritance_accessors_typeParameter2() async {
+    return super.test_inconsistentMethodInheritance_accessors_typeParameter2();
+  }
+
+  @override
+  @failingTest
+  test_inconsistentMethodInheritance_accessors_typeParameters1() async {
+    return super.test_inconsistentMethodInheritance_accessors_typeParameters1();
+  }
+
+  @override
+  @failingTest
+  test_inconsistentMethodInheritance_accessors_typeParameters_diamond() async {
+    return super
+        .test_inconsistentMethodInheritance_accessors_typeParameters_diamond();
+  }
+
+  @override
+  @failingTest
+  test_inconsistentMethodInheritance_methods_typeParameter2() async {
+    return super.test_inconsistentMethodInheritance_methods_typeParameter2();
+  }
+
+  @override
+  @failingTest
+  test_inconsistentMethodInheritance_methods_typeParameters1() async {
+    return super.test_inconsistentMethodInheritance_methods_typeParameters1();
+  }
+
+  @override
+  @failingTest
+  test_inconsistentMethodInheritance_overrideTrumpsInherits_getter() async {
+    return super
+        .test_inconsistentMethodInheritance_overrideTrumpsInherits_getter();
+  }
+
+  @override
+  @failingTest
+  test_inconsistentMethodInheritance_overrideTrumpsInherits_method() async {
+    return super
+        .test_inconsistentMethodInheritance_overrideTrumpsInherits_method();
+  }
+
+  @override
+  @failingTest
+  test_inconsistentMethodInheritance_overrideTrumpsInherits_setter() async {
+    return super
+        .test_inconsistentMethodInheritance_overrideTrumpsInherits_setter();
+  }
+
+  @override
+  @failingTest
+  test_initializingFormalForNonExistentField() async {
+    return super.test_initializingFormalForNonExistentField();
+  }
+
+  @override
+  @failingTest
+  test_instance_creation_inside_annotation() async {
+    return super.test_instance_creation_inside_annotation();
+  }
+
+  @override
+  @failingTest
+  test_invalidAnnotation_constantVariable_field() async {
+    return super.test_invalidAnnotation_constantVariable_field();
+  }
+
+  @override
+  @failingTest
+  test_invalidAnnotation_constantVariable_field_importWithPrefix() async {
+    return super
+        .test_invalidAnnotation_constantVariable_field_importWithPrefix();
+  }
+
+  @override
+  @failingTest
+  test_invalidAnnotation_constantVariable_topLevel() async {
+    return super.test_invalidAnnotation_constantVariable_topLevel();
+  }
+
+  @override
+  @failingTest
+  test_invalidAssignment_compoundAssignment() async {
+    return super.test_invalidAssignment_compoundAssignment();
+  }
+
+  @override
+  @failingTest
+  test_invalidAssignment_defaultValue_named() async {
+    return super.test_invalidAssignment_defaultValue_named();
+  }
+
+  @override
+  @failingTest
+  test_invalidAssignment_defaultValue_optional() async {
+    return super.test_invalidAssignment_defaultValue_optional();
+  }
+
+  @override
+  @failingTest
+  test_invalidAssignment_implicitlyImplementFunctionViaCall_1() async {
+    return super.test_invalidAssignment_implicitlyImplementFunctionViaCall_1();
+  }
+
+  @override
+  @failingTest
+  test_invalidAssignment_implicitlyImplementFunctionViaCall_2() async {
+    return super.test_invalidAssignment_implicitlyImplementFunctionViaCall_2();
+  }
+
+  @override
+  @failingTest
+  test_invalidAssignment_implicitlyImplementFunctionViaCall_3() async {
+    return super.test_invalidAssignment_implicitlyImplementFunctionViaCall_3();
+  }
+
+  @override
+  @failingTest
+  test_invalidAssignment_implicitlyImplementFunctionViaCall_4() async {
+    return super.test_invalidAssignment_implicitlyImplementFunctionViaCall_4();
+  }
+
+  @override
+  @failingTest
+  test_invalidOverrideDifferentDefaultValues_named() async {
+    return super.test_invalidOverrideDifferentDefaultValues_named();
+  }
+
+  @override
+  @failingTest
+  test_invalidOverrideDifferentDefaultValues_named_function() async {
+    return super.test_invalidOverrideDifferentDefaultValues_named_function();
+  }
+
+  @override
+  @failingTest
+  test_invalidOverrideDifferentDefaultValues_positional() async {
+    return super.test_invalidOverrideDifferentDefaultValues_positional();
+  }
+
+  @override
+  @failingTest
+  test_invalidOverrideDifferentDefaultValues_positional_changedOrder() async {
+    return super
+        .test_invalidOverrideDifferentDefaultValues_positional_changedOrder();
+  }
+
+  @override
+  @failingTest
+  test_invalidOverrideDifferentDefaultValues_positional_function() async {
+    return super
+        .test_invalidOverrideDifferentDefaultValues_positional_function();
+  }
+
+  @override
+  @failingTest
+  test_invalidOverrideReturnType_returnType_parameterizedTypes() async {
+    return super.test_invalidOverrideReturnType_returnType_parameterizedTypes();
+  }
+
+  @override
+  @failingTest
+  test_invocationOfNonFunction_functionTypeTypeParameter() async {
+    return super.test_invocationOfNonFunction_functionTypeTypeParameter();
+  }
+
+  @override
+  @failingTest
+  test_invocationOfNonFunction_proxyOnFunctionClass() async {
+    return super.test_invocationOfNonFunction_proxyOnFunctionClass();
+  }
+
+  @override
+  @failingTest
+  test_issue_24191() async {
+    return super.test_issue_24191();
+  }
+
+  @override
+  @failingTest
+  test_listElementTypeNotAssignable() async {
+    return super.test_listElementTypeNotAssignable();
+  }
+
+  @override
+  @failingTest
+  test_loadLibraryDefined() async {
+    fail('This test fails only in checked mode.');
+    return super.test_loadLibraryDefined();
+  }
+
+  @override
+  @failingTest
+  test_mapKeyTypeNotAssignable() async {
+    return super.test_mapKeyTypeNotAssignable();
+  }
+
+  @override
+  @failingTest
+  test_memberWithClassName_setter() async {
+    return super.test_memberWithClassName_setter();
+  }
+
+  @override
+  @failingTest
+  test_methodDeclaration_scope_signature() async {
+    return super.test_methodDeclaration_scope_signature();
+  }
+
+  @override
+  @failingTest
+  test_nativeConstConstructor() async {
+    return super.test_nativeConstConstructor();
+  }
+
+  @override
+  @failingTest
+  test_nativeFunctionBodyInNonSDKCode_function() async {
+    return super.test_nativeFunctionBodyInNonSDKCode_function();
+  }
+
+  @override
+  @failingTest
+  test_newWithUndefinedConstructor() async {
+    return super.test_newWithUndefinedConstructor();
+  }
+
+  @override
+  @failingTest
+  test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter() async {
+    return super.test_nonAbstractClassInheritsAbstractMemberOne_mixin_getter();
+  }
+
+  @override
+  @failingTest
+  test_nonAbstractClassInheritsAbstractMemberOne_mixin_setter() async {
+    return super.test_nonAbstractClassInheritsAbstractMemberOne_mixin_setter();
+  }
+
+  @override
+  @failingTest
+  test_nonAbstractClassInheritsAbstractMemberOne_overridesMethodInObject() async {
+    return super
+        .test_nonAbstractClassInheritsAbstractMemberOne_overridesMethodInObject();
+  }
+
+  @override
+  @failingTest
+  test_nonConstantDefaultValue_constField() async {
+    return super.test_nonConstantDefaultValue_constField();
+  }
+
+  @override
+  @failingTest
+  test_nonConstantDefaultValue_function_named() async {
+    return super.test_nonConstantDefaultValue_function_named();
+  }
+
+  @override
+  @failingTest
+  test_nonConstantDefaultValue_function_positional() async {
+    return super.test_nonConstantDefaultValue_function_positional();
+  }
+
+  @override
+  @failingTest
+  test_nonConstantDefaultValue_inConstructor_named() async {
+    return super.test_nonConstantDefaultValue_inConstructor_named();
+  }
+
+  @override
+  @failingTest
+  test_nonConstantDefaultValue_inConstructor_positional() async {
+    return super.test_nonConstantDefaultValue_inConstructor_positional();
+  }
+
+  @override
+  @failingTest
+  test_nonConstantDefaultValue_method_named() async {
+    return super.test_nonConstantDefaultValue_method_named();
+  }
+
+  @override
+  @failingTest
+  test_nonConstantDefaultValue_method_positional() async {
+    return super.test_nonConstantDefaultValue_method_positional();
+  }
+
+  @override
+  @failingTest
+  test_nonConstantDefaultValue_typedConstList() async {
+    return super.test_nonConstantDefaultValue_typedConstList();
+  }
+
+  @override
+  @failingTest
+  test_nonConstantValueInInitializer_namedArgument() async {
+    return super.test_nonConstantValueInInitializer_namedArgument();
+  }
+
+  @override
+  @failingTest
+  test_nonConstCaseExpression_constField() async {
+    return super.test_nonConstCaseExpression_constField();
+  }
+
+  @override
+  @failingTest
+  test_nonConstListElement_constField() async {
+    return super.test_nonConstListElement_constField();
+  }
+
+  @override
+  @failingTest
+  test_nonConstMapKey_constField() async {
+    return super.test_nonConstMapKey_constField();
+  }
+
+  @override
+  @failingTest
+  test_nonConstMapValue_constField() async {
+    return super.test_nonConstMapValue_constField();
+  }
+
+  @override
+  @failingTest
+  test_nonConstValueInInitializer_binary_bool() async {
+    return super.test_nonConstValueInInitializer_binary_bool();
+  }
+
+  @override
+  @failingTest
+  test_nonConstValueInInitializer_binary_dynamic() async {
+    return super.test_nonConstValueInInitializer_binary_dynamic();
+  }
+
+  @override
+  @failingTest
+  test_nonConstValueInInitializer_binary_int() async {
+    return super.test_nonConstValueInInitializer_binary_int();
+  }
+
+  @override
+  @failingTest
+  test_nonConstValueInInitializer_binary_num() async {
+    return super.test_nonConstValueInInitializer_binary_num();
+  }
+
+  @override
+  @failingTest
+  test_nonConstValueInInitializer_redirecting() async {
+    return super.test_nonConstValueInInitializer_redirecting();
+  }
+
+  @override
+  @failingTest
+  test_nonConstValueInInitializer_unary() async {
+    return super.test_nonConstValueInInitializer_unary();
+  }
+
+  @override
+  @failingTest
+  test_nonGenerativeConstructor() async {
+    return super.test_nonGenerativeConstructor();
+  }
+
+  @override
+  @failingTest
+  test_parameterDefaultDoesNotReferToParameterName() async {
+    return super.test_parameterDefaultDoesNotReferToParameterName();
+  }
+
+  @override
+  @failingTest
+  test_propagateTypeArgs_intoSupertype() async {
+    return super.test_propagateTypeArgs_intoSupertype();
+  }
+
+  @override
+  @failingTest
+  test_proxy_annotation_prefixed() async {
+    return super.test_proxy_annotation_prefixed();
+  }
+
+  @override
+  @failingTest
+  test_proxy_annotation_prefixed2() async {
+    return super.test_proxy_annotation_prefixed2();
+  }
+
+  @override
+  @failingTest
+  test_proxy_annotation_prefixed3() async {
+    return super.test_proxy_annotation_prefixed3();
+  }
+
+  @override
+  @failingTest
+  test_proxy_annotation_proxyHasPrefixedIdentifier() async {
+    return super.test_proxy_annotation_proxyHasPrefixedIdentifier();
+  }
+
+  @override
+  @failingTest
+  test_proxy_annotation_simple() async {
+    return super.test_proxy_annotation_simple();
+  }
+
+  @override
+  @failingTest
+  test_proxy_annotation_superclass() async {
+    return super.test_proxy_annotation_superclass();
+  }
+
+  @override
+  @failingTest
+  test_proxy_annotation_superclass_mixin() async {
+    return super.test_proxy_annotation_superclass_mixin();
+  }
+
+  @override
+  @failingTest
+  test_proxy_annotation_superinterface() async {
+    return super.test_proxy_annotation_superinterface();
+  }
+
+  @override
+  @failingTest
+  test_recursiveConstructorRedirect() async {
+    return super.test_recursiveConstructorRedirect();
+  }
+
+  @override
+  @failingTest
+  test_redirectToNonConstConstructor() async {
+    return super.test_redirectToNonConstConstructor();
+  }
+
+  @override
+  @failingTest
+  test_referenceToDeclaredVariableInInitializer_constructorName() async {
+    return super
+        .test_referenceToDeclaredVariableInInitializer_constructorName();
+  }
+
+  @override
+  @failingTest
+  test_returnOfInvalidType_dynamicAsTypeArgument() async {
+    return super.test_returnOfInvalidType_dynamicAsTypeArgument();
+  }
+
+  @override
+  @failingTest
+  test_reversedTypeArguments() async {
+    return super.test_reversedTypeArguments();
+  }
+
+  @override
+  @failingTest
+  test_sharedDeferredPrefix() async {
+    return super.test_sharedDeferredPrefix();
+  }
+
+  @override
+  @failingTest
+  test_staticAccessToInstanceMember_annotation() async {
+    return super.test_staticAccessToInstanceMember_annotation();
+  }
+
+  @override
+  @failingTest
+  test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment() async {
+    fail('This test fails only in checked mode.');
+    return super
+        .test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_noAssignment();
+  }
+
+  @override
+  @failingTest
+  test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment() async {
+    fail('This test fails only in checked mode.');
+    return super
+        .test_typePromotion_conditional_useInThen_accessedInClosure_noAssignment();
+  }
+
+  @override
+  @failingTest
+  test_typePromotion_if_accessedInClosure_noAssignment() async {
+    fail('This test fails only in checked mode.');
+    return super.test_typePromotion_if_accessedInClosure_noAssignment();
+  }
+
+  @override
+  @failingTest
+  test_undefinedConstructorInInitializer_explicit_named() async {
+    return super.test_undefinedConstructorInInitializer_explicit_named();
+  }
+
+  @override
+  @failingTest
+  test_undefinedConstructorInInitializer_redirecting() async {
+    return super.test_undefinedConstructorInInitializer_redirecting();
+  }
+
+  @override
+  @failingTest
+  test_undefinedGetter_static_conditionalAccess() async {
+    return super.test_undefinedGetter_static_conditionalAccess();
+  }
+
+  @override
+  @failingTest
+  test_undefinedGetter_typeSubstitution() async {
+    return super.test_undefinedGetter_typeSubstitution();
+  }
+
+  @override
+  @failingTest
+  test_undefinedIdentifier_synthetic_whenExpression() async {
+    return super.test_undefinedIdentifier_synthetic_whenExpression();
+  }
+
+  @override
+  @failingTest
+  test_undefinedIdentifier_synthetic_whenMethodName() async {
+    return super.test_undefinedIdentifier_synthetic_whenMethodName();
+  }
+
+  @override
+  @failingTest
+  test_undefinedOperator_tilde() async {
+    return super.test_undefinedOperator_tilde();
+  }
+
+  @override
+  @failingTest
+  test_unqualifiedReferenceToNonLocalStaticMember_fromComment_new() async {
+    return super
+        .test_unqualifiedReferenceToNonLocalStaticMember_fromComment_new();
+  }
+
+  @override
+  @failingTest
+  test_unusedShownName_unresolved() async {
+    return super.test_unusedShownName_unresolved();
+  }
+
+  @override
+  @failingTest
+  test_uriDoesNotExist_dll() async {
+    return super.test_uriDoesNotExist_dll();
+  }
+
+  @override
+  @failingTest
+  test_uriDoesNotExist_dylib() async {
+    return super.test_uriDoesNotExist_dylib();
+  }
+
+  @override
+  @failingTest
+  test_uriDoesNotExist_so() async {
+    return super.test_uriDoesNotExist_so();
+  }
+}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index c518a0e..4b2b19e 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -1872,6 +1872,19 @@
     verify([source]);
   }
 
+  test_fieldFormalParameter_functionTyped_named() async {
+    Source source = addSource(r'''
+class C {
+  final Function field;
+
+  C({String this.field(int value)});
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   test_fieldInitializedByMultipleInitializers() async {
     Source source = addSource(r'''
 class A {
diff --git a/pkg/analyzer/test/generated/package_test.dart b/pkg/analyzer/test/generated/package_test.dart
index 241078b..4dd7bf4 100644
--- a/pkg/analyzer/test/generated/package_test.dart
+++ b/pkg/analyzer/test/generated/package_test.dart
@@ -4,6 +4,7 @@
 
 library analyzer.test.generated.package_test;
 
+import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/package.dart';
@@ -67,7 +68,7 @@
 
     DependencyFinder finder = new DependencyFinder(resourceProvider);
     expect(() => finder.transitiveDependenciesFor(packageMap, packagePath),
-        throws);
+        throwsA(new isInstanceOf<AnalysisException>()));
   }
 
   void test_transitiveDependenciesFor_noDependencies() {
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index dc9ea66..6f0daff 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -51,6 +51,12 @@
     }
   }
 
+  void expectInOneOf(List<String> events) {
+    if (_stack.isEmpty || !events.contains(_stack.last)) {
+      fail('Expected one of $events, but found $_stack');
+    }
+  }
+
   void end(String event) {
     expectIn(event);
     _stack.removeLast();
@@ -617,12 +623,6 @@
   }
 
   @override
-  void handleNativeClause(Token nativeToken, bool hasName) {
-    expectIn('ClassDeclaration');
-    listener.handleNativeClause(nativeToken, hasName);
-  }
-
-  @override
   void endClassDeclaration(
       int interfacesCount,
       Token beginToken,
@@ -651,9 +651,10 @@
   }
 
   @override
-  void endConditionalUri(Token ifKeyword, Token equalitySign) {
+  void endConditionalUri(
+      Token ifKeyword, Token leftParen, Token equalSign, Token rightParen) {
     end('ConditionalUri');
-    listener.endConditionalUri(ifKeyword, equalitySign);
+    listener.endConditionalUri(ifKeyword, leftParen, equalSign, rightParen);
   }
 
   @override
@@ -915,9 +916,9 @@
   }
 
   @override
-  void endMetadataStar(int count, bool forParameter) {
+  void endMetadataStar(int count) {
     end('MetadataStar');
-    listener.endMetadataStar(count, forParameter);
+    listener.endMetadataStar(count);
   }
 
   @override
@@ -967,9 +968,10 @@
   }
 
   @override
-  void endPartOf(Token partKeyword, Token semicolon, bool hasName) {
+  void endPartOf(
+      Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
     end('PartOf');
-    listener.endPartOf(partKeyword, semicolon, hasName);
+    listener.endPartOf(partKeyword, ofKeyword, semicolon, hasName);
   }
 
   @override
@@ -1123,9 +1125,15 @@
   }
 
   @override
-  void handleBinaryExpression(Token token) {
-    listener.handleBinaryExpression(token);
-    // TODO(danrubel): implement handleBinaryExpression
+  void beginBinaryExpression(Token token) {
+    listener.beginBinaryExpression(token);
+    // TODO(danrubel): implement beginBinaryExpression
+  }
+
+  @override
+  void endBinaryExpression(Token token) {
+    listener.endBinaryExpression(token);
+    // TODO(danrubel): implement endBinaryExpression
   }
 
   @override
@@ -1142,8 +1150,8 @@
   }
 
   @override
-  void handleCatchBlock(Token onKeyword, Token catchKeyword) {
-    listener.handleCatchBlock(onKeyword, catchKeyword);
+  void handleCatchBlock(Token onKeyword, Token catchKeyword, Token comma) {
+    listener.handleCatchBlock(onKeyword, catchKeyword, comma);
     // TODO(danrubel): implement handleCatchBlock
   }
 
@@ -1314,6 +1322,30 @@
   }
 
   @override
+  void handleNativeClause(Token nativeToken, bool hasName) {
+    expectInOneOf(['ClassDeclaration', 'Method']);
+    listener.handleNativeClause(nativeToken, hasName);
+  }
+
+  @override
+  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
+    expectInOneOf(['Method']);
+    listener.handleNativeFunctionBody(nativeToken, semicolon);
+  }
+
+  @override
+  void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {
+    expectInOneOf(['Method']);
+    listener.handleNativeFunctionBodyIgnored(nativeToken, semicolon);
+  }
+
+  @override
+  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
+    expectInOneOf(['Method']);
+    listener.handleNativeFunctionBodySkipped(nativeToken, semicolon);
+  }
+
+  @override
   void handleNoArguments(Token token) {
     listener.handleNoArguments(token);
     // TODO(danrubel): implement handleNoArguments
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 77d50c5..12ef674 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -59,14 +59,7 @@
 
 @reflectiveTest
 class ClassMemberParserTest_Fasta extends FastaParserTestCase
-    with ClassMemberParserTestMixin {
-  @override
-  @failingTest
-  void test_parseConstructor_assert() {
-    // TODO(paulberry): Fasta doesn't support asserts in initializers
-    super.test_parseConstructor_assert();
-  }
-}
+    with ClassMemberParserTestMixin {}
 
 /**
  * Tests of the fasta parser based on [ComplexParserTestMixin].
@@ -313,24 +306,18 @@
   @override
   @failingTest
   void test_covariantTopLevelDeclaration_class() {
-    // TODO(brianwilkerson) Does not recover.
-    //   type 'FunctionDeclarationImpl' is not a subtype of type 'ClassDeclaration' of 'member' where
-    //     FunctionDeclarationImpl is from package:analyzer/src/dart/ast/ast.dart
-    //     ClassDeclaration is from package:analyzer/dart/ast/ast.dart
-    //
-    //   test/generated/parser_test.dart 2418:31                            FastaParserTestCase&ErrorParserTestMixin.test_covariantTopLevelDeclaration_class
+    // TODO(brianwilkerson) Wrong errors:
+    // Expected 1 errors of type ParserErrorCode.COVARIANT_TOP_LEVEL_DECLARATION, found 0;
+    // 0 errors of type ParserErrorCode.EXTRANEOUS_MODIFIER, found 1 (0)
     super.test_covariantTopLevelDeclaration_class();
   }
 
   @override
   @failingTest
   void test_covariantTopLevelDeclaration_enum() {
-    // TODO(brianwilkerson) Does not recover.
-    //   type 'FunctionDeclarationImpl' is not a subtype of type 'EnumDeclaration' of 'member' where
-    //   FunctionDeclarationImpl is from package:analyzer/src/dart/ast/ast.dart
-    //   EnumDeclaration is from package:analyzer/dart/ast/ast.dart
-    //
-    //   test/generated/parser_test.dart 2426:30                            FastaParserTestCase&ErrorParserTestMixin.test_covariantTopLevelDeclaration_enum
+    // TODO(brianwilkerson) Wrong errors:
+    // Expected 1 errors of type ParserErrorCode.COVARIANT_TOP_LEVEL_DECLARATION, found 0;
+    // 0 errors of type ParserErrorCode.EXTRANEOUS_MODIFIER, found 1 (0)
     super.test_covariantTopLevelDeclaration_enum();
   }
 
@@ -720,14 +707,6 @@
 
   @override
   @failingTest
-  void test_expectedTypeName_as() {
-    // TODO(brianwilkerson) Wrong errors:
-    // Expected 1 errors of type ParserErrorCode.EXPECTED_TYPE_NAME, found 0
-    super.test_expectedTypeName_as();
-  }
-
-  @override
-  @failingTest
   void test_expectedTypeName_as_void() {
     // TODO(brianwilkerson) Does not recover.
     //   Expected: true
@@ -741,14 +720,6 @@
 
   @override
   @failingTest
-  void test_expectedTypeName_is() {
-    // TODO(brianwilkerson) Wrong errors:
-    // Expected 1 errors of type ParserErrorCode.EXPECTED_TYPE_NAME, found 0
-    super.test_expectedTypeName_is();
-  }
-
-  @override
-  @failingTest
   void test_expectedTypeName_is_void() {
     // TODO(brianwilkerson) Does not recover.
     //   Expected: true
@@ -882,14 +853,6 @@
 
   @override
   @failingTest
-  void test_externalMethodWithBody() {
-    // TODO(brianwilkerson) Wrong errors:
-    // Expected 1 errors of type ParserErrorCode.EXTERNAL_METHOD_WITH_BODY, found 0
-    super.test_externalMethodWithBody();
-  }
-
-  @override
-  @failingTest
   void test_externalOperatorWithBody() {
     // TODO(brianwilkerson) Wrong errors:
     // Expected 1 errors of type ParserErrorCode.EXTERNAL_OPERATOR_WITH_BODY, found 0
@@ -1131,6 +1094,22 @@
     super.test_getterInFunction_expression_returnType();
   }
 
+  @failingTest
+  void test_getterNativeWithBody() {
+    createParser('String get m native "str" => 0;');
+    parser.parseClassMember('C') as MethodDeclaration;
+    if (!allowNativeClause) {
+      assertErrorsWithCodes([
+        ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION,
+        ParserErrorCode.EXTERNAL_METHOD_WITH_BODY,
+      ]);
+    } else {
+      assertErrorsWithCodes([
+        ParserErrorCode.EXTERNAL_METHOD_WITH_BODY,
+      ]);
+    }
+  }
+
   @override
   @failingTest
   void test_getterWithParameters() {
@@ -3113,6 +3092,8 @@
   @failingTest
   void
       test_parseAssignableExpression_expression_args_dot_typeArgumentComments() {
+    // TODO(brianwilkerson) Does not inject generic type arguments following a
+    // function-valued expression.
     super
         .test_parseAssignableExpression_expression_args_dot_typeArgumentComments();
   }
@@ -3120,78 +3101,82 @@
   @override
   @failingTest
   void test_parseAssignableExpression_expression_args_dot_typeArguments() {
+    // TODO(brianwilkerson) Does not parse generic type arguments following a
+    // function-valued expression.
     super.test_parseAssignableExpression_expression_args_dot_typeArguments();
   }
 
   @override
   @failingTest
   void test_parseCascadeSection_ia_typeArgumentComments() {
+    // TODO(brianwilkerson) Does not inject generic type arguments following an
+    // index expression.
     super.test_parseCascadeSection_ia_typeArgumentComments();
   }
 
   @override
   @failingTest
   void test_parseCascadeSection_ia_typeArguments() {
+    // TODO(brianwilkerson) Does not parse generic type arguments following an
+    // index expression.
     super.test_parseCascadeSection_ia_typeArguments();
   }
 
   @override
   @failingTest
   void test_parseCascadeSection_paa_typeArgumentComments() {
+    // TODO(brianwilkerson) Does not inject generic type arguments following a
+    // function-valued expression.
     super.test_parseCascadeSection_paa_typeArgumentComments();
   }
 
   @override
   @failingTest
   void test_parseCascadeSection_paa_typeArguments() {
+    // TODO(brianwilkerson) Does not parse generic type arguments following a
+    // function-valued expression.
     super.test_parseCascadeSection_paa_typeArguments();
   }
 
   @override
   @failingTest
   void test_parseCascadeSection_paapaa_typeArgumentComments() {
+    // TODO(brianwilkerson) Does not inject generic type arguments following a
+    // function-valued expression.
     super.test_parseCascadeSection_paapaa_typeArgumentComments();
   }
 
   @override
   @failingTest
   void test_parseCascadeSection_paapaa_typeArguments() {
+    // TODO(brianwilkerson) Does not parse generic type arguments following a
+    // function-valued expression.
     super.test_parseCascadeSection_paapaa_typeArguments();
   }
 
   @override
   @failingTest
-  void test_parseExpression_assign_compound() {
-    super.test_parseExpression_assign_compound();
-  }
-
-  @override
-  @failingTest
   void test_parseInstanceCreationExpression_type_named_typeArgumentComments() {
+    // TODO(brianwilkerson) Does not inject generic type arguments.
     super
         .test_parseInstanceCreationExpression_type_named_typeArgumentComments();
   }
 
   @override
-  void test_parseListLiteral_empty_oneToken_withComment() {
-    super.test_parseListLiteral_empty_oneToken_withComment();
-  }
-
-  @override
-  @failingTest
-  void test_parsePrimaryExpression_super() {
-    super.test_parsePrimaryExpression_super();
-  }
-
-  @override
   @failingTest
   void test_parseUnaryExpression_decrement_super() {
+    // TODO(brianwilkerson) Does not recover.
+    // Expected: TokenType:<MINUS>
+    //   Actual: TokenType:<MINUS_MINUS>
     super.test_parseUnaryExpression_decrement_super();
   }
 
   @override
   @failingTest
   void test_parseUnaryExpression_decrement_super_withComment() {
+    // TODO(brianwilkerson) Does not recover.
+    // Expected: TokenType:<MINUS>
+    //   Actual: TokenType:<MINUS_MINUS>
     super.test_parseUnaryExpression_decrement_super_withComment();
   }
 }
@@ -3216,19 +3201,12 @@
 
   @override
   set enableAssertInitializer(bool value) {
-    if (value == true) {
-      // TODO(paulberry,ahe): it looks like asserts in initializer lists are not
-      // supported by Fasta.
-      throw new UnimplementedError();
-    }
+    // Asserts in initializer lists are always anabled.
   }
 
   @override
   set enableLazyAssignmentOperators(bool value) {
-    // TODO: implement enableLazyAssignmentOperators
-    if (value == true) {
-      throw new UnimplementedError();
-    }
+    // Lazy assignment operators are always enabled
   }
 
   @override
@@ -3378,7 +3356,12 @@
   @override
   CompilationUnit parseDirectives(String source,
       [List<ErrorCode> errorCodes = const <ErrorCode>[]]) {
-    return _runParser(source, null, errorCodes);
+    // TODO(paulberry,ahe,danrubel): analyzer parser has the ability to
+    // stop parsing as soon as the first non-directive is encountered; this is
+    // useful for quickly traversing an import graph.  Consider adding a similar
+    // ability to Fasta's parser.
+    throw 'fasta parser does not have a method that just parses directives'
+        ' and stops when it finds the first declaration or EOF.';
   }
 
   @override
@@ -3569,7 +3552,8 @@
   @override
   Statement parseStatement(String source,
       [bool enableLazyAssignmentOperators]) {
-    return _runParser(source, (parser) => parser.parseStatement) as Statement;
+    return _runParser(source, (parser) => parser.parseStatement, null)
+        as Statement;
   }
 
   @override
@@ -3613,15 +3597,16 @@
       [List<ErrorCode> errorCodes = const <ErrorCode>[]]) {
     createParser(source);
     Object result = _parserProxy._run(getParseFunction);
-    assertErrorsWithCodes(errorCodes);
+    if (errorCodes != null) {
+      assertErrorsWithCodes(errorCodes);
+    }
     return result;
   }
 
   List<ErrorCode> _toFastaGeneratedAnalyzerErrorCodes(
           List<ErrorCode> expectedErrorCodes) =>
       expectedErrorCodes.map((code) {
-        if (code == ParserErrorCode.ABSTRACT_CLASS_MEMBER ||
-            code == ParserErrorCode.ABSTRACT_ENUM ||
+        if (code == ParserErrorCode.ABSTRACT_ENUM ||
             code == ParserErrorCode.ABSTRACT_TOP_LEVEL_FUNCTION ||
             code == ParserErrorCode.ABSTRACT_TOP_LEVEL_VARIABLE ||
             code == ParserErrorCode.ABSTRACT_TYPEDEF ||
@@ -3645,12 +3630,14 @@
   @override
   @failingTest
   void test_parseFormalParameterList_prefixedType_partial() {
+    // TODO(brianwilkerson) Does not recover.
     super.test_parseFormalParameterList_prefixedType_partial();
   }
 
   @override
   @failingTest
   void test_parseFormalParameterList_prefixedType_partial2() {
+    // TODO(brianwilkerson) Does not recover.
     super.test_parseFormalParameterList_prefixedType_partial2();
   }
 
@@ -3865,9 +3852,17 @@
   @override
   FunctionBody parseFunctionBody(
       bool mayBeEmpty, ParserErrorCode emptyErrorCode, bool inExpression) {
-    return _run((parser) => (token) =>
-            parser.parseFunctionBody(token, inExpression, mayBeEmpty))
-        as FunctionBody;
+    return _run((parser) => (token) {
+          token = parser.parseAsyncModifier(token);
+          token = parser.parseFunctionBody(token, inExpression, mayBeEmpty);
+          if (!inExpression) {
+            if (![';', '}'].contains(token.lexeme)) {
+              fail('Expected ";" or "}", but found: ${token.lexeme}');
+            }
+            token = token.next;
+          }
+          return token;
+        }) as FunctionBody;
   }
 
   @override
@@ -3931,7 +3926,7 @@
       // firstToken should be set by beginCompilationUnit event.
     }
     _currentFastaToken = parseFunction(_currentFastaToken);
-    expect(_currentFastaToken.isEof, isTrue);
+    expect(_currentFastaToken.isEof, isTrue, reason: _currentFastaToken.lexeme);
     if (nodeCount >= 0) {
       expect(_astBuilder.stack, hasLength(nodeCount));
     }
@@ -4722,13 +4717,6 @@
 
   @override
   @failingTest
-  void test_relationalExpression_missing_RHS() {
-    // TODO(brianwilkerson) reportUnrecoverableErrorWithToken
-    super.test_relationalExpression_missing_RHS();
-  }
-
-  @override
-  @failingTest
   void test_relationalExpression_precedence_shift_right() {
     // TODO(brianwilkerson) reportUnrecoverableErrorWithToken
     super.test_relationalExpression_precedence_shift_right();
@@ -4847,38 +4835,6 @@
 
   @override
   @failingTest
-  void test_parseConstructorName_named_noPrefix() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseConstructorName'.
-    super.test_parseConstructorName_named_noPrefix();
-  }
-
-  @override
-  @failingTest
-  void test_parseConstructorName_named_prefixed() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseConstructorName'.
-    super.test_parseConstructorName_named_prefixed();
-  }
-
-  @override
-  @failingTest
-  void test_parseConstructorName_unnamed_noPrefix() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseConstructorName'.
-    super.test_parseConstructorName_unnamed_noPrefix();
-  }
-
-  @override
-  @failingTest
-  void test_parseConstructorName_unnamed_prefixed() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseConstructorName'.
-    super.test_parseConstructorName_unnamed_prefixed();
-  }
-
-  @override
-  @failingTest
   void test_parseDocumentationComment_block() {
     // TODO(brianwilkerson) exception:
     // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseDocumentationCommentTokens'.
@@ -4902,361 +4858,6 @@
   }
 
   @override
-  @failingTest
-  void test_parseDottedName_multiple() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseDottedName'.
-    super.test_parseDottedName_multiple();
-  }
-
-  @override
-  @failingTest
-  void test_parseDottedName_single() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseDottedName'.
-    super.test_parseDottedName_single();
-  }
-
-  @override
-  @failingTest
-  void test_parseExtendsClause() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseExtendsClause'.
-    super.test_parseExtendsClause();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_const_functionType() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_const_functionType();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_const_namedType() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_const_namedType();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_const_noType() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_const_noType();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_final_functionType() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_final_functionType();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_final_namedType() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_final_namedType();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_final_noType() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_final_noType();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_final_prefixedType() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_final_prefixedType();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_type_function() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_type_function();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_type_parameterized() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_type_parameterized();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_type_prefixed() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_type_prefixed();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_type_prefixed_noIdentifier() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_type_prefixed_noIdentifier();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_type_prefixedAndParameterized() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_type_prefixedAndParameterized();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_type_simple() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_type_simple();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_type_simple_noIdentifier_inFunctionType() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super
-        .test_parseFinalConstVarOrType_type_simple_noIdentifier_inFunctionType();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_var() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_var();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_void() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_void();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_void_identifier() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_void_identifier();
-  }
-
-  @override
-  @failingTest
-  void test_parseFinalConstVarOrType_void_noIdentifier() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseFinalConstVarOrType'.
-    super.test_parseFinalConstVarOrType_void_noIdentifier();
-  }
-
-  @override
-  @failingTest
-  void test_parseFunctionBody_block() {
-    // TODO(brianwilkerson) exception:
-    //   'package:front_end/src/fasta/source/stack_listener.dart': Failed assertion: line 311 pos 12: 'arrayLength > 0': is not true.
-    //   dart:core                                                          _AssertionError._throwNew
-    //   package:front_end/src/fasta/source/stack_listener.dart 311:12      Stack.pop
-    //   package:front_end/src/fasta/source/stack_listener.dart 95:25       StackListener.pop
-    //   package:analyzer/src/fasta/ast_builder.dart 287:18                 AstBuilder.endBlockFunctionBody
-    //   test/generated/parser_fasta_listener.dart 592:14                   ForwardingTestListener.endBlockFunctionBody
-    //   package:front_end/src/fasta/parser/parser.dart 2648:14             Parser.parseFunctionBody
-    super.test_parseFunctionBody_block();
-  }
-
-  @override
-  @failingTest
-  void test_parseFunctionBody_block_async() {
-    // TODO(brianwilkerson) The method 'parseFunctionBody' does not handle
-    // preceding modifiers.
-    super.test_parseFunctionBody_block_async();
-  }
-
-  @override
-  @failingTest
-  void test_parseFunctionBody_block_asyncGenerator() {
-    // TODO(brianwilkerson) The method 'parseFunctionBody' does not handle
-    // preceding modifiers.
-    super.test_parseFunctionBody_block_asyncGenerator();
-  }
-
-  @override
-  @failingTest
-  void test_parseFunctionBody_block_syncGenerator() {
-    // TODO(brianwilkerson) The method 'parseFunctionBody' does not handle
-    // preceding modifiers.
-    super.test_parseFunctionBody_block_syncGenerator();
-  }
-
-  @override
-  @failingTest
-  void test_parseFunctionBody_empty() {
-    // TODO(brianwilkerson) exception:
-    //   'package:front_end/src/fasta/source/stack_listener.dart': Failed assertion: line 311 pos 12: 'arrayLength > 0': is not true.
-    //   dart:core                                                          _AssertionError._throwNew
-    //   package:front_end/src/fasta/source/stack_listener.dart 311:12      Stack.pop
-    //   package:front_end/src/fasta/source/stack_listener.dart 95:25       StackListener.pop
-    //   package:analyzer/src/fasta/ast_builder.dart 269:5                  AstBuilder.handleEmptyFunctionBody
-    //   test/generated/parser_fasta_listener.dart 1171:14                  ForwardingTestListener.handleEmptyFunctionBody
-    //   package:front_end/src/fasta/parser/parser.dart 2607:16             Parser.parseFunctionBody
-    super.test_parseFunctionBody_empty();
-  }
-
-  @override
-  @failingTest
-  void test_parseFunctionBody_expression() {
-    // TODO(brianwilkerson) exception:
-    //   'package:front_end/src/fasta/source/stack_listener.dart': Failed assertion: line 311 pos 12: 'arrayLength > 0': is not true.
-    //   dart:core                                                          _AssertionError._throwNew
-    //   package:front_end/src/fasta/source/stack_listener.dart 311:12      Stack.pop
-    //   package:front_end/src/fasta/source/stack_listener.dart 95:25       StackListener.pop
-    //   package:analyzer/src/fasta/ast_builder.dart 379:18                 AstBuilder.handleExpressionFunctionBody
-    //   test/generated/parser_fasta_listener.dart 1177:14                  ForwardingTestListener.handleExpressionFunctionBody
-    //   package:front_end/src/fasta/parser/parser.dart 2614:18             Parser.parseFunctionBody
-    super.test_parseFunctionBody_expression();
-  }
-
-  @override
-  @failingTest
-  void test_parseFunctionBody_expression_async() {
-    // TODO(brianwilkerson) The method 'parseFunctionBody' does not handle
-    // preceding modifiers.
-    super.test_parseFunctionBody_expression_async();
-  }
-
-  @override
-  @failingTest
-  void test_parseIdentifierList_multiple() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseIdentifierList'.
-    super.test_parseIdentifierList_multiple();
-  }
-
-  @override
-  @failingTest
-  void test_parseIdentifierList_single() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseIdentifierList'.
-    super.test_parseIdentifierList_single();
-  }
-
-  @override
-  @failingTest
-  void test_parseImplementsClause_multiple() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseImplementsClause'.
-    super.test_parseImplementsClause_multiple();
-  }
-
-  @override
-  @failingTest
-  void test_parseImplementsClause_single() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseImplementsClause'.
-    super.test_parseImplementsClause_single();
-  }
-
-  @override
-  @failingTest
-  void test_parseLibraryIdentifier_multiple() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseLibraryIdentifier'.
-    super.test_parseLibraryIdentifier_multiple();
-  }
-
-  @override
-  @failingTest
-  void test_parseLibraryIdentifier_single() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseLibraryIdentifier'.
-    super.test_parseLibraryIdentifier_single();
-  }
-
-  @override
-  @failingTest
-  void test_parseModifiers_abstract() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseModifiers'.
-    super.test_parseModifiers_abstract();
-  }
-
-  @override
-  @failingTest
-  void test_parseModifiers_const() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseModifiers'.
-    super.test_parseModifiers_const();
-  }
-
-  @override
-  @failingTest
-  void test_parseModifiers_covariant() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseModifiers'.
-    super.test_parseModifiers_covariant();
-  }
-
-  @override
-  @failingTest
-  void test_parseModifiers_external() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseModifiers'.
-    super.test_parseModifiers_external();
-  }
-
-  @override
-  @failingTest
-  void test_parseModifiers_factory() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseModifiers'.
-    super.test_parseModifiers_factory();
-  }
-
-  @override
-  @failingTest
-  void test_parseModifiers_final() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseModifiers'.
-    super.test_parseModifiers_final();
-  }
-
-  @override
-  @failingTest
-  void test_parseModifiers_static() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseModifiers'.
-    super.test_parseModifiers_static();
-  }
-
-  @override
-  @failingTest
-  void test_parseModifiers_var() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseModifiers'.
-    super.test_parseModifiers_var();
-  }
-
-  @override
 //  @failingTest
   void test_parseReturnType_void() {
     // TODO(brianwilkerson) Passes, but ought to fail.
@@ -5265,13 +4866,6 @@
 
   @override
   @failingTest
-  void test_parseTypeArgumentList_empty() {
-    // TODO(brianwilkerson) Does not recover from an empty list.
-    super.test_parseTypeArgumentList_empty();
-  }
-
-  @override
-  @failingTest
   void test_parseTypeArgumentList_nested_withComment_double() {
     // TODO(brianwilkerson) Does not capture comment when splitting '>>' into
     // two tokens.
@@ -5304,38 +4898,6 @@
   void test_parseTypeParameterList_withTrailingEquals() {
     super.test_parseTypeParameterList_withTrailingEquals();
   }
-
-  @override
-  @failingTest
-  void test_parseVariableDeclaration_equals() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseVariableDeclaration'.
-    super.test_parseVariableDeclaration_equals();
-  }
-
-  @override
-  @failingTest
-  void test_parseVariableDeclaration_noEquals() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseVariableDeclaration'.
-    super.test_parseVariableDeclaration_noEquals();
-  }
-
-  @override
-  @failingTest
-  void test_parseWithClause_multiple() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseWithClause'.
-    super.test_parseWithClause_multiple();
-  }
-
-  @override
-  @failingTest
-  void test_parseWithClause_single() {
-    // TODO(brianwilkerson) exception:
-    // NoSuchMethodError: Class 'ParserProxy' has no instance method 'parseWithClause'.
-    super.test_parseWithClause_single();
-  }
 }
 
 /**
@@ -5346,20 +4908,6 @@
     with StatementParserTestMixin {
   @override
   @failingTest
-  void test_parseAssertStatement_trailingComma_message() {
-    // TODO(brianwilkerson) Does not handle optional trailing comma.
-    super.test_parseAssertStatement_trailingComma_message();
-  }
-
-  @override
-  @failingTest
-  void test_parseAssertStatement_trailingComma_noMessage() {
-    // TODO(brianwilkerson) Does not handle optional trailing comma.
-    super.test_parseAssertStatement_trailingComma_noMessage();
-  }
-
-  @override
-  @failingTest
   void test_parseBreakStatement_noLabel() {
     // TODO(brianwilkerson)
     // Expected 1 errors of type ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, found 0
@@ -5381,13 +4929,6 @@
     // Expected 1 errors of type ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, found 0
     super.test_parseContinueStatement_noLabel();
   }
-
-  @override
-  @failingTest
-  void test_parseStatement_emptyTypeArgumentList() {
-    // TODO(brianwilkerson) Does not recover from empty list.
-    super.test_parseStatement_emptyTypeArgumentList();
-  }
 }
 
 /**
@@ -5509,14 +5050,4 @@
     super.test_parseCompilationUnitMember_abstractAsPrefix();
     assertNoErrors();
   }
-
-  @override
-  @failingTest
-  void test_parseDirectives_mixed() {
-    // TODO(paulberry,ahe): This test verifies the analyzer parser's ability to
-    // stop parsing as soon as the first non-directive is encountered; this is
-    // useful for quickly traversing an import graph.  Consider adding a similar
-    // ability to Fasta's parser.
-    super.test_parseDirectives_mixed();
-  }
 }
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 72cfe3c..f5bfbba 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -44,6 +44,8 @@
 abstract class AbstractParserTestCase implements ParserTestHelpers {
   bool get allowNativeClause;
 
+  set allowNativeClause(bool value);
+
   void set enableAssertInitializer(bool value);
 
   void set enableGenericMethodComments(bool value);
@@ -937,15 +939,69 @@
         new isInstanceOf<ExpressionFunctionBody>());
   }
 
-  void test_parseClassMember_method_native() {
-    createParser('m() native "str";');
-    var method = parser.parseClassMember('C') as MethodDeclaration;
+  void test_parseClassMember_method_native_allowed() {
+    allowNativeClause = true;
+    _parseClassMember_method_native();
     assertNoErrors();
+  }
 
-    var body = method.body as NativeFunctionBody;
-    expect(body.nativeKeyword, isNotNull);
-    expect(body.stringLiteral, isNotNull);
-    expect(body.semicolon, isNotNull);
+  void test_parseClassMember_method_native_missing_literal_allowed() {
+    allowNativeClause = true;
+    _parseClassMember_method_native_missing_literal();
+    assertNoErrors();
+  }
+
+  void test_parseClassMember_method_native_missing_literal_not_allowed() {
+    allowNativeClause = false;
+    _parseClassMember_method_native_missing_literal();
+    if (usingFastaParser) {
+      assertErrorsWithCodes([
+        ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION,
+      ]);
+    } else {
+      assertNoErrors();
+    }
+  }
+
+  void test_parseClassMember_method_native_not_allowed() {
+    allowNativeClause = false;
+    _parseClassMember_method_native();
+    if (usingFastaParser) {
+      assertErrorsWithCodes([
+        ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION,
+      ]);
+    } else {
+      assertNoErrors();
+    }
+  }
+
+  void test_parseClassMember_method_native_with_body_allowed() {
+    allowNativeClause = true;
+    _parseClassMember_method_native_with_body();
+    if (usingFastaParser) {
+      assertErrorsWithCodes([
+        ParserErrorCode.EXTERNAL_METHOD_WITH_BODY,
+      ]);
+    } else {
+      assertErrorsWithCodes([
+        ParserErrorCode.EXPECTED_TOKEN,
+      ]);
+    }
+  }
+
+  void test_parseClassMember_method_native_with_body_not_allowed() {
+    allowNativeClause = false;
+    _parseClassMember_method_native_with_body();
+    if (usingFastaParser) {
+      assertErrorsWithCodes([
+        ParserErrorCode.NATIVE_CLAUSE_SHOULD_BE_ANNOTATION,
+        ParserErrorCode.EXTERNAL_METHOD_WITH_BODY,
+      ]);
+    } else {
+      assertErrorsWithCodes([
+        ParserErrorCode.EXPECTED_TOKEN,
+      ]);
+    }
   }
 
   void test_parseClassMember_method_operator_noType() {
@@ -1571,6 +1627,30 @@
   void _assertIsDeclarationName(SimpleIdentifier name, [bool expected = true]) {
     expect(name.inDeclarationContext(), expected);
   }
+
+  void _parseClassMember_method_native() {
+    createParser('m() native "str";');
+    var method = parser.parseClassMember('C') as MethodDeclaration;
+    var body = method.body as NativeFunctionBody;
+    expect(body.nativeKeyword, isNotNull);
+    expect(body.stringLiteral, isNotNull);
+    expect(body.stringLiteral?.stringValue, "str");
+    expect(body.semicolon, isNotNull);
+  }
+
+  void _parseClassMember_method_native_missing_literal() {
+    createParser('m() native;');
+    var method = parser.parseClassMember('C') as MethodDeclaration;
+    var body = method.body as NativeFunctionBody;
+    expect(body.nativeKeyword, isNotNull);
+    expect(body.stringLiteral, isNull);
+    expect(body.semicolon, isNotNull);
+  }
+
+  void _parseClassMember_method_native_with_body() {
+    createParser('m() native "str" {}');
+    parser.parseClassMember('C') as MethodDeclaration;
+  }
 }
 
 /**
@@ -6368,7 +6448,7 @@
   }
 
   void test_parsePrimaryExpression_super() {
-    Expression expression = parsePrimaryExpression('super.x');
+    Expression expression = parseExpression('super.x');
     expect(expression, isNotNull);
     assertNoErrors();
     var propertyAccess = expression as PropertyAccess;
@@ -10728,6 +10808,208 @@
     expect(reference.offset, 15);
   }
 
+  void test_parseDottedName_multiple() {
+    createParser('a.b.c');
+    DottedName name = parser.parseDottedName();
+    expectNotNullIfNoErrors(name);
+    listener.assertNoErrors();
+    expectDottedName(name, ["a", "b", "c"]);
+  }
+
+  void test_parseDottedName_single() {
+    createParser('a');
+    DottedName name = parser.parseDottedName();
+    expectNotNullIfNoErrors(name);
+    listener.assertNoErrors();
+    expectDottedName(name, ["a"]);
+  }
+
+  void test_parseFinalConstVarOrType_const_functionType() {
+    createParser('const int Function(int) f');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    Token keyword = result.keyword;
+    expect(keyword, isNotNull);
+    expect(keyword.type.isKeyword, true);
+    expect(keyword.keyword, Keyword.CONST);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_const_namedType() {
+    createParser('const A a');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    Token keyword = result.keyword;
+    expect(keyword, isNotNull);
+    expect(keyword.type.isKeyword, true);
+    expect(keyword.keyword, Keyword.CONST);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_const_noType() {
+    createParser('const');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    Token keyword = result.keyword;
+    expect(keyword, isNotNull);
+    expect(keyword.type.isKeyword, true);
+    expect(keyword.keyword, Keyword.CONST);
+    expect(result.type, isNull);
+  }
+
+  void test_parseFinalConstVarOrType_final_functionType() {
+    createParser('final int Function(int) f');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    Token keyword = result.keyword;
+    expect(keyword, isNotNull);
+    expect(keyword.type.isKeyword, true);
+    expect(keyword.keyword, Keyword.FINAL);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_final_namedType() {
+    createParser('final A a');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    Token keyword = result.keyword;
+    expect(keyword, isNotNull);
+    expect(keyword.type.isKeyword, true);
+    expect(keyword.keyword, Keyword.FINAL);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_final_noType() {
+    createParser('final');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    Token keyword = result.keyword;
+    expect(keyword, isNotNull);
+    expect(keyword.type.isKeyword, true);
+    expect(keyword.keyword, Keyword.FINAL);
+    expect(result.type, isNull);
+  }
+
+  void test_parseFinalConstVarOrType_final_prefixedType() {
+    createParser('final p.A a');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    Token keyword = result.keyword;
+    expect(keyword, isNotNull);
+    expect(keyword.type.isKeyword, true);
+    expect(keyword.keyword, Keyword.FINAL);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_type_function() {
+    createParser('int Function(int) f');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    expect(result.keyword, isNull);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_type_parameterized() {
+    createParser('A<B> a');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    expect(result.keyword, isNull);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_type_prefixed() {
+    createParser('p.A a');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    expect(result.keyword, isNull);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_type_prefixed_noIdentifier() {
+    createParser('p.A,');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    expect(result.keyword, isNull);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_type_prefixedAndParameterized() {
+    createParser('p.A<B> a');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    expect(result.keyword, isNull);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_type_simple() {
+    createParser('A a');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    expect(result.keyword, isNull);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_type_simple_noIdentifier_inFunctionType() {
+    createParser('A,');
+    FinalConstVarOrType result =
+        parser.parseFinalConstVarOrType(false, inFunctionType: true);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    expect(result.keyword, isNull);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_var() {
+    createParser('var');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    Token keyword = result.keyword;
+    expect(keyword, isNotNull);
+    expect(keyword.type.isKeyword, true);
+    expect(keyword.keyword, Keyword.VAR);
+    expect(result.type, isNull);
+  }
+
+  void test_parseFinalConstVarOrType_void() {
+    createParser('void f()');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    expect(result.keyword, isNull);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_void_identifier() {
+    createParser('void x');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertNoErrors();
+    expect(result.keyword, isNull);
+    expect(result.type, isNotNull);
+  }
+
+  void test_parseFinalConstVarOrType_void_noIdentifier() {
+    createParser('void,');
+    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
+    expectNotNullIfNoErrors(result);
+    listener.assertErrorsWithCodes(
+        [ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE]);
+  }
+
   void test_parseFunctionBody_skip_block() {
     ParserTestCase.parseFunctionBodies = false;
     createParser('{}');
@@ -10768,6 +11050,70 @@
     expect(functionBody, new isInstanceOf<EmptyFunctionBody>());
   }
 
+  void test_parseModifiers_abstract() {
+    createParser('abstract A');
+    Modifiers modifiers = parser.parseModifiers();
+    expectNotNullIfNoErrors(modifiers);
+    listener.assertNoErrors();
+    expect(modifiers.abstractKeyword, isNotNull);
+  }
+
+  void test_parseModifiers_const() {
+    createParser('const A');
+    Modifiers modifiers = parser.parseModifiers();
+    expectNotNullIfNoErrors(modifiers);
+    listener.assertNoErrors();
+    expect(modifiers.constKeyword, isNotNull);
+  }
+
+  void test_parseModifiers_covariant() {
+    createParser('covariant A');
+    Modifiers modifiers = parser.parseModifiers();
+    expectNotNullIfNoErrors(modifiers);
+    listener.assertNoErrors();
+    expect(modifiers.covariantKeyword, isNotNull);
+  }
+
+  void test_parseModifiers_external() {
+    createParser('external A');
+    Modifiers modifiers = parser.parseModifiers();
+    expectNotNullIfNoErrors(modifiers);
+    listener.assertNoErrors();
+    expect(modifiers.externalKeyword, isNotNull);
+  }
+
+  void test_parseModifiers_factory() {
+    createParser('factory A');
+    Modifiers modifiers = parser.parseModifiers();
+    expectNotNullIfNoErrors(modifiers);
+    listener.assertNoErrors();
+    expect(modifiers.factoryKeyword, isNotNull);
+  }
+
+  void test_parseModifiers_final() {
+    createParser('final A');
+    Modifiers modifiers = parser.parseModifiers();
+    expectNotNullIfNoErrors(modifiers);
+    listener.assertNoErrors();
+    expect(modifiers.finalKeyword, isNotNull);
+  }
+
+  void test_parseModifiers_static() {
+    createParser('static A');
+    Modifiers modifiers = parser.parseModifiers();
+    expectNotNullIfNoErrors(modifiers);
+    listener.assertNoErrors();
+    expect(modifiers.staticKeyword, isNotNull);
+  }
+
+  void test_parseModifiers_var() {
+    createParser('var A');
+    Modifiers modifiers = parser.parseModifiers();
+    expectNotNullIfNoErrors(modifiers);
+    listener.assertNoErrors();
+    expect(modifiers.varKeyword, isNotNull);
+  }
+
   void test_Parser() {
     expect(new Parser(null, null), isNotNull);
   }
@@ -11021,6 +11367,51 @@
  * More complex tests should be defined in the class [ComplexParserTest].
  */
 abstract class SimpleParserTestMixin implements AbstractParserTestCase {
+  ConstructorName parseConstructorName(String name) {
+    createParser('new $name();');
+    Statement statement = parser.parseStatement2();
+    expect(statement, new isInstanceOf<ExpressionStatement>());
+    Expression expression = (statement as ExpressionStatement).expression;
+    expect(expression, new isInstanceOf<InstanceCreationExpression>());
+    return (expression as InstanceCreationExpression).constructorName;
+  }
+
+  ExtendsClause parseExtendsClause(String clause) {
+    createParser('class TestClass $clause {}');
+    CompilationUnit unit = parser.parseCompilationUnit2();
+    expect(unit, isNotNull);
+    expect(unit.declarations, hasLength(1));
+    ClassDeclaration classDecl = unit.declarations[0];
+    expect(classDecl, isNotNull);
+    return classDecl.extendsClause;
+  }
+
+  List<SimpleIdentifier> parseIdentifierList(String identifiers) {
+    createParser('show $identifiers');
+    List<Combinator> combinators = parser.parseCombinators();
+    expect(combinators, hasLength(1));
+    return (combinators[0] as ShowCombinator).shownNames;
+  }
+
+  ImplementsClause parseImplementsClause(String clause) {
+    createParser('class TestClass $clause {}');
+    CompilationUnit unit = parser.parseCompilationUnit2();
+    expect(unit, isNotNull);
+    expect(unit.declarations, hasLength(1));
+    ClassDeclaration classDecl = unit.declarations[0];
+    expect(classDecl, isNotNull);
+    return classDecl.implementsClause;
+  }
+
+  LibraryIdentifier parseLibraryIdentifier(String name) {
+    createParser('library $name;');
+    CompilationUnit unit = parser.parseCompilationUnit2();
+    expect(unit, isNotNull);
+    expect(unit.directives, hasLength(1));
+    LibraryDirective directive = unit.directives[0];
+    return directive.name;
+  }
+
   /**
    * Parse the given [content] as a sequence of statements by enclosing it in a
    * block. The [expectedCount] is the number of statements that are expected to
@@ -11034,6 +11425,26 @@
     expect(block.statements, hasLength(expectedCount));
   }
 
+  VariableDeclaration parseVariableDeclaration(String declaration) {
+    createParser(declaration);
+    CompilationUnit unit = parser.parseCompilationUnit2();
+    expect(unit, isNotNull);
+    expect(unit.declarations, hasLength(1));
+    TopLevelVariableDeclaration decl = unit.declarations[0];
+    expect(decl, isNotNull);
+    return decl.variables.variables[0];
+  }
+
+  WithClause parseWithClause(String clause) {
+    createParser('class TestClass extends Object $clause {}');
+    CompilationUnit unit = parser.parseCompilationUnit2();
+    expect(unit, isNotNull);
+    expect(unit.declarations, hasLength(1));
+    ClassDeclaration classDecl = unit.declarations[0];
+    expect(classDecl, isNotNull);
+    return classDecl.withClause;
+  }
+
   void test_parseAnnotation_n1() {
     createParser('@A');
     Annotation annotation = parser.parseAnnotation();
@@ -11349,8 +11760,7 @@
   }
 
   void test_parseConstructorName_named_noPrefix() {
-    createParser('A.n;');
-    ConstructorName name = parser.parseConstructorName();
+    ConstructorName name = parseConstructorName('A.n');
     expectNotNullIfNoErrors(name);
     listener.assertNoErrors();
     expect(name.type, isNotNull);
@@ -11359,8 +11769,7 @@
   }
 
   void test_parseConstructorName_named_prefixed() {
-    createParser('p.A.n;');
-    ConstructorName name = parser.parseConstructorName();
+    ConstructorName name = parseConstructorName('p.A.n');
     expectNotNullIfNoErrors(name);
     listener.assertNoErrors();
     expect(name.type, isNotNull);
@@ -11369,8 +11778,7 @@
   }
 
   void test_parseConstructorName_unnamed_noPrefix() {
-    createParser('A;');
-    ConstructorName name = parser.parseConstructorName();
+    ConstructorName name = parseConstructorName('A');
     expectNotNullIfNoErrors(name);
     listener.assertNoErrors();
     expect(name.type, isNotNull);
@@ -11379,8 +11787,7 @@
   }
 
   void test_parseConstructorName_unnamed_prefixed() {
-    createParser('p.A;');
-    ConstructorName name = parser.parseConstructorName();
+    ConstructorName name = parseConstructorName('p.A');
     expectNotNullIfNoErrors(name);
     listener.assertNoErrors();
     expect(name.type, isNotNull);
@@ -11426,25 +11833,8 @@
     expect(comment.isEndOfLine, isFalse);
   }
 
-  void test_parseDottedName_multiple() {
-    createParser('a.b.c');
-    DottedName name = parser.parseDottedName();
-    expectNotNullIfNoErrors(name);
-    listener.assertNoErrors();
-    expectDottedName(name, ["a", "b", "c"]);
-  }
-
-  void test_parseDottedName_single() {
-    createParser('a');
-    DottedName name = parser.parseDottedName();
-    expectNotNullIfNoErrors(name);
-    listener.assertNoErrors();
-    expectDottedName(name, ["a"]);
-  }
-
   void test_parseExtendsClause() {
-    createParser('extends B');
-    ExtendsClause clause = parser.parseExtendsClause();
+    ExtendsClause clause = parseExtendsClause('extends B');
     expectNotNullIfNoErrors(clause);
     listener.assertNoErrors();
     expect(clause.extendsKeyword, isNotNull);
@@ -11452,192 +11842,6 @@
     expect(clause.superclass, new isInstanceOf<TypeName>());
   }
 
-  void test_parseFinalConstVarOrType_const_functionType() {
-    createParser('const int Function(int) f');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    Token keyword = result.keyword;
-    expect(keyword, isNotNull);
-    expect(keyword.type.isKeyword, true);
-    expect(keyword.keyword, Keyword.CONST);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_const_namedType() {
-    createParser('const A a');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    Token keyword = result.keyword;
-    expect(keyword, isNotNull);
-    expect(keyword.type.isKeyword, true);
-    expect(keyword.keyword, Keyword.CONST);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_const_noType() {
-    createParser('const');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    Token keyword = result.keyword;
-    expect(keyword, isNotNull);
-    expect(keyword.type.isKeyword, true);
-    expect(keyword.keyword, Keyword.CONST);
-    expect(result.type, isNull);
-  }
-
-  void test_parseFinalConstVarOrType_final_functionType() {
-    createParser('final int Function(int) f');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    Token keyword = result.keyword;
-    expect(keyword, isNotNull);
-    expect(keyword.type.isKeyword, true);
-    expect(keyword.keyword, Keyword.FINAL);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_final_namedType() {
-    createParser('final A a');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    Token keyword = result.keyword;
-    expect(keyword, isNotNull);
-    expect(keyword.type.isKeyword, true);
-    expect(keyword.keyword, Keyword.FINAL);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_final_noType() {
-    createParser('final');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    Token keyword = result.keyword;
-    expect(keyword, isNotNull);
-    expect(keyword.type.isKeyword, true);
-    expect(keyword.keyword, Keyword.FINAL);
-    expect(result.type, isNull);
-  }
-
-  void test_parseFinalConstVarOrType_final_prefixedType() {
-    createParser('final p.A a');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    Token keyword = result.keyword;
-    expect(keyword, isNotNull);
-    expect(keyword.type.isKeyword, true);
-    expect(keyword.keyword, Keyword.FINAL);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_type_function() {
-    createParser('int Function(int) f');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    expect(result.keyword, isNull);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_type_parameterized() {
-    createParser('A<B> a');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    expect(result.keyword, isNull);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_type_prefixed() {
-    createParser('p.A a');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    expect(result.keyword, isNull);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_type_prefixed_noIdentifier() {
-    createParser('p.A,');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    expect(result.keyword, isNull);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_type_prefixedAndParameterized() {
-    createParser('p.A<B> a');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    expect(result.keyword, isNull);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_type_simple() {
-    createParser('A a');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    expect(result.keyword, isNull);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_type_simple_noIdentifier_inFunctionType() {
-    createParser('A,');
-    FinalConstVarOrType result =
-        parser.parseFinalConstVarOrType(false, inFunctionType: true);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    expect(result.keyword, isNull);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_var() {
-    createParser('var');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    Token keyword = result.keyword;
-    expect(keyword, isNotNull);
-    expect(keyword.type.isKeyword, true);
-    expect(keyword.keyword, Keyword.VAR);
-    expect(result.type, isNull);
-  }
-
-  void test_parseFinalConstVarOrType_void() {
-    createParser('void f()');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    expect(result.keyword, isNull);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_void_identifier() {
-    createParser('void x');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertNoErrors();
-    expect(result.keyword, isNull);
-    expect(result.type, isNotNull);
-  }
-
-  void test_parseFinalConstVarOrType_void_noIdentifier() {
-    createParser('void,');
-    FinalConstVarOrType result = parser.parseFinalConstVarOrType(false);
-    expectNotNullIfNoErrors(result);
-    listener.assertErrorsWithCodes(
-        [ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE]);
-  }
-
   void test_parseFunctionBody_block() {
     createParser('{}');
     FunctionBody functionBody = parser.parseFunctionBody(false, null, false);
@@ -11745,24 +11949,21 @@
   }
 
   void test_parseIdentifierList_multiple() {
-    createParser('a, b, c');
-    List<SimpleIdentifier> list = parser.parseIdentifierList();
+    List<SimpleIdentifier> list = parseIdentifierList('a, b, c');
     expectNotNullIfNoErrors(list);
     listener.assertNoErrors();
     expect(list, hasLength(3));
   }
 
   void test_parseIdentifierList_single() {
-    createParser('a');
-    List<SimpleIdentifier> list = parser.parseIdentifierList();
+    List<SimpleIdentifier> list = parseIdentifierList('a');
     expectNotNullIfNoErrors(list);
     listener.assertNoErrors();
     expect(list, hasLength(1));
   }
 
   void test_parseImplementsClause_multiple() {
-    createParser('implements A, B, C');
-    ImplementsClause clause = parser.parseImplementsClause();
+    ImplementsClause clause = parseImplementsClause('implements A, B, C');
     expectNotNullIfNoErrors(clause);
     listener.assertNoErrors();
     expect(clause.interfaces, hasLength(3));
@@ -11770,8 +11971,7 @@
   }
 
   void test_parseImplementsClause_single() {
-    createParser('implements A');
-    ImplementsClause clause = parser.parseImplementsClause();
+    ImplementsClause clause = parseImplementsClause('implements A');
     expectNotNullIfNoErrors(clause);
     listener.assertNoErrors();
     expect(clause.interfaces, hasLength(1));
@@ -11780,8 +11980,7 @@
 
   void test_parseLibraryIdentifier_multiple() {
     String name = "a.b.c";
-    createParser(name);
-    LibraryIdentifier identifier = parser.parseLibraryIdentifier();
+    LibraryIdentifier identifier = parseLibraryIdentifier(name);
     expectNotNullIfNoErrors(identifier);
     listener.assertNoErrors();
     expect(identifier.name, name);
@@ -11789,77 +11988,12 @@
 
   void test_parseLibraryIdentifier_single() {
     String name = "a";
-    createParser(name);
-    LibraryIdentifier identifier = parser.parseLibraryIdentifier();
+    LibraryIdentifier identifier = parseLibraryIdentifier(name);
     expectNotNullIfNoErrors(identifier);
     listener.assertNoErrors();
     expect(identifier.name, name);
   }
 
-  void test_parseModifiers_abstract() {
-    createParser('abstract A');
-    Modifiers modifiers = parser.parseModifiers();
-    expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
-    expect(modifiers.abstractKeyword, isNotNull);
-  }
-
-  void test_parseModifiers_const() {
-    createParser('const A');
-    Modifiers modifiers = parser.parseModifiers();
-    expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
-    expect(modifiers.constKeyword, isNotNull);
-  }
-
-  void test_parseModifiers_covariant() {
-    createParser('covariant A');
-    Modifiers modifiers = parser.parseModifiers();
-    expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
-    expect(modifiers.covariantKeyword, isNotNull);
-  }
-
-  void test_parseModifiers_external() {
-    createParser('external A');
-    Modifiers modifiers = parser.parseModifiers();
-    expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
-    expect(modifiers.externalKeyword, isNotNull);
-  }
-
-  void test_parseModifiers_factory() {
-    createParser('factory A');
-    Modifiers modifiers = parser.parseModifiers();
-    expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
-    expect(modifiers.factoryKeyword, isNotNull);
-  }
-
-  void test_parseModifiers_final() {
-    createParser('final A');
-    Modifiers modifiers = parser.parseModifiers();
-    expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
-    expect(modifiers.finalKeyword, isNotNull);
-  }
-
-  void test_parseModifiers_static() {
-    createParser('static A');
-    Modifiers modifiers = parser.parseModifiers();
-    expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
-    expect(modifiers.staticKeyword, isNotNull);
-  }
-
-  void test_parseModifiers_var() {
-    createParser('var A');
-    Modifiers modifiers = parser.parseModifiers();
-    expectNotNullIfNoErrors(modifiers);
-    listener.assertNoErrors();
-    expect(modifiers.varKeyword, isNotNull);
-  }
-
   void test_parseOptionalReturnType() {
     // TODO(brianwilkerson) Implement tests for this method.
   }
@@ -12320,8 +12454,7 @@
   }
 
   void test_parseVariableDeclaration_equals() {
-    createParser('a = b');
-    VariableDeclaration declaration = parser.parseVariableDeclaration();
+    VariableDeclaration declaration = parseVariableDeclaration('var a = b;');
     expectNotNullIfNoErrors(declaration);
     listener.assertNoErrors();
     expect(declaration.name, isNotNull);
@@ -12330,8 +12463,7 @@
   }
 
   void test_parseVariableDeclaration_noEquals() {
-    createParser('a');
-    VariableDeclaration declaration = parser.parseVariableDeclaration();
+    VariableDeclaration declaration = parseVariableDeclaration('var a;');
     expectNotNullIfNoErrors(declaration);
     listener.assertNoErrors();
     expect(declaration.name, isNotNull);
@@ -12340,8 +12472,7 @@
   }
 
   void test_parseWithClause_multiple() {
-    createParser('with A, B, C');
-    WithClause clause = parser.parseWithClause();
+    WithClause clause = parseWithClause('with A, B, C');
     expectNotNullIfNoErrors(clause);
     listener.assertNoErrors();
     expect(clause.withKeyword, isNotNull);
@@ -12349,8 +12480,7 @@
   }
 
   void test_parseWithClause_single() {
-    createParser('with M');
-    WithClause clause = parser.parseWithClause();
+    WithClause clause = parseWithClause('with M');
     expectNotNullIfNoErrors(clause);
     listener.assertNoErrors();
     expect(clause.withKeyword, isNotNull);
@@ -13521,7 +13651,51 @@
 }
 
 @reflectiveTest
-class TopLevelParserTest extends ParserTestCase with TopLevelParserTestMixin {}
+class TopLevelParserTest extends ParserTestCase with TopLevelParserTestMixin {
+  void test_parseDirectives_complete() {
+    CompilationUnit unit =
+        parseDirectives("#! /bin/dart\nlibrary l;\nclass A {}");
+    expect(unit.scriptTag, isNotNull);
+    expect(unit.directives, hasLength(1));
+  }
+
+  void test_parseDirectives_empty() {
+    CompilationUnit unit = parseDirectives("");
+    expect(unit.scriptTag, isNull);
+    expect(unit.directives, hasLength(0));
+  }
+
+  void test_parseDirectives_mixed() {
+    CompilationUnit unit =
+        parseDirectives("library l; class A {} part 'foo.dart';");
+    expect(unit.scriptTag, isNull);
+    expect(unit.directives, hasLength(1));
+  }
+
+  void test_parseDirectives_multiple() {
+    CompilationUnit unit = parseDirectives("library l;\npart 'a.dart';");
+    expect(unit.scriptTag, isNull);
+    expect(unit.directives, hasLength(2));
+  }
+
+  void test_parseDirectives_script() {
+    CompilationUnit unit = parseDirectives("#! /bin/dart");
+    expect(unit.scriptTag, isNotNull);
+    expect(unit.directives, hasLength(0));
+  }
+
+  void test_parseDirectives_single() {
+    CompilationUnit unit = parseDirectives("library l;");
+    expect(unit.scriptTag, isNull);
+    expect(unit.directives, hasLength(1));
+  }
+
+  void test_parseDirectives_topLevelDeclaration() {
+    CompilationUnit unit = parseDirectives("class A {}");
+    expect(unit.scriptTag, isNull);
+    expect(unit.directives, hasLength(0));
+  }
+}
 
 /**
  * Tests which exercise the parser using a complete compilation unit or
@@ -14609,50 +14783,6 @@
     expect(partOfDirective.semicolon, isNotNull);
   }
 
-  void test_parseDirectives_complete() {
-    CompilationUnit unit =
-        parseDirectives("#! /bin/dart\nlibrary l;\nclass A {}");
-    expect(unit.scriptTag, isNotNull);
-    expect(unit.directives, hasLength(1));
-  }
-
-  void test_parseDirectives_empty() {
-    CompilationUnit unit = parseDirectives("");
-    expect(unit.scriptTag, isNull);
-    expect(unit.directives, hasLength(0));
-  }
-
-  void test_parseDirectives_mixed() {
-    CompilationUnit unit =
-        parseDirectives("library l; class A {} part 'foo.dart';");
-    expect(unit.scriptTag, isNull);
-    expect(unit.directives, hasLength(1));
-  }
-
-  void test_parseDirectives_multiple() {
-    CompilationUnit unit = parseDirectives("library l;\npart 'a.dart';");
-    expect(unit.scriptTag, isNull);
-    expect(unit.directives, hasLength(2));
-  }
-
-  void test_parseDirectives_script() {
-    CompilationUnit unit = parseDirectives("#! /bin/dart");
-    expect(unit.scriptTag, isNotNull);
-    expect(unit.directives, hasLength(0));
-  }
-
-  void test_parseDirectives_single() {
-    CompilationUnit unit = parseDirectives("library l;");
-    expect(unit.scriptTag, isNull);
-    expect(unit.directives, hasLength(1));
-  }
-
-  void test_parseDirectives_topLevelDeclaration() {
-    CompilationUnit unit = parseDirectives("class A {}");
-    expect(unit.scriptTag, isNull);
-    expect(unit.directives, hasLength(0));
-  }
-
   void test_parseEnumDeclaration_one() {
     createParser("enum E {ONE}");
     EnumDeclaration declaration = parseFullCompilationUnitMember();
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index b9bdd6a..ff38d06 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -3180,26 +3180,28 @@
 
   test_visitFieldFormalParameter_functionType() async {
     InterfaceType intType = _typeProvider.intType;
-    TypeName intTypeName = AstTestFactory.typeName4("int");
-    String innerParameterName = "a";
-    SimpleFormalParameterImpl parameter =
-        AstTestFactory.simpleFormalParameter3(innerParameterName);
-    parameter.element = parameter.identifier.staticElement =
-        ElementFactory.requiredParameter(innerParameterName);
-    String outerParameterName = "p";
-    FormalParameter node = AstTestFactory.fieldFormalParameter(
-        null,
-        intTypeName,
-        outerParameterName,
-        AstTestFactory.formalParameterList([parameter]));
-    node.identifier.staticElement =
-        ElementFactory.requiredParameter(outerParameterName);
-    DartType parameterType = _resolveFormalParameter(node, [intType.element]);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is FunctionType, FunctionType, parameterType);
-    FunctionType functionType = parameterType as FunctionType;
-    expect(functionType.returnType, same(intType));
-    expect(functionType.parameters, hasLength(1));
+    TypeName intTypeName = AstTestFactory.typeName4('int');
+
+    String aName = 'a';
+    SimpleFormalParameterImpl aNode =
+        AstTestFactory.simpleFormalParameter3(aName);
+    aNode.element = aNode.identifier.staticElement =
+        ElementFactory.requiredParameter(aName);
+
+    String pName = 'p';
+    FormalParameter pNode = AstTestFactory.fieldFormalParameter(
+        null, intTypeName, pName, AstTestFactory.formalParameterList([aNode]));
+    var pElement = ElementFactory.requiredParameter(pName);
+    pNode.identifier.staticElement = pElement;
+
+    FunctionType pType = new FunctionTypeImpl(
+        new GenericFunctionTypeElementImpl.forOffset(-1)
+          ..parameters = [aNode.element]);
+    pElement.type = pType;
+
+    _resolveFormalParameter(pNode, [intType.element]);
+    expect(pType.returnType, same(intType));
+    expect(pType.parameters, hasLength(1));
     _listener.assertNoErrors();
   }
 
@@ -3281,28 +3283,38 @@
     // class P {}
     ClassElement elementR = ElementFactory.classElement2('R');
     ClassElement elementP = ElementFactory.classElement2('P');
-    FunctionElement elementF = ElementFactory.functionElement('f');
-    ParameterElementImpl requiredParameter =
-        ElementFactory.requiredParameter('p');
-    FunctionTypedFormalParameter parameterDeclaration = AstTestFactory
-        .functionTypedFormalParameter(AstTestFactory.typeName4('R'), 'g', [
-      AstTestFactory.simpleFormalParameter4(AstTestFactory.typeName4('P'), 'p')
-    ]);
-    parameterDeclaration.identifier.staticElement = requiredParameter;
-    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
+
+    SimpleFormalParameter pNode = AstTestFactory.simpleFormalParameter4(
+        AstTestFactory.typeName4('P'), 'p');
+    ParameterElementImpl pElement = ElementFactory.requiredParameter('p');
+    pNode.identifier.staticElement = pElement;
+
+    FunctionTypedFormalParameter gNode = AstTestFactory
+        .functionTypedFormalParameter(
+            AstTestFactory.typeName4('R'), 'g', [pNode]);
+    ParameterElementImpl gElement = ElementFactory.requiredParameter('g');
+    gNode.identifier.staticElement = gElement;
+
+    FunctionTypeImpl gType = new FunctionTypeImpl(
+        new GenericFunctionTypeElementImpl.forOffset(-1)
+          ..parameters = [pElement]);
+    gElement.type = gType;
+
+    FunctionDeclaration fNode = AstTestFactory.functionDeclaration(
         AstTestFactory.typeName4('R'),
         null,
         'f',
         AstTestFactory.functionExpression2(
-            AstTestFactory.formalParameterList([parameterDeclaration]), null));
-    declaration.name.staticElement = elementF;
-    _resolveNode(declaration, [elementR, elementP]);
-    expect(declaration.returnType.type, elementR.type);
-    FunctionTypedFormalParameter parameter =
-        declaration.functionExpression.parameters.parameters[0];
-    expect(parameter.returnType.type, elementR.type);
-    SimpleFormalParameter innerParameter = parameter.parameters.parameters[0];
-    expect(innerParameter.type.type, elementP.type);
+            AstTestFactory.formalParameterList([gNode]), null));
+    fNode.name.staticElement = ElementFactory.functionElement('f');
+
+    _resolveNode(fNode, [elementR, elementP]);
+
+    expect(fNode.returnType.type, elementR.type);
+    expect(gType.returnType, elementR.type);
+    expect(gNode.returnType.type, elementR.type);
+    expect(pNode.type.type, elementP.type);
+
     _listener.assertNoErrors();
   }
 
@@ -3311,29 +3323,38 @@
     // class R {}
     ClassElement elementR = ElementFactory.classElement2('R');
     TypeParameterElement elementE = ElementFactory.typeParameterElement('E');
-    FunctionElement elementF = ElementFactory.functionElement('f');
-    ParameterElementImpl requiredParameter =
-        ElementFactory.requiredParameter('g');
-    requiredParameter.typeParameters = <TypeParameterElement>[elementE];
-    FunctionTypedFormalParameter parameterDeclaration = AstTestFactory
-        .functionTypedFormalParameter(AstTestFactory.typeName4('R'), 'g', [
-      AstTestFactory.simpleFormalParameter4(AstTestFactory.typeName4('E'), 'e')
-    ]);
-    parameterDeclaration.identifier.staticElement = requiredParameter;
-    FunctionDeclaration declaration = AstTestFactory.functionDeclaration(
+
+    SimpleFormalParameterImpl eNode = AstTestFactory.simpleFormalParameter4(
+        AstTestFactory.typeName4('E'), 'e');
+    eNode.element = ElementFactory.requiredParameter('e');
+
+    FunctionTypedFormalParameter gNode = AstTestFactory
+        .functionTypedFormalParameter(
+            AstTestFactory.typeName4('R'), 'g', [eNode]);
+    ParameterElementImpl gElement = ElementFactory.requiredParameter('g');
+    gNode.identifier.staticElement = gElement;
+
+    FunctionTypeImpl gType =
+        new FunctionTypeImpl(new GenericFunctionTypeElementImpl.forOffset(-1)
+          ..typeParameters = [elementE]
+          ..parameters = [eNode.element]);
+    gElement.type = gType;
+
+    FunctionDeclaration fNode = AstTestFactory.functionDeclaration(
         AstTestFactory.typeName4('R'),
         null,
         'f',
         AstTestFactory.functionExpression2(
-            AstTestFactory.formalParameterList([parameterDeclaration]), null));
-    declaration.name.staticElement = elementF;
-    _resolveNode(declaration, [elementR]);
-    expect(declaration.returnType.type, elementR.type);
-    FunctionTypedFormalParameter parameter =
-        declaration.functionExpression.parameters.parameters[0];
-    expect(parameter.returnType.type, elementR.type);
-    SimpleFormalParameter innerParameter = parameter.parameters.parameters[0];
-    expect(innerParameter.type.type, elementE.type);
+            AstTestFactory.formalParameterList([gNode]), null));
+    fNode.name.staticElement = ElementFactory.functionElement('f');
+
+    _resolveNode(fNode, [elementR]);
+
+    expect(fNode.returnType.type, elementR.type);
+    expect(gType.returnType, elementR.type);
+    expect(gNode.returnType.type, elementR.type);
+    expect(eNode.type.type, elementE.type);
+
     _listener.assertNoErrors();
   }
 
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index 6a828a7..a45894a 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -27,8 +27,8 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:test/test.dart';
 
 import '../src/context/mock_sdk.dart';
@@ -343,6 +343,8 @@
 
   bool get enableNewAnalysisDriver => false;
 
+  bool get enableKernelDriver => false;
+
   /**
    * Return a type provider that can be used to test the results of resolution.
    *
@@ -687,7 +689,8 @@
           fileContentOverlay,
           null,
           sourceFactory,
-          options);
+          options,
+          enableKernelDriver: enableKernelDriver);
       scheduler.start();
     } else {
       if (packages != null) {
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index a142b74..c4bf958 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -2789,7 +2789,7 @@
 ''', noErrors: false // TODO(paulberry): remove when dartbug.com/28515 fixed.
         );
     expectFunctionType('f', '<T>(T) → T',
-        elementTypeParams: '[T]', typeFormals: '[T]');
+        elementTypeParams: '[]', typeFormals: '[T]');
     SimpleIdentifier f = findIdentifier('f');
     ParameterElementImpl e = f.staticElement;
     FunctionType type = e.type;
@@ -3680,6 +3680,18 @@
     assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
   }
 
+  test_notInstantiatedBound_functionType() async {
+    await resolveTestUnit(r'''
+class A<T extends int> {}
+class C<T extends Function(A)> {}
+class D<T extends A Function()> {}
+''', noErrors: false);
+    assertErrors(testSource, [
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      StrongModeCode.NOT_INSTANTIATED_BOUND
+    ]);
+  }
+
   test_notInstantiatedBound_indirect_class_class() async {
     String code = r'''
 class A<T> {}
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index 4788b9f..99c2991 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -26,6 +26,7 @@
 import 'java_core_test.dart' as java_core_test;
 import 'java_io_test.dart' as java_io_test;
 import 'non_error_resolver_driver_test.dart' as non_error_resolver_driver_test;
+import 'non_error_resolver_kernel_test.dart' as non_error_resolver_kernel_test;
 import 'non_error_resolver_test.dart' as non_error_resolver_test;
 import 'non_hint_code_driver_test.dart' as non_hint_code_driver_test;
 import 'non_hint_code_test.dart' as non_hint_code_test;
@@ -74,6 +75,7 @@
     java_core_test.main();
     java_io_test.main();
     non_error_resolver_driver_test.main();
+    non_error_resolver_kernel_test.main();
     non_error_resolver_test.main();
     non_hint_code_driver_test.main();
     non_hint_code_test.main();
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index 101d91a..222afd5 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -217,7 +217,7 @@
     pathTranslator.newFile('/$optionsFileName', r''':''');
     expect(() {
       _getOptions('/');
-    }, throws);
+    }, throwsException);
   }
 
   void test_getOptions_simple() {
diff --git a/pkg/analyzer/test/source/package_map_resolver_test.dart b/pkg/analyzer/test/source/package_map_resolver_test.dart
index 8347270..924704d 100644
--- a/pkg/analyzer/test/source/package_map_resolver_test.dart
+++ b/pkg/analyzer/test/source/package_map_resolver_test.dart
@@ -45,13 +45,13 @@
   void test_new_null_packageMap() {
     expect(() {
       new PackageMapUriResolver(provider, null);
-    }, throws);
+    }, throwsArgumentError);
   }
 
   void test_new_null_resourceProvider() {
     expect(() {
       new PackageMapUriResolver(null, <String, List<Folder>>{});
-    }, throws);
+    }, throwsArgumentError);
   }
 
   void test_resolve_multiple_folders() {
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index 0023832..79514ad 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -140,6 +140,7 @@
   external factory String.fromCharCodes(Iterable<int> charCodes,
                                         [int start = 0, int end]);
   String operator +(String other) => null;
+  bool operator ==(Object other);
   bool get isEmpty => false;
   bool get isNotEmpty => false;
   int get length => 0;
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index 0f0c004..30d792b 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -14,8 +14,8 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
 
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index b830847..fb5e28c 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -24,8 +24,8 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index 4b98ee4..461f417 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -15,8 +15,8 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:convert/convert.dart';
 import 'package:crypto/crypto.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart
index 7e79afa..3538988 100644
--- a/pkg/analyzer/test/src/dart/constant/value_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/value_test.dart
@@ -18,11 +18,10 @@
   });
 }
 
-const Matcher isEvaluationException = const isInstanceOf<EvaluationException>();
-
 const int LONG_MAX_VALUE = 0x7fffffffffffffff;
 
-const Matcher throwsEvaluationException = const Throws(isEvaluationException);
+final Matcher throwsEvaluationException =
+    throwsA(new isInstanceOf<EvaluationException>());
 
 @reflectiveTest
 class DartObjectImplTest extends EngineTestCase {
diff --git a/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart b/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
new file mode 100644
index 0000000..1142ac0
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
@@ -0,0 +1,199 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'recovery_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ClassDeclarationTest);
+    defineReflectiveTests(CompilationUnitMemberTest);
+    defineReflectiveTests(ImportDirectiveTest);
+  });
+}
+
+/**
+ * Test how well the parser recovers when the clauses in a class declaration are
+ * out of order.
+ */
+@reflectiveTest
+class ClassDeclarationTest extends AbstractRecoveryTest {
+  @failingTest
+  void test_implementsBeforeExtends() {
+    // Parser crashes
+    testRecovery('''
+class A implements B extends C {}
+''', [ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS], '''
+class A extends C implements B {}
+''');
+  }
+
+  @failingTest
+  void test_implementsBeforeWith() {
+    // Parser crashes
+    testRecovery('''
+class A extends B implements C with D {}
+''', [ParserErrorCode.IMPLEMENTS_BEFORE_WITH], '''
+class A extends B with D implements C {}
+''');
+  }
+
+  @failingTest
+  void test_implementsBeforeWithBeforeExtends() {
+    // Parser crashes
+    testRecovery('''
+class A implements B with C extends D {}
+''', [ParserErrorCode.IMPLEMENTS_BEFORE_WITH], '''
+class A extends D with C implements B {}
+''');
+  }
+
+  @failingTest
+  void test_multipleExtends() {
+    // Parser crashes
+    testRecovery('''
+class A extends B extends C {}
+''', [ParserErrorCode.MULTIPLE_EXTENDS_CLAUSES], '''
+class A extends B {}
+''');
+  }
+
+  @failingTest
+  void test_multipleImplements() {
+    // Parser crashes
+    testRecovery('''
+class A implements B implements C, D {}
+''', [ParserErrorCode.MULTIPLE_IMPLEMENTS_CLAUSES], '''
+class A implements B, C, D {}
+''');
+  }
+
+  @failingTest
+  void test_multipleWith() {
+    // Parser crashes
+    testRecovery('''
+class A extends B with C, D with E {}
+''', [ParserErrorCode.MULTIPLE_WITH_CLAUSES], '''
+class A extends B with C, D, E {}
+''');
+  }
+
+  @failingTest
+  void test_withBeforeExtends() {
+    // Parser crashes
+    testRecovery('''
+class A with B extends C {}
+''', [ParserErrorCode.WITH_BEFORE_EXTENDS], '''
+class A extends C with B {}
+''');
+  }
+}
+
+/**
+ * Test how well the parser recovers when the members of a compilation unit are
+ * out of order.
+ */
+@reflectiveTest
+class CompilationUnitMemberTest extends AbstractRecoveryTest {
+  @failingTest
+  void test_declarationBeforeDirective() {
+    // Expected 1 errors of type ParserErrorCode.DIRECTIVE_AFTER_DECLARATION, found 0
+    testRecovery('''
+class C { }
+import 'bar.dart';
+''', [ParserErrorCode.DIRECTIVE_AFTER_DECLARATION], '''
+import 'bar.dart';
+class C { }
+''');
+  }
+
+  @failingTest
+  void test_exportBeforeLibrary() {
+    // Expected 1 errors of type ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST, found 0
+    testRecovery('''
+export 'bar.dart';
+library l;
+''', [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST], '''
+library l;
+export 'bar.dart';
+''');
+  }
+
+  @failingTest
+  void test_importBeforeLibrary() {
+    // Expected 1 errors of type ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST, found 0
+    testRecovery('''
+import 'bar.dart';
+library l;
+''', [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST], '''
+library l;
+import 'bar.dart';
+''');
+  }
+
+  @failingTest
+  void test_partBeforeExport() {
+    // Expected 1 errors of type ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, found 0
+    testRecovery('''
+part 'foo.dart';
+export 'bar.dart';
+''', [ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE], '''
+export 'bar.dart';
+part 'foo.dart';
+''');
+  }
+
+  @failingTest
+  void test_partBeforeImport() {
+    // Expected 1 errors of type ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, found 0
+    testRecovery('''
+part 'foo.dart';
+import 'bar.dart';
+''', [ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE], '''
+import 'bar.dart';
+part 'foo.dart';
+''');
+  }
+
+  @failingTest
+  void test_partBeforeLibrary() {
+    // Expected 1 errors of type ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST, found 0
+    testRecovery('''
+part 'foo.dart';
+library l;
+''', [ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST], '''
+library l;
+part 'foo.dart';
+''');
+  }
+}
+
+/**
+ * Test how well the parser recovers when the members of an import directive are
+ * out of order.
+ */
+@reflectiveTest
+class ImportDirectiveTest extends AbstractRecoveryTest {
+  @failingTest
+  void test_combinatorsBeforeAndAfterPrefix() {
+    // Parser crashes
+    testRecovery('''
+import 'bar.dart' show A as p show B;
+''', [/*ParserErrorCode.PREFIX_AFTER_COMBINATOR*/], '''
+import 'bar.dart' as p show A show B;
+''');
+  }
+
+  @failingTest
+  void test_combinatorsBeforePrefix() {
+    // Parser crashes
+    testRecovery('''
+import 'bar.dart' show A as p;
+''', [/*ParserErrorCode.PREFIX_AFTER_COMBINATOR*/], '''
+import 'bar.dart' as p show A;
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart b/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
new file mode 100644
index 0000000..19cff05
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'recovery_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(MiscellaneousTest);
+    defineReflectiveTests(ModifiersTest);
+  });
+}
+
+/**
+ * Test how well the parser recovers in other cases.
+ */
+@reflectiveTest
+class MiscellaneousTest extends AbstractRecoveryTest {
+  @failingTest
+  void test_classTypeAlias_withBody() {
+    // Parser crashes
+    testRecovery('''
+class B = Object with A {}
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+class B = Object with A;
+''');
+  }
+}
+
+/**
+ * Test how well the parser recovers when extra modifiers are provided.
+ */
+@reflectiveTest
+class ModifiersTest extends AbstractRecoveryTest {
+  void test_classDeclaration_static() {
+    testRecovery('''
+static class A {}
+''', [ParserErrorCode.EXTRANEOUS_MODIFIER], '''
+class A {}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart b/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
new file mode 100644
index 0000000..0ca2a9f
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
@@ -0,0 +1,298 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'recovery_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(MissingCodeTest);
+  });
+}
+
+/**
+ * Test how well the parser recovers when non-paired tokens are missing.
+ */
+@reflectiveTest
+class MissingCodeTest extends AbstractRecoveryTest {
+  @failingTest
+  void test_ampersand() {
+    // Parser crashes
+    testBinaryExpression('&');
+  }
+
+  @failingTest
+  void test_ampersand_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('&');
+  }
+
+  void test_asExpression() {
+    testRecovery('''
+convert(x) => x as ;
+''', [ParserErrorCode.EXPECTED_TYPE_NAME], '''
+convert(x) => x as _s_;
+''');
+  }
+
+  @failingTest
+  void test_assignmentExpression() {
+    // Parser crashes
+    testRecovery('''
+f() {
+  var x;
+  x = 
+}
+''', [ParserErrorCode.MISSING_IDENTIFIER], '''
+f() {
+  var x;
+  x = _s_;
+}
+''');
+  }
+
+  @failingTest
+  void test_bar() {
+    // Parser crashes
+    testBinaryExpression('|');
+  }
+
+  @failingTest
+  void test_bar_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('|');
+  }
+
+  @failingTest
+  void test_combinatorsBeforePrefix() {
+    //Expected 1 errors of type ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT, found 0
+    testRecovery('''
+import 'bar.dart' deferred;
+''', [ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT], '''
+import 'bar.dart' deferred as _s_;
+''');
+  }
+
+  @failingTest
+  void test_conditionalExpression_else() {
+    // Parser crashes
+    testRecovery('''
+f() => x ? y : 
+''', [ParserErrorCode.MISSING_IDENTIFIER], '''
+f() => x ? y : _s_;
+''');
+  }
+
+  @failingTest
+  void test_conditionalExpression_then() {
+    // Parser crashes
+    testRecovery('''
+f() => x ? : z
+''', [ParserErrorCode.MISSING_IDENTIFIER], '''
+f() => x ? _s_ : z;
+''');
+  }
+
+  @failingTest
+  void test_equalEqual() {
+    // Parser crashes
+    testBinaryExpression('==');
+  }
+
+  @failingTest
+  void test_equalEqual_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('==');
+  }
+
+  @failingTest
+  void test_greaterThan() {
+    // Parser crashes
+    testBinaryExpression('>');
+  }
+
+  @failingTest
+  void test_greaterThan_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('>');
+  }
+
+  @failingTest
+  void test_greaterThanGreaterThan() {
+    // Parser crashes
+    testBinaryExpression('>>');
+  }
+
+  @failingTest
+  void test_greaterThanGreaterThan_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('>>');
+  }
+
+  @failingTest
+  void test_greaterThanOrEqual() {
+    // Parser crashes
+    testBinaryExpression('>=');
+  }
+
+  @failingTest
+  void test_greaterThanOrEqual_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('>=');
+  }
+
+  @failingTest
+  void test_hat() {
+    // Parser crashes
+    testBinaryExpression('^');
+  }
+
+  @failingTest
+  void test_hat_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('^');
+  }
+
+  void test_isExpression() {
+    testRecovery('''
+f(x) {
+  if (x is ) {}
+}
+''', [ParserErrorCode.EXPECTED_TYPE_NAME], '''
+f(x) {
+  if (x is _s_) {}
+}
+''');
+  }
+
+  @failingTest
+  void test_lessThan() {
+    // Parser crashes
+    testBinaryExpression('<');
+  }
+
+  @failingTest
+  void test_lessThan_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('<');
+  }
+
+  @failingTest
+  void test_lessThanLessThan() {
+    // Parser crashes
+    testBinaryExpression('<<');
+  }
+
+  @failingTest
+  void test_lessThanLessThan_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('<<');
+  }
+
+  @failingTest
+  void test_lessThanOrEqual() {
+    // Parser crashes
+    testBinaryExpression('<=');
+  }
+
+  @failingTest
+  void test_lessThanOrEqual_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('<=');
+  }
+
+  @failingTest
+  void test_minus() {
+    // Parser crashes
+    testBinaryExpression('-');
+  }
+
+  @failingTest
+  void test_minus_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('-');
+  }
+
+  @failingTest
+  void test_percent() {
+    // Parser crashes
+    testBinaryExpression('%');
+  }
+
+  @failingTest
+  void test_percent_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('%');
+  }
+
+  @failingTest
+  void test_plus() {
+    // Parser crashes
+    testBinaryExpression('+');
+  }
+
+  @failingTest
+  void test_plus_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('+');
+  }
+
+  @failingTest
+  void test_slash() {
+    // Parser crashes
+    testBinaryExpression('/');
+  }
+
+  @failingTest
+  void test_slash_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('/');
+  }
+
+  @failingTest
+  void test_star() {
+    // Parser crashes
+    testBinaryExpression('*');
+  }
+
+  @failingTest
+  void test_star_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('*');
+  }
+
+  @failingTest
+  void test_tildeSlash() {
+    // Parser crashes
+    testBinaryExpression('~/');
+  }
+
+  @failingTest
+  void test_tildeSlash_super() {
+    // Parser crashes
+    testUserDefinableOperatorWithSuper('~/');
+  }
+
+  void testBinaryExpression(String operator) {
+    testRecovery('''
+f() => x $operator
+''', [ParserErrorCode.MISSING_IDENTIFIER], '''
+f() => x $operator _s_;
+''');
+  }
+
+  void testUserDefinableOperatorWithSuper(String operator) {
+    testRecovery('''
+class C {
+  int operator $operator(x) => super $operator
+}
+''', [ParserErrorCode.MISSING_IDENTIFIER], '''
+class C {
+  int operator $operator(x) => super $operator _s_;
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
new file mode 100644
index 0000000..2173912
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
@@ -0,0 +1,236 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'recovery_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AngleBracketsTest);
+    defineReflectiveTests(BracesTest);
+    defineReflectiveTests(BracketsTest);
+    defineReflectiveTests(ParenthesesTest);
+  });
+}
+
+/**
+ * Test how well the parser recovers when angle brackets (`<` and `>`) are
+ * mismatched.
+ */
+@reflectiveTest
+class AngleBracketsTest extends AbstractRecoveryTest {
+  @failingTest
+  void test_typeArguments_inner_last() {
+    // Parser crashes
+    testRecovery('''
+List<List<int>
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+List<List<int>> _s_;
+''');
+  }
+
+  @failingTest
+  void test_typeArguments_inner_notLast() {
+    // Parser crashes
+    testRecovery('''
+Map<List<int, List<String>>
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+Map<List<int>, List<String>> _s_;
+''');
+  }
+
+  @failingTest
+  void test_typeArguments_outer_last() {
+    // Parser crashes
+    testRecovery('''
+List<int
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+List<int> _s_;
+''');
+  }
+}
+
+/**
+ * Test how well the parser recovers when curly braces are mismatched.
+ */
+@reflectiveTest
+class BracesTest extends AbstractRecoveryTest {
+  void test_statement_if_last() {
+    testRecovery('''
+f(x) {
+  if (x != null) {
+}
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+f(x) {
+  if (x != null) {}
+}
+''');
+  }
+
+  @failingTest
+  void test_statement_if_while() {
+    // Expected a list of length 2; found a list of length 1
+    testRecovery('''
+f(x) {
+  if (x != null) {
+  while (x == null) {}
+}
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+f(x) {
+  if (x != null) {}
+  while (x == null) {}
+}
+''');
+  }
+
+  @failingTest
+  void test_unit_functionBody_class() {
+    // Parser crashes
+    testRecovery('''
+f(x) {
+class C {}
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+f(x) {}
+class C {}
+''');
+  }
+
+  @failingTest
+  void test_unit_functionBody_function() {
+    // Expected a list of length 2; found a list of length 1
+    testRecovery('''
+f(x) {
+g(y) => y;
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+f(x) {}
+g(y) => y;
+''');
+  }
+
+  void test_unit_functionBody_last() {
+    testRecovery('''
+f(x) {
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+f(x) {}
+''');
+  }
+
+  @failingTest
+  void test_unit_functionBody_variable() {
+    // Expected a list of length 2; found a list of length 1
+    testRecovery('''
+f(x) {
+int y = 0;
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+f(x) {}
+int y = 0;
+''');
+  }
+}
+
+/**
+ * Test how well the parser recovers when square brackets are mismatched.
+ */
+@reflectiveTest
+class BracketsTest extends AbstractRecoveryTest {
+  @failingTest
+  void test_indexOperator() {
+    // Parser crashes
+    testRecovery('''
+f(x) => l[x
+''', [ScannerErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN], '''
+f(x) => l[x];
+''');
+  }
+
+  @failingTest
+  void test_listLiteral_inner_last() {
+    // Parser crashes
+    testRecovery('''
+var x = [[0], [1];
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+var x = [[0], [1]];
+''');
+  }
+
+  @failingTest
+  void test_listLiteral_inner_notLast() {
+    // Parser crashes
+    testRecovery('''
+var x = [[0], [1, [2]];
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+var x = [[0], [1], [2]];
+''');
+  }
+
+  @failingTest
+  void test_listLiteral_outer_last() {
+    // Parser crashes
+    testRecovery('''
+var x = [0, 1
+''', [ScannerErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN], '''
+var x = [0, 1];
+''');
+  }
+}
+
+/**
+ * Test how well the parser recovers when parentheses are mismatched.
+ */
+@reflectiveTest
+class ParenthesesTest extends AbstractRecoveryTest {
+  @failingTest
+  void test_if_last() {
+    // Parser crashes
+    testRecovery('''
+f(x) {
+  if (x
+}
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+f(x) {
+  if (x);
+}
+''');
+  }
+
+  @failingTest
+  void test_if_while() {
+    // Parser crashes
+    testRecovery('''
+f(x) {
+  if (x
+  while(x != null) {}
+}
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+f(x) {
+  if (x);
+  while(x != null) {}
+}
+''');
+  }
+
+  @failingTest
+  void test_parameterList_class() {
+    // Parser crashes
+    testRecovery('''
+f(x
+class C {}
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+f(x) {}
+class C {}
+''');
+  }
+
+  @failingTest
+  void test_parameterList_eof() {
+    // Parser crashes
+    testRecovery('''
+f(x
+''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+f(x) {}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart b/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
new file mode 100644
index 0000000..b88d5e8
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
@@ -0,0 +1,133 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:test/test.dart';
+
+import '../../../generated/parser_fasta_test.dart';
+
+/**
+ * The base class for tests that test how well the parser recovers from various
+ * syntactic errors.
+ */
+abstract class AbstractRecoveryTest extends FastaParserTestCase {
+  void testRecovery(
+      String invalidCode, List<ErrorCode> errorCodes, String validCode) {
+    CompilationUnit invalidUnit = parseCompilationUnit(invalidCode, errorCodes);
+    CompilationUnit validUnit = parseCompilationUnit(validCode);
+    ResultComparator.compare(invalidUnit, validUnit);
+  }
+}
+
+/**
+ * An object used to compare to AST structures and cause the test to fail if
+ * they differ in any important ways.
+ */
+class ResultComparator extends AstComparator {
+  bool failDifferentLength(List first, List second) {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write('Expected a list of length ');
+    buffer.write(second.length);
+    buffer.write('; found a list of length ');
+    buffer.writeln(first.length);
+    if (first is NodeList) {
+      _safelyWriteNodePath(buffer, first.owner);
+    }
+    fail(buffer.toString());
+    return false;
+  }
+
+  @override
+  bool failIfNotNull(Object first, Object second) {
+    if (second != null) {
+      StringBuffer buffer = new StringBuffer();
+      buffer.write('Expected null; found a ');
+      buffer.writeln(second.runtimeType);
+      if (second is AstNode) {
+        _safelyWriteNodePath(buffer, second);
+      }
+      fail(buffer.toString());
+    }
+    return true;
+  }
+
+  @override
+  bool failIsNull(Object first, Object second) {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write('Expected a ');
+    buffer.write(first.runtimeType);
+    buffer.writeln('; found null');
+    if (first is AstNode) {
+      _safelyWriteNodePath(buffer, first);
+    }
+    fail(buffer.toString());
+    return false;
+  }
+
+  @override
+  bool failRuntimeType(Object first, Object second) {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write('Expected a ');
+    buffer.writeln(second.runtimeType);
+    buffer.write('; found ');
+    buffer.writeln(first.runtimeType);
+    if (first is AstNode) {
+      _safelyWriteNodePath(buffer, first);
+    }
+    fail(buffer.toString());
+    return false;
+  }
+
+  /**
+   * Overridden to allow the valid code to contain an explicit identifier where
+   * a synthetic identifier is expected to be inserted by recovery.
+   */
+  @override
+  bool isEqualNodes(AstNode first, AstNode second) {
+    if (first is SimpleIdentifier && second is SimpleIdentifier) {
+      if (first.isSynthetic && second.name == '_s_') {
+        return true;
+      }
+    }
+    return super.isEqualNodes(first, second);
+  }
+
+  /**
+   * Overridden to ignore the offsets of tokens because these can legitimately
+   * be different.
+   */
+  @override
+  bool isEqualTokensNotNull(Token first, Token second) =>
+      first.length == second.length && first.lexeme == second.lexeme;
+
+  void _safelyWriteNodePath(StringBuffer buffer, AstNode node) {
+    buffer.write('  path: ');
+    if (node == null) {
+      buffer.write(' null');
+    } else {
+      _writeNodePath(buffer, node);
+    }
+  }
+
+  void _writeNodePath(StringBuffer buffer, AstNode node) {
+    AstNode parent = node.parent;
+    if (parent != null) {
+      _writeNodePath(buffer, parent);
+      buffer.write(', ');
+    }
+    buffer.write(node.runtimeType);
+  }
+
+  /**
+   * Compare the [first] and [second] nodes, failing the test if they are
+   * different.
+   */
+  static void compare(AstNode first, AstNode second) {
+    ResultComparator comparator = new ResultComparator();
+    comparator.isEqualNodes(first, second);
+  }
+}
diff --git a/pkg/analyzer/test/src/fasta/recovery/test_all.dart b/pkg/analyzer/test/src/fasta/recovery/test_all.dart
new file mode 100644
index 0000000..31a376c
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/test_all.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'code_order_test.dart' as code_order;
+import 'extra_code_test.dart' as extra_code;
+import 'missing_code_test.dart' as missing_code;
+import 'paired_tokens_test.dart' as paired_tokens;
+
+main() {
+  defineReflectiveSuite(() {
+    code_order.main();
+    extra_code.main();
+    missing_code.main();
+    paired_tokens.main();
+  }, name: 'recovery');
+}
diff --git a/pkg/analyzer/test/src/fasta/test_all.dart b/pkg/analyzer/test/src/fasta/test_all.dart
new file mode 100644
index 0000000..7b06963
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'recovery/test_all.dart' as recovery;
+
+main() {
+  defineReflectiveSuite(() {
+    recovery.main();
+  }, name: 'fasta');
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index ec6a310..0abaeb3 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -3848,7 +3848,18 @@
 const vFunctionTypeAlias = p.F;
 ''');
     if (isStrongMode) {
-      checkElementText(library, r'''
+      if (isSharedFrontEnd) {
+        checkElementText(library, r'''
+import 'a.dart' as p;
+const Type vClass =
+        C/*location: a.dart;C*/;
+const Type vEnum =
+        E/*location: a.dart;E*/;
+const Type vFunctionTypeAlias =
+        F/*location: a.dart;F*/;
+''');
+      } else {
+        checkElementText(library, r'''
 import 'a.dart' as p;
 const Type vClass =
         p/*location: test.dart;p*/.
@@ -3860,6 +3871,7 @@
         p/*location: test.dart;p*/.
         F/*location: a.dart;F*/;
 ''');
+      }
     } else {
       checkElementText(library, r'''
 import 'a.dart' as p;
@@ -6023,7 +6035,7 @@
   test_function_parameter_parameters() async {
     var library = await checkLibrary('f(g(x, y)) {}');
     checkElementText(library, r'''
-dynamic f(dynamic g(dynamic x, dynamic y)) {}
+dynamic f((dynamic, dynamic) → dynamic g) {}
 ''');
   }
 
@@ -6086,7 +6098,7 @@
   test_function_type_parameter_with_function_typed_parameter() async {
     var library = await checkLibrary('void f<T, U>(T x(U u)) {}');
     checkElementText(library, r'''
-void f<T, U>(T x(U u)) {}
+void f<T, U>((U) → T x) {}
 ''');
   }
 
@@ -6224,7 +6236,7 @@
 void f(int Function(int a, String b) p(num c)) => null;
 ''');
     checkElementText(library, r'''
-void f((int, String) → int p(num c)) {}
+void f((num) → (int, String) → int p) {}
 ''');
   }
 
@@ -6703,7 +6715,7 @@
 var v = h(/*info:INFERRED_TYPE_CLOSURE*/(y) {});
 ''');
     checkElementText(library, r'''
-typedef void F(int g(String s));
+typedef void F((String) → int g);
 dynamic v;
 dynamic h(F f) {}
 ''');
@@ -6723,7 +6735,7 @@
   void f(int x, (U) → int g) {}
 }
 abstract class D<V, W> {
-  void f(int x, W g(V s));
+  void f(int x, (V) → W g);
 }
 ''');
     } else {
@@ -6732,7 +6744,7 @@
   void f(int x, dynamic g) {}
 }
 abstract class D<V, W> {
-  void f(int x, W g(V s));
+  void f(int x, (V) → W g);
 }
 ''');
     }
@@ -6755,24 +6767,12 @@
 }
 ''');
     if (isStrongMode) {
-      if (isSharedFrontEnd) {
-        // Front-end copies FunctionType instances, which means that if it has
-        // parameter names in superclass, then we have names also in the
-        // subclass.
-        checkElementText(library, r'''
-import 'a.dart';
-class C extends D {
-  void f(int x, int g(String s)) {}
-}
-''');
-      } else {
-        checkElementText(library, r'''
+      checkElementText(library, r'''
 import 'a.dart';
 class C extends D {
   void f(int x, (String) → int g) {}
 }
 ''');
-      }
     } else {
       checkElementText(library, r'''
 import 'a.dart';
@@ -6792,7 +6792,7 @@
   void f(int x, (String) → int g) {}
 }
 abstract class D {
-  void f(int x, int g(String s));
+  void f(int x, (String) → int g);
 }
 ''');
     } else {
@@ -6801,7 +6801,7 @@
   void f(int x, dynamic g) {}
 }
 abstract class D {
-  void f(int x, int g(String s));
+  void f(int x, (String) → int g);
 }
 ''');
     }
@@ -6814,7 +6814,7 @@
 ''');
     checkElementText(library, r'''
 dynamic v;
-dynamic f(void g(int x, () → void h)) {}
+dynamic f((int, () → void) → void g) {}
 ''');
   }
 
@@ -6825,7 +6825,7 @@
 ''');
     checkElementText(library, r'''
 dynamic v;
-dynamic f({void g(int x, () → void h)}) {}
+dynamic f({(int, () → void) → void g}) {}
 ''');
   }
 
@@ -6838,7 +6838,7 @@
   void set f((String) → int g) {}
 }
 abstract class D {
-  void set f(int g(String s));
+  void set f((String) → int g);
 }
 ''');
     } else {
@@ -6847,7 +6847,7 @@
   void set f(dynamic g) {}
 }
 abstract class D {
-  void set f(int g(String s));
+  void set f((String) → int g);
 }
 ''');
     }
@@ -6904,14 +6904,14 @@
     if (isStrongMode) {
       checkElementText(library, r'''
 List<((String) → int) → Object> v;
-int f(int x(String y)) {}
-String g(int x(String y)) {}
+int f((String) → int x) {}
+String g((String) → int x) {}
 ''');
     } else {
       checkElementText(library, r'''
 dynamic v;
-int f(int x(String y)) {}
-String g(int x(String y)) {}
+int f((String) → int x) {}
+String g((String) → int x) {}
 ''');
     }
   }
@@ -8249,7 +8249,7 @@
     var library = await checkLibrary('class C { void f<T, U>(T x(U u)) {} }');
     checkElementText(library, r'''
 class C {
-  void f<T, U>(T x(U u)) {}
+  void f<T, U>((U) → T x) {}
 }
 ''');
   }
@@ -8589,7 +8589,7 @@
     var library = await checkLibrary('class C { f(g(x, y)) {} }');
     checkElementText(library, r'''
 class C {
-  dynamic f(dynamic g(dynamic x, dynamic y)) {}
+  dynamic f((dynamic, dynamic) → dynamic g) {}
 }
 ''');
   }
@@ -8598,7 +8598,7 @@
     var library = await checkLibrary('class C<A, B> { f(A g(B x)) {} }');
     checkElementText(library, r'''
 class C<A, B> {
-  dynamic f(A g(B x)) {}
+  dynamic f((B) → A g) {}
 }
 ''');
   }
@@ -9403,14 +9403,14 @@
   test_typedef_parameter_parameters() async {
     var library = await checkLibrary('typedef F(g(x, y));');
     checkElementText(library, r'''
-typedef dynamic F(dynamic g(dynamic x, dynamic y));
+typedef dynamic F((dynamic, dynamic) → dynamic g);
 ''');
   }
 
   test_typedef_parameter_parameters_in_generic_class() async {
     var library = await checkLibrary('typedef F<A, B>(A g(B x));');
     checkElementText(library, r'''
-typedef dynamic F<A, B>(A g(B x));
+typedef dynamic F<A, B>((B) → A g);
 ''');
   }
 
@@ -9444,9 +9444,15 @@
 
   test_typedef_parameters_named() async {
     var library = await checkLibrary('typedef F({y, z, x});');
-    checkElementText(library, r'''
+    if (isSharedFrontEnd) {
+      checkElementText(library, r'''
+typedef dynamic F({dynamic x}, {dynamic y}, {dynamic z});
+''');
+    } else {
+      checkElementText(library, r'''
 typedef dynamic F({dynamic y}, {dynamic z}, {dynamic x});
 ''');
+    }
   }
 
   test_typedef_return_type() async {
@@ -9497,17 +9503,31 @@
   test_typedef_type_parameters_bound_recursive() async {
     shouldCompareLibraryElements = false;
     var library = await checkLibrary('typedef void F<T extends F>();');
-    checkElementText(library, r'''
+    if (isSharedFrontEnd) {
+      // Typedefs cannot reference themselves.
+      checkElementText(library, r'''
+typedef void F<T extends dynamic>();
+''');
+    } else {
+      checkElementText(library, r'''
 typedef void F<T extends F>();
 ''');
+    }
   }
 
   test_typedef_type_parameters_bound_recursive2() async {
     shouldCompareLibraryElements = false;
     var library = await checkLibrary('typedef void F<T extends List<F>>();');
-    checkElementText(library, r'''
+    if (isSharedFrontEnd) {
+      // Typedefs cannot reference themselves.
+      checkElementText(library, r'''
+typedef void F<T extends List<dynamic>>();
+''');
+    } else {
+      checkElementText(library, r'''
 typedef void F<T extends List<F>>();
 ''');
+    }
   }
 
   test_typedef_type_parameters_f_bound_complex() async {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
index fcb4f8a..5130f65 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
@@ -11,12 +11,12 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/kernel/resynthesize.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/compiler_options.dart';
 import 'package:front_end/file_system.dart';
 import 'package:front_end/src/base/libraries_specification.dart';
 import 'package:front_end/src/base/performace_logger.dart';
 import 'package:front_end/src/base/processed_options.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:front_end/src/fasta/uri_translator_impl.dart';
 import 'package:front_end/src/incremental/kernel_driver.dart';
 import 'package:kernel/kernel.dart' as kernel;
@@ -217,11 +217,6 @@
   }
 
   @failingTest
-  test_const_reference_type_imported_withPrefix() async {
-    await super.test_const_reference_type_imported_withPrefix();
-  }
-
-  @failingTest
   @fastaProblem
   test_const_reference_unresolved_prefix0() async {
     // https://github.com/dart-lang/sdk/issues/30267
@@ -307,6 +302,60 @@
 
   @failingTest
   @notForDart2
+  test_defaultValue_refersToGenericClass_constructor() async {
+    // Analyzer allows the inferred type of a const to refer to type parameters
+    // that are in scope; Dart 2.0 infers a different type so that the constant
+    // doesn't depend on a (non-constant) type parameter.
+    await super.test_defaultValue_refersToGenericClass_constructor();
+  }
+
+  @failingTest
+  @notForDart2
+  test_defaultValue_refersToGenericClass_constructor2() async {
+    // Analyzer allows the inferred type of a const to refer to type parameters
+    // that are in scope; Dart 2.0 infers a different type so that the constant
+    // doesn't depend on a (non-constant) type parameter.
+    await super.test_defaultValue_refersToGenericClass_constructor2();
+  }
+
+  @failingTest
+  @notForDart2
+  test_defaultValue_refersToGenericClass_functionG() async {
+    // Analyzer allows the inferred type of a const to refer to type parameters
+    // that are in scope; Dart 2.0 infers a different type so that the constant
+    // doesn't depend on a (non-constant) type parameter.
+    await super.test_defaultValue_refersToGenericClass_functionG();
+  }
+
+  @failingTest
+  @notForDart2
+  test_defaultValue_refersToGenericClass_methodG() async {
+    // Analyzer allows the inferred type of a const to refer to type parameters
+    // that are in scope; Dart 2.0 infers a different type so that the constant
+    // doesn't depend on a (non-constant) type parameter.
+    await super.test_defaultValue_refersToGenericClass_methodG();
+  }
+
+  @failingTest
+  @notForDart2
+  test_defaultValue_refersToGenericClass_methodG_classG() async {
+    // Analyzer allows the inferred type of a const to refer to type parameters
+    // that are in scope; Dart 2.0 infers a different type so that the constant
+    // doesn't depend on a (non-constant) type parameter.
+    await super.test_defaultValue_refersToGenericClass_methodG_classG();
+  }
+
+  @failingTest
+  @notForDart2
+  test_defaultValue_refersToGenericClass_methodNG() async {
+    // Analyzer allows the inferred type of a const to refer to type parameters
+    // that are in scope; Dart 2.0 infers a different type so that the constant
+    // doesn't depend on a (non-constant) type parameter.
+    await super.test_defaultValue_refersToGenericClass_methodNG();
+  }
+
+  @failingTest
+  @notForDart2
   test_export_configurations_useDefault() async {
     await super.test_export_configurations_useDefault();
   }
@@ -337,15 +386,11 @@
 
   @failingTest
   test_genericFunction_asGenericFunctionReturnType() async {
+    // TODO(scheglov): triage
     await super.test_genericFunction_asGenericFunctionReturnType();
   }
 
   @failingTest
-  test_genericFunction_asParameterType() async {
-    await super.test_genericFunction_asParameterType();
-  }
-
-  @failingTest
   @notForDart2
   test_import_configurations_useDefault() async {
     await super.test_import_configurations_useDefault();
@@ -358,55 +403,44 @@
   }
 
   @failingTest
-  test_import_deferred() async {
-    await super.test_import_deferred();
-  }
-
-  @failingTest
+  @fastaProblem
   test_import_invalidUri_metadata() async {
+    // https://github.com/dart-lang/sdk/issues/30725
     await super.test_import_invalidUri_metadata();
   }
 
   @failingTest
-  test_inferred_type_refers_to_function_typed_parameter_type_generic_class() async {
-    await super
-        .test_inferred_type_refers_to_function_typed_parameter_type_generic_class();
-  }
-
-  @failingTest
-  test_inferred_type_refers_to_method_function_typed_parameter_type() async {
-    await super
-        .test_inferred_type_refers_to_method_function_typed_parameter_type();
-  }
-
-  @failingTest
-  test_inferred_type_refers_to_setter_function_typed_parameter_type() async {
-    await super
-        .test_inferred_type_refers_to_setter_function_typed_parameter_type();
-  }
-
-  @failingTest
+  @fastaProblem
   test_instantiateToBounds_boundRefersToEarlierTypeArgument() async {
+    // https://github.com/dart-lang/sdk/issues/30724
     await super.test_instantiateToBounds_boundRefersToEarlierTypeArgument();
   }
 
   @failingTest
+  @fastaProblem
   test_instantiateToBounds_boundRefersToItself() async {
+    // https://github.com/dart-lang/sdk/issues/30724
     await super.test_instantiateToBounds_boundRefersToItself();
   }
 
   @failingTest
+  @fastaProblem
   test_instantiateToBounds_boundRefersToLaterTypeArgument() async {
+    // https://github.com/dart-lang/sdk/issues/30724
     await super.test_instantiateToBounds_boundRefersToLaterTypeArgument();
   }
 
   @failingTest
+  @fastaProblem
   test_instantiateToBounds_functionTypeAlias_simple() async {
+    // https://github.com/dart-lang/sdk/issues/30724
     await super.test_instantiateToBounds_functionTypeAlias_simple();
   }
 
   @failingTest
+  @fastaProblem
   test_instantiateToBounds_simple() async {
+    // https://github.com/dart-lang/sdk/issues/30724
     await super.test_instantiateToBounds_simple();
   }
 
@@ -425,11 +459,6 @@
   }
 
   @failingTest
-  test_invalid_importPrefix_asTypeArgument() async {
-    await super.test_invalid_importPrefix_asTypeArgument();
-  }
-
-  @failingTest
   @fastaProblem
   test_invalid_nameConflict_imported() async {
     // https://github.com/dart-lang/sdk/issues/30267
@@ -458,62 +487,58 @@
   }
 
   @failingTest
+  @fastaProblem
   test_invalidUri_part_emptyUri() async {
+    // https://github.com/dart-lang/sdk/issues/30725
     await super.test_invalidUri_part_emptyUri();
   }
 
   @failingTest
+  @fastaProblem
   test_invalidUris() async {
+    // https://github.com/dart-lang/sdk/issues/30725
     await super.test_invalidUris();
   }
 
   @failingTest
-  test_library_documented_lines() async {
-    await super.test_library_documented_lines();
-  }
-
-  @failingTest
-  test_library_documented_stars() async {
-    await super.test_library_documented_stars();
-  }
-
-  @failingTest
-  test_metadata_classTypeAlias() async {
-    await super.test_metadata_classTypeAlias();
-  }
-
-  @failingTest
-  test_metadata_enumDeclaration() async {
-    await super.test_metadata_enumDeclaration();
-  }
-
-  @failingTest
+  @fastaProblem
   test_metadata_exportDirective() async {
+    // https://github.com/dart-lang/sdk/issues/30284
     await super.test_metadata_exportDirective();
   }
 
   @failingTest
+  @fastaProblem
   test_metadata_fieldFormalParameter() async {
+    // https://github.com/dart-lang/sdk/issues/30035
     await super.test_metadata_fieldFormalParameter();
   }
 
   @failingTest
+  @fastaProblem
   test_metadata_fieldFormalParameter_withDefault() async {
+    // https://github.com/dart-lang/sdk/issues/30035
     await super.test_metadata_fieldFormalParameter_withDefault();
   }
 
   @failingTest
+  @fastaProblem
   test_metadata_functionTypedFormalParameter() async {
+    // https://github.com/dart-lang/sdk/issues/30035
     await super.test_metadata_functionTypedFormalParameter();
   }
 
   @failingTest
+  @fastaProblem
   test_metadata_functionTypedFormalParameter_withDefault() async {
+    // https://github.com/dart-lang/sdk/issues/30035
     await super.test_metadata_functionTypedFormalParameter_withDefault();
   }
 
   @failingTest
+  @fastaProblem
   test_metadata_importDirective() async {
+    // https://github.com/dart-lang/sdk/issues/30284
     await super.test_metadata_importDirective();
   }
 
@@ -525,141 +550,117 @@
   }
 
   @failingTest
+  @fastaProblem
   test_metadata_libraryDirective() async {
+    // https://github.com/dart-lang/sdk/issues/30284
     await super.test_metadata_libraryDirective();
   }
 
   @failingTest
   test_metadata_partDirective() async {
+    // https://github.com/dart-lang/sdk/issues/30284
     await super.test_metadata_partDirective();
   }
 
   @failingTest
   test_metadata_simpleFormalParameter() async {
+    // https://github.com/dart-lang/sdk/issues/30035
     await super.test_metadata_simpleFormalParameter();
   }
 
   @failingTest
   test_metadata_simpleFormalParameter_withDefault() async {
+    // https://github.com/dart-lang/sdk/issues/30035
     await super.test_metadata_simpleFormalParameter_withDefault();
   }
 
   @failingTest
   test_parameter_checked() async {
+    // TODO(scheglov): triage
     await super.test_parameter_checked();
   }
 
   @failingTest
   test_parameter_checked_inherited() async {
+    // TODO(scheglov): triage
     await super.test_parameter_checked_inherited();
   }
 
   @failingTest
-  test_parameter_covariant_inherited() async {
-    await super.test_parameter_covariant_inherited();
-  }
-
-  @failingTest
+  @fastaProblem
   test_parts_invalidUri() async {
+    // https://github.com/dart-lang/sdk/issues/30725
     await super.test_parts_invalidUri();
   }
 
   @failingTest
+  @fastaProblem
   test_parts_invalidUri_nullStringValue() async {
+    // https://github.com/dart-lang/sdk/issues/30725
     await super.test_parts_invalidUri_nullStringValue();
   }
 
   @failingTest
   test_syntheticFunctionType_genericClosure() async {
+    // TODO(scheglov): this does not work even in Analyzer
     await super.test_syntheticFunctionType_genericClosure();
   }
 
   @failingTest
   test_syntheticFunctionType_inGenericClass() async {
+    // TODO(scheglov): this does not work even in Analyzer
     await super.test_syntheticFunctionType_inGenericClass();
   }
 
   @failingTest
   test_syntheticFunctionType_noArguments() async {
+    // TODO(scheglov): this does not work even in Analyzer
     await super.test_syntheticFunctionType_noArguments();
   }
 
   @failingTest
   test_syntheticFunctionType_withArguments() async {
+    // TODO(scheglov): this does not work even in Analyzer
     await super.test_syntheticFunctionType_withArguments();
   }
 
   @failingTest
-  test_type_invalid_topLevelVariableElement_asType() async {
-    await super.test_type_invalid_topLevelVariableElement_asType();
-  }
-
-  @failingTest
-  test_type_invalid_topLevelVariableElement_asTypeArgument() async {
-    await super.test_type_invalid_topLevelVariableElement_asTypeArgument();
-  }
-
-  @failingTest
-  test_type_invalid_typeParameter_asPrefix() async {
-    await super.test_type_invalid_typeParameter_asPrefix();
-  }
-
-  @failingTest
   test_type_reference_to_typedef_with_type_arguments() async {
+    // TODO(scheglov): triage
     await super.test_type_reference_to_typedef_with_type_arguments();
   }
 
   @failingTest
   test_type_reference_to_typedef_with_type_arguments_implicit() async {
+    // TODO(scheglov): triage
     await super.test_type_reference_to_typedef_with_type_arguments_implicit();
   }
 
   @failingTest
-  test_type_unresolved() async {
-    await super.test_type_unresolved();
-  }
-
-  @failingTest
-  test_type_unresolved_prefixed() async {
-    await super.test_type_unresolved_prefixed();
-  }
-
-  @failingTest
   test_typedef_documented() async {
+    // TODO(scheglov): implement
     await super.test_typedef_documented();
   }
 
   @failingTest
   test_typedef_generic() async {
+    // TODO(scheglov): triage
     await super.test_typedef_generic();
   }
 
   @failingTest
   test_typedef_generic_asFieldType() async {
+    // TODO(scheglov): triage
     await super.test_typedef_generic_asFieldType();
   }
 
   @failingTest
-  test_typedef_parameters_named() async {
-    await super.test_typedef_parameters_named();
-  }
-
-  @failingTest
   test_typedef_type_parameters_bound() async {
+    // TODO(scheglov): triage
     await super.test_typedef_type_parameters_bound();
   }
 
   @failingTest
-  test_typedef_type_parameters_bound_recursive() async {
-    await super.test_typedef_type_parameters_bound_recursive();
-  }
-
-  @failingTest
-  test_typedef_type_parameters_bound_recursive2() async {
-    await super.test_typedef_type_parameters_bound_recursive2();
-  }
-
-  @failingTest
   @fastaProblem
   test_unresolved_annotation_instanceCreation_argument_super() async {
     // https://github.com/dart-lang/sdk/issues/30267
diff --git a/pkg/analyzer/test/src/task/strong/front_end_inference_test.dart b/pkg/analyzer/test/src/task/strong/front_end_inference_test.dart
index 60b23c5..b4e7ecc 100644
--- a/pkg/analyzer/test/src/task/strong/front_end_inference_test.dart
+++ b/pkg/analyzer/test/src/task/strong/front_end_inference_test.dart
@@ -8,7 +8,6 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/scanner.dart';
 import 'package:front_end/src/base/instrumentation.dart' as fasta;
 import 'package:front_end/src/fasta/compiler_context.dart' as fasta;
 import 'package:front_end/src/fasta/testing/validating_instrumentation.dart'
diff --git a/pkg/analyzer/test/src/task/strong/front_end_runtime_check_test.dart b/pkg/analyzer/test/src/task/strong/front_end_runtime_check_test.dart
index 6f8d945..3b37edd 100644
--- a/pkg/analyzer/test/src/task/strong/front_end_runtime_check_test.dart
+++ b/pkg/analyzer/test/src/task/strong/front_end_runtime_check_test.dart
@@ -70,6 +70,7 @@
             target is ThisExpression,
             isDynamicInvoke(leftHandSide.identifier),
             target.staticType,
+            null,
             leftHandSide.identifier.offset);
       }
     }
@@ -112,11 +113,16 @@
       _annotateCheckReturn(
           getImplicitOperationCast(node), node.methodName.offset);
       _annotateCallKind(null, isThis, isDynamicInvoke(node.methodName), null,
-          node.argumentList.offset);
+          null, node.argumentList.offset);
     } else {
       _annotateCheckReturn(getImplicitCast(node), node.argumentList.offset);
-      _annotateCallKind(staticElement, isThis, isDynamicInvoke(node.methodName),
-          target?.staticType, node.argumentList.offset);
+      _annotateCallKind(
+          staticElement,
+          isThis,
+          isDynamicInvoke(node.methodName),
+          target?.staticType,
+          node.methodName.staticType,
+          node.argumentList.offset);
     }
   }
 
@@ -164,7 +170,7 @@
   /// depends on the `@checkInterface` annotations on the static target of the
   /// call.
   void _annotateCallKind(Element staticElement, bool isThis, bool isDynamic,
-      DartType targetType, int offset) {
+      DartType targetType, DartType methodType, int offset) {
     if (staticElement is FunctionElement &&
         staticElement.enclosingElement is CompilationUnitElement) {
       // Invocation of a top level function; no annotation needed.
@@ -173,7 +179,8 @@
     if (isDynamic) {
       if (targetType == null &&
           staticElement != null &&
-          staticElement is! MethodElement) {
+          staticElement is! MethodElement &&
+          methodType is FunctionType) {
         // Sometimes analyzer annotates invocations of function objects as
         // dynamic (presumably due to "dynamic is bottom" behavior).  Ignore
         // this.
@@ -208,47 +215,60 @@
     }
   }
 
-  /// Generates the appropriate `@checkFormal` and `@checkInterface` annotations
-  /// (if any) for a method formal parameter, method type parameter, or field
-  /// declaration.
+  /// Generates the appropriate `@covariance` annotation (if any) for a method
+  /// formal parameter, method type parameter, or field declaration.
   ///
   /// When these annotations are generated for a field declaration, they
   /// implicitly refer to the value parameter of the synthetic setter.
   ///
-  /// An annotation of `@checkFormal=unsafe` indicates that the parameter needs
+  /// An annotation of `@covariance=explicit` indicates that the parameter needs
   /// to be type checked regardless of the call site.
   ///
-  /// An annotation of `@checkFormal=semiSafe` indicates that the parameter
+  /// An annotation of `@covariance=genericImpl` indicates that the parameter
   /// needs to be type checked when the call site is annotated
   /// `@callKind=dynamic` or `@callKind=closure`, or the call site is
   /// unannotated and the corresponding parameter in the interface target is
-  /// annotated `@checkInterface=semiTyped`.
+  /// annotated `@covariance=genericInterface`.
   ///
-  /// No `@checkFormal` annotation indicates that the parameter only needs to be
+  /// No `@covariance` annotation indicates that the parameter only needs to be
   /// type checked if the call site is annotated `@callKind=dynamic`.
   void _annotateFormalParameter(
       Element element, int offset, ClassDeclaration cls) {
+    bool isExplicit = false;
+    bool isGenericImpl = false;
     if (element is ParameterElement && element.isCovariant) {
-      _recordCheckFormal(offset, 'unsafe');
+      isExplicit = true;
     } else if (cls != null) {
       var covariantParams = getClassCovariantParameters(cls);
-      if (covariantParams != null && covariantParams.contains(element)) {
-        _recordCheckFormal(offset, 'semiSafe');
+      if (covariantParams != null && covariantParams.contains(element) ||
+          cls?.typeParameters != null &&
+              element is ParameterElement &&
+              _isFormalSemiTyped(
+                  cls.typeParameters.typeParameters, element.type)) {
+        isGenericImpl = true;
       }
     }
+    bool isGenericInterface = false;
     if (cls?.typeParameters != null) {
       if (element is ParameterElement) {
         if (_isFormalSemiTyped(
             cls.typeParameters.typeParameters, element.type)) {
-          _recordCheckInterface(offset, 'semiTyped');
+          isGenericInterface = true;
         }
       } else if (element is TypeParameterElement && element.bound != null) {
         if (_isFormalSemiTyped(
             cls.typeParameters.typeParameters, element.bound)) {
-          _recordCheckInterface(offset, 'semiTyped');
+          isGenericInterface = true;
         }
       }
     }
+    var covariance = <String>[];
+    if (isExplicit) covariance.add('explicit');
+    if (isGenericInterface) covariance.add('genericInterface');
+    if (isGenericImpl) covariance.add('genericImpl');
+    if (covariance.isNotEmpty) {
+      _recordCovariance(offset, covariance.join(', '));
+    }
   }
 
   /// Generates the appropriate `@checkTearOff` annotation (if any) for a call
@@ -271,31 +291,54 @@
   ///
   /// An annotation of `@forwardingStub=rettype name(args)` indicates that a
   /// forwarding stub must be inserted into the class having the given name and
-  /// return type.  Each argument is listed in `args` as `safety type name`,
-  /// where safety is one of `safe` or `semiSafe`.
+  /// return type.  Each argument is listed in `args` as
+  /// `covariance=(...) type name`, where the words between the parentheses are
+  /// the same as for the `@covariance=` annotation.
   void _emitForwardingStubs(Declaration node, int offset) {
     var covariantParams = getSuperclassCovariantParameters(node);
+    void emitStubFor(DartType returnType, String name,
+        List<ParameterElement> parameters, String accessorType) {
+      var paramDescrs = <String>[];
+      for (var param in parameters) {
+        var covariances = <String>[];
+        if (covariantParams.contains(param)) {
+          if (param.isCovariant) {
+            covariances.add('explicit');
+          } else {
+            covariances.add('genericImpl');
+          }
+        }
+        var covariance = 'covariance=(${covariances.join(', ')})';
+        var typeDescr = _typeToString(param.type);
+        var paramName = accessorType == 'set' ? 'value' : param.name;
+        // TODO(paulberry): if necessary, support other parameter kinds
+        assert(param.parameterKind == ParameterKind.REQUIRED);
+        paramDescrs.add('$covariance $typeDescr $paramName');
+      }
+      var returnTypeDescr = _typeToString(returnType);
+      var stubParts = [returnTypeDescr];
+      if (accessorType != null) stubParts.add(accessorType);
+      stubParts.add('$name(${paramDescrs.join(', ')})');
+      _recordForwardingStub(offset, stubParts.join(' '));
+    }
+
     if (covariantParams != null && covariantParams.isNotEmpty) {
       for (var member
           in covariantParams.map((p) => p.enclosingElement).toSet()) {
         var memberName = member.name;
         if (member is PropertyAccessorElement) {
-          throw new UnimplementedError(); // TODO(paulberry)
-        } else if (member is MethodElement) {
-          var paramDescrs = <String>[];
-          for (var param in member.parameters) {
-            // TODO(paulberry): test the safe case
-            var safetyDescr =
-                covariantParams.contains(param) ? 'semiSafe' : 'safe';
-            var typeDescr = _typeToString(param.type);
-            var paramName = param.name;
-            // TODO(paulberry): if necessary, support other parameter kinds
-            assert(param.parameterKind == ParameterKind.REQUIRED);
-            paramDescrs.add('$safetyDescr $typeDescr $paramName');
+          if (member.isSetter) {
+            emitStubFor(
+                member.returnType,
+                memberName.substring(0, memberName.length - 1),
+                member.parameters,
+                'set');
+          } else {
+            emitStubFor(
+                member.returnType, memberName, member.parameters, 'get');
           }
-          var returnTypeDescr = _typeToString(member.returnType);
-          var stub = '$returnTypeDescr $memberName(${paramDescrs.join(', ')})';
-          _recordForwardingStub(offset, stub);
+        } else if (member is MethodElement) {
+          emitStubFor(member.returnType, memberName, member.parameters, null);
         } else {
           throw new StateError('Unexpected covariant member $member');
         }
@@ -330,16 +373,6 @@
         uri, offset, 'callKind', new fasta.InstrumentationValueLiteral(kind));
   }
 
-  void _recordCheckFormal(int offset, String safety) {
-    _instrumentation.record(uri, offset, 'checkFormal',
-        new fasta.InstrumentationValueLiteral(safety));
-  }
-
-  void _recordCheckInterface(int offset, String safety) {
-    _instrumentation.record(uri, offset, 'checkInterface',
-        new fasta.InstrumentationValueLiteral(safety));
-  }
-
   void _recordCheckReturn(int offset, DartType castType) {
     _instrumentation.record(uri, offset, 'checkReturn',
         new InstrumentationValueForType(castType, _elementNamer));
@@ -350,6 +383,11 @@
         new InstrumentationValueForType(castType, _elementNamer));
   }
 
+  void _recordCovariance(int offset, String covariance) {
+    _instrumentation.record(uri, offset, 'covariance',
+        new fasta.InstrumentationValueLiteral(covariance));
+  }
+
   void _recordForwardingStub(int offset, String descr) {
     _instrumentation.record(uri, offset, 'forwardingStub',
         new fasta.InstrumentationValueLiteral(descr));
diff --git a/pkg/analyzer/test/src/task/strong/front_end_test_common.dart b/pkg/analyzer/test/src/task/strong/front_end_test_common.dart
index f0b75da..304f03a 100644
--- a/pkg/analyzer/test/src/task/strong/front_end_test_common.dart
+++ b/pkg/analyzer/test/src/task/strong/front_end_test_common.dart
@@ -10,10 +10,11 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:front_end/src/base/instrumentation.dart' as fasta;
@@ -21,6 +22,7 @@
 import 'package:front_end/src/fasta/testing/validating_instrumentation.dart'
     as fasta;
 import 'package:front_end/src/fasta/util/relativize.dart' show relativizeUri;
+import 'package:front_end/src/testing/package_root.dart' as package_root;
 import 'package:kernel/kernel.dart' as fasta;
 import 'package:path/path.dart' as pathos;
 import 'package:test/test.dart';
@@ -213,6 +215,41 @@
       .join(', ');
 }
 
+abstract class RunFrontEndTest {
+  String get testSubdir;
+
+  test_run() async {
+    String pkgPath = package_root.packageRoot;
+    String fePath = pathos.join(pkgPath, 'front_end', 'testcases', testSubdir);
+    List<File> dartFiles = new Directory(fePath)
+        .listSync()
+        .where((entry) => entry is File && entry.path.endsWith('.dart'))
+        .map((entry) => entry as File)
+        .toList();
+
+    var allProblems = new StringBuffer();
+    for (File file in dartFiles) {
+      var test = new _FrontEndInferenceTest(this);
+      await test.setUp();
+      try {
+        String code = file.readAsStringSync();
+        String problems = await test.runTest(file.path, code);
+        if (problems != null) {
+          allProblems.writeln(problems);
+        }
+      } finally {
+        await test.tearDown();
+      }
+    }
+    if (allProblems.isNotEmpty) {
+      fail(allProblems.toString());
+    }
+  }
+
+  void visitUnit(TypeProvider typeProvider, CompilationUnit unit,
+      fasta.ValidatingInstrumentation validation, Uri uri);
+}
+
 class _FrontEndInferenceTest extends BaseAnalysisDriverTest {
   final RunFrontEndTest _frontEndTestRunner;
 
@@ -285,55 +322,3 @@
     }
   }
 }
-
-abstract class RunFrontEndTest {
-  String get testSubdir;
-
-  test_run() async {
-    String pkgPath = _findPkgRoot();
-    String fePath = pathos.join(pkgPath, 'front_end', 'testcases', testSubdir);
-    List<File> dartFiles = new Directory(fePath)
-        .listSync()
-        .where((entry) => entry is File && entry.path.endsWith('.dart'))
-        .map((entry) => entry as File)
-        .toList();
-
-    var allProblems = new StringBuffer();
-    for (File file in dartFiles) {
-      var test = new _FrontEndInferenceTest(this);
-      await test.setUp();
-      try {
-        String code = file.readAsStringSync();
-        String problems = await test.runTest(file.path, code);
-        if (problems != null) {
-          allProblems.writeln(problems);
-        }
-      } finally {
-        await test.tearDown();
-      }
-    }
-    if (allProblems.isNotEmpty) {
-      fail(allProblems.toString());
-    }
-  }
-
-  /**
-   * Expects that the [Platform.script] is a test inside of `pkg/analyzer/test`
-   * folder, and return the absolute path of the `pkg` folder.
-   */
-  String _findPkgRoot() {
-    String scriptPath = pathos.fromUri(Platform.script);
-    List<String> parts = pathos.split(scriptPath);
-    for (int i = 0; i < parts.length - 2; i++) {
-      if (parts[i] == 'pkg' &&
-          parts[i + 1] == 'analyzer' &&
-          parts[i + 2] == 'test') {
-        return pathos.joinAll(parts.sublist(0, i + 1));
-      }
-    }
-    throw new StateError('Unable to find sdk/pkg/ in $scriptPath');
-  }
-
-  void visitUnit(TypeProvider typeProvider, CompilationUnit unit,
-      fasta.ValidatingInstrumentation validation, Uri uri);
-}
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 76f9bb3..484e5c4 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -23,8 +23,8 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:source_span/source_span.dart';
 import 'package:test/test.dart';
 
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index 6287bed..d6d0d19 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -2,13 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analyzer.test.src.test_all;
-
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'command_line/test_all.dart' as command_line;
 import 'context/test_all.dart' as context;
 import 'dart/test_all.dart' as dart;
+import 'fasta/test_all.dart' as fasta;
 import 'lint/test_all.dart' as lint;
 import 'source/test_all.dart' as source;
 import 'summary/test_all.dart' as summary;
@@ -21,6 +20,7 @@
     command_line.main();
     context.main();
     dart.main();
+    fasta.main();
     lint.main();
     source.main();
     summary.main();
diff --git a/pkg/analyzer/tool/fasta_migration_progress.sh b/pkg/analyzer/tool/fasta_migration_progress.sh
new file mode 100644
index 0000000..4011ce0
--- /dev/null
+++ b/pkg/analyzer/tool/fasta_migration_progress.sh
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Script that collects progress metrics of the analyzer/FE integration.
+
+# Metric 1: parser tests via fasta
+
+# Run the suite to extract the total number of tests from the runner output.
+# TODO(sigmund): don't require `dart` to be on the path.
+total=$(dart pkg/analyzer/test/generated/parser_fasta_test.dart | \
+  tail -1 | \
+  sed -e "s/.*+\([0-9]*\)[^0-9].*All tests passed.*$/\1/")
+
+# Count tests marked with the @failingTest annotation.
+fail=$(cat pkg/analyzer/test/generated/parser_fasta_test.dart | \
+  grep failingTest | wc -l)
+
+pass_rate=$(bc <<< "scale=1; 100*($total-$fail)/$total")
+echo "Parser-fasta tests:         $(($total - $fail))/$total ($pass_rate%)"
+
+# Metric 2: analyzer tests with fasta enabled.
+
+# Run analyzer tests forcing the fasta parser, then process the logged output to
+# count the number of individual tests (a single test case in a test file) that
+# are passing or failing.
+
+echo "Analyzer tests files:"
+logfile=$1
+delete=0
+
+# If a log file is provided on the command line, reuse it and don't run the
+# suite again.
+if [[ $logfile == '' ]]; then
+  logfile=$(mktemp log-XXXXXX.txt)
+  echo "  Log file: $logfile"
+  # TODO: delete by default and stop logging the location of the file.
+  # delete=1
+  python tools/test.py -m release --checked --use-sdk \
+     --vm-options="-DuseFastaParser=true" \
+     pkg/analy > $logfile
+fi;
+
+pass=$(tail -1 $logfile | sed -e "s/.*+\s*\([0-9]*\) |.*$/\1/")
+fail=$(tail -1 $logfile | sed -e "s/.* -\s*\([0-9]*\)\].*$/\1/")
+pass_rate=$(bc <<< "scale=1; 100*$pass/($pass + $fail)")
+
+echo "  Test files passing:       $pass/$(($pass + $fail)) ($pass_rate%)"
+
+# Tests use package:test, which contains a summary line saying how many tests
+# passed and failed. The line has this form:
+#
+#    MM:SS  +pp -ff: Some tests failed
+#
+# but also contains some escape sequences for color highlighting. The code below
+# extracts the passing (pp) and failing (ff) numbers and tallies them up:
+cat $logfile | \
+  grep "Some tests failed" | \
+  sed -e "s/.*+\([0-9]*\).* -\([0-9]*\).*/\1 \2/" | \
+   awk '{
+    pass += $1
+    total += $1 + $2
+  } END {
+    printf ("  Individual tests passing: %d/%d (%.1f%)\n", \
+      pass/2, total/2,(100 * pass / total))
+  }'
+
+if [[ $delete == 1 ]]; then
+  echo "rm $logfile"
+fi
+
+# TODO: Add metric 3 - coverage of error codes
diff --git a/pkg/analyzer/tool/summary/check_test.dart b/pkg/analyzer/tool/summary/check_test.dart
index 88d630d..bccb46f 100644
--- a/pkg/analyzer/tool/summary/check_test.dart
+++ b/pkg/analyzer/tool/summary/check_test.dart
@@ -4,9 +4,8 @@
 
 library analyzer.tool.summary.check_test;
 
-import 'dart:io';
-
 import 'package:front_end/src/codegen/tools.dart';
+import 'package:front_end/src/testing/package_root.dart' as package_root;
 import 'package:path/path.dart';
 
 import 'generate.dart';
@@ -16,8 +15,7 @@
  * user to run generate.dart.
  */
 main() async {
-  String script = Platform.script.toFilePath(windows: Platform.isWindows);
-  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  String pkgPath = normalize(join(package_root.packageRoot, 'analyzer'));
   await GeneratedContent.checkAll(
       pkgPath, 'tool/summary/generate.dart', allTargets);
 }
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index 6ac6197..afa5205 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -25,14 +25,14 @@
 import 'package:front_end/src/codegen/tools.dart';
 import 'package:front_end/src/fasta/scanner/string_scanner.dart';
 import 'package:front_end/src/scanner/token.dart' show Token;
+import 'package:front_end/src/testing/package_root.dart' as package_root;
 import 'package:path/path.dart';
 
 import 'idl_model.dart' as idlModel;
 import 'mini_ast.dart';
 
 main() async {
-  String script = Platform.script.toFilePath(windows: Platform.isWindows);
-  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  String pkgPath = normalize(join(package_root.packageRoot, 'analyzer'));
   await GeneratedContent.generateAll(pkgPath, allTargets);
 }
 
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index 6a15270..74a9fd6b 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -187,13 +187,6 @@
     push(popList(memberCount));
   }
 
-  @override
-  void handleNativeClause(Token nativeToken, bool hasName) {
-    if (hasName) {
-      pop(); // Pop the native clause which in this case is a StringLiteral.
-    }
-  }
-
   void endClassDeclaration(
       int interfacesCount,
       Token beginToken,
@@ -311,6 +304,14 @@
   }
 
   @override
+  void handleNativeClause(Token nativeToken, bool hasName) {
+    debugEvent("NativeClause");
+    if (hasName) {
+      pop(); // Pop the native name which is a StringLiteral.
+    }
+  }
+
+  @override
   void endMember() {
     debugEvent("Member");
   }
@@ -327,7 +328,7 @@
   }
 
   @override
-  void endMetadataStar(int count, bool forParameter) {
+  void endMetadataStar(int count) {
     debugEvent("MetadataStar");
     push(popList(count) ?? NullValue.Metadata);
   }
@@ -384,7 +385,7 @@
   }
 
   @override
-  void handleBinaryExpression(Token token) {
+  void endBinaryExpression(Token token) {
     debugEvent("BinaryExpression");
     pop(); // RHS
     pop(); // LHS
@@ -402,6 +403,17 @@
     push(NullValue.FunctionBody);
   }
 
+  @override
+  void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {
+    debugEvent("NativeFunctionBodyIgnored");
+  }
+
+  @override
+  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
+    debugEvent("NativeFunctionBodySkipped");
+    push(NullValue.FunctionBody);
+  }
+
   void handleIdentifier(Token token, IdentifierContext context) {
     if (context == IdentifierContext.enumValueDeclaration) {
       var comment = new Comment(token.precedingComments);
diff --git a/pkg/analyzer/tool/task_dependency_graph/check_test.dart b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
index cfd3322..c1308db 100644
--- a/pkg/analyzer/tool/task_dependency_graph/check_test.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
@@ -4,9 +4,8 @@
 
 library analyzer.tool.task_dependency_graph.check_test;
 
-import 'dart:io';
-
 import 'package:front_end/src/codegen/tools.dart';
+import 'package:front_end/src/testing/package_root.dart' as package_root;
 import 'package:path/path.dart';
 
 import 'generate.dart';
@@ -16,8 +15,7 @@
  * user to run generate.dart.
  */
 main() async {
-  String script = Platform.script.toFilePath(windows: Platform.isWindows);
-  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  String pkgPath = normalize(join(package_root.packageRoot, 'analyzer'));
   await GeneratedContent.checkAll(pkgPath,
       'tool/task_dependency_graph/generate.dart', <GeneratedContent>[target]);
 }
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index c109d99..f43e097 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -37,9 +37,10 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:front_end/src/codegen/tools.dart';
+import 'package:front_end/src/testing/package_root.dart' as package_root;
 import 'package:path/path.dart' as path;
 import 'package:path/path.dart';
 
@@ -47,8 +48,7 @@
  * Generate the target .dot file.
  */
 main() async {
-  String script = Platform.script.toFilePath(windows: Platform.isWindows);
-  String pkgPath = normalize(join(dirname(script), '..', '..'));
+  String pkgPath = normalize(join(package_root.packageRoot, 'analyzer'));
   await GeneratedContent
       .generateAll(pkgPath, <GeneratedContent>[target, htmlTarget]);
 }
@@ -89,7 +89,7 @@
    * result descriptors.
    */
   void findExtensions(AstNode node, TopLevelVariableElement extensionIdVariable,
-      void callback(descriptorName)) {
+      void callback(String descriptorName)) {
     Set<PropertyAccessorElement> resultDescriptors =
         new Set<PropertyAccessorElement>();
     node.accept(new ExtensionFinder(
diff --git a/pkg/analyzer_cli/lib/src/batch_mode.dart b/pkg/analyzer_cli/lib/src/batch_mode.dart
index 8b73af1..40037cb 100644
--- a/pkg/analyzer_cli/lib/src/batch_mode.dart
+++ b/pkg/analyzer_cli/lib/src/batch_mode.dart
@@ -29,7 +29,7 @@
     int totalTests = 0;
     ErrorSeverity batchResult = ErrorSeverity.NONE;
     // Read line from stdin.
-    Stream cmdLine =
+    Stream<String> cmdLine =
         stdin.transform(UTF8.decoder).transform(new LineSplitter());
     cmdLine.listen((String line) async {
       // Maybe finish.
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index c76de07..6299984 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -31,8 +31,8 @@
 import 'package:bazel_worker/bazel_worker.dart';
 import 'package:collection/collection.dart';
 import 'package:convert/convert.dart';
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:front_end/src/byte_store/cache.dart';
 
 /**
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index e993f1c..4bee8f4 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -39,8 +39,8 @@
 import 'package:analyzer_cli/src/options.dart';
 import 'package:analyzer_cli/src/perf_report.dart';
 import 'package:analyzer_cli/starter.dart' show CommandLineStarter;
+import 'package:front_end/byte_store.dart';
 import 'package:front_end/src/base/performace_logger.dart';
-import 'package:front_end/src/byte_store/byte_store.dart';
 import 'package:linter/src/rules.dart' as linter;
 import 'package:meta/meta.dart';
 import 'package:package_config/discovery.dart' as pkg_discovery;
@@ -866,6 +866,9 @@
     if (options.enableAssertInitializer != null) {
       contextOptions.enableAssertInitializer = options.enableAssertInitializer;
     }
+    if (options.previewDart2) {
+      contextOptions.useFastaParser = true;
+    }
 
     _directoryToAnalysisOptions[contextRootDirectory] = contextOptions;
     return contextOptions;
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index cf9e6f2..5cee893 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -114,6 +114,9 @@
   /// (Or null if not enabled.)
   final String perfReport;
 
+  /// Whether to enable the Dart 2.0 Front End.
+  final bool previewDart2;
+
   /// Batch mode (for unit testing)
   final bool batchMode;
 
@@ -186,6 +189,7 @@
         log = args['log'],
         machineFormat = args['format'] == 'machine',
         perfReport = args['x-perf-report'],
+        previewDart2 = args['preview-dart-2'],
         batchMode = args['batch'],
         showPackageWarnings = args['show-package-warnings'] ||
             args['package-warnings'] ||
@@ -506,6 +510,11 @@
               'of "libraryUri".',
           allowMultiple: true,
           splitCommas: false,
+          hide: hide)
+      ..addFlag('preview-dart-2',
+          help: 'Enable the Dart 2.0 Front End implementation.',
+          defaultsTo: false,
+          negatable: false,
           hide: hide);
 
     try {
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 2d09e03..6e80d21 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -751,6 +751,12 @@
     expect(outSink.toString(), contains('Avoid empty else statements'));
   }
 
+  test_previewDart2() async {
+    await drive('data/options_tests_project/test_file.dart',
+        args: ['--preview-dart-2']);
+    expect(driver.context.analysisOptions.useFastaParser, isTrue);
+  }
+
   test_strongSdk() async {
     String testDir = path.join(testDirectory, 'data', 'strong_sdk');
     await drive(path.join(testDir, 'main.dart'), args: ['--strong']);
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 63e0d99..9d50de3 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -76,6 +76,7 @@
         expect(options.warningsAreFatal, isFalse);
         expect(options.strongMode, isFalse);
         expect(options.lintsAreFatal, isFalse);
+        expect(options.previewDart2, isFalse);
       });
 
       test('batch', () {
@@ -256,6 +257,12 @@
               outStringBuffer.toString(), contains('Analytics are currently'));
         });
       }
+
+      test('preview FE', () {
+        CommandLineOptions options =
+            CommandLineOptions.parse(['--preview-dart-2', 'foo.dart']);
+        expect(options.previewDart2, isTrue);
+      });
     });
   });
   defineReflectiveTests(CommandLineOptionsTest);
diff --git a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
index c0f65fb..7256fff 100644
--- a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
+++ b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
@@ -38,7 +38,8 @@
 
   @override
   Future<Isolate> _spawnIsolate() {
-    return Isolate.spawn(entryPoint, _receivePort.sendPort,
+    return Isolate.spawn(
+        (message) => entryPoint(message as SendPort), _receivePort.sendPort,
         onError: _errorPort?.sendPort, onExit: _exitPort?.sendPort);
   }
 }
diff --git a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
index 006ada1..54a1efe 100644
--- a/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
+++ b/pkg/analyzer_plugin/lib/src/protocol/protocol_internal.dart
@@ -84,7 +84,7 @@
  * Compare the lists [listA] and [listB], using [itemEqual] to compare
  * list elements.
  */
-bool listEqual(List listA, List listB, bool itemEqual(a, b)) {
+bool listEqual<T>(List<T> listA, List<T> listB, bool itemEqual(T a, T b)) {
   if (listA == null) {
     return listB == null;
   }
@@ -106,7 +106,7 @@
  * Compare the maps [mapA] and [mapB], using [valueEqual] to compare map
  * values.
  */
-bool mapEqual(Map mapA, Map mapB, bool valueEqual(a, b)) {
+bool mapEqual<K, V>(Map<K, V> mapA, Map<K, V> mapB, bool valueEqual(V a, V b)) {
   if (mapA == null) {
     return mapB == null;
   }
@@ -316,7 +316,7 @@
       return {};
     } else if (json is Map) {
       Map<K, V> result = <K, V>{};
-      json.forEach((String key, value) {
+      json.forEach((key, value) {
         K decodedKey;
         if (keyDecoder != null) {
           decodedKey = keyDecoder('$jsonPath.key', key);
diff --git a/pkg/analyzer_plugin/test/integration/support/integration_tests.dart b/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
index 5e48868..3f6a1c3 100644
--- a/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
+++ b/pkg/analyzer_plugin/test/integration/support/integration_tests.dart
@@ -886,7 +886,7 @@
    * substructure did not match.
    */
   checkSubstructure(item, Matcher matcher, List<MismatchDescriber> mismatches,
-      Description describeSubstructure(Description)) {
+      Description describeSubstructure(Description description)) {
     Map subState = {};
     if (!matcher.matches(item, subState)) {
       mismatches.add((Description mismatchDescription) {
diff --git a/pkg/analyzer_plugin/tool/spec/from_html.dart b/pkg/analyzer_plugin/tool/spec/from_html.dart
index 5ce58d4..3a108d0 100644
--- a/pkg/analyzer_plugin/tool/spec/from_html.dart
+++ b/pkg/analyzer_plugin/tool/spec/from_html.dart
@@ -121,7 +121,7 @@
       dom.Element element, List<String> requiredAttributes, String context,
       {List<String> optionalAttributes: const []}) {
     Set<String> attributesFound = new Set<String>();
-    element.attributes.forEach((String name, String value) {
+    element.attributes.forEach((name, value) {
       if (!requiredAttributes.contains(name) &&
           !optionalAttributes.contains(name)) {
         throw new Exception(
diff --git a/pkg/compiler/README.md b/pkg/compiler/README.md
index e91c939..746e47d 100644
--- a/pkg/compiler/README.md
+++ b/pkg/compiler/README.md
@@ -780,7 +780,6 @@
 `lib/src/js_backend/js_interop_analysis.dart`
 `lib/src/js_backend/backend_impact.dart`
 `lib/src/js_backend/constant_emitter.dart`
-`lib/src/js_backend/lookup_map_analysis.dart`
 `lib/src/js_backend/namer_names.dart`
 `lib/src/js_backend/runtime_types.dart`
 `lib/src/js_backend/no_such_method_registry.dart`
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index e95088f..45d6a0d 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:front_end/src/fasta/scanner.dart' show Token;
+
 import 'common/names.dart' show Identifiers;
 import 'common/resolution.dart' show ParsingContext, Resolution;
 import 'common/tasks.dart' show CompilerTask, Measurer;
@@ -19,7 +21,6 @@
 import 'js_backend/js_backend.dart' show JavaScriptBackend;
 import 'js_backend/runtime_types.dart';
 import 'resolution/tree_elements.dart' show TreeElements;
-import 'package:front_end/src/fasta/scanner.dart' show Token;
 import 'tree/tree.dart';
 import 'util/util.dart';
 import 'world.dart' show ClosedWorldRefiner;
@@ -211,10 +212,19 @@
   /// the closure class.
   FunctionEntity get callMethod => null;
 
+  /// List of locals that this closure class has created corresponding field
+  /// entities for.
+  @deprecated
+  List<Local> get createdFieldEntities => const <Local>[];
+
   /// As shown in the example in the comments at the top of this class, we
   /// create fields in the closure class for each captured variable. This is an
-  /// accessor to that set of fields.
-  List<Local> get createdFieldEntities => const <Local>[];
+  /// accessor the [local] for which [field] was created.
+  /// Returns the [local] for which [field] was created.
+  Local getLocalForField(FieldEntity field) {
+    failedAt(field, "No local for $field.");
+    return null;
+  }
 
   /// Convenience pointer to the field entity representation in the closure
   /// class of the element representing `this`.
@@ -348,8 +358,8 @@
       ClosureClassMap cached = _closureMemberMappingCache[element];
       if (cached != null) return cached;
       if (element.resolvedAst.kind != ResolvedAstKind.PARSED) {
-        return _closureMemberMappingCache[element] =
-            new ClosureClassMap(null, null, null, new ThisLocal(element));
+        return _closureMemberMappingCache[element] = new ClosureClassMap(
+            null, null, null, new ThisLocalVariable(element));
       }
       return reporter.withCurrentElement(element.implementation, () {
         Node node = element.resolvedAst.node;
@@ -370,8 +380,8 @@
         } else if (element.isSynthesized) {
           reporter.internalError(
               element, "Unexpected synthesized element: $element");
-          _closureMemberMappingCache[element] =
-              new ClosureClassMap(null, null, null, new ThisLocal(element));
+          _closureMemberMappingCache[element] = new ClosureClassMap(
+              null, null, null, new ThisLocalVariable(element));
         } else {
           assert(element.isField,
               failedAt(element, "Expected $element to be a field."));
@@ -386,8 +396,8 @@
                     element,
                     "Expected $element (${element.runtimeType}) "
                     "to be an instance field."));
-            _closureMemberMappingCache[element] =
-                new ClosureClassMap(null, null, null, new ThisLocal(element));
+            _closureMemberMappingCache[element] = new ClosureClassMap(
+                null, null, null, new ThisLocalVariable(element));
           }
         }
         assert(_closureMemberMappingCache[element] != null,
@@ -541,26 +551,31 @@
 /// fields.
 class BoxLocal extends Local {
   final String name;
-  final MemberEntity memberContext;
 
   final int hashCode = _nextHashCode = (_nextHashCode + 10007).toUnsigned(30);
   static int _nextHashCode = 0;
 
-  BoxLocal(this.name, this.memberContext);
-
-  Entity get executableContext => memberContext;
+  BoxLocal(this.name);
 
   String toString() => 'BoxLocal($name)';
 }
 
+class BoxLocalVariable extends BoxLocal implements LocalVariable {
+  final MemberElement memberContext;
+
+  BoxLocalVariable(String name, this.memberContext) : super(name);
+
+  ExecutableElement get executableContext => memberContext;
+}
+
 // TODO(ngeoffray, ahe): These classes continuously cause problems.  We need to
 // find a more general solution.
 class BoxFieldElement extends ElementX
     implements TypedElement, FieldElement, PrivatelyNamedJSEntity {
   final LocalVariableElement variableElement;
-  final BoxLocal box;
+  final BoxLocalVariable box;
 
-  BoxFieldElement(String name, this.variableElement, BoxLocal box)
+  BoxFieldElement(String name, this.variableElement, BoxLocalVariable box)
       : this.box = box,
         super(name, ElementKind.FIELD, box.executableContext);
 
@@ -614,24 +629,26 @@
 
 /// A local variable used encode the direct (uncaptured) references to [this].
 class ThisLocal extends Local {
-  final MemberEntity memberContext;
+  final ClassEntity enclosingClass;
 
-  ThisLocal(this.memberContext);
-
-  Entity get executableContext => memberContext;
+  ThisLocal(MemberEntity member) : enclosingClass = member.enclosingClass;
 
   String get name => 'this';
 
-  ClassEntity get enclosingClass => memberContext.enclosingClass;
-
   bool operator ==(other) {
-    return other is ThisLocal &&
-        other.name == name &&
-        other.memberContext == memberContext &&
-        other.enclosingClass == enclosingClass;
+    return other is ThisLocal && other.enclosingClass == enclosingClass;
   }
 
-  int get hashCode => memberContext.hashCode + enclosingClass.hashCode;
+  int get hashCode => enclosingClass.hashCode;
+}
+
+/// A local variable used encode the direct (uncaptured) references to [this].
+class ThisLocalVariable extends ThisLocal implements LocalVariable {
+  final MemberElement memberContext;
+
+  ThisLocalVariable(this.memberContext) : super(memberContext);
+
+  ExecutableElement get executableContext => memberContext;
 }
 
 /// Call method of a closure class.
@@ -798,6 +815,9 @@
     return fields;
   }
 
+  @override
+  Local getLocalForField(covariant ClosureFieldElement field) => field.local;
+
   void addFreeVariable(Local element) {
     assert(freeVariableMap[element] == null);
     freeVariableMap[element] = null;
@@ -1054,7 +1074,7 @@
     // optimization: factories have type parameters as function
     // parameters, and type parameters are declared in the class, not
     // the factory.
-    bool inCurrentContext(Local variable) {
+    bool inCurrentContext(LocalVariable variable) {
       return variable == executableContext ||
           variable.executableContext == executableContext;
     }
@@ -1079,7 +1099,7 @@
   }
 
   void useTypeVariableAsLocal(ResolutionTypeVariableType typeVariable) {
-    useLocal(new TypeVariableLocal(
+    useLocal(new TypeVariableLocalVariable(
         typeVariable, outermostElement, outermostElement.memberContext));
   }
 
@@ -1260,7 +1280,7 @@
   // current [closureData].
   // The boxed variables are updated in the [capturedVariableMapping].
   void attachCapturedScopeVariables(Node node) {
-    BoxLocal box = null;
+    BoxLocalVariable box = null;
     Map<LocalVariableElement, BoxFieldElement> scopeMapping =
         new Map<LocalVariableElement, BoxFieldElement>();
 
@@ -1269,7 +1289,7 @@
         if (box == null) {
           // TODO(floitsch): construct better box names.
           String boxName = getBoxFieldName(closureFieldCounter++);
-          box = new BoxLocal(boxName, executableContext.memberContext);
+          box = new BoxLocalVariable(boxName, executableContext.memberContext);
         }
         String elementName = variable.name;
         String boxedName =
@@ -1442,7 +1462,7 @@
       ThisLocal thisElement = null;
       if (element.isInstanceMember || element.isGenerativeConstructor) {
         MemberElement member = element;
-        thisElement = new ThisLocal(member);
+        thisElement = new ThisLocalVariable(member);
       }
       closureData = new ClosureClassMap(null, null, null, thisElement);
       memberMappingCache[element] = closureData;
@@ -1533,11 +1553,8 @@
 /// A type variable as a local variable.
 class TypeVariableLocal implements Local {
   final TypeVariableType typeVariable;
-  final Entity executableContext;
-  final MemberEntity memberContext;
 
-  TypeVariableLocal(
-      this.typeVariable, this.executableContext, this.memberContext);
+  TypeVariableLocal(this.typeVariable);
 
   String get name => typeVariable.element.name;
 
@@ -1557,6 +1574,16 @@
   }
 }
 
+class TypeVariableLocalVariable extends TypeVariableLocal
+    implements LocalVariable {
+  final ExecutableElement executableContext;
+  final MemberElement memberContext;
+
+  TypeVariableLocalVariable(
+      TypeVariableType typeVariable, this.executableContext, this.memberContext)
+      : super(typeVariable);
+}
+
 ///
 /// Move the below classes to a JS model eventually.
 ///
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 00c5f39..7c64a31 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -1168,9 +1168,6 @@
       SourceInformation position = spannable.sourceInformation;
       if (position != null) return position.sourceSpan;
       return _spanFromStrategy(element);
-    } else if (spannable is Local) {
-      Local local = spannable;
-      return _spanFromStrategy(local.executableContext);
     } else {
       return _spanFromStrategy(spannable);
     }
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index b526071..e029d2e 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -891,6 +891,9 @@
     assert(PRECEDENCE_MAP[operator.kind] != null);
   }
 
+  static bool potentialOperator(BinaryOperator operator) =>
+      PRECEDENCE_MAP[operator.kind] != null;
+
   ConstantExpressionKind get kind => ConstantExpressionKind.BINARY;
 
   accept(ConstantExpressionVisitor visitor, [context]) {
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 52de7d6..afdb303 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -202,8 +202,8 @@
     passThrough(argument);
   }
 
-  String getDepsOutput(Map<Uri, api.Input> sourceFiles) {
-    var filenames = sourceFiles.keys.map((uri) => '$uri').toList();
+  String getDepsOutput(Iterable<Uri> sourceFiles) {
+    var filenames = sourceFiles.map((uri) => '$uri').toList();
     filenames.sort();
     return filenames.join("\n");
   }
@@ -547,7 +547,7 @@
       fail('Compilation failed.');
     }
     writeString(
-        Uri.parse('$out.deps'), getDepsOutput(inputProvider.sourceFiles));
+        Uri.parse('$out.deps'), getDepsOutput(inputProvider.getSourceUris()));
     int dartCharactersRead = inputProvider.dartCharactersRead;
     int jsCharactersWritten = outputProvider.totalCharactersWrittenJavaScript;
     int jsCharactersPrimary = outputProvider.totalCharactersWrittenPrimary;
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 8ef340a..ac290bf 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -400,7 +400,6 @@
   UNIMPLEMENTED_SETTER,
   UNIMPLEMENTED_SETTER_ONE,
   UNMATCHED_TOKEN,
-  UNRECOGNIZED_VERSION_OF_LOOKUP_MAP,
   UNSUPPORTED_BANG_EQ_EQ,
   UNSUPPORTED_EQ_EQ_EQ,
   UNSUPPORTED_LITERAL_SYMBOL,
@@ -3715,11 +3714,6 @@
           "more code and prevents the compiler from doing some optimizations.",
           howToFix: "Consider removing this 'noSuchMethod' implementation."),
 
-      MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP: const MessageTemplate(
-          MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP,
-          "Unsupported version of package:lookup_map.",
-          howToFix: DONT_KNOW_HOW_TO_FIX),
-
       MessageKind.DUPLICATE_SERIALIZED_LIBRARY: const MessageTemplate(
           MessageKind.DUPLICATE_SERIALIZED_LIBRARY,
           "Library '#{libraryUri}' found in both '#{sourceUri1}' and "
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index 3e3a149..737751c 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -1109,9 +1109,23 @@
   Name get memberName;
 }
 
+/// A local function, variable, parameter or synthesized local.
+abstract class LocalVariable implements Local {
+  /// The context in which this local is defined.
+  ExecutableElement get executableContext;
+
+  /// The outermost member that contains this element.
+  ///
+  /// For top level, static or instance members, the member context is the
+  /// element itself. For parameters, local variables and nested closures, the
+  /// member context is the top level, static or instance member in which it is
+  /// defined.
+  MemberElement get memberContext;
+}
+
 /// A function, variable or parameter defined in an executable context.
 abstract class LocalElement extends Element
-    implements AstElement, TypedElement, Local {
+    implements AstElement, TypedElement, LocalVariable {
   ExecutableElement get executableContext;
 }
 
diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart
index 237df90..abb4d19 100644
--- a/pkg/compiler/lib/src/elements/entities.dart
+++ b/pkg/compiler/lib/src/elements/entities.dart
@@ -232,21 +232,7 @@
 /// but since one type variable can introduce different locals in different
 /// factories and constructors it is not itself a [Local] but instead
 /// a non-element [Local] is created through a specialized class.
-// TODO(johnniwinther): Should [Local] have `isAssignable` or `type`?
-abstract class Local extends Entity {
-  /// The context in which this local is defined.
-  // TODO(johnniwinther): Remove this. It is only used in the AST based closure
-  // converter.
-  Entity get executableContext;
-
-  /// The outermost member that contains this element.
-  ///
-  /// For top level, static or instance members, the member context is the
-  /// element itself. For parameters, local variables and nested closures, the
-  /// member context is the top level, static or instance member in which it is
-  /// defined.
-  MemberEntity get memberContext;
-}
+abstract class Local extends Entity {}
 
 /// The structure of function parameters.
 class ParameterStructure {
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 6df87c3..6784979 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -3409,7 +3409,6 @@
 
   JumpTargetX(this.statement, this.nestingLevel, this.executableContext);
 
-  @override
   MemberElement get memberContext => executableContext.memberContext;
 
   LabelDefinition<Node> addLabel(Label label, String labelName,
diff --git a/pkg/compiler/lib/src/inferrer/ast_inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/ast_inferrer_engine.dart
index 6e8e11b..a84cc67 100644
--- a/pkg/compiler/lib/src/inferrer/ast_inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/ast_inferrer_engine.dart
@@ -94,6 +94,11 @@
     return null;
   }
 
+  @override
+  bool hasCallType(covariant ClassElement cls) {
+    return cls.callType != null;
+  }
+
   /// Computes a 'size' of [_element] based on the number of selectors in the
   /// associated [TreeElements]. This is used for sorting member for the type
   /// inference work-queue.
diff --git a/pkg/compiler/lib/src/inferrer/builder.dart b/pkg/compiler/lib/src/inferrer/builder.dart
index 900f453..c5df0f7 100644
--- a/pkg/compiler/lib/src/inferrer/builder.dart
+++ b/pkg/compiler/lib/src/inferrer/builder.dart
@@ -2798,17 +2798,9 @@
       }
     }
 
-    return inferrer.registerCalledSelector(
-        callType,
-        node,
-        selector,
-        mask,
-        receiverType,
-        outermostElement,
-        arguments,
-        sideEffects,
-        inLoop,
-        isConditional);
+    return inferrer.registerCalledSelector(callType, node, selector, mask,
+        receiverType, outermostElement, arguments, sideEffects,
+        inLoop: inLoop, isConditional: isConditional);
   }
 
   TypeInformation handleDynamicInvoke(ast.Send node) {
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index a62cd1cf..4062371 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -6,10 +6,17 @@
 
 import '../closure.dart';
 import '../common.dart';
+import '../common/names.dart';
 import '../constants/constant_system.dart';
 import '../elements/entities.dart';
+import '../elements/jumps.dart';
+import '../elements/types.dart';
+import '../kernel/element_map.dart';
 import '../options.dart';
 import '../types/constants.dart';
+import '../types/types.dart';
+import '../universe/selector.dart';
+import '../universe/side_effects.dart';
 import '../world.dart';
 import 'inferrer_engine.dart';
 import 'locals_handler.dart';
@@ -30,8 +37,16 @@
   final TypeSystem<ir.Node> _types;
   final MemberEntity _analyzedMember;
   final ir.Node _analyzedNode;
-  LocalsHandler _locals;
+  final KernelToElementMapForBuilding _elementMap;
+  final KernelToLocalsMap _localsMap;
+  final GlobalTypeInferenceElementData<ir.Node> _memberData;
 
+  LocalsHandler _locals;
+  SideEffects _sideEffects = new SideEffects.empty();
+  final Map<JumpTarget, List<LocalsHandler>> _breaksFor =
+      <JumpTarget, List<LocalsHandler>>{};
+  final Map<JumpTarget, List<LocalsHandler>> _continuesFor =
+      <JumpTarget, List<LocalsHandler>>{};
   TypeInformation _returnType;
 
   KernelTypeGraphBuilder(
@@ -41,8 +56,11 @@
       this._inferrer,
       this._analyzedMember,
       this._analyzedNode,
+      this._elementMap,
+      this._localsMap,
       [this._locals])
-      : this._types = _inferrer.types {
+      : this._types = _inferrer.types,
+        this._memberData = _inferrer.dataOfMember(_analyzedMember) {
     if (_locals != null) return;
 
     FieldInitializationScope<ir.Node> fieldScope =
@@ -53,6 +71,10 @@
         _inferrer, _types, _options, _analyzedNode, fieldScope);
   }
 
+  int _loopLevel = 0;
+
+  bool get inLoop => _loopLevel > 0;
+
   TypeInformation run() {
     if (_analyzedMember.isField) {
       if (_analyzedNode == null || _analyzedNode is ir.NullLiteral) {
@@ -95,54 +117,105 @@
     return node == null ? null : node.accept(this);
   }
 
+  void visitList(List<ir.Node> nodes) {
+    if (nodes == null) return;
+    nodes.forEach(visit);
+  }
+
+  void handleParameter(ir.VariableDeclaration node, {bool isOptional}) {
+    Local local = _localsMap.getLocalVariable(node);
+    DartType type = _localsMap.getLocalType(_elementMap, local);
+    _locals.update(local, _inferrer.typeOfParameter(local), node, type);
+    if (isOptional) {
+      TypeInformation type = visit(node.initializer);
+      _inferrer.setDefaultTypeOfParameter(local, type,
+          isInstanceMember: _analyzedMember.isInstanceMember);
+    }
+  }
+
   @override
   TypeInformation visitFunctionNode(ir.FunctionNode node) {
-    // TODO(redemption): Handle constructors.
     // TODO(redemption): Handle native methods.
-    // TODO(redemption): Set up parameters.
+
+    int position = 0;
+    for (ir.VariableDeclaration parameter in node.positionalParameters) {
+      handleParameter(parameter,
+          isOptional: position >= node.requiredParameterCount);
+      position++;
+    }
+    for (ir.VariableDeclaration parameter in node.namedParameters) {
+      handleParameter(parameter, isOptional: true);
+    }
     visit(node.body);
-    switch (node.asyncMarker) {
-      case ir.AsyncMarker.Sync:
-        if (_returnType == null) {
-          // No return in the body.
-          _returnType = _locals.seenReturnOrThrow
-              ? _types.nonNullEmpty() // Body always throws.
-              : _types.nullType;
-        } else if (!_locals.seenReturnOrThrow) {
-          // We haven'TypeInformation seen returns on all branches. So the method may
-          // also return null.
-          recordReturnType(_types.nullType);
+    MemberEntity analyzedMember = _analyzedMember;
+    if (analyzedMember is ConstructorEntity &&
+        analyzedMember.isGenerativeConstructor) {
+      // TODO(redemption): Handle initializers.
+      ClassEntity cls = analyzedMember.enclosingClass;
+      if (cls.isAbstract) {
+        if (_closedWorld.isInstantiated(cls)) {
+          _returnType = _types.nonNullSubclass(cls);
+        } else {
+          // TODO(johnniwinther): Avoid analyzing [_analyzedMember] in this
+          // case; it's never called.
+          _returnType = _types.nonNullEmpty();
         }
-        break;
+      } else {
+        _returnType = _types.nonNullExact(cls);
+      }
+    } else {
+      switch (node.asyncMarker) {
+        case ir.AsyncMarker.Sync:
+          if (_returnType == null) {
+            // No return in the body.
+            _returnType = _locals.seenReturnOrThrow
+                ? _types.nonNullEmpty() // Body always throws.
+                : _types.nullType;
+          } else if (!_locals.seenReturnOrThrow) {
+            // We haven'TypeInformation seen returns on all branches. So the
+            // method may also return null.
+            recordReturnType(_types.nullType);
+          }
+          break;
 
-      case ir.AsyncMarker.SyncStar:
-        // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type
-        //               contained is the method body's return type.
-        recordReturnType(_types.syncStarIterableType);
-        break;
+        case ir.AsyncMarker.SyncStar:
+          // TODO(asgerf): Maybe make a ContainerTypeMask for these? The type
+          //               contained is the method body's return type.
+          recordReturnType(_types.syncStarIterableType);
+          break;
 
-      case ir.AsyncMarker.Async:
-        recordReturnType(_types.asyncFutureType);
-        break;
+        case ir.AsyncMarker.Async:
+          recordReturnType(_types.asyncFutureType);
+          break;
 
-      case ir.AsyncMarker.AsyncStar:
-        recordReturnType(_types.asyncStarStreamType);
-        break;
-      case ir.AsyncMarker.SyncYielding:
-        failedAt(
-            _analyzedMember, "Unexpected async marker: ${node.asyncMarker}");
-        break;
+        case ir.AsyncMarker.AsyncStar:
+          recordReturnType(_types.asyncStarStreamType);
+          break;
+        case ir.AsyncMarker.SyncYielding:
+          failedAt(
+              _analyzedMember, "Unexpected async marker: ${node.asyncMarker}");
+          break;
+      }
     }
     return _returnType;
   }
 
   @override
-  TypeInformation defaultExpression(ir.Expression expression) {
-    // TODO(efortuna): Remove when more is implemented.
+  TypeInformation defaultExpression(ir.Expression node) {
+    // TODO(johnniwinther): Make this throw to assert that all expressions are
+    // handled.
     return _types.dynamicType;
   }
 
   @override
+  TypeInformation defaultStatement(ir.Statement node) {
+    // TODO(johnniwinther): Make this throw to assert that all statements are
+    // handled.
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   TypeInformation visitNullLiteral(ir.NullLiteral literal) {
     return _types.nullType;
   }
@@ -207,4 +280,227 @@
     return _types.getConcreteTypeFor(
         computeTypeMask(_closedWorld, constantSystem.createDouble(node.value)));
   }
+
+  @override
+  TypeInformation visitVariableDeclaration(ir.VariableDeclaration node) {
+    assert(
+        node.parent is! ir.FunctionNode, "Unexpected parameter declaration.");
+    Local local = _localsMap.getLocalVariable(node);
+    DartType type = _localsMap.getLocalType(_elementMap, local);
+    if (node.initializer == null) {
+      _locals.update(local, _types.nullType, node, type);
+    } else {
+      _locals.update(local, visit(node.initializer), node, type);
+    }
+    return null;
+  }
+
+  @override
+  TypeInformation visitVariableGet(ir.VariableGet node) {
+    return _locals.use(_localsMap.getLocalVariable(node.variable));
+  }
+
+  @override
+  TypeInformation visitVariableSet(ir.VariableSet node) {
+    Local local = _localsMap.getLocalVariable(node.variable);
+    DartType type = _localsMap.getLocalType(_elementMap, local);
+    TypeInformation rhsType = visit(node.value);
+    _locals.update(local, rhsType, node, type);
+    return rhsType;
+  }
+
+  ArgumentsTypes analyzeArguments(ir.Arguments arguments) {
+    List<TypeInformation> positional = <TypeInformation>[];
+    Map<String, TypeInformation> named;
+    for (ir.Expression argument in arguments.positional) {
+      positional.add(argument.accept(this));
+    }
+    for (ir.NamedExpression argument in arguments.named) {
+      named ??= <String, TypeInformation>{};
+      named[argument.name] = argument.value.accept(this);
+    }
+
+    /// TODO(johnniwinther): Track `isThisExposed`.
+    return new ArgumentsTypes(positional, named);
+  }
+
+  @override
+  TypeInformation visitMethodInvocation(ir.MethodInvocation node) {
+    TypeInformation receiverType = visit(node.receiver);
+    Selector selector = _elementMap.getSelector(node);
+    TypeMask mask = _memberData.typeOfSend(node);
+
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    if (selector.name == '==' || selector.name == '!=') {
+      if (_types.isNull(receiverType)) {
+        // TODO(johnniwinther): Add null check.
+        return _types.boolType;
+      } else if (_types.isNull(arguments.positional[0])) {
+        // TODO(johnniwinther): Add null check.
+        return _types.boolType;
+      }
+    }
+    return handleDynamicInvoke(
+        CallType.access, node, selector, mask, receiverType, arguments);
+  }
+
+  TypeInformation handleDynamicInvoke(
+      CallType callType,
+      ir.Node node,
+      Selector selector,
+      TypeMask mask,
+      TypeInformation receiverType,
+      ArgumentsTypes arguments) {
+    assert(receiverType != null);
+    if (_types.selectorNeedsUpdate(receiverType, mask)) {
+      mask = receiverType == _types.dynamicType
+          ? null
+          : _types.newTypedSelector(receiverType, mask);
+      _inferrer.updateSelectorInMember(
+          _analyzedMember, callType, node, selector, mask);
+    }
+
+    // TODO(johnniwinther): Refine receiver on non-captured locals.
+
+    return _inferrer.registerCalledSelector(callType, node, selector, mask,
+        receiverType, _analyzedMember, arguments, _sideEffects,
+        inLoop: inLoop, isConditional: false);
+  }
+
+  @override
+  TypeInformation visitLet(ir.Let node) {
+    visit(node.variable);
+    return visit(node.body);
+  }
+
+  @override
+  TypeInformation visitForInStatement(ir.ForInStatement node) {
+    TypeInformation expressionType = visit(node.iterable);
+    Selector iteratorSelector = Selectors.iterator;
+    TypeMask iteratorMask = _memberData.typeOfIterator(node);
+    Selector currentSelector = Selectors.current;
+    TypeMask currentMask = _memberData.typeOfIteratorCurrent(node);
+    Selector moveNextSelector = Selectors.moveNext;
+    TypeMask moveNextMask = _memberData.typeOfIteratorMoveNext(node);
+
+    TypeInformation iteratorType = handleDynamicInvoke(
+        CallType.forIn,
+        node,
+        iteratorSelector,
+        iteratorMask,
+        expressionType,
+        new ArgumentsTypes.empty());
+
+    handleDynamicInvoke(CallType.forIn, node, moveNextSelector, moveNextMask,
+        iteratorType, new ArgumentsTypes.empty());
+    TypeInformation currentType = handleDynamicInvoke(CallType.forIn, node,
+        currentSelector, currentMask, iteratorType, new ArgumentsTypes.empty());
+
+    Local variable = _localsMap.getLocalVariable(node.variable);
+    DartType variableType = _localsMap.getLocalType(_elementMap, variable);
+    _locals.update(variable, currentType, node.variable, variableType);
+
+    JumpTarget target = _localsMap.getJumpTargetForForIn(node);
+    return handleLoop(node, target, () {
+      visit(node.body);
+    });
+  }
+
+  void _setupBreaksAndContinues(JumpTarget target) {
+    if (target == null) return;
+    if (target.isContinueTarget) _continuesFor[target] = <LocalsHandler>[];
+    if (target.isBreakTarget) _breaksFor[target] = <LocalsHandler>[];
+  }
+
+  void _clearBreaksAndContinues(JumpTarget element) {
+    _continuesFor.remove(element);
+    _breaksFor.remove(element);
+  }
+
+  List<LocalsHandler> _getBreaks(JumpTarget target) {
+    List<LocalsHandler> list = <LocalsHandler>[_locals];
+    if (target == null) return list;
+    if (!target.isBreakTarget) return list;
+    return list..addAll(_breaksFor[target]);
+  }
+
+  List<LocalsHandler> _getLoopBackEdges(JumpTarget target) {
+    List<LocalsHandler> list = <LocalsHandler>[_locals];
+    if (target == null) return list;
+    if (!target.isContinueTarget) return list;
+    return list..addAll(_continuesFor[target]);
+  }
+
+  TypeInformation handleLoop(ir.Node node, JumpTarget target, void logic()) {
+    _loopLevel++;
+    bool changed = false;
+    LocalsHandler saved = _locals;
+    saved.startLoop(node);
+    do {
+      // Setup (and clear in case of multiple iterations of the loop)
+      // the lists of breaks and continues seen in the loop.
+      _setupBreaksAndContinues(target);
+      _locals = new LocalsHandler.from(saved, node);
+      logic();
+      changed = saved.mergeAll(_getLoopBackEdges(target));
+    } while (changed);
+    _loopLevel--;
+    saved.endLoop(node);
+    bool keepOwnLocals = node is! ir.DoStatement;
+    saved.mergeAfterBreaks(_getBreaks(target), keepOwnLocals: keepOwnLocals);
+    _locals = saved;
+    _clearBreaksAndContinues(target);
+    return null;
+  }
+
+  @override
+  TypeInformation visitConstructorInvocation(ir.ConstructorInvocation node) {
+    ConstructorEntity constructor = _elementMap.getConstructor(node.target);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    // TODO(redemption): Handle initializers.
+    // TODO(redemption): Handle foreign constructors.
+    Selector selector = _elementMap.getSelector(node);
+    TypeMask mask = _memberData.typeOfSend(node);
+    return handleConstructorInvoke(
+        node, selector, mask, constructor, arguments);
+  }
+
+  TypeInformation handleConstructorInvoke(ir.Node node, Selector selector,
+      TypeMask mask, ConstructorEntity constructor, ArgumentsTypes arguments) {
+    TypeInformation returnType =
+        handleStaticInvoke(node, selector, mask, constructor, arguments);
+    // TODO(redemption): Special-case `List` constructors.
+    return returnType;
+  }
+
+  TypeInformation handleStaticInvoke(ir.Node node, Selector selector,
+      TypeMask mask, MemberEntity element, ArgumentsTypes arguments) {
+    return _inferrer.registerCalledMember(node, selector, mask, _analyzedMember,
+        element, arguments, _sideEffects, inLoop);
+  }
+
+  @override
+  TypeInformation visitStaticInvocation(ir.StaticInvocation node) {
+    MemberEntity member = _elementMap.getMember(node.target);
+    ArgumentsTypes arguments = analyzeArguments(node.arguments);
+    // TODO(redemption): Handle foreign functions.
+    Selector selector = _elementMap.getSelector(node);
+    TypeMask mask = _memberData.typeOfSend(node);
+    if (member.isConstructor) {
+      return handleConstructorInvoke(node, selector, mask, member, arguments);
+    } else if (member.isFunction) {
+      return handleStaticInvoke(node, selector, mask, member, arguments);
+    } else {
+      handleStaticInvoke(node, selector, mask, member, arguments);
+      return _inferrer.registerCalledClosure(
+          node,
+          selector,
+          mask,
+          _inferrer.typeOfMember(member),
+          _analyzedMember,
+          arguments,
+          _sideEffects,
+          inLoop);
+    }
+  }
 }
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
index b04c4ab..be9293e 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_engine.dart
@@ -11,12 +11,7 @@
 import '../common_elements.dart';
 import '../constants/values.dart';
 import '../elements/elements.dart'
-    show
-        ClassElement,
-        ConstructorElement,
-        Elements,
-        MemberElement,
-        ParameterElement;
+    show ConstructorElement, Elements, MemberElement, ParameterElement;
 import '../elements/entities.dart';
 import '../elements/names.dart';
 import '../js_backend/annotations.dart';
@@ -123,9 +118,9 @@
   Iterable<MemberEntity> getCallersOf(MemberEntity element);
 
   // TODO(johnniwinther): Make this private again.
-  GlobalTypeInferenceElementData dataOfMember(MemberEntity element);
+  GlobalTypeInferenceElementData<T> dataOfMember(MemberEntity element);
 
-  GlobalTypeInferenceElementData lookupDataOfMember(MemberEntity element);
+  GlobalTypeInferenceElementData<T> lookupDataOfMember(MemberEntity element);
 
   bool checkIfExposesThis(ConstructorEntity element);
 
@@ -169,7 +164,7 @@
   ///
   /// [inLoop] tells whether the call happens in a loop.
   TypeInformation registerCalledMember(
-      Spannable node,
+      Object node,
       Selector selector,
       TypeMask mask,
       MemberEntity caller,
@@ -194,8 +189,8 @@
       MemberEntity caller,
       ArgumentsTypes arguments,
       SideEffects sideEffects,
-      bool inLoop,
-      bool isConditional);
+      {bool inLoop,
+      bool isConditional});
 
   /// Update the assignments to parameters in the graph. [remove] tells whether
   /// assignments must be added or removed. If [init] is false, parameters are
@@ -759,6 +754,9 @@
   /// `null` if the initializer is not a constant value.
   ConstantValue getFieldConstant(FieldEntity field);
 
+  /// Returns `true` if [cls] has a 'call' method.
+  bool hasCallType(ClassEntity cls);
+
   void processLoopInformation() {
     types.allocatedCalls.forEach((dynamic info) {
       if (!info.inLoop) return;
@@ -958,7 +956,7 @@
   }
 
   TypeInformation registerCalledMember(
-      Spannable node,
+      Object node,
       Selector selector,
       TypeMask mask,
       MemberEntity caller,
@@ -984,8 +982,8 @@
         selector.isCall &&
         callee is ConstructorEntity &&
         callee.isGenerativeConstructor) {
-      ClassElement cls = callee.enclosingClass;
-      if (cls.callType != null) {
+      ClassEntity cls = callee.enclosingClass;
+      if (hasCallType(cls)) {
         types.allocatedClosures.add(info);
       }
     }
@@ -1004,8 +1002,8 @@
       MemberEntity caller,
       ArgumentsTypes arguments,
       SideEffects sideEffects,
-      bool inLoop,
-      bool isConditional) {
+      {bool inLoop,
+      bool isConditional}) {
     if (selector.isClosureCall) {
       return registerCalledClosure(node, selector, mask, receiverType, caller,
           arguments, sideEffects, inLoop);
@@ -1105,7 +1103,7 @@
   }
 
   TypeInformation typeOfMemberWithSelector(
-      covariant MemberElement element, Selector selector) {
+      MemberEntity element, Selector selector) {
     if (element.name == Identifiers.noSuchMethod_ &&
         selector.name != element.name) {
       // An invocation can resolve to a [noSuchMethod], in which case
@@ -1119,11 +1117,11 @@
             : types.functionType;
       } else if (element.isField) {
         return typeOfMember(element);
-      } else if (Elements.isUnresolved(element)) {
-        return types.dynamicType;
-      } else {
-        assert(element.isGetter);
+      } else if (element.isGetter) {
         return returnTypeOfMember(element);
+      } else {
+        assert(element is MemberElement && Elements.isUnresolved(element));
+        return types.dynamicType;
       }
     } else if (element.isGetter || element.isField) {
       assert(selector.isCall || selector.isSetter);
diff --git a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
index 537076a..b2b1da2 100644
--- a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
@@ -144,7 +144,14 @@
   TypeInformation computeMemberTypeInformation(
       MemberEntity member, ir.Node body) {
     KernelTypeGraphBuilder visitor = new KernelTypeGraphBuilder(
-        options, closedWorld, _closureDataLookup, this, member, body);
+        options,
+        closedWorld,
+        _closureDataLookup,
+        this,
+        member,
+        body,
+        _elementMap,
+        _globalLocalsMap.getLocalsMap(member));
     return visitor.run();
   }
 
@@ -198,7 +205,14 @@
 
   @override
   GlobalTypeInferenceElementData<ir.Node> createElementData() {
-    throw new UnimplementedError('KernelInferrerEngine.createElementData');
+    return new KernelGlobalTypeInferenceElementData();
+  }
+
+  @override
+  bool hasCallType(ClassEntity cls) {
+    return _elementMap.types
+            .getCallType(_elementMap.elementEnvironment.getThisType(cls)) !=
+        null;
   }
 }
 
@@ -277,13 +291,12 @@
 
   @override
   ParameterTypeInformation createParameterTypeInformation(
-      Local parameter, TypeSystem<ir.Node> types) {
+      covariant JLocal parameter, TypeSystem<ir.Node> types) {
     MemberEntity context = parameter.memberContext;
     KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(context);
     ir.FunctionNode functionNode =
         localsMap.getFunctionNodeForParameter(parameter);
-    DartType type =
-        _elementMap.getDartType(localsMap.getParameterType(parameter));
+    DartType type = localsMap.getLocalType(_elementMap, parameter);
     MemberEntity member;
     bool isClosure = false;
     if (functionNode.parent is ir.Member) {
@@ -337,3 +350,85 @@
     }
   }
 }
+
+class KernelGlobalTypeInferenceElementData
+    extends GlobalTypeInferenceElementData<ir.Node> {
+  // TODO(johnniwinther): Rename this together with [typeOfSend].
+  Map<ir.Node, TypeMask> _sendMap;
+
+  Map<ir.ForInStatement, TypeMask> _iteratorMap;
+  Map<ir.ForInStatement, TypeMask> _currentMap;
+  Map<ir.ForInStatement, TypeMask> _moveNextMap;
+
+  @override
+  TypeMask typeOfSend(ir.Node node) {
+    if (_sendMap == null) return null;
+    return _sendMap[node];
+  }
+
+  @override
+  void setCurrentTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
+    _currentMap ??= <ir.ForInStatement, TypeMask>{};
+    _currentMap[node] = mask;
+  }
+
+  @override
+  void setMoveNextTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
+    _moveNextMap ??= <ir.ForInStatement, TypeMask>{};
+    _moveNextMap[node] = mask;
+  }
+
+  @override
+  void setIteratorTypeMask(covariant ir.ForInStatement node, TypeMask mask) {
+    _iteratorMap ??= <ir.ForInStatement, TypeMask>{};
+    _iteratorMap[node] = mask;
+  }
+
+  @override
+  TypeMask typeOfIteratorCurrent(covariant ir.ForInStatement node) {
+    if (_currentMap == null) return null;
+    return _currentMap[node];
+  }
+
+  @override
+  TypeMask typeOfIteratorMoveNext(covariant ir.ForInStatement node) {
+    if (_moveNextMap == null) return null;
+    return _moveNextMap[node];
+  }
+
+  @override
+  TypeMask typeOfIterator(covariant ir.ForInStatement node) {
+    if (_iteratorMap == null) return null;
+    return _iteratorMap[node];
+  }
+
+  @override
+  void setOperatorTypeMaskInComplexSendSet(ir.Node node, TypeMask mask) {
+    throw new UnsupportedError(
+        'KernelGlobalTypeInferenceElementData.setOperatorTypeMaskInComplexSendSet');
+  }
+
+  @override
+  void setGetterTypeMaskInComplexSendSet(ir.Node node, TypeMask mask) {
+    throw new UnsupportedError(
+        'KernelGlobalTypeInferenceElementData.setGetterTypeMaskInComplexSendSet');
+  }
+
+  @override
+  void setTypeMask(ir.Node node, TypeMask mask) {
+    _sendMap ??= <ir.Node, TypeMask>{};
+    _sendMap[node] = mask;
+  }
+
+  @override
+  TypeMask typeOfOperator(ir.Node node) {
+    throw new UnsupportedError(
+        'KernelGlobalTypeInferenceElementData.typeOfOperator');
+  }
+
+  @override
+  TypeMask typeOfGetter(ir.Node node) {
+    throw new UnsupportedError(
+        'KernelGlobalTypeInferenceElementData.typeOfGetter');
+  }
+}
diff --git a/pkg/compiler/lib/src/inferrer/node_tracer.dart b/pkg/compiler/lib/src/inferrer/node_tracer.dart
index b8b08db..5b199eb 100644
--- a/pkg/compiler/lib/src/inferrer/node_tracer.dart
+++ b/pkg/compiler/lib/src/inferrer/node_tracer.dart
@@ -5,7 +5,6 @@
 library compiler.src.inferrer.node_tracer;
 
 import '../common/names.dart' show Identifiers;
-import '../elements/elements.dart';
 import '../elements/entities.dart';
 import '../types/types.dart' show ContainerTypeMask, MapTypeMask;
 import '../util/util.dart' show Setlet;
@@ -205,7 +204,7 @@
       ClosureCallSiteTypeInformation info) {}
 
   visitStaticCallSiteTypeInformation(StaticCallSiteTypeInformation info) {
-    MemberElement called = info.calledElement;
+    MemberEntity called = info.calledElement;
     TypeInformation inferred = inferrer.types.getInferredTypeOfMember(called);
     if (inferred == currentUser) {
       addNewEscapeInformation(info);
@@ -294,10 +293,10 @@
     return isIndexSetArgument(info, 1);
   }
 
-  void bailoutIfReaches(bool predicate(ParameterElement e)) {
+  void bailoutIfReaches(bool predicate(ParameterTypeInformation e)) {
     for (var user in currentUser.users) {
       if (user is ParameterTypeInformation) {
-        if (predicate(user.parameter)) {
+        if (predicate(user)) {
           bailout('Reached suppressed parameter without precise receiver');
           break;
         }
@@ -402,13 +401,13 @@
    * The definition of what a list adding method is has to stay in sync with
    * [mightAddToContainer].
    */
-  bool isParameterOfListAddingMethod(ParameterElement element) {
-    if (!element.isRegularParameter) return false;
-    if (element.enclosingClass !=
+  bool isParameterOfListAddingMethod(ParameterTypeInformation parameterInfo) {
+    if (!parameterInfo.isRegularParameter) return false;
+    if (parameterInfo.method.enclosingClass !=
         inferrer.closedWorld.commonElements.jsArrayClass) {
       return false;
     }
-    String name = element.enclosingElement.name;
+    String name = parameterInfo.method.name;
     return (name == '[]=') || (name == 'add') || (name == 'insert');
   }
 
@@ -417,13 +416,13 @@
    * The definition of what a list adding method is has to stay in sync with
    * [isIndexSetKey] and [isIndexSetValue].
    */
-  bool isParameterOfMapAddingMethod(ParameterElement element) {
-    if (!element.isRegularParameter) return false;
-    if (element.enclosingClass !=
+  bool isParameterOfMapAddingMethod(ParameterTypeInformation parameterInfo) {
+    if (!parameterInfo.isRegularParameter) return false;
+    if (parameterInfo.method.enclosingClass !=
         inferrer.closedWorld.commonElements.mapLiteralClass) {
       return false;
     }
-    String name = element.enclosingElement.name;
+    String name = parameterInfo.method.name;
     return (name == '[]=');
   }
 
@@ -464,8 +463,8 @@
         .canFunctionParametersBeUsedForGlobalOptimizations(info.method)) {
       bailout('Escape to code that has special backend treatment');
     }
-    if (isParameterOfListAddingMethod(info.parameter) ||
-        isParameterOfMapAddingMethod(info.parameter)) {
+    if (isParameterOfListAddingMethod(info) ||
+        isParameterOfMapAddingMethod(info)) {
       // These elements are being handled in
       // [visitDynamicCallSiteTypeInformation].
       return;
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index ca26040..5df2869 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -7,7 +7,6 @@
 import 'dart:collection' show Queue;
 
 import '../compiler.dart' show Compiler;
-import '../elements/elements.dart';
 import '../elements/entities.dart';
 import '../tree/tree.dart' as ast show Node;
 import '../types/masks.dart'
@@ -134,7 +133,7 @@
     TypeMask result = const TypeMask.nonNullEmpty();
     Iterable<MemberEntity> elements =
         inferrer.closedWorld.locateMembers(selector, mask);
-    for (MemberElement element in elements) {
+    for (MemberEntity element in elements) {
       TypeMask type = inferrer.typeOfMemberWithSelector(element, selector).type;
       result = result.union(type, inferrer.closedWorld);
     }
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 25632db..819e9a8 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -6,7 +6,8 @@
 
 import 'dart:collection' show IterableBase;
 
-import '../common.dart';
+import 'package:kernel/ast.dart' as ir;
+
 import '../common/names.dart' show Identifiers;
 import '../constants/values.dart';
 import '../elements/elements.dart'
@@ -382,12 +383,13 @@
    * to enable counting the global number of call sites of [element].
    *
    * A call site is either an AST [ast.Node], an [Element] (see uses of
-   * [synthesizeForwardingCall] in [SimpleTypeInferrerVisitor]).
+   * [synthesizeForwardingCall] in [SimpleTypeInferrerVisitor]) or an IR
+   * [ir.Node].
    *
    * The global information is summarized in [cleanup], after which [_callers]
    * is set to `null`.
    */
-  Map<MemberEntity, Setlet<Spannable>> _callers;
+  Map<MemberEntity, Setlet<Object>> _callers;
 
   MemberTypeInformation._internal(this._member) : super._internal(null) {
     assert(_checkMember(_member));
@@ -401,12 +403,12 @@
 
   String get debugName => '$member';
 
-  void addCall(MemberEntity caller, Spannable node) {
-    _callers ??= <MemberEntity, Setlet<Spannable>>{};
+  void addCall(MemberEntity caller, Object node) {
+    _callers ??= <MemberEntity, Setlet<Object>>{};
     _callers.putIfAbsent(caller, () => new Setlet()).add(node);
   }
 
-  void removeCall(MemberEntity caller, node) {
+  void removeCall(MemberEntity caller, Object node) {
     if (_callers == null) return;
     Setlet calls = _callers[caller];
     if (calls == null) return;
@@ -715,6 +717,8 @@
 
   Local get parameter => _parameter;
 
+  bool get isRegularParameter => !_isInitializingFormal;
+
   String get debugName => '$parameter';
 
   void tagAsTearOffClosureParameter(InferrerEngine inferrer) {
@@ -831,9 +835,9 @@
     case CallType.complex:
       return call is ast.SendSet;
     case CallType.access:
-      return call is ast.Send;
+      return call is ast.Send || call is ir.Node;
     case CallType.forIn:
-      return call is ast.ForIn;
+      return call is ast.ForIn || call is ir.ForInStatement;
   }
   throw new StateError('Unexpected call type $callType.');
 }
@@ -863,7 +867,8 @@
     assert(_checkCaller(caller));
     // [_call] is either an AST node or a constructor element in case of a
     // a forwarding constructor _call.
-    assert(_call is ast.Node || _call is ConstructorElement);
+    assert(
+        _call is ast.Node || _call is ConstructorElement || _call is ir.Node);
   }
 
   bool _checkCaller(MemberEntity caller) {
@@ -886,7 +891,7 @@
 
   StaticCallSiteTypeInformation(
       MemberTypeInformation context,
-      Spannable call,
+      Object call,
       MemberEntity enclosing,
       this.calledElement,
       Selector selector,
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 086f8ad..0d3c246 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -64,8 +64,6 @@
 import 'impact_transformer.dart';
 import 'interceptor_data.dart';
 import 'js_interop_analysis.dart' show JsInteropAnalysis;
-import 'lookup_map_analysis.dart'
-    show LookupMapResolutionAnalysis, LookupMapAnalysis;
 import 'mirrors_analysis.dart';
 import 'mirrors_data.dart';
 import 'namer.dart';
@@ -383,12 +381,6 @@
   /// constructors for custom elements.
   CustomElementsCodegenAnalysis _customElementsCodegenAnalysis;
 
-  /// Resolution support for tree-shaking entries of `LookupMap`.
-  LookupMapResolutionAnalysis lookupMapResolutionAnalysis;
-
-  /// Codegen support for tree-shaking entries of `LookupMap`.
-  LookupMapAnalysis _lookupMapAnalysis;
-
   /// Codegen support for typed JavaScript interop.
   JsInteropAnalysis jsInteropAnalysis;
 
@@ -461,8 +453,6 @@
     jsInteropAnalysis = new JsInteropAnalysis(this);
     _mirrorsResolutionAnalysis =
         compiler.frontendStrategy.createMirrorsResolutionAnalysis(this);
-    lookupMapResolutionAnalysis = new LookupMapResolutionAnalysis(
-        reporter, compiler.frontendStrategy.elementEnvironment);
 
     noSuchMethodRegistry = new NoSuchMethodRegistry(
         commonElements, compiler.frontendStrategy.createNoSuchMethodResolver());
@@ -529,15 +519,6 @@
     return _mirrorsCodegenAnalysis;
   }
 
-  /// Codegen support for tree-shaking entries of `LookupMap`.
-  LookupMapAnalysis get lookupMapAnalysis {
-    assert(
-        _lookupMapAnalysis != null,
-        failedAt(NO_LOCATION_SPANNABLE,
-            "LookupMapAnalysis has not been created yet."));
-    return _lookupMapAnalysis;
-  }
-
   OneShotInterceptorData get oneShotInterceptorData {
     assert(
         _oneShotInterceptorData != null,
@@ -771,7 +752,6 @@
             mirrorsDataBuilder,
             noSuchMethodRegistry,
             customElementsResolutionAnalysis,
-            lookupMapResolutionAnalysis,
             mirrorsResolutionAnalysis,
             typeVariableResolutionAnalysis,
             _nativeResolutionEnqueuer,
@@ -798,13 +778,6 @@
         new BackendImpacts(compiler.options, commonElements);
     _typeVariableCodegenAnalysis = new TypeVariableCodegenAnalysis(
         closedWorld.elementEnvironment, this, commonElements, mirrorsData);
-    _lookupMapAnalysis = new LookupMapAnalysis(
-        reporter,
-        constantSystem,
-        constants,
-        elementEnvironment,
-        commonElements,
-        lookupMapResolutionAnalysis);
     _mirrorsCodegenAnalysis = mirrorsResolutionAnalysis.close();
     _customElementsCodegenAnalysis = new CustomElementsCodegenAnalysis(
         constantSystem,
@@ -834,7 +807,6 @@
             closedWorld.rtiNeed,
             customElementsCodegenAnalysis,
             typeVariableCodegenAnalysis,
-            lookupMapAnalysis,
             mirrorsCodegenAnalysis,
             nativeCodegenEnqueuer));
   }
@@ -964,8 +936,6 @@
     Uri uri = library.canonicalUri;
     if (uri == Uris.dart_html) {
       htmlLibraryIsLoaded = true;
-    } else if (uri == LookupMapResolutionAnalysis.PACKAGE_LOOKUP_MAP) {
-      lookupMapResolutionAnalysis.init(library);
     }
   }
 
@@ -1015,7 +985,6 @@
         nativeCodegenEnqueuer,
         namer,
         oneShotInterceptorData,
-        lookupMapAnalysis,
         rtiChecksBuilder);
     return const WorldImpact();
   }
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index 1f4e024..a5a2ac3 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -18,7 +18,6 @@
 import 'backend_impact.dart';
 import 'backend_usage.dart';
 import 'custom_elements_analysis.dart';
-import 'lookup_map_analysis.dart' show LookupMapAnalysis;
 import 'mirrors_analysis.dart';
 import 'runtime_types.dart';
 import 'type_variable_handler.dart';
@@ -33,7 +32,6 @@
 
   final CustomElementsCodegenAnalysis _customElementsAnalysis;
   final TypeVariableCodegenAnalysis _typeVariableCodegenAnalysis;
-  final LookupMapAnalysis _lookupMapAnalysis;
   final MirrorsCodegenAnalysis _mirrorsAnalysis;
 
   final NativeCodegenEnqueuer _nativeEnqueuer;
@@ -48,7 +46,6 @@
       this._rtiNeed,
       this._customElementsAnalysis,
       this._typeVariableCodegenAnalysis,
-      this._lookupMapAnalysis,
       this._mirrorsAnalysis,
       this._nativeEnqueuer);
 
@@ -79,7 +76,6 @@
     if (nativeUsage) {
       _nativeEnqueuer.onInstantiatedType(type);
     }
-    _lookupMapAnalysis.registerInstantiatedType(type);
   }
 
   /// Called to enable support for isolates. Any backend specific [WorldImpact]
@@ -142,7 +138,6 @@
     // Return early if any elements are added to avoid counting the elements as
     // due to mirrors.
     enqueuer.applyImpact(_customElementsAnalysis.flush());
-    enqueuer.applyImpact(_lookupMapAnalysis.flush());
     enqueuer.applyImpact(_typeVariableCodegenAnalysis.flush());
 
     if (_backendUsage.isNoSuchMethodUsed && !_isNoSuchMethodUsed) {
@@ -158,21 +153,13 @@
   }
 
   @override
-  void onQueueClosed() {
-    _lookupMapAnalysis.onQueueClosed();
-  }
+  void onQueueClosed() {}
 
   /// Adds the impact of [constant] to [impactBuilder].
   void _computeImpactForCompileTimeConstant(
       ConstantValue constant, WorldImpactBuilder impactBuilder) {
     _computeImpactForCompileTimeConstantInternal(constant, impactBuilder);
 
-    if (_lookupMapAnalysis.isLookupMap(constant)) {
-      // Note: internally, this registration will temporarily remove the
-      // constant dependencies and add them later on-demand.
-      _lookupMapAnalysis.registerLookupMapReference(constant);
-    }
-
     for (ConstantValue dependency in constant.getDependencies()) {
       _computeImpactForCompileTimeConstant(dependency, impactBuilder);
     }
@@ -202,10 +189,8 @@
       if (type.representedType.isInterfaceType) {
         InterfaceType representedType = type.representedType;
         _customElementsAnalysis.registerTypeConstant(representedType.element);
-        _lookupMapAnalysis.registerTypeConstant(representedType.element);
       }
     }
-    _lookupMapAnalysis.registerConstantKey(constant);
   }
 
   void _computeImpactForInstantiatedConstantType(
@@ -320,7 +305,6 @@
     }
 
     _customElementsAnalysis.registerInstantiatedClass(cls);
-    _lookupMapAnalysis.registerInstantiatedClass(cls);
     return impactBuilder;
   }
 
@@ -336,7 +320,6 @@
 
   @override
   void logSummary(void log(String message)) {
-    _lookupMapAnalysis.logSummary(log);
     _nativeEnqueuer.logSummary(log);
   }
 }
diff --git a/pkg/compiler/lib/src/js_backend/impact_transformer.dart b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
index d390090..dff5872 100644
--- a/pkg/compiler/lib/src/js_backend/impact_transformer.dart
+++ b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
@@ -27,7 +27,6 @@
 import 'checked_mode_helpers.dart';
 import 'custom_elements_analysis.dart';
 import 'interceptor_data.dart';
-import 'lookup_map_analysis.dart';
 import 'mirrors_data.dart';
 import 'namer.dart';
 import 'native_data.dart';
@@ -347,7 +346,6 @@
   final NativeCodegenEnqueuer _nativeCodegenEnqueuer;
   final Namer _namer;
   final OneShotInterceptorData _oneShotInterceptorData;
-  final LookupMapAnalysis _lookupMapAnalysis;
   final RuntimeTypesChecksBuilder _rtiChecksBuilder;
 
   CodegenImpactTransformer(
@@ -362,7 +360,6 @@
       this._nativeCodegenEnqueuer,
       this._namer,
       this._oneShotInterceptorData,
-      this._lookupMapAnalysis,
       this._rtiChecksBuilder);
 
   void onIsCheckForCodegen(DartType type, TransformedWorldImpact transformed) {
@@ -409,14 +406,8 @@
 
     for (TypeUse typeUse in impact.typeUses) {
       DartType type = typeUse.type;
-      switch (typeUse.kind) {
-        case TypeUseKind.INSTANTIATION:
-          _lookupMapAnalysis.registerInstantiatedType(type);
-          break;
-        case TypeUseKind.IS_CHECK:
-          onIsCheckForCodegen(type, transformed);
-          break;
-        default:
+      if (typeUse.kind == TypeUseKind.IS_CHECK) {
+        onIsCheckForCodegen(type, transformed);
       }
     }
 
@@ -427,26 +418,19 @@
     }
 
     for (StaticUse staticUse in impact.staticUses) {
-      switch (staticUse.kind) {
-        case StaticUseKind.CALL_METHOD:
-          FunctionEntity callMethod = staticUse.element;
-          // TODO(johnniwinther): Remove [localFunctionNeedsRti] and use
-          // the call method instead.
-          if (_rtiNeed.methodNeedsRti(callMethod)) {
+      if (staticUse.kind == StaticUseKind.CALL_METHOD) {
+        FunctionEntity callMethod = staticUse.element;
+        // TODO(johnniwinther): Remove [localFunctionNeedsRti] and use
+        // the call method instead.
+        if (_rtiNeed.methodNeedsRti(callMethod)) {
+          _impacts.computeSignature
+              .registerImpact(transformed, _elementEnvironment);
+        } else if (callMethod is SynthesizedCallMethodElementX) {
+          if (_rtiNeed.localFunctionNeedsRti(callMethod.expression)) {
             _impacts.computeSignature
                 .registerImpact(transformed, _elementEnvironment);
-          } else if (callMethod is SynthesizedCallMethodElementX) {
-            if (_rtiNeed.localFunctionNeedsRti(callMethod.expression)) {
-              _impacts.computeSignature
-                  .registerImpact(transformed, _elementEnvironment);
-            }
           }
-          break;
-        case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
-        case StaticUseKind.CONSTRUCTOR_INVOKE:
-          _lookupMapAnalysis.registerInstantiatedType(staticUse.type);
-          break;
-        default:
+        }
       }
     }
 
diff --git a/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart b/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
deleted file mode 100644
index 4fddd0c..0000000
--- a/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
+++ /dev/null
@@ -1,524 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Analysis to determine how to generate code for `LookupMap`s.
-library compiler.src.js_backend.lookup_map_analysis;
-
-import 'package:pub_semver/pub_semver.dart';
-
-import '../common.dart';
-import '../common_elements.dart';
-import '../compile_time_constants.dart';
-import '../constants/constant_system.dart';
-import '../constants/values.dart'
-    show
-        ConstantValue,
-        ConstructedConstantValue,
-        ListConstantValue,
-        NullConstantValue,
-        StringConstantValue,
-        TypeConstantValue;
-import '../elements/elements.dart' show FieldElement;
-import '../elements/entities.dart';
-import '../elements/types.dart';
-import '../universe/use.dart' show ConstantUse, StaticUse;
-import '../universe/world_impact.dart'
-    show WorldImpact, StagedWorldImpactBuilder;
-
-/// Lookup map handling for resolution.
-///
-/// This analysis checks for the import of `package:lookup_map/lookup_map.dart`,
-/// and if found, read the `_version` variable from it.
-///
-/// In [LookupMapAnalysis] the value of `_version` is checked to ensure that it
-/// is valid to perform the optimization of `LookupMap`. The actual optimization
-/// is performed by [LookupMapAnalysis].
-class LookupMapResolutionAnalysis {
-  static final Uri PACKAGE_LOOKUP_MAP =
-      new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart');
-
-  /// Reference the diagnostic reporting system for logging and reporting issues
-  /// to the end-user.
-  final DiagnosticReporter _reporter;
-
-  final ElementEnvironment _elementEnvironment;
-
-  /// The resolved [FieldEntity] associated with the top-level `_version`.
-  FieldEntity lookupMapVersionVariable;
-
-  /// The resolved [LibraryEntity] associated with
-  /// `package:lookup_map/lookup_map.dart`.
-  LibraryEntity lookupMapLibrary;
-
-  final StagedWorldImpactBuilder _impactBuilder =
-      new StagedWorldImpactBuilder();
-
-  LookupMapResolutionAnalysis(this._reporter, this._elementEnvironment);
-
-  /// Compute the [WorldImpact] for the constants registered since last flush.
-  WorldImpact flush() {
-    return _impactBuilder.flush();
-  }
-
-  /// Initializes this analysis by providing the resolved library. This is
-  /// invoked during resolution when the `lookup_map` library is discovered.
-  void init(LibraryEntity library) {
-    lookupMapLibrary = library;
-    // We will enable the lookupMapAnalysis as long as we get a known version of
-    // the lookup_map package. We otherwise produce a warning.
-    lookupMapVersionVariable =
-        _elementEnvironment.lookupLibraryMember(lookupMapLibrary, '_version');
-    if (lookupMapVersionVariable == null) {
-      _reporter.reportHintMessage(
-          library, MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP);
-    } else {
-      _impactBuilder
-          .registerStaticUse(new StaticUse.staticGet(lookupMapVersionVariable));
-    }
-  }
-}
-
-/// An analysis and optimization to remove unused entries from a `LookupMap`.
-///
-/// `LookupMaps` are defined in `package:lookup_map/lookup_map.dart`. They are
-/// simple maps that contain constant expressions as keys, and that only support
-/// the lookup operation.
-///
-/// This analysis and optimization will tree-shake the contents of the maps by
-/// looking at the program and finding which keys are clearly unused. Not all
-/// constants can be approximated statically, so this optimization is limited to
-/// the following keys:
-///
-///   * Const expressions that can only be created via const constructors. This
-///   excludes primitives, strings, and any const type that overrides the ==
-///   operator.
-///
-///   * Type literals.
-///
-/// Type literals are more complex than const expressions because they can be
-/// created in multiple ways. We can approximate the possible set of keys if we
-/// follow these rules:
-///
-///   * Include all type-literals used explicitly in the code (excluding
-///   obviously the uses that can be removed from LookupMaps)
-///
-///   * Include every reflectable type-literal if a mirror API is used to create
-///   types (e.g.  ClassMirror.reflectedType).
-///
-///   * Include all allocated types if the program contains `e.runtimeType`
-///   expressions.
-///
-///   * Include all generic-type arguments, if the program uses type
-///   variables in expressions such as `class A<T> { Type get extract => T }`.
-///
-// TODO(sigmund): add support for const expressions, currently this
-// implementation only supports Type literals. To support const expressions we
-// need to change some of the invariants below (e.g. we can no longer use the
-// ClassEntity of a type to refer to keys we need to discover).
-// TODO(sigmund): detect uses of mirrors
-class LookupMapAnalysis {
-  const LookupMapAnalysis._();
-
-  factory LookupMapAnalysis(
-      DiagnosticReporter reporter,
-      ConstantSystem constantSystem,
-      ConstantEnvironment constants,
-      ElementEnvironment elementEnvironment,
-      CommonElements commonElements,
-      LookupMapResolutionAnalysis analysis) {
-    /// Checks if the version of lookup_map is valid, and if so, enable this
-    /// analysis during codegen.
-    FieldElement lookupMapVersionVariable = analysis.lookupMapVersionVariable;
-    if (lookupMapVersionVariable == null) return const LookupMapAnalysis._();
-
-    // At this point, the lookupMapVersionVariable should be resolved and it's
-    // constant value should be available.
-    StringConstantValue value =
-        constants.getConstantValue(lookupMapVersionVariable.constant);
-    if (value == null) {
-      reporter.reportHintMessage(lookupMapVersionVariable,
-          MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP);
-      return const LookupMapAnalysis._();
-    }
-
-    // TODO(sigmund): add proper version resolution using the pub_semver package
-    // when we introduce the next version.
-    Version version;
-    try {
-      version = new Version.parse(value.primitiveValue);
-    } catch (e) {}
-
-    if (version == null || !_validLookupMapVersionConstraint.allows(version)) {
-      reporter.reportHintMessage(lookupMapVersionVariable,
-          MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP);
-      return const LookupMapAnalysis._();
-    }
-
-    ClassEntity typeLookupMapClass =
-        elementEnvironment.lookupClass(analysis.lookupMapLibrary, 'LookupMap');
-    FieldEntity entriesField =
-        elementEnvironment.lookupClassMember(typeLookupMapClass, '_entries');
-    FieldEntity keyField =
-        elementEnvironment.lookupClassMember(typeLookupMapClass, '_key');
-    FieldEntity valueField =
-        elementEnvironment.lookupClassMember(typeLookupMapClass, '_value');
-    // TODO(sigmund): Maybe inline nested maps to make the output code smaller?
-
-    return new _LookupMapAnalysis(constantSystem, elementEnvironment,
-        commonElements, entriesField, keyField, valueField, typeLookupMapClass);
-  }
-
-  /// Compute the [WorldImpact] for the constants registered since last flush.
-  WorldImpact flush() => const WorldImpact();
-
-  /// Whether [constant] is an instance of a `LookupMap`.
-  bool isLookupMap(ConstantValue constant) => false;
-
-  /// Registers an instance of a lookup-map with the analysis.
-  void registerLookupMapReference(ConstantValue lookupMap) {}
-
-  /// Callback from the enqueuer, invoked when [element] is instantiated.
-  void registerInstantiatedClass(ClassEntity element) {}
-
-  /// Callback from the enqueuer, invoked when [type] is instantiated.
-  void registerInstantiatedType(InterfaceType type) {}
-
-  /// Callback from the codegen enqueuer, invoked when a constant (which is
-  /// possibly a const key or a type literal) is used in the program.
-  void registerTypeConstant(ClassEntity element) {}
-
-  void registerConstantKey(ConstantValue constant) {}
-
-  void logSummary(void log(String message)) {}
-
-  void onQueueClosed() {}
-}
-
-class _LookupMapAnalysis implements LookupMapAnalysis {
-  static final Uri PACKAGE_LOOKUP_MAP =
-      new Uri(scheme: 'package', path: 'lookup_map/lookup_map.dart');
-
-  final ConstantSystem _constantSystem;
-
-  final ElementEnvironment _elementEnvironment;
-
-  final CommonElements _commonElements;
-
-  /// The resolved [ClassEntity] associated with `LookupMap`.
-  final ClassEntity _typeLookupMapClass;
-
-  /// The resolved [FieldEntity] for `LookupMap._entries`.
-  final FieldEntity _entriesField;
-
-  /// The resolved [FieldEntity] for `LookupMap._key`.
-  final FieldEntity _keyField;
-
-  /// The resolved [FieldEntity] for `LookupMap._value`.
-  final FieldEntity _valueField;
-
-  /// Constant instances of `LookupMap` and information about them tracked by
-  /// this analysis.
-  final Map<ConstantValue, _LookupMapInfo> _lookupMaps = {};
-
-  /// Keys that we have discovered to be in use in the program.
-  final Set<ConstantValue> _inUse = new Set<ConstantValue>();
-
-  /// Internal helper to memoize the mapping between class elements and their
-  /// corresponding type constants.
-  final Map<ClassEntity, TypeConstantValue> _typeConstants =
-      <ClassEntity, TypeConstantValue>{};
-
-  /// Internal helper to memoize which classes (ignoring Type) override equals.
-  ///
-  /// Const keys of these types will not be tree-shaken because we can't
-  /// statically guarantee that the program doesn't produce an equivalent key at
-  /// runtime. Technically if we limit lookup-maps to check for identical keys,
-  /// we could allow const instances of these types.  However, we internally use
-  /// a hash map within lookup-maps today, so we need this restriction.
-  final Map<ClassEntity, bool> _typesWithEquals = <ClassEntity, bool>{};
-
-  /// Pending work to do if we discover that a new key is in use. For each key
-  /// that we haven't seen, we record the list of lookup-maps that contain an
-  /// entry with that key.
-  final _pending = <ConstantValue, List<_LookupMapInfo>>{};
-
-  final StagedWorldImpactBuilder _impactBuilder =
-      new StagedWorldImpactBuilder();
-
-  _LookupMapAnalysis(
-      this._constantSystem,
-      this._elementEnvironment,
-      this._commonElements,
-      this._entriesField,
-      this._keyField,
-      this._valueField,
-      this._typeLookupMapClass);
-
-  /// Compute the [WorldImpact] for the constants registered since last flush.
-  WorldImpact flush() {
-    return _impactBuilder.flush();
-  }
-
-  /// Whether [constant] is an instance of a `LookupMap`.
-  bool isLookupMap(ConstantValue constant) {
-    if (constant is ConstructedConstantValue) {
-      InterfaceType type = constant.type;
-      ClassEntity superclass = type.element;
-      while (superclass != null) {
-        if (superclass == _typeLookupMapClass) return true;
-        superclass = _elementEnvironment.getSuperClass(superclass);
-      }
-    }
-    return false;
-  }
-
-  /// Registers an instance of a lookup-map with the analysis.
-  void registerLookupMapReference(ConstantValue lookupMap) {
-    assert(isLookupMap(lookupMap));
-    _lookupMaps.putIfAbsent(
-        lookupMap, () => new _LookupMapInfo(lookupMap, this).._updateUsed());
-  }
-
-  /// Whether [key] is a constant value whose type overrides equals.
-  bool _overridesEquals(ConstantValue key) {
-    if (key is ConstructedConstantValue) {
-      ClassEntity element = key.type.element;
-      return _typesWithEquals.putIfAbsent(element, () {
-        ClassEntity cls = element;
-        while (cls != _commonElements.objectClass) {
-          MemberEntity member =
-              _elementEnvironment.lookupClassMember(cls, '==');
-          if (member != null) {
-            return true;
-          }
-          cls = _elementEnvironment.getSuperClass(cls);
-        }
-        return false;
-      });
-    }
-    return false;
-  }
-
-  /// Whether we need to preserve [key]. This is true for keys that are not
-  /// candidates for tree-shaking in the first place (primitives and non-type
-  /// const values overriding equals) and keys that we have seen in the program.
-  bool _shouldKeep(ConstantValue key) =>
-      key.isPrimitive || _inUse.contains(key) || _overridesEquals(key);
-
-  void _addClassUse(ClassEntity cls) {
-    TypeConstantValue f() => _constantSystem.createType(
-        _commonElements, _elementEnvironment.getRawType(cls));
-    ConstantValue key = _typeConstants.putIfAbsent(cls, f);
-    _addUse(key);
-  }
-
-  /// Record that [key] is used and update every lookup map that contains it.
-  void _addUse(ConstantValue key) {
-    if (_inUse.add(key)) {
-      _pending[key]?.forEach((info) => info._markUsed(key));
-      _pending.remove(key);
-    }
-  }
-
-  /// If [key] is a type, cache it in [_typeConstants].
-  _registerTypeKey(ConstantValue key) {
-    if (key is TypeConstantValue && key.representedType is InterfaceType) {
-      InterfaceType type = key.representedType;
-      _typeConstants[type.element] = key;
-    } else {
-      // TODO(sigmund): report error?
-    }
-  }
-
-  /// Callback from the enqueuer, invoked when [element] is instantiated.
-  void registerInstantiatedClass(ClassEntity element) {
-    // TODO(sigmund): only add if .runtimeType is ever used
-    _addClassUse(element);
-  }
-
-  /// Callback from the enqueuer, invoked when [type] is instantiated.
-  void registerInstantiatedType(InterfaceType type) {
-    // TODO(sigmund): only add if .runtimeType is ever used
-    _addClassUse(type.element);
-    // TODO(sigmund): only do this when type-argument expressions are used?
-    _addGenerics(type);
-  }
-
-  /// Records generic type arguments in [type], in case they are retrieved and
-  /// returned using a type-argument expression.
-  void _addGenerics(InterfaceType type) {
-    if (type.typeArguments.isEmpty) return;
-    for (DartType arg in type.typeArguments) {
-      if (arg is InterfaceType) {
-        _addClassUse(arg.element);
-        // Note: this call was needed to generate correct code for
-        // type_lookup_map/generic_type_test
-        // TODO(sigmund): can we get rid of this?
-        _impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-            // TODO(johnniwinther): Find the right [CallStructure].
-            _commonElements.createRuntimeType,
-            null));
-        _addGenerics(arg);
-      }
-    }
-  }
-
-  /// Callback from the codegen enqueuer, invoked when a constant (which is
-  /// possibly a const key or a type literal) is used in the program.
-  void registerTypeConstant(ClassEntity element) {
-    _addClassUse(element);
-  }
-
-  void registerConstantKey(ConstantValue constant) {
-    if (constant.isPrimitive || _overridesEquals(constant)) return;
-    _addUse(constant);
-  }
-
-  void logSummary(void log(String message)) {
-    // When --verbose is passed, we show the total number and set of keys that
-    // were tree-shaken from lookup maps.
-    var sb = new StringBuffer();
-    int count = 0;
-    for (var info in _lookupMaps.values) {
-      for (var key in info.unusedEntries.keys) {
-        if (count != 0) sb.write(',');
-        sb.write(key.toDartText());
-        count++;
-      }
-    }
-    log(count == 0
-        ? 'lookup-map: nothing was tree-shaken'
-        : 'lookup-map: found $count unused keys ($sb)');
-  }
-
-  /// Callback from the backend, invoked when reaching the end of the enqueuing
-  /// process, but before emitting the code. At this moment we have discovered
-  /// all types used in the program and we can tree-shake anything that is
-  /// unused.
-  void onQueueClosed() {
-    _lookupMaps.values.forEach((info) {
-      assert(!info.emitted);
-      info.emitted = true;
-      info._prepareForEmission();
-    });
-
-    // Release resources.
-    _lookupMaps.clear();
-    _pending.clear();
-    _inUse.clear();
-  }
-}
-
-/// Internal information about the entries on a lookup-map.
-class _LookupMapInfo {
-  /// The original reference to the constant value.
-  ///
-  /// This reference will be mutated in place to remove it's entries when the
-  /// map is first seen during codegen, and to restore them (or a subset of
-  /// them) when we have finished discovering which entries are used. This has
-  /// the side-effect that `orignal.getDependencies()` will be empty during
-  /// most of codegen until we are ready to emit the constants. However,
-  /// restoring the entries before emitting code lets us keep the emitter logic
-  /// agnostic of this optimization.
-  final ConstructedConstantValue original;
-
-  /// Reference to the lookup map analysis to be able to refer to data shared
-  /// across infos.
-  final _LookupMapAnalysis analysis;
-
-  /// Whether we have already emitted this constant.
-  bool emitted = false;
-
-  /// Whether the `LookupMap` constant was built using the `LookupMap.pair`
-  /// constructor.
-  bool singlePair;
-
-  /// Entries in the lookup map whose keys have not been seen in the rest of the
-  /// program.
-  Map<ConstantValue, ConstantValue> unusedEntries =
-      <ConstantValue, ConstantValue>{};
-
-  /// Entries that have been used, and thus will be part of the generated code.
-  Map<ConstantValue, ConstantValue> usedEntries =
-      <ConstantValue, ConstantValue>{};
-
-  /// Creates and initializes the information containing all keys of the
-  /// original map marked as unused.
-  _LookupMapInfo(this.original, this.analysis) {
-    ConstantValue key = original.fields[analysis._keyField];
-    singlePair = !key.isNull;
-
-    if (singlePair) {
-      unusedEntries[key] = original.fields[analysis._valueField];
-
-      // Note: we modify the constant in-place, see comment in [original].
-      original.fields[analysis._keyField] = new NullConstantValue();
-      original.fields[analysis._valueField] = new NullConstantValue();
-    } else {
-      ListConstantValue list = original.fields[analysis._entriesField];
-      List<ConstantValue> keyValuePairs = list.entries;
-      for (int i = 0; i < keyValuePairs.length; i += 2) {
-        ConstantValue key = keyValuePairs[i];
-        unusedEntries[key] = keyValuePairs[i + 1];
-      }
-
-      // Note: we modify the constant in-place, see comment in [original].
-      original.fields[analysis._entriesField] =
-          new ListConstantValue(list.type, []);
-    }
-  }
-
-  /// Check every key in unusedEntries and mark it as used if the analysis has
-  /// already discovered them. This is meant to be called once to finalize
-  /// initialization after constructing an instance of this class. Afterwards,
-  /// we call [_markUsed] on each individual key as it gets discovered.
-  void _updateUsed() {
-    // Note: we call toList because `_markUsed` modifies the map.
-    for (ConstantValue key in unusedEntries.keys.toList()) {
-      analysis._registerTypeKey(key);
-      if (analysis._shouldKeep(key)) {
-        _markUsed(key);
-      } else {
-        analysis._pending.putIfAbsent(key, () => []).add(this);
-      }
-    }
-  }
-
-  /// Marks that [key] has been seen, and thus, the corresponding entry in this
-  /// map should be considered reachable.
-  _markUsed(ConstantValue key) {
-    assert(!emitted);
-    assert(unusedEntries.containsKey(key));
-    assert(!usedEntries.containsKey(key));
-    ConstantValue constant = unusedEntries.remove(key);
-    usedEntries[key] = constant;
-    analysis._impactBuilder
-        .registerConstantUse(new ConstantUse.lookupMap(constant));
-  }
-
-  /// Restores [original] to contain all of the entries marked as possibly used.
-  void _prepareForEmission() {
-    ListConstantValue originalEntries = original.fields[analysis._entriesField];
-    InterfaceType listType = originalEntries.type;
-    List<ConstantValue> keyValuePairs = <ConstantValue>[];
-    usedEntries.forEach((key, value) {
-      keyValuePairs.add(key);
-      keyValuePairs.add(value);
-    });
-
-    // Note: we are restoring the entries here, see comment in [original].
-    if (singlePair) {
-      assert(keyValuePairs.length == 0 || keyValuePairs.length == 2);
-      if (keyValuePairs.length == 2) {
-        original.fields[analysis._keyField] = keyValuePairs[0];
-        original.fields[analysis._valueField] = keyValuePairs[1];
-      }
-    } else {
-      original.fields[analysis._entriesField] =
-          new ListConstantValue(listType, keyValuePairs);
-    }
-  }
-}
-
-final _validLookupMapVersionConstraint = new VersionConstraint.parse('^0.0.1');
diff --git a/pkg/compiler/lib/src/js_backend/mirrors_data.dart b/pkg/compiler/lib/src/js_backend/mirrors_data.dart
index 6cb80fd..a32d4cb 100644
--- a/pkg/compiler/lib/src/js_backend/mirrors_data.dart
+++ b/pkg/compiler/lib/src/js_backend/mirrors_data.dart
@@ -566,13 +566,16 @@
 
     // Compute a mapping from class to the closures it contains, so we
     // can include the correct ones when including the class.
-    Map<ClassEntity, List<Local>> closureMap =
+    Map<ClassEntity, List<Local>> classToClosuresMap =
         new Map<ClassEntity, List<Local>>();
-    for (Local closure in worldBuilder.localFunctions) {
-      closureMap
-          .putIfAbsent(closure.memberContext.enclosingClass, () => [])
+    Map<Local, MemberEntity> closureToMemberMap =
+        new Map<Local, MemberEntity>();
+    worldBuilder.forEachLocalFunction((MemberEntity member, Local closure) {
+      closureToMemberMap[closure] = member;
+      classToClosuresMap
+          .putIfAbsent(member.enclosingClass, () => [])
           .add(closure);
-    }
+    });
     bool foundClosure = false;
     for (ClassEntity cls in worldBuilder.directlyInstantiatedClasses) {
       // Do not process internal classes.
@@ -611,7 +614,7 @@
           });
         }
         // 5) all its closures
-        List<Local> closures = closureMap[cls];
+        List<Local> closures = classToClosuresMap[cls];
         if (closures != null) {
           _closuresNeededForReflection.addAll(closures);
           foundClosure = true;
@@ -632,10 +635,10 @@
         });
         // Also add in closures. Those might be reflectable is their enclosing
         // member is.
-        List<Local> closures = closureMap[cls];
+        List<Local> closures = classToClosuresMap[cls];
         if (closures != null) {
           for (Local closure in closures) {
-            MemberEntity member = closure.memberContext;
+            MemberEntity member = closureToMemberMap[closure];
             if (_memberReferencedFromMirrorSystem(member)) {
               _closuresNeededForReflection.add(closure);
               foundClosure = true;
@@ -657,10 +660,10 @@
       });
     }
     // And closures inside top-level elements that do not have a surrounding
-    // class. These will be in the [:null:] bucket of the [closureMap].
-    if (closureMap.containsKey(null)) {
-      for (Local closure in closureMap[null]) {
-        if (isMemberReferencedFromMirrorSystem(closure.memberContext)) {
+    // class. These will be in the [:null:] bucket of the [classToClosureMap].
+    if (classToClosuresMap.containsKey(null)) {
+      for (Local closure in classToClosuresMap[null]) {
+        if (isMemberReferencedFromMirrorSystem(closureToMemberMap[closure])) {
           _closuresNeededForReflection.add(closure);
           foundClosure = true;
         }
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 9ac8b1e..2df2e48 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -1689,6 +1689,7 @@
   /// Furthermore, this function is injective, that is, it never returns the
   /// same name for two different inputs.
   String safeVariableName(String name) {
+    name = name.replaceAll('#', '_');
     if (jsVariableReserved.contains(name) || name.startsWith(r'$')) {
       return '\$$name';
     }
diff --git a/pkg/compiler/lib/src/js_backend/resolution_listener.dart b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
index 8512956..2d8d21c 100644
--- a/pkg/compiler/lib/src/js_backend/resolution_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
@@ -24,7 +24,6 @@
 import 'checked_mode_helpers.dart';
 import 'custom_elements_analysis.dart';
 import 'interceptor_data.dart';
-import 'lookup_map_analysis.dart' show LookupMapResolutionAnalysis;
 import 'mirrors_analysis.dart';
 import 'mirrors_data.dart';
 import 'native_data.dart' show NativeBasicData;
@@ -50,7 +49,6 @@
 
   final NoSuchMethodRegistry _noSuchMethodRegistry;
   final CustomElementsResolutionAnalysis _customElementsAnalysis;
-  final LookupMapResolutionAnalysis _lookupMapResolutionAnalysis;
   final MirrorsResolutionAnalysis _mirrorsAnalysis;
   final TypeVariableResolutionAnalysis _typeVariableResolutionAnalysis;
 
@@ -71,7 +69,6 @@
       this._mirrorsDataBuilder,
       this._noSuchMethodRegistry,
       this._customElementsAnalysis,
-      this._lookupMapResolutionAnalysis,
       this._mirrorsAnalysis,
       this._typeVariableResolutionAnalysis,
       this._nativeEnqueuer,
@@ -204,8 +201,6 @@
     // due to mirrors.
     enqueuer.applyImpact(_customElementsAnalysis.flush(),
         impactSource: _customElementsAnalysis);
-    enqueuer.applyImpact(_lookupMapResolutionAnalysis.flush(),
-        impactSource: _lookupMapResolutionAnalysis);
     enqueuer.applyImpact(_typeVariableResolutionAnalysis.flush(),
         impactSource: _typeVariableResolutionAnalysis);
 
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 572bbe8..32d177d 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -823,11 +823,16 @@
     return new jsAst.ArrayInitializer(elements);
   }
 
+  String getTypeVariableName(TypeVariableType type) {
+    String name = type.element.name;
+    return name.replaceAll('#', '_');
+  }
+
   jsAst.Expression getTypeEncoding(Emitter emitter, DartType type,
       {bool alwaysGenerateFunction: false}) {
     ClassEntity contextClass = DartTypes.getClassContext(type);
     jsAst.Expression onVariable(TypeVariableType v) {
-      return new jsAst.VariableUse(v.element.name);
+      return new jsAst.VariableUse(getTypeVariableName(v));
     }
 
     jsAst.Expression encoding =
@@ -842,7 +847,7 @@
             .typeArguments
             .map((DartType _type) {
           TypeVariableType type = _type;
-          return type.element.name;
+          return getTypeVariableName(type);
         }).toList();
       }
       return js('function(#) { return # }', [parameters, encoding]);
@@ -912,6 +917,9 @@
   }
 
   String getVariableName(String name) {
+    // Kernel type variable names for anonymous mixin applications have names
+    // canonicalized to a non-identified, e.g. '#U0'.
+    name = name.replaceAll('#', '_');
     return namer.safeVariableName(name);
   }
 
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 bc724b8..a3774ff 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -35,7 +35,7 @@
   InterceptorData get _interceptorData => _closedWorld.interceptorData;
 
   jsAst.Expression generateClassConstructor(
-      ClassEntity classElement, Iterable<jsAst.Name> fields, bool hasRtiField) {
+      ClassEntity classElement, List<jsAst.Name> fields, bool hasRtiField) {
     // TODO(sra): Implement placeholders in VariableDeclaration position:
     //
     //     String constructorName = namer.getNameOfClass(classElement);
@@ -50,10 +50,16 @@
       typeParameters = rtiName;
       typeInits = js('this.# = #', [rtiName, rtiName]);
     }
+    List<jsAst.Parameter> parameters = new List<jsAst.Parameter>.generate(
+        fields.length, (i) => new jsAst.Parameter('t$i'));
+    List<jsAst.Expression> fieldInitializers =
+        new List<jsAst.Expression>.generate(fields.length, (i) {
+      return js('this.# = #', [fields[i], parameters[i]]);
+    });
     return js('function(#, #) { #; #; this.#();}', [
-      fields,
+      parameters,
       typeParameters,
-      fields.map((name) => js('this.# = #', [name, name])),
+      fieldInitializers,
       typeInits,
       _namer.deferredAction
     ]);
diff --git a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
index a1b0903..98989b0 100644
--- a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
+++ b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
@@ -6,25 +6,37 @@
 
 import '../constants/values.dart';
 import '../elements/elements.dart' show Elements;
-import '../elements/entities.dart' show Entity, FieldEntity;
-import '../elements/resolution_types.dart';
+import '../elements/entities.dart'
+    show Entity, ClassEntity, FieldEntity, MemberEntity, TypedefEntity;
+import '../elements/resolution_types.dart'
+    show GenericType, ResolutionDartType, ResolutionTypeKind;
+import '../elements/types.dart';
 import '../js_backend/js_backend.dart' show SyntheticConstantKind;
+import 'sorter.dart' show Sorter;
 
 /// A canonical but arbitrary ordering of constants. The ordering is 'stable'
 /// under perturbation of the source.
-int deepCompareConstants(ConstantValue a, ConstantValue b) {
-  return _CompareVisitor.compareValues(a, b);
+abstract class ConstantOrdering {
+  factory ConstantOrdering(Sorter sorter) = _ConstantOrdering;
+
+  int compare(ConstantValue a, ConstantValue b);
 }
 
-class _CompareVisitor implements ConstantValueVisitor<int, ConstantValue> {
-  const _CompareVisitor();
+class _ConstantOrdering
+    implements ConstantOrdering, ConstantValueVisitor<int, ConstantValue> {
+  final Sorter _sorter;
+  _DartTypeOrdering _dartTypeOrdering;
+  _ConstantOrdering(this._sorter) {
+    _dartTypeOrdering = new _DartTypeOrdering(this);
+  }
 
-  static int compareValues(ConstantValue a, ConstantValue b) {
+  int compare(ConstantValue a, ConstantValue b) => compareValues(a, b);
+
+  int compareValues(ConstantValue a, ConstantValue b) {
     if (identical(a, b)) return 0;
     int r = _KindVisitor.kind(a).compareTo(_KindVisitor.kind(b));
     if (r != 0) return r;
-    r = a.accept(const _CompareVisitor(), b);
-    return r;
+    return a.accept(this, b);
   }
 
   static int compareNullable(int compare(a, b), a, b) {
@@ -50,7 +62,26 @@
     return Elements.compareByPosition(a, b);
   }
 
-  static int compareDartTypes(ResolutionDartType a, ResolutionDartType b) {
+  int compareClasses(ClassEntity a, ClassEntity b) {
+    int r = a.name.compareTo(b.name);
+    if (r != 0) return r;
+    return _sorter.compareClassesByLocation(a, b);
+  }
+
+  int compareMembers(MemberEntity a, MemberEntity b) {
+    int r = a.name.compareTo(b.name);
+    if (r != 0) return r;
+    return _sorter.compareMembersByLocation(a, b);
+  }
+
+  int compareTypedefs(TypedefEntity a, TypedefEntity b) {
+    int r = a.name.compareTo(b.name);
+    if (r != 0) return r;
+    return _sorter.compareTypedefsByLocation(a, b);
+  }
+
+  static int _compareResolutionDartTypes(
+      ResolutionDartType a, ResolutionDartType b) {
     if (a == b) return 0;
     int r = a.kind.index.compareTo(b.kind.index);
     if (r != 0) return r;
@@ -60,15 +91,23 @@
     if (a is GenericType) {
       GenericType aGeneric = a;
       GenericType bGeneric = b;
-      r = compareLists(
-          compareDartTypes, aGeneric.typeArguments, bGeneric.typeArguments);
+      r = compareLists(_compareResolutionDartTypes, aGeneric.typeArguments,
+          bGeneric.typeArguments);
       if (r != 0) return r;
     }
     throw 'unexpected compareDartTypes  $a  $b';
   }
 
+  int compareDartTypes(DartType a, DartType b) {
+    if (a is ResolutionDartType && b is ResolutionDartType) {
+      // TODO(redemption): Remove this path.
+      return _compareResolutionDartTypes(a, b);
+    }
+    return _dartTypeOrdering.compare(a, b);
+  }
+
   int visitFunction(FunctionConstantValue a, FunctionConstantValue b) {
-    return compareElements(a.element, b.element);
+    return compareMembers(a.element, b.element);
   }
 
   int visitNull(NullConstantValue a, NullConstantValue b) {
@@ -102,9 +141,7 @@
   int visitList(ListConstantValue a, ListConstantValue b) {
     int r = compareLists(compareValues, a.entries, b.entries);
     if (r != 0) return r;
-    ResolutionInterfaceType type1 = a.type;
-    ResolutionInterfaceType type2 = b.type;
-    return compareDartTypes(type1, type2);
+    return compareDartTypes(a.type, b.type);
   }
 
   int visitMap(MapConstantValue a, MapConstantValue b) {
@@ -112,21 +149,18 @@
     if (r != 0) return r;
     r = compareLists(compareValues, a.values, b.values);
     if (r != 0) return r;
-    ResolutionInterfaceType type1 = a.type;
-    ResolutionInterfaceType type2 = b.type;
-    return compareDartTypes(type1, type2);
+    return compareDartTypes(a.type, b.type);
   }
 
   int visitConstructed(ConstructedConstantValue a, ConstructedConstantValue b) {
-    ResolutionInterfaceType type1 = a.type;
-    ResolutionInterfaceType type2 = b.type;
-    int r = compareDartTypes(type1, type2);
+    int r = compareDartTypes(a.type, b.type);
     if (r != 0) return r;
 
-    List<FieldEntity> aFields = a.fields.keys.toList()..sort(compareElements);
-    List<FieldEntity> bFields = b.fields.keys.toList()..sort(compareElements);
+    // TODO(sra): Avoid all these tear-offs.
+    List<FieldEntity> aFields = a.fields.keys.toList()..sort(compareMembers);
+    List<FieldEntity> bFields = b.fields.keys.toList()..sort(compareMembers);
 
-    r = compareLists(compareElements, aFields, bFields);
+    r = compareLists(compareMembers, aFields, bFields);
     if (r != 0) return r;
 
     return compareLists(
@@ -138,13 +172,11 @@
   int visitType(TypeConstantValue a, TypeConstantValue b) {
     int r = compareDartTypes(a.representedType, b.representedType);
     if (r != 0) return r;
-    ResolutionInterfaceType type1 = a.type;
-    ResolutionInterfaceType type2 = b.type;
-    return compareDartTypes(type1, type2);
+    return compareDartTypes(a.type, b.type);
   }
 
   int visitInterceptor(InterceptorConstantValue a, InterceptorConstantValue b) {
-    return compareElements(a.cls, b.cls);
+    return compareClasses(a.cls, b.cls);
   }
 
   int visitSynthetic(SyntheticConstantValue a, SyntheticConstantValue b) {
@@ -178,6 +210,8 @@
   int visitDeferred(DeferredConstantValue a, DeferredConstantValue b) {
     int r = compareValues(a.referenced, b.referenced);
     if (r != 0) return r;
+    // TODO(sra): Implement deferred imports for Kernel.
+    // TODO(sra): What kind of Entity is `prefix`?
     return compareElements(a.prefix, b.prefix);
   }
 }
@@ -218,3 +252,94 @@
   int visitSynthetic(SyntheticConstantValue a, _) => SYNTHETIC;
   int visitDeferred(DeferredConstantValue a, _) => DEFERRED;
 }
+
+/// Visitor for distinguishing types by kind.
+class _DartTypeKindVisitor extends DartTypeVisitor<int, Null> {
+  const _DartTypeKindVisitor();
+
+  static int kind(DartType type) {
+    assert(_usesLegacyOrder);
+    return type.accept(const _DartTypeKindVisitor(), null);
+  }
+
+  int visitVoidType(covariant VoidType type, _) => 6;
+  int visitTypeVariableType(covariant TypeVariableType type, _) => 3;
+  int visitFunctionType(covariant FunctionType type, _) => 0;
+  int visitInterfaceType(covariant InterfaceType type, _) => 1;
+  int visitTypedefType(covariant TypedefType type, _) => 2;
+  int visitDynamicType(covariant DynamicType type, _) => 5;
+
+  // Check that the ordering of different kinds of type is consistent with
+  // ResolutionDartTypes.
+  // TODO(redemption): Remove this check.
+  static bool _usesLegacyOrder = () {
+    var v = const _DartTypeKindVisitor();
+    assert(
+        v.visitFunctionType(null, null) == ResolutionTypeKind.FUNCTION.index);
+    assert(
+        v.visitInterfaceType(null, null) == ResolutionTypeKind.INTERFACE.index);
+    assert(v.visitTypedefType(null, null) == ResolutionTypeKind.TYPEDEF.index);
+    assert(v.visitTypeVariableType(null, null) ==
+        ResolutionTypeKind.TYPE_VARIABLE.index);
+    // There is no analogue of ResolutionTypeKind.MALFORMED_TYPE.
+    assert(v.visitDynamicType(null, null) == ResolutionTypeKind.DYNAMIC.index);
+    assert(v.visitVoidType(null, null) == ResolutionTypeKind.VOID.index);
+    return true;
+  }();
+}
+
+class _DartTypeOrdering extends DartTypeVisitor<int, DartType> {
+  final _ConstantOrdering _constantOrdering;
+  DartType _root;
+  _DartTypeOrdering(this._constantOrdering);
+
+  int compare(DartType a, DartType b) {
+    if (a == b) return 0;
+    int r =
+        _DartTypeKindVisitor.kind(a).compareTo(_DartTypeKindVisitor.kind(b));
+    if (r != 0) return r;
+    _root = a;
+    r = a.accept(this, b);
+    _root = null;
+    return r;
+  }
+
+  int visitVoidType(covariant VoidType type, covariant VoidType other) {
+    throw new UnsupportedError('Unreachable');
+  }
+
+  int visitTypeVariableType(
+      covariant TypeVariableType type, covariant TypeVariableType other) {
+    throw new UnsupportedError(
+        "Type variables are not expected in constants: '$type' in '$_root'");
+  }
+
+  int visitFunctionType(covariant FunctionType type, DartType _other) {
+    throw new UnimplementedError(
+        "Unimplemented FuntionType '$type' in '$_root'");
+  }
+
+  int visitInterfaceType(
+      covariant InterfaceType type, covariant InterfaceType other) {
+    int r = _constantOrdering.compareClasses(type.element, other.element);
+    if (r != 0) return r;
+    return _compareTypeArguments(type.typeArguments, other.typeArguments);
+  }
+
+  int visitTypedefType(
+      covariant TypedefType type, covariant TypedefType other) {
+    int r = _constantOrdering.compareTypedefs(type.element, other.element);
+    if (r != 0) return r;
+    return _compareTypeArguments(type.typeArguments, other.typeArguments);
+  }
+
+  int visitDynamicType(
+      covariant DynamicType type, covariant DynamicType other) {
+    throw new UnsupportedError('Unreachable');
+  }
+
+  int _compareTypeArguments(
+      List<DartType> aArguments, List<DartType> bArguments) {
+    return _ConstantOrdering.compareLists(compare, aArguments, bArguments);
+  }
+}
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
index 7655b13..162075a 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart
@@ -86,10 +86,9 @@
   * Emits the precompiled constructor when in CSP mode.
   */
   void emitConstructorsForCSP(Class cls) {
-    List<jsAst.Name> fieldNames = <jsAst.Name>[];
-
     if (!compiler.options.useContentSecurityPolicy) return;
 
+    List<jsAst.Name> fieldNames = <jsAst.Name>[];
     if (!cls.onlyForRti && !cls.isNative) {
       fieldNames = cls.fields.map((Field field) => field.name).toList();
     }
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index e6a2e20..6dfae6a 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -40,7 +40,7 @@
 import '../../universe/world_builder.dart' show CodegenWorldBuilder;
 import '../../util/uri_extras.dart' show relativize;
 import '../../world.dart' show ClosedWorld;
-import '../constant_ordering.dart' show deepCompareConstants;
+import '../constant_ordering.dart' show ConstantOrdering;
 import '../headers.dart';
 import '../js_emitter.dart' hide Emitter, EmitterFactory;
 import '../js_emitter.dart' as js_emitter show EmitterBase, EmitterFactory;
@@ -97,6 +97,7 @@
   final NsmEmitter nsmEmitter;
   final InterceptorEmitter interceptorEmitter;
   final Sorter _sorter;
+  final ConstantOrdering _constantOrdering;
 
   // TODO(johnniwinther): Wrap these fields in a caching strategy.
   final List<jsAst.Statement> cachedEmittedConstantsAst = <jsAst.Statement>[];
@@ -169,10 +170,12 @@
   final bool generateSourceMap;
 
   Emitter(this.compiler, this.namer, this._closedWorld, this.generateSourceMap,
-      this.task, this._sorter)
+      this.task, Sorter sorter)
       : classEmitter = new ClassEmitter(_closedWorld),
         interceptorEmitter = new InterceptorEmitter(_closedWorld),
-        nsmEmitter = new NsmEmitter(_closedWorld) {
+        nsmEmitter = new NsmEmitter(_closedWorld),
+        _sorter = sorter,
+        _constantOrdering = new ConstantOrdering(sorter) {
     constantEmitter = new ConstantEmitter(
         compiler.options,
         _closedWorld.commonElements,
@@ -236,7 +239,7 @@
     if (r != 0) return r;
 
     // Resolve collisions in the long name by using a structural order.
-    return deepCompareConstants(a, b);
+    return _constantOrdering.compare(a, b);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
index c89f050..3425fb4 100644
--- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/emitter.dart
@@ -31,7 +31,7 @@
   Emitter createEmitter(CodeEmitterTask task, Namer namer,
       ClosedWorld closedWorld, Sorter sorter) {
     return new Emitter(
-        task.compiler, namer, task.nativeEmitter, closedWorld, task);
+        task.compiler, namer, task.nativeEmitter, closedWorld, sorter, task);
   }
 }
 
@@ -44,9 +44,9 @@
   JavaScriptBackend get _backend => _compiler.backend;
 
   Emitter(this._compiler, this.namer, NativeEmitter nativeEmitter,
-      this._closedWorld, CodeEmitterTask task)
+      this._closedWorld, Sorter sorter, CodeEmitterTask task)
       : _emitter = new ModelEmitter(
-            _compiler, namer, nativeEmitter, _closedWorld, task);
+            _compiler, namer, nativeEmitter, _closedWorld, sorter, task);
 
   DiagnosticReporter get reporter => _compiler.reporter;
 
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
index 76f8914..6f4ba3c 100644
--- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
@@ -30,11 +30,12 @@
     show JavaScriptBackend, Namer, ConstantEmitter;
 import '../../js_backend/interceptor_data.dart';
 import '../../world.dart';
-import '../constant_ordering.dart' show deepCompareConstants;
+import '../constant_ordering.dart' show ConstantOrdering;
 import '../code_emitter_task.dart';
 import '../js_emitter.dart' show NativeEmitter;
 import '../js_emitter.dart' show NativeGenerator, buildTearOffCode;
 import '../model.dart';
+import '../sorter.dart' show Sorter;
 
 class ModelEmitter {
   final Compiler compiler;
@@ -42,6 +43,7 @@
   ConstantEmitter constantEmitter;
   final NativeEmitter nativeEmitter;
   final ClosedWorld _closedWorld;
+  final ConstantOrdering _constantOrdering;
 
   JavaScriptBackend get backend => compiler.backend;
 
@@ -54,7 +56,8 @@
   static const String typeNameProperty = r"builtin$cls";
 
   ModelEmitter(this.compiler, this.namer, this.nativeEmitter, this._closedWorld,
-      CodeEmitterTask task) {
+      Sorter sorter, CodeEmitterTask task)
+      : _constantOrdering = new ConstantOrdering(sorter) {
     this.constantEmitter = new ConstantEmitter(
         compiler.options,
         _closedWorld.commonElements,
@@ -114,7 +117,7 @@
     if (r != 0) return r;
 
     // Resolve collisions in the long name by using a structural order.
-    return deepCompareConstants(a, b);
+    return _constantOrdering.compare(a, b);
   }
 
   js.Expression generateStaticClosureAccess(MethodElement element) {
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index 449c45f..a296b45 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -4,9 +4,6 @@
 
 library dart2js.js_emitter.parameter_stub_generator;
 
-import '../closure.dart' show ClosureClassElement;
-import '../common.dart';
-import '../common_elements.dart';
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../js/js.dart' as jsAst;
@@ -27,7 +24,6 @@
 class ParameterStubGenerator {
   static final Set<Selector> emptySelectorSet = new Set<Selector>();
 
-  final CommonElements _commonElements;
   final CodeEmitterTask _emitterTask;
   final Namer _namer;
   final NativeData _nativeData;
@@ -35,14 +31,8 @@
   final CodegenWorldBuilder _codegenWorldBuilder;
   final ClosedWorld _closedWorld;
 
-  ParameterStubGenerator(
-      this._commonElements,
-      this._emitterTask,
-      this._namer,
-      this._nativeData,
-      this._interceptorData,
-      this._codegenWorldBuilder,
-      this._closedWorld);
+  ParameterStubGenerator(this._emitterTask, this._namer, this._nativeData,
+      this._interceptorData, this._codegenWorldBuilder, this._closedWorld);
 
   Emitter get _emitter => _emitterTask.emitter;
 
@@ -217,23 +207,6 @@
   // (3) foo$3$d(a, b, d) => MyClass.foo$4$c$d(this, a, b, null, d);
   List<ParameterStubMethod> generateParameterStubs(FunctionEntity member,
       {bool canTearOff: true}) {
-    {
-      var enclosingClass = member.enclosingClass;
-      if (enclosingClass != null && enclosingClass.isClosure) {
-        if (enclosingClass is ClosureClassElement) {
-          // TODO(redemption): What is the equivalent invariant for J-entities?
-          var methodElement = enclosingClass.methodElement;
-          if (enclosingClass.supertype.element ==
-              _commonElements.boundClosureClass) {
-            failedAt(methodElement, 'Bound closure1.');
-          }
-          if (methodElement.isInstanceMember) {
-            failedAt(methodElement, 'Bound closure2.');
-          }
-        }
-      }
-    }
-
     // The set of selectors that apply to `member`. For example, for
     // a member `foo(x, [y])` the following selectors may apply:
     // `foo(x)`, and `foo(x, y)`.
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index f0290b0..58d7ac0 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -976,14 +976,8 @@
       FunctionEntity element, bool canTearOff) {
     if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[];
 
-    ParameterStubGenerator generator = new ParameterStubGenerator(
-        _commonElements,
-        _task,
-        _namer,
-        _nativeData,
-        _interceptorData,
-        _worldBuilder,
-        _closedWorld);
+    ParameterStubGenerator generator = new ParameterStubGenerator(_task, _namer,
+        _nativeData, _interceptorData, _worldBuilder, _closedWorld);
     return generator.generateParameterStubs(element, canTearOff: canTearOff);
   }
 
diff --git a/pkg/compiler/lib/src/js_emitter/sorter.dart b/pkg/compiler/lib/src/js_emitter/sorter.dart
index 3b99320..d3cfff6 100644
--- a/pkg/compiler/lib/src/js_emitter/sorter.dart
+++ b/pkg/compiler/lib/src/js_emitter/sorter.dart
@@ -20,6 +20,11 @@
 
   /// Returns a sorted list of [members].
   Iterable<MemberEntity> sortMembers(Iterable<MemberEntity> members);
+
+  int compareLibrariesByLocation(LibraryEntity a, LibraryEntity b);
+  int compareClassesByLocation(ClassEntity a, ClassEntity b);
+  int compareTypedefsByLocation(TypedefEntity a, TypedefEntity b);
+  int compareMembersByLocation(MemberEntity a, MemberEntity b);
 }
 
 class ElementSorter implements Sorter {
@@ -61,4 +66,24 @@
   List<MemberEntity> sortMembers(Iterable<MemberEntity> members) {
     return Elements.sortedByPosition(new List.from(members, growable: false));
   }
+
+  @override
+  int compareLibrariesByLocation(
+          covariant LibraryElement a, covariant LibraryElement b) =>
+      Elements.compareByPosition(a, b);
+
+  @override
+  int compareClassesByLocation(
+          covariant ClassElement a, covariant ClassElement b) =>
+      Elements.compareByPosition(a, b);
+
+  @override
+  int compareTypedefsByLocation(
+          covariant TypedefElement a, covariant TypedefElement b) =>
+      Elements.compareByPosition(a, b);
+
+  @override
+  int compareMembersByLocation(
+          covariant MemberElement a, covariant MemberElement b) =>
+      Elements.compareByPosition(a, b);
 }
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
index 1a2f821..fb87f93 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -35,7 +35,7 @@
   Emitter createEmitter(CodeEmitterTask task, Namer namer,
       ClosedWorld closedWorld, Sorter sorter) {
     return new Emitter(task.compiler, namer, task.nativeEmitter, closedWorld,
-        task, generateSourceMap);
+        sorter, task, generateSourceMap);
   }
 }
 
@@ -47,10 +47,16 @@
 
   JavaScriptBackend get _backend => _compiler.backend;
 
-  Emitter(this._compiler, this.namer, NativeEmitter nativeEmitter,
-      this._closedWorld, CodeEmitterTask task, bool shouldGenerateSourceMap)
+  Emitter(
+      this._compiler,
+      this.namer,
+      NativeEmitter nativeEmitter,
+      this._closedWorld,
+      Sorter sorter,
+      CodeEmitterTask task,
+      bool shouldGenerateSourceMap)
       : _emitter = new ModelEmitter(_compiler, namer, nativeEmitter,
-            _closedWorld, task, shouldGenerateSourceMap);
+            _closedWorld, sorter, task, shouldGenerateSourceMap);
 
   DiagnosticReporter get reporter => _compiler.reporter;
 
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index ba6fc2a..42baa5f 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -724,7 +724,7 @@
     }
 
     var statements = <js.Statement>[];
-    var parameters = <js.Name>[];
+    var parameters = <js.Parameter>[];
     var thisRef;
 
     if (cls.isSoftDeferred) {
@@ -755,17 +755,17 @@
     }
 
     for (Field field in cls.fields) {
-      js.Name paramName = field.name;
-      parameters.add(paramName);
+      js.Parameter parameter = new js.Parameter('t${parameters.length}');
+      parameters.add(parameter);
       statements
-          .add(js.js.statement('#.# = #', [thisRef, field.name, paramName]));
+          .add(js.js.statement('#.# = #', [thisRef, field.name, parameter]));
     }
 
     if (cls.hasRtiField) {
-      js.Name paramName = namer.rtiFieldJsName;
-      parameters.add(paramName);
+      js.Parameter parameter = new js.Parameter('t${parameters.length}');
+      parameters.add(parameter);
       statements.add(js.js
-          .statement('#.# = #', [thisRef, namer.rtiFieldJsName, paramName]));
+          .statement('#.# = #', [thisRef, namer.rtiFieldJsName, parameter]));
     }
 
     return js.js('function #(#) { # }', [name, parameters, statements]);
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 03834c8..baa5dd8 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -48,11 +48,12 @@
 import '../../js_backend/interceptor_data.dart';
 import '../../world.dart';
 import '../code_emitter_task.dart';
-import '../constant_ordering.dart' show deepCompareConstants;
+import '../constant_ordering.dart' show ConstantOrdering;
 import '../headers.dart';
 import '../js_emitter.dart' show NativeEmitter;
 import '../js_emitter.dart' show buildTearOffCode, NativeGenerator;
 import '../model.dart';
+import '../sorter.dart' show Sorter;
 
 part 'deferred_fragment_hash.dart';
 part 'fragment_emitter.dart';
@@ -64,6 +65,7 @@
   final NativeEmitter nativeEmitter;
   final bool shouldGenerateSourceMap;
   final ClosedWorld _closedWorld;
+  final ConstantOrdering _constantOrdering;
 
   // The full code that is written to each hunk part-file.
   final Map<Fragment, CodeOutput> outputBuffers = <Fragment, CodeOutput>{};
@@ -80,7 +82,8 @@
   static const String typeNameProperty = r"builtin$cls";
 
   ModelEmitter(this.compiler, this.namer, this.nativeEmitter, this._closedWorld,
-      CodeEmitterTask task, this.shouldGenerateSourceMap) {
+      Sorter sorter, CodeEmitterTask task, this.shouldGenerateSourceMap)
+      : _constantOrdering = new ConstantOrdering(sorter) {
     this.constantEmitter = new ConstantEmitter(
         compiler.options,
         _closedWorld.commonElements,
@@ -136,7 +139,7 @@
     if (r != 0) return r;
 
     // Resolve collisions in the long name by using a structural order.
-    return deepCompareConstants(a, b);
+    return _constantOrdering.compare(a, b);
   }
 
   js.Expression generateStaticClosureAccess(MethodElement element) {
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 8850fd1..b3af8cd 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -14,6 +14,7 @@
 import '../elements/types.dart';
 import '../kernel/element_map.dart';
 import '../kernel/env.dart';
+import '../ssa/type_builder.dart';
 import '../world.dart';
 import 'elements.dart';
 import 'closure_visitors.dart';
@@ -400,6 +401,17 @@
 
   List<Local> get createdFieldEntities => localToFieldMap.keys.toList();
 
+  @override
+  Local getLocalForField(FieldEntity field) {
+    for (Local local in localToFieldMap.keys) {
+      if (localToFieldMap[local] == field) {
+        return local;
+      }
+    }
+    failedAt(field, "No local for $field.");
+    return null;
+  }
+
   FieldEntity get thisFieldEntity => localToFieldMap[thisLocal];
 
   void forEachCapturedVariable(f(Local from, JField to)) {
@@ -420,7 +432,7 @@
   }
 
   bool isVariableBoxed(Local variable) =>
-      localToFieldMap.keys.contains(variable);
+      boxedVariables.keys.contains(variable);
 
   bool get isClosure => true;
 }
@@ -497,24 +509,35 @@
       'ClosureClassDefinition(kind:$kind,cls:$cls,location:$location)';
 }
 
-class ClosureMemberData implements MemberData {
+abstract class ClosureMemberData implements MemberData {
   final MemberDefinition definition;
+  final InterfaceType memberThisType;
 
-  ClosureMemberData(this.definition);
+  ClosureMemberData(this.definition, this.memberThisType);
 
   @override
   Iterable<ConstantValue> getMetadata(KernelToElementMap elementMap) {
     return const <ConstantValue>[];
   }
+
+  @override
+  InterfaceType getMemberThisType(KernelToElementMapForBuilding elementMap) {
+    return memberThisType;
+  }
 }
 
 class ClosureFunctionData extends ClosureMemberData implements FunctionData {
   final FunctionType functionType;
   final ir.FunctionNode functionNode;
+  final ClassTypeVariableAccess classTypeVariableAccess;
 
   ClosureFunctionData(
-      ClosureMemberDefinition definition, this.functionType, this.functionNode)
-      : super(definition);
+      ClosureMemberDefinition definition,
+      InterfaceType memberThisType,
+      this.functionType,
+      this.functionNode,
+      this.classTypeVariableAccess)
+      : super(definition, memberThisType);
 
   void forEachParameter(KernelToElementMapForBuilding elementMap,
       void f(DartType type, String name, ConstantValue defaultValue)) {
@@ -548,7 +571,8 @@
 }
 
 class ClosureFieldData extends ClosureMemberData implements FieldData {
-  ClosureFieldData(MemberDefinition definition) : super(definition);
+  ClosureFieldData(MemberDefinition definition, InterfaceType memberThisType)
+      : super(definition, memberThisType);
 
   @override
   DartType getFieldType(KernelToElementMap elementMap) {
@@ -583,6 +607,10 @@
   ConstantValue getFieldConstantValue(KernelToElementMap elementMap) {
     return null;
   }
+
+  @override
+  ClassTypeVariableAccess get classTypeVariableAccess =>
+      ClassTypeVariableAccess.none;
 }
 
 class ClosureMemberDefinition implements MemberDefinition {
diff --git a/pkg/compiler/lib/src/js_model/closure_visitors.dart b/pkg/compiler/lib/src/js_model/closure_visitors.dart
index a489dc6..af0d87d 100644
--- a/pkg/compiler/lib/src/js_model/closure_visitors.dart
+++ b/pkg/compiler/lib/src/js_model/closure_visitors.dart
@@ -260,6 +260,21 @@
         scope.hasThisLocal);
   }
 
+  void visitSuperMethodInvocation(ir.SuperMethodInvocation invocation) {
+    if (_hasThisLocal) _registerNeedsThis();
+    invocation.visitChildren(this);
+  }
+
+  void visitSuperPropertySet(ir.SuperPropertySet propertySet) {
+    if (_hasThisLocal) _registerNeedsThis();
+    propertySet.visitChildren(this);
+  }
+
+  void visitSuperPropertyGet(ir.SuperPropertyGet propertyGet) {
+    if (_hasThisLocal) _registerNeedsThis();
+    propertyGet.visitChildren(this);
+  }
+
   void visitInvokable(ir.TreeNode node) {
     assert(node is ir.Member ||
         node is ir.FunctionExpression ||
diff --git a/pkg/compiler/lib/src/js_model/locals.dart b/pkg/compiler/lib/src/js_model/locals.dart
index c26233f..b30dfdd 100644
--- a/pkg/compiler/lib/src/js_model/locals.dart
+++ b/pkg/compiler/lib/src/js_model/locals.dart
@@ -10,7 +10,9 @@
 import '../common.dart';
 import '../elements/entities.dart';
 import '../elements/jumps.dart';
+import '../elements/types.dart';
 import '../kernel/element_map.dart';
+import '../kernel/indexed.dart';
 
 class GlobalLocalsMap {
   Map<MemberEntity, KernelToLocalsMap> _localsMaps =
@@ -18,6 +20,14 @@
 
   /// Returns the [KernelToLocalsMap] for [member].
   KernelToLocalsMap getLocalsMap(MemberEntity member) {
+    // If element is a ConstructorBodyEntity, its localsMap is the same as for
+    // ConstructorEntity, because both of these entities came from the same
+    // constructor node. The entities are two separate parts because JS does not
+    // have the concept of an initializer list, so the constructor (initializer
+    // list) and the constructor body are implemented as two separate
+    // constructor steps.
+    MemberEntity entity = member;
+    if (entity is ConstructorBodyEntity) member = entity.constructor;
     return _localsMaps.putIfAbsent(
         member, () => new KernelToLocalsMapImpl(member));
   }
@@ -34,10 +44,11 @@
 
 class KernelToLocalsMapImpl implements KernelToLocalsMap {
   final List<MemberEntity> _members = <MemberEntity>[];
+  final EntityDataMap<JLocal, LocalData> _locals =
+      new EntityDataMap<JLocal, LocalData>();
   Map<ir.VariableDeclaration, JLocal> _map = <ir.VariableDeclaration, JLocal>{};
   Map<ir.TreeNode, JJumpTarget> _jumpTargetMap;
   Set<ir.BreakStatement> _breaksAsContinue;
-  List<ir.VariableDeclaration> _parameterList = <ir.VariableDeclaration>[];
 
   MemberEntity get currentMember => _members.last;
 
@@ -138,24 +149,21 @@
   @override
   Local getLocalVariable(ir.VariableDeclaration node) {
     return _map.putIfAbsent(node, () {
-      Local local;
-      if (node.parent is ir.FunctionNode) {
-        local = new JParameter(_parameterList.length, node.name, currentMember);
-        _parameterList.add(node);
-      } else {
-        local = new JLocal(node.name, currentMember);
-      }
+      JLocal local = new JLocal(node.name, currentMember,
+          isRegularParameter: node.parent is ir.FunctionNode);
+      _locals.register<JLocal, LocalData>(local, new LocalData(node));
       return local;
     });
   }
 
   @override
-  ir.FunctionNode getFunctionNodeForParameter(covariant JParameter parameter) {
-    return _parameterList[parameter.parameterIndex].parent;
+  ir.FunctionNode getFunctionNodeForParameter(covariant JLocal parameter) {
+    return _locals.getData(parameter).functionNode;
   }
 
-  ir.DartType getParameterType(covariant JParameter parameter) {
-    return _parameterList[parameter.parameterIndex].type;
+  @override
+  DartType getLocalType(KernelToElementMap elementMap, covariant JLocal local) {
+    return _locals.getData(local).getDartType(elementMap);
   }
 
   @override
@@ -218,8 +226,6 @@
 
   @override
   visitBreakStatement(ir.BreakStatement node) {
-    // TODO(johnniwinther): Add labels if the enclosing loop is not the implicit
-    // break target.
     JJumpTarget target;
     ir.TreeNode body = node.target.body;
     ir.TreeNode parent = node.target.parent;
@@ -271,8 +277,17 @@
         label.isContinueTarget = true;
       }
     } else {
+      // We have code like
+      //
+      //     label: if (c) {
+      //         if (c < 10) break label;
+      //     }
+      //
+      // and label is therefore always needed.
       target = _getJumpTarget(node.target);
       target.isBreakTarget = true;
+      JLabelDefinition label = _getOrCreateLabel(target, node.target);
+      label.isBreakTarget = true;
     }
     jumpTargetMap[node] = target;
     super.visitBreakStatement(node);
@@ -314,9 +329,6 @@
   bool isContinueTarget = false;
 
   @override
-  Entity get executableContext => memberContext;
-
-  @override
   LabelDefinition<ir.Node> addLabel(ir.Node label, String labelName,
       {bool isBreakTarget: false, bool isContinueTarget: false}) {
     _labels ??= <LabelDefinition<ir.Node>>[];
@@ -382,17 +394,14 @@
   }
 }
 
-class JLocal implements Local {
+class JLocal extends IndexedLocal {
   final String name;
   final MemberEntity memberContext;
 
-  JLocal(this.name, this.memberContext);
-
   /// True if this local represents a local parameter.
-  bool get isRegularParameter => false;
+  final bool isRegularParameter;
 
-  @override
-  Entity get executableContext => memberContext;
+  JLocal(this.name, this.memberContext, {this.isRegularParameter: false});
 
   String get _kind => 'local';
 
@@ -411,13 +420,16 @@
   }
 }
 
-class JParameter extends JLocal {
-  final int parameterIndex;
+class LocalData {
+  final ir.VariableDeclaration node;
 
-  JParameter(this.parameterIndex, String name, MemberEntity memberContext)
-      : super(name, memberContext);
+  DartType _type;
 
-  bool get isRegularParameter => true;
+  LocalData(this.node);
 
-  String get _kind => 'parameter';
+  DartType getDartType(KernelToElementMap elementMap) {
+    return _type ??= elementMap.getDartType(node.type);
+  }
+
+  ir.FunctionNode get functionNode => node.parent;
 }
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index 27f83a5..80d50d5 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -18,6 +18,7 @@
 import '../js_emitter/code_emitter_task.dart';
 import '../js_model/closure.dart' show JRecordField, KernelScopeInfo;
 import '../native/native.dart' as native;
+import '../ssa/type_builder.dart';
 import '../types/types.dart';
 import '../universe/call_structure.dart';
 import '../universe/selector.dart';
@@ -28,6 +29,9 @@
   /// Access to the commonly used elements and types.
   CommonElements get commonElements;
 
+  /// Access to the [DartTypes] object.
+  DartTypes get types;
+
   /// Returns the [DartType] corresponding to [type].
   DartType getDartType(ir.DartType type);
 
@@ -179,6 +183,15 @@
   /// Returns the definition information for [member].
   MemberDefinition getMemberDefinition(covariant MemberEntity member);
 
+  /// Returns the type of `this` in [member], or `null` if member is defined in
+  /// a static context.
+  InterfaceType getMemberThisType(covariant MemberEntity member);
+
+  /// Returns how [member] has access to type variables of the this type
+  /// returned by [getMemberThisType].
+  ClassTypeVariableAccess getClassTypeVariableAccessForMember(
+      MemberEntity member);
+
   /// Returns the definition information for [cls].
   ClassDefinition getClassDefinition(covariant ClassEntity cls);
 
@@ -403,8 +416,8 @@
   /// Returns the [ir.FunctionNode] that declared [parameter].
   ir.FunctionNode getFunctionNodeForParameter(Local parameter);
 
-  /// Returns the [ir.DartType] of [parameter].
-  ir.DartType getParameterType(Local parameter);
+  /// Returns the [DartType] of [local].
+  DartType getLocalType(KernelToElementMap elementMap, Local local);
 
   /// Returns the [JumpTarget] for the break statement [node].
   JumpTarget getJumpTargetForBreak(ir.BreakStatement node);
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index a8ac5a0..aabdf9b 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -39,6 +39,7 @@
 import '../ordered_typeset.dart';
 import '../options.dart';
 import '../ssa/kernel_impact.dart';
+import '../ssa/type_builder.dart';
 import '../universe/class_set.dart';
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
@@ -137,6 +138,10 @@
           spannable.memberIndex < _members.length) {
         MemberData data = _members.getData(spannable);
         return data.definition.location;
+      } else if (spannable is KLocalFunction) {
+        return getSourceSpan(spannable.memberContext, currentElement);
+      } else if (spannable is JLocal) {
+        return getSourceSpan(spannable.memberContext, currentElement);
       }
       return null;
     }
@@ -1161,7 +1166,7 @@
         }
         if (parent is ir.FunctionDeclaration ||
             parent is ir.FunctionExpression) {
-          Local localFunction = getLocalFunction(parent);
+          KLocalFunction localFunction = getLocalFunction(parent);
           executableContext = localFunction;
           memberContext = localFunction.memberContext;
           break;
@@ -1439,7 +1444,7 @@
   @override
   FunctionType getFunctionTypeOfTypedef(TypedefEntity typedef) {
     // TODO(redemption): Support this.
-    throw new UnsupportedError('ElementEnvironment.getTypedefAlias');
+    throw new UnsupportedError('ElementEnvironment.getFunctionTypeOfTypedef');
   }
 }
 
@@ -1660,6 +1665,13 @@
 
   @override
   bool checkClass(ClassEntity cls) => true;
+
+  @override
+  void forEachLocalFunction(void f(MemberEntity member, Local localFunction)) {
+    for (KLocalFunction local in localFunctions) {
+      f(local.memberContext, local);
+    }
+  }
 }
 
 abstract class KernelClosedWorldMixin implements ClosedWorldBase {
@@ -1982,6 +1994,15 @@
     }
   }
 
+  InterfaceType getMemberThisType(MemberEntity member) {
+    return _members.getData(member).getMemberThisType(this);
+  }
+
+  ClassTypeVariableAccess getClassTypeVariableAccessForMember(
+      MemberEntity member) {
+    return _members.getData(member).classTypeVariableAccess;
+  }
+
   @override
   bool checkFamily(Entity entity) {
     assert(
@@ -2049,7 +2070,7 @@
       JConstructorBody constructorBody = createConstructorBody(constructor);
       _members.register<IndexedFunction, FunctionData>(
           constructorBody,
-          new FunctionDataImpl(
+          new ConstructorBodyDataImpl(
               node,
               node.function,
               new SpecialMemberDefinition(
@@ -2105,7 +2126,8 @@
     env.forEachConstructorBody(f);
   }
 
-  JRecordField _constructBoxedField(
+  JRecordField _constructRecordFieldEntry(
+      InterfaceType memberThisType,
       ir.VariableDeclaration variable,
       BoxLocal boxLocal,
       JClass container,
@@ -2116,11 +2138,13 @@
         new JRecordField(local.name, boxLocal, container, variable.isConst);
     _members.register(
         boxedField,
-        new ClosureFieldData(new ClosureMemberDefinition(
-            boxedField,
-            computeSourceSpanFromTreeNode(variable),
-            MemberKind.closureField,
-            variable)));
+        new ClosureFieldData(
+            new ClosureMemberDefinition(
+                boxedField,
+                computeSourceSpanFromTreeNode(variable),
+                MemberKind.closureField,
+                variable),
+            memberThisType));
     memberMap[boxedField.name] = boxedField;
 
     return boxedField;
@@ -2152,25 +2176,43 @@
       containerData.orderedTypeSet = setBuilder.createOrderedTypeSet(
           containerData.supertype, const Link<InterfaceType>());
 
-      BoxLocal boxLocal = new BoxLocal(box.name, member);
+      BoxLocal boxLocal = new BoxLocal(box.name);
+      InterfaceType memberThisType = member.enclosingClass != null
+          ? _elementEnvironment.getThisType(member.enclosingClass)
+          : null;
       for (ir.VariableDeclaration variable in info.boxedVariables) {
         boxedFields[localsMap.getLocalVariable(variable)] =
-            _constructBoxedField(
-                variable, boxLocal, container, memberMap, localsMap);
+            _constructRecordFieldEntry(memberThisType, variable, boxLocal,
+                container, memberMap, localsMap);
       }
     }
     return boxedFields;
   }
 
+  bool _isInRecord(
+          Local local, Map<Local, JRecordField> recordFieldsVisibleInScope) =>
+      recordFieldsVisibleInScope.containsKey(local);
+
   KernelClosureClass constructClosureClass(
       MemberEntity member,
       ir.FunctionNode node,
       JLibrary enclosingLibrary,
-      Map<Local, JRecordField> boxedCapturedVariables,
+      Map<Local, JRecordField> recordFieldsVisibleInScope,
       KernelScopeInfo info,
       ir.Location location,
       KernelToLocalsMap localsMap,
       InterfaceType supertype) {
+    InterfaceType memberThisType = member.enclosingClass != null
+        ? _elementEnvironment.getThisType(member.enclosingClass)
+        : null;
+    ClassTypeVariableAccess typeVariableAccess =
+        _members.getData(member).classTypeVariableAccess;
+    if (typeVariableAccess == ClassTypeVariableAccess.instanceField) {
+      // A closure in a field initializer will only be executed in the
+      // constructor and type variables are therefore accessed through
+      // parameters.
+      typeVariableAccess = ClassTypeVariableAccess.parameter;
+    }
     String name = _computeClosureName(node);
     SourceSpan location = computeSourceSpanFromTreeNode(node);
     Map<String, MemberEntity> memberMap = <String, MemberEntity>{};
@@ -2198,8 +2240,6 @@
     } else if (node.parent is ir.FunctionExpression) {
       closureEntity = new JLocal('', localsMap.currentMember);
     }
-    Local thisLocal =
-        info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null;
 
     KernelClosureClass cls = new KernelClosureClass.fromScopeInfo(
         classEntity,
@@ -2208,40 +2248,9 @@
         info,
         localsMap,
         closureEntity,
-        thisLocal);
-    int fieldNumber = 0;
-    for (ir.VariableDeclaration variable in info.freeVariables) {
-      // Make a corresponding field entity in this closure class for every
-      // single freeVariable in the KernelScopeInfo.freeVariable.
-      _constructClosureField(
-          member,
-          cls,
-          memberMap,
-          localsMap.getLocalVariable(variable),
-          variable,
-          variable.isConst,
-          !(variable.isFinal || variable.isConst),
-          boxedCapturedVariables,
-          fieldNumber,
-          info.capturedVariablesAccessor,
-          localsMap);
-      fieldNumber++;
-    }
-    if (info.thisUsedAsFreeVariable) {
-      _constructClosureField(
-          member,
-          cls,
-          memberMap,
-          cls.thisLocal,
-          getMemberDefinition(member).node,
-          true,
-          false,
-          boxedCapturedVariables,
-          fieldNumber,
-          info.capturedVariablesAccessor,
-          localsMap);
-      fieldNumber++;
-    }
+        info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null);
+    _buildClosureClassFields(cls, member, memberThisType, info, localsMap,
+        recordFieldsVisibleInScope, memberMap);
 
     FunctionEntity callMethod = new JClosureCallMethod(
         cls, _getParameterStructure(node), _getAsyncMarker(node));
@@ -2250,28 +2259,111 @@
         new ClosureFunctionData(
             new ClosureMemberDefinition(
                 callMethod, location, MemberKind.closureCall, node.parent),
+            memberThisType,
             getFunctionType(node),
-            node));
+            node,
+            typeVariableAccess));
     memberMap[callMethod.name] = cls.callMethod = callMethod;
     return cls;
   }
 
-  _constructClosureField(
-      MemberEntity member,
-      KernelClosureClass cls,
-      Map<String, MemberEntity> memberMap,
+  void _buildClosureClassFields(
+    KernelClosureClass cls,
+    MemberEntity member,
+    InterfaceType memberThisType,
+    KernelScopeInfo info,
+    KernelToLocalsMap localsMap,
+    Map<Local, JRecordField> recordFieldsVisibleInScope,
+    Map<String, MemberEntity> memberMap,
+  ) {
+    // TODO(efortuna): Limit field number usage to when we need to distinguish
+    // between two variables with the same name from different scopes.
+    int fieldNumber = 0;
+    for (ir.VariableDeclaration variable in info.freeVariables) {
+      // Make a corresponding field entity in this closure class for the
+      // free variables in the KernelScopeInfo.freeVariable.
+      Local capturedLocal = localsMap.getLocalVariable(variable);
+      if (_isInRecord(capturedLocal, recordFieldsVisibleInScope)) {
+        bool constructedField = _constructClosureFieldForRecord(
+            capturedLocal,
+            cls,
+            memberThisType,
+            memberMap,
+            variable,
+            recordFieldsVisibleInScope,
+            fieldNumber);
+        if (constructedField) fieldNumber++;
+      } else {
+        _constructClosureField(
+            capturedLocal,
+            cls,
+            memberThisType,
+            memberMap,
+            variable,
+            variable.isConst,
+            !(variable.isFinal || variable.isConst),
+            fieldNumber);
+        fieldNumber++;
+      }
+    }
+    if (info.thisUsedAsFreeVariable) {
+      _constructClosureField(cls.thisLocal, cls, memberThisType, memberMap,
+          getMemberDefinition(member).node, true, false, fieldNumber);
+      fieldNumber++;
+    }
+  }
+
+  /// Records point to one or more local variables declared in another scope
+  /// that are captured in a scope. Access to those variables goes entirely
+  /// through the record container, so we only create a field for the *record*
+  /// holding [capturedLocal] and not the individual local variables accessed
+  /// through the record. Records, by definition, are not mutable (though the
+  /// locals they contain may be). Returns `true` if we constructed a new field
+  /// in the closure class.
+  bool _constructClosureFieldForRecord(
       Local capturedLocal,
+      KernelClosureClass cls,
+      InterfaceType memberThisType,
+      Map<String, MemberEntity> memberMap,
+      ir.TreeNode sourceNode,
+      Map<Local, JRecordField> recordFieldsVisibleInScope,
+      int fieldNumber) {
+    JRecordField recordField = recordFieldsVisibleInScope[capturedLocal];
+
+    // Don't construct a new field if the box that holds this local already has
+    // a field in the closure class.
+    if (cls.localToFieldMap.containsKey(recordField.box)) {
+      cls.boxedVariables[capturedLocal] = recordField;
+      return false;
+    }
+
+    FieldEntity closureField =
+        new JClosureField('_box_$fieldNumber', cls, true, false);
+
+    _members.register<IndexedField, FieldData>(
+        closureField,
+        new ClosureFieldData(
+            new ClosureMemberDefinition(
+                cls.localToFieldMap[capturedLocal],
+                computeSourceSpanFromTreeNode(sourceNode),
+                MemberKind.closureField,
+                sourceNode),
+            memberThisType));
+    memberMap[closureField.name] = closureField;
+    cls.localToFieldMap[recordField.box] = closureField;
+    cls.boxedVariables[capturedLocal] = recordField;
+    return true;
+  }
+
+  _constructClosureField(
+      Local capturedLocal,
+      KernelClosureClass cls,
+      InterfaceType memberThisType,
+      Map<String, MemberEntity> memberMap,
       ir.TreeNode sourceNode,
       bool isConst,
       bool isAssignable,
-      Map<Local, JRecordField> boxedCapturedVariables,
-      int fieldNumber,
-      NodeBox box,
-      KernelToLocalsMap localsMap) {
-    // NOTE: This construction *order* may be slightly different than the
-    // old Element version. The old version did all the boxed items and then
-    // all the others.
-    JRecordField field = boxedCapturedVariables[capturedLocal];
+      int fieldNumber) {
     FieldEntity closureField = new JClosureField(
         _getClosureVariableName(capturedLocal.name, fieldNumber),
         cls,
@@ -2280,18 +2372,15 @@
 
     _members.register<IndexedField, FieldData>(
         closureField,
-        new ClosureFieldData(new ClosureMemberDefinition(
-            cls.localToFieldMap[capturedLocal],
-            computeSourceSpanFromTreeNode(sourceNode),
-            MemberKind.closureField,
-            sourceNode)));
+        new ClosureFieldData(
+            new ClosureMemberDefinition(
+                cls.localToFieldMap[capturedLocal],
+                computeSourceSpanFromTreeNode(sourceNode),
+                MemberKind.closureField,
+                sourceNode),
+            memberThisType));
     memberMap[closureField.name] = closureField;
-    if (boxedCapturedVariables.containsKey(capturedLocal)) {
-      cls.localToFieldMap[field.box] = closureField;
-      cls.boxedVariables[capturedLocal] = field;
-    } else {
-      cls.localToFieldMap[capturedLocal] = closureField;
-    }
+    cls.localToFieldMap[capturedLocal] = closureField;
   }
 
   // Returns a non-unique name for the given closure element.
diff --git a/pkg/compiler/lib/src/kernel/element_map_mixins.dart b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
index fd1df4f..d997a6a 100644
--- a/pkg/compiler/lib/src/kernel/element_map_mixins.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
@@ -105,14 +105,29 @@
     return node.importUri == Uris.dart__foreign_helper;
   }
 
-  /// Looks up [typeName] for use in the spec-string of a `JS` called.
+  /// Looks up [typeName] for use in the spec-string of a `JS` call.
   // TODO(johnniwinther): Use this in [native.NativeBehavior] instead of calling
   // the `ForeignResolver`.
-  // TODO(johnniwinther): Cache the result to avoid redundant lookups?
   native.TypeLookup typeLookup({bool resolveAsRaw: true}) {
+    return resolveAsRaw
+        ? (_cachedTypeLookupRaw ??= _typeLookup(resolveAsRaw: true))
+        : (_cachedTypeLookupFull ??= _typeLookup(resolveAsRaw: false));
+  }
+
+  native.TypeLookup _cachedTypeLookupRaw;
+  native.TypeLookup _cachedTypeLookupFull;
+
+  native.TypeLookup _typeLookup({bool resolveAsRaw: true}) {
+    bool cachedMayLookupInMain;
+    bool mayLookupInMain() {
+      var mainUri = elementEnvironment.mainLibrary.canonicalUri;
+      // Tests permit lookup outside of dart: libraries.
+      return mainUri.path.contains('sdk/tests/compiler/dart2js_native') ||
+          mainUri.path.contains('sdk/tests/compiler/dart2js_extra');
+    }
+
     DartType lookup(String typeName, {bool required}) {
-      DartType findIn(Uri uri) {
-        LibraryEntity library = elementEnvironment.lookupLibrary(uri);
+      DartType findInLibrary(LibraryEntity library) {
         if (library != null) {
           ClassEntity cls = elementEnvironment.lookupClass(library, typeName);
           if (cls != null) {
@@ -125,9 +140,18 @@
         return null;
       }
 
-      // TODO(johnniwinther): Narrow the set of lookups base on the depending
+      DartType findIn(Uri uri) {
+        return findInLibrary(elementEnvironment.lookupLibrary(uri));
+      }
+
+      // TODO(johnniwinther): Narrow the set of lookups based on the depending
       // library.
-      DartType type = findIn(Uris.dart_core);
+      // TODO(johnniwinther): Cache more results to avoid redundant lookups?
+      DartType type;
+      if (cachedMayLookupInMain ??= mayLookupInMain()) {
+        type ??= findInLibrary(elementEnvironment.mainLibrary);
+      }
+      type ??= findIn(Uris.dart_core);
       type ??= findIn(Uris.dart__js_helper);
       type ??= findIn(Uris.dart__interceptors);
       type ??= findIn(Uris.dart__isolate_helper);
@@ -455,6 +479,7 @@
 class Constantifier extends ir.ExpressionVisitor<ConstantExpression> {
   final bool requireConstant;
   final KernelToElementMapBaseMixin elementMap;
+  ir.TreeNode failNode;
 
   Constantifier(this.elementMap, {this.requireConstant: true});
 
@@ -463,16 +488,17 @@
   ConstantExpression visit(ir.Expression node) {
     ConstantExpression constant = node.accept(this);
     if (constant == null && requireConstant) {
-      throw new UnsupportedError(
-          "No constant computed for $node (${node.runtimeType})");
+      elementMap.reporter.reportErrorMessage(
+          computeSourceSpanFromTreeNode(failNode ?? node),
+          MessageKind.NOT_A_COMPILE_TIME_CONSTANT);
+      return new NullConstantExpression();
     }
     return constant;
   }
 
   ConstantExpression defaultExpression(ir.Expression node) {
     if (requireConstant) {
-      throw new UnimplementedError(
-          'Unimplemented constant expression $node (${node.runtimeType})');
+      failNode ??= node;
     }
     return null;
   }
@@ -672,8 +698,8 @@
   @override
   ConstantExpression visitPropertyGet(ir.PropertyGet node) {
     if (node.name.name != 'length') {
-      throw new UnimplementedError(
-          'Unexpected constant expression $node (${node.runtimeType})');
+      failNode ??= node;
+      return null;
     }
     ConstantExpression receiver = visit(node.receiver);
     if (receiver == null) return null;
@@ -751,7 +777,8 @@
   @override
   ConstantExpression visitLogicalExpression(ir.LogicalExpression node) {
     BinaryOperator operator = BinaryOperator.parse(node.operator);
-    if (operator != null) {
+    if (operator != null &&
+        BinaryConstantExpression.potentialOperator(operator)) {
       ConstantExpression left = visit(node.left);
       if (left == null) return null;
       ConstantExpression right = visit(node.right);
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 2ee702c2..26d8f27 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -4,6 +4,7 @@
 
 library dart2js.kernel.env;
 
+import 'package:front_end/src/fasta/kernel/redirecting_factory_body.dart' as ir;
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/clone.dart';
 import 'package:kernel/type_algebra.dart';
@@ -15,6 +16,7 @@
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../ordered_typeset.dart';
+import '../ssa/type_builder.dart';
 import 'element_map.dart';
 import 'element_map_impl.dart';
 import 'element_map_mixins.dart';
@@ -270,9 +272,15 @@
             // Skip synthetic .dill members.
             continue;
           }
-          if (member is ir.Constructor ||
-              member is ir.Procedure &&
-                  member.kind == ir.ProcedureKind.Factory) {
+          if (member is ir.Constructor) {
+            if (!includeStatic) continue;
+            _constructorMap[member.name.name] = member;
+          } else if (member is ir.Procedure &&
+              member.kind == ir.ProcedureKind.Factory) {
+            if (member.function.body is ir.RedirectingFactoryBody) {
+              // Don't include redirecting factories.
+              continue;
+            }
             if (!includeStatic) continue;
             _constructorMap[member.name.name] = member;
           } else if (member is ir.Procedure) {
@@ -470,9 +478,13 @@
   MemberDefinition get definition;
 
   Iterable<ConstantValue> getMetadata(KernelToElementMap elementMap);
+
+  InterfaceType getMemberThisType(KernelToElementMapForBuilding elementMap);
+
+  ClassTypeVariableAccess get classTypeVariableAccess;
 }
 
-class MemberDataImpl implements MemberData {
+abstract class MemberDataImpl implements MemberData {
   /// TODO(johnniwinther): Remove this from the [MemberData] interface. Use
   /// `definition.node` instead.
   final ir.Member node;
@@ -488,9 +500,16 @@
     return _metadata ??= elementMap.getMetadata(node.annotations);
   }
 
-  MemberData copy() {
-    return new MemberDataImpl(node, definition);
+  InterfaceType getMemberThisType(KernelToElementMapForBuilding elementMap) {
+    MemberEntity member = elementMap.getMember(node);
+    ClassEntity cls = member.enclosingClass;
+    if (cls != null) {
+      return elementMap.elementEnvironment.getThisType(cls);
+    }
+    return null;
   }
+
+  MemberData copy();
 }
 
 abstract class FunctionData implements MemberData {
@@ -530,7 +549,7 @@
 
     for (int i = 0; i < functionNode.positionalParameters.length; i++) {
       handleParameter(functionNode.positionalParameters[i],
-          isOptional: i < functionNode.requiredParameterCount);
+          isOptional: i >= functionNode.requiredParameterCount);
     }
     functionNode.namedParameters.toList()
       ..sort(namedOrdering)
@@ -541,6 +560,12 @@
   FunctionData copy() {
     return new FunctionDataImpl(node, functionNode, definition);
   }
+
+  @override
+  ClassTypeVariableAccess get classTypeVariableAccess {
+    if (node.isInstanceMember) return ClassTypeVariableAccess.property;
+    return ClassTypeVariableAccess.none;
+  }
 }
 
 abstract class ConstructorData extends FunctionData {
@@ -576,6 +601,22 @@
   ConstructorData copy() {
     return new ConstructorDataImpl(node, functionNode, definition);
   }
+
+  @override
+  ClassTypeVariableAccess get classTypeVariableAccess =>
+      ClassTypeVariableAccess.parameter;
+}
+
+class ConstructorBodyDataImpl extends FunctionDataImpl {
+  ConstructorBodyDataImpl(
+      ir.Member node, ir.FunctionNode functionNode, MemberDefinition definition)
+      : super(node, functionNode, definition);
+
+  // TODO(johnniwinther,sra): Constructor bodies should access type variables
+  // through `this`.
+  @override
+  ClassTypeVariableAccess get classTypeVariableAccess =>
+      ClassTypeVariableAccess.parameter;
 }
 
 abstract class FieldData extends MemberData {
@@ -650,6 +691,12 @@
   }
 
   @override
+  ClassTypeVariableAccess get classTypeVariableAccess {
+    if (node.isInstanceMember) return ClassTypeVariableAccess.instanceField;
+    return ClassTypeVariableAccess.none;
+  }
+
+  @override
   FieldData copy() {
     return new FieldDataImpl(node, definition);
   }
diff --git a/pkg/compiler/lib/src/kernel/indexed.dart b/pkg/compiler/lib/src/kernel/indexed.dart
index ba81fc4..bf7be15 100644
--- a/pkg/compiler/lib/src/kernel/indexed.dart
+++ b/pkg/compiler/lib/src/kernel/indexed.dart
@@ -44,6 +44,10 @@
   int get typedefIndex => _index;
 }
 
+abstract class IndexedLocal extends _Indexed implements Local {
+  int get localIndex => _index;
+}
+
 /// Base implementation for an index based map of entities of type [E].
 abstract class EntityMapBase<E extends _Indexed> {
   List<E> _list = <E>[];
diff --git a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
index 8ced1c7..f670224 100644
--- a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
@@ -96,10 +96,11 @@
     KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(work.element);
     KernelSsaGraphBuilder builder = new KernelSsaGraphBuilder(
         work.element,
-        work.element.enclosingClass,
+        _elementMap.getMemberThisType(work.element),
         _compiler,
         _elementMap,
-        new KernelToTypeInferenceMapImpl(closedWorld),
+        new KernelToTypeInferenceMapImpl(
+            work.element, _compiler.globalInference.results),
         localsMap,
         closedWorld,
         _compiler.codegenWorldBuilder,
@@ -114,88 +115,102 @@
 }
 
 class KernelToTypeInferenceMapImpl implements KernelToTypeInferenceMap {
-  final ClosedWorld _closedWorld;
+  final GlobalTypeInferenceResults _globalInferenceResults;
+  GlobalTypeInferenceElementResult _targetResults;
 
-  KernelToTypeInferenceMapImpl(this._closedWorld);
+  KernelToTypeInferenceMapImpl(
+      MemberEntity target, this._globalInferenceResults) {
+    _targetResults = _resultOf(target);
+  }
 
-  @override
+  GlobalTypeInferenceElementResult _resultOf(MemberEntity e) =>
+      _globalInferenceResults
+          .resultOfMember(e is ConstructorBodyEntity ? e.constructor : e);
+
+  TypeMask getReturnTypeOf(FunctionEntity function) {
+    return TypeMaskFactory.inferredReturnTypeForElement(
+        function, _globalInferenceResults);
+  }
+
+  TypeMask typeOfInvocation(ir.MethodInvocation node, ClosedWorld closedWorld) {
+    return _targetResults.typeOfSend(node);
+  }
+
+  TypeMask typeOfGet(ir.PropertyGet node) {
+    return _targetResults.typeOfSend(node);
+  }
+
+  TypeMask typeOfSet(ir.PropertySet node, ClosedWorld closedWorld) {
+    return closedWorld.commonMasks.dynamicType;
+  }
+
+  TypeMask typeOfListLiteral(
+      MemberEntity owner, ir.ListLiteral listLiteral, ClosedWorld closedWorld) {
+    return _resultOf(owner).typeOfListLiteral(listLiteral) ??
+        closedWorld.commonMasks.dynamicType;
+  }
+
+  TypeMask typeOfIterator(ir.ForInStatement node) {
+    return _targetResults.typeOfIterator(node);
+  }
+
+  TypeMask typeOfIteratorCurrent(ir.ForInStatement node) {
+    return _targetResults.typeOfIteratorCurrent(node);
+  }
+
+  TypeMask typeOfIteratorMoveNext(ir.ForInStatement node) {
+    return _targetResults.typeOfIteratorMoveNext(node);
+  }
+
+  bool isJsIndexableIterator(ir.ForInStatement node, ClosedWorld closedWorld) {
+    TypeMask mask = typeOfIterator(node);
+    return mask != null &&
+        mask.satisfies(
+            closedWorld.commonElements.jsIndexableClass, closedWorld) &&
+        // String is indexable but not iterable.
+        !mask.satisfies(closedWorld.commonElements.jsStringClass, closedWorld);
+  }
+
+  bool isFixedLength(TypeMask mask, ClosedWorld closedWorld) {
+    if (mask.isContainer && (mask as ContainerTypeMask).length != null) {
+      // A container on which we have inferred the length.
+      return true;
+    }
+    // TODO(sra): Recognize any combination of fixed length indexables.
+    if (mask.containsOnly(closedWorld.commonElements.jsFixedArrayClass) ||
+        mask.containsOnly(
+            closedWorld.commonElements.jsUnmodifiableArrayClass) ||
+        mask.containsOnlyString(closedWorld) ||
+        closedWorld.commonMasks.isTypedArray(mask)) {
+      return true;
+    }
+    return false;
+  }
+
+  TypeMask inferredIndexType(ir.ForInStatement node) {
+    return TypeMaskFactory.inferredTypeForSelector(
+        new Selector.index(), typeOfIterator(node), _globalInferenceResults);
+  }
+
+  TypeMask getInferredTypeOf(MemberEntity member) {
+    return TypeMaskFactory.inferredTypeForMember(
+        member, _globalInferenceResults);
+  }
+
+  TypeMask getInferredTypeOfParameter(Local parameter) {
+    return TypeMaskFactory.inferredTypeForParameter(
+        parameter, _globalInferenceResults);
+  }
+
+  TypeMask selectorTypeOf(Selector selector, TypeMask mask) {
+    return TypeMaskFactory.inferredTypeForSelector(
+        selector, mask, _globalInferenceResults);
+  }
+
   TypeMask typeFromNativeBehavior(
       NativeBehavior nativeBehavior, ClosedWorld closedWorld) {
     return TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld);
   }
-
-  @override
-  TypeMask selectorTypeOf(Selector selector, TypeMask mask) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
-
-  @override
-  TypeMask getInferredTypeOf(MemberEntity member) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
-
-  @override
-  TypeMask getInferredTypeOfParameter(Local parameter) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
-
-  @override
-  TypeMask inferredIndexType(ir.ForInStatement forInStatement) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
-
-  @override
-  bool isJsIndexableIterator(
-      ir.ForInStatement forInStatement, ClosedWorld closedWorld) {
-    return false;
-  }
-
-  @override
-  bool isFixedLength(TypeMask mask, ClosedWorld closedWorld) {
-    return false;
-  }
-
-  @override
-  TypeMask typeOfIteratorMoveNext(ir.ForInStatement forInStatement) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
-
-  @override
-  TypeMask typeOfIteratorCurrent(ir.ForInStatement forInStatement) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
-
-  @override
-  TypeMask typeOfIterator(ir.ForInStatement forInStatement) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
-
-  @override
-  TypeMask typeOfListLiteral(
-      MemberEntity owner, ir.ListLiteral listLiteral, ClosedWorld closedWorld) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
-
-  @override
-  TypeMask typeOfSet(ir.PropertySet write, ClosedWorld closedWorld) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
-
-  @override
-  TypeMask typeOfGet(ir.PropertyGet read) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
-
-  @override
-  TypeMask typeOfInvocation(
-      ir.MethodInvocation invocation, ClosedWorld closedWorld) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
-
-  @override
-  TypeMask getReturnTypeOf(FunctionEntity function) {
-    return _closedWorld.commonMasks.dynamicType;
-  }
 }
 
 class KernelSorter implements Sorter {
@@ -222,28 +237,11 @@
 
   @override
   Iterable<MemberEntity> sortMembers(Iterable<MemberEntity> members) {
-    return members.toList()
-      ..sort((MemberEntity member1, MemberEntity member2) {
-        int r = _compareLibraries(member1.library, member2.library);
-        if (r != 0) return r;
-        MemberDefinition definition1 = elementMap.getMemberDefinition(member1);
-        MemberDefinition definition2 = elementMap.getMemberDefinition(member2);
-        return _compareSourceSpans(
-            member1, definition1.location, member2, definition2.location);
-      });
+    return members.toList()..sort(compareMembersByLocation);
   }
 
   @override
   Iterable<ClassEntity> sortClasses(Iterable<ClassEntity> classes) {
-    int compareClasses(ClassEntity cls1, ClassEntity cls2) {
-      int r = _compareLibraries(cls1.library, cls2.library);
-      if (r != 0) return r;
-      ClassDefinition definition1 = elementMap.getClassDefinition(cls1);
-      ClassDefinition definition2 = elementMap.getClassDefinition(cls2);
-      return _compareSourceSpans(
-          cls1, definition1.location, cls2, definition2.location);
-    }
-
     List<ClassEntity> regularClasses = <ClassEntity>[];
     List<ClassEntity> unnamedMixins = <ClassEntity>[];
     for (ClassEntity cls in classes) {
@@ -254,7 +252,7 @@
       }
     }
     List<ClassEntity> sorted = <ClassEntity>[];
-    regularClasses.sort(compareClasses);
+    regularClasses.sort(compareClassesByLocation);
     sorted.addAll(regularClasses);
     unnamedMixins.sort((a, b) {
       int result = _compareLibraries(a.library, b.library);
@@ -274,4 +272,36 @@
     assert(typedefs.isEmpty);
     return typedefs;
   }
+
+  @override
+  int compareLibrariesByLocation(LibraryEntity a, LibraryEntity b) {
+    return _compareLibraries(a, b);
+  }
+
+  @override
+  int compareClassesByLocation(ClassEntity a, ClassEntity b) {
+    int r = _compareLibraries(a.library, b.library);
+    if (r != 0) return r;
+    ClassDefinition definition1 = elementMap.getClassDefinition(a);
+    ClassDefinition definition2 = elementMap.getClassDefinition(b);
+    return _compareSourceSpans(
+        a, definition1.location, b, definition2.location);
+  }
+
+  @override
+  int compareTypedefsByLocation(TypedefEntity a, TypedefEntity b) {
+    // TODO(redemption): Support this.
+    failedAt(a, 'KernelSorter.compareTypedefsByLocation unimplemented');
+    return 0;
+  }
+
+  @override
+  int compareMembersByLocation(MemberEntity a, MemberEntity b) {
+    int r = _compareLibraries(a.library, b.library);
+    if (r != 0) return r;
+    MemberDefinition definition1 = elementMap.getMemberDefinition(a);
+    MemberDefinition definition2 = elementMap.getMemberDefinition(b);
+    return _compareSourceSpans(
+        a, definition1.location, b, definition2.location);
+  }
 }
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 1f18433..3b23db7 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -97,6 +97,8 @@
   /// [handleInvalidFunctionBody] which is called immediately after.
   bool lastErrorWasNativeFunctionBody = false;
 
+  LiteralString nativeName;
+
   ElementListener(this.scannerOptions, DiagnosticReporter reporter,
       this.compilationUnitElement, this.idGenerator)
       : this.reporter = reporter,
@@ -178,7 +180,8 @@
   }
 
   @override
-  void endConditionalUri(Token ifToken, Token equalSign) {
+  void endConditionalUri(
+      Token ifToken, Token leftParen, Token equalSign, Token rightParen) {
     StringNode uri = popNode();
     LiteralString conditionValue = (equalSign != null) ? popNode() : null;
     DottedName identifier = popNode();
@@ -244,7 +247,8 @@
   }
 
   @override
-  void endPartOf(Token partKeyword, Token semicolon, bool hasName) {
+  void endPartOf(
+      Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
     Expression name = popNode();
     addPartOfTag(
         new PartOf(partKeyword, name, popMetadata(compilationUnitElement)));
@@ -279,11 +283,7 @@
   }
 
   @override
-  void handleNativeClause(Token nativeToken, bool hasName) {
-    if (hasName) {
-      popNode(); // Pop the native clause which in this case is a StringLiteral.
-    }
-  }
+  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {}
 
   @override
   void endClassDeclaration(
@@ -527,6 +527,10 @@
 
   @override
   void handleRecoverableError(Token token, Message message) {
+    if (message == codes.messageNativeClauseShouldBeAnnotation) {
+      native.checkAllowedLibrary(this, token);
+      return;
+    }
     handleError(token, message);
   }
 
@@ -552,7 +556,7 @@
     switch (message.code.dart2jsCode) {
       case "MISSING_TOKEN_BEFORE_THIS":
         String expected = arguments["string"];
-        // TODO(danrubel) This functionality is being replaced by
+        // TODO(danrubel): This functionality is being replaced by
         // the parser's ensureSemicolon method.
         if (identical(";", expected)) {
           // When a semicolon is missing, it often leads to an error on the
@@ -874,14 +878,14 @@
   }
 
   @override
-  void endLiteralString(int count, Token endToken) {
+  void endLiteralString(int interpolationCount, Token endToken) {
     StringQuoting quoting = popQuoting();
 
     Link<StringInterpolationPart> parts = const Link<StringInterpolationPart>();
     // Parts of the string interpolation are popped in reverse order,
     // starting with the last literal string part.
     bool isLast = true;
-    for (int i = 0; i < count; i++) {
+    for (int i = 0; i < interpolationCount; i++) {
       LiteralString string = popNode();
       DartString validation = stringValidator.validateInterpolationPart(
           string.token, quoting,
@@ -908,6 +912,15 @@
   }
 
   @override
+  void handleNativeClause(Token nativeToken, bool hasName) {
+    if (hasName) {
+      nativeName = popNode(); // LiteralString
+    } else {
+      nativeName = null;
+    }
+  }
+
+  @override
   void handleStringJuxtaposition(int stringCount) {
     assert(stringCount != 0);
     Expression accumulator = popNode();
diff --git a/pkg/compiler/lib/src/parser/node_listener.dart b/pkg/compiler/lib/src/parser/node_listener.dart
index f297808..27144d0 100644
--- a/pkg/compiler/lib/src/parser/node_listener.dart
+++ b/pkg/compiler/lib/src/parser/node_listener.dart
@@ -91,7 +91,8 @@
   }
 
   @override
-  void endPartOf(Token partKeyword, Token semicolon, bool hasName) {
+  void endPartOf(
+      Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
     Expression name = popNode(); // name
     pushNode(new PartOf(
         partKeyword,
@@ -319,6 +320,12 @@
     pushNode(new RedirectingFactoryBody(beginToken, endToken, popNode()));
   }
 
+  @override
+  void handleNativeFunctionBody(Token nativeToken, Token semicolon) {
+    pushNode(new Return(nativeToken, semicolon, nativeName));
+  }
+
+  @override
   void handleEmptyFunctionBody(Token semicolon) {
     endBlockFunctionBody(0, null, semicolon);
   }
@@ -377,7 +384,7 @@
   }
 
   @override
-  void handleBinaryExpression(Token token) {
+  void endBinaryExpression(Token token) {
     Node argument = popNode();
     Node receiver = popNode();
     String tokenString = token.stringValue;
@@ -500,6 +507,14 @@
   }
 
   @override
+  void handleNativeFunctionBodyIgnored(Token nativeToken, Token semicolon) {}
+
+  @override
+  void handleNativeFunctionBodySkipped(Token nativeToken, Token semicolon) {
+    pushNode(new Block(new NodeList.empty()));
+  }
+
+  @override
   void handleNoFunctionBody(Token token) {
     pushNode(new EmptyStatement(token));
   }
@@ -852,7 +867,7 @@
   }
 
   @override
-  void handleCatchBlock(Token onKeyword, Token catchKeyword) {
+  void handleCatchBlock(Token onKeyword, Token catchKeyword, Token comma) {
     Block block = popNode();
     NodeList formals = catchKeyword != null ? popNode() : null;
     TypeAnnotation type = onKeyword != null ? popNode() : null;
@@ -961,7 +976,7 @@
   }
 
   @override
-  void endMetadataStar(int count, bool forParameter) {
+  void endMetadataStar(int count) {
     if (0 == count) {
       pushNode(null);
     } else {
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
index 8bce3ca..7eec9b8 100644
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -304,6 +304,7 @@
   ResolutionDartType createMixinsOptimized(
       BaseClassElementX element, MixinApplication superMixin,
       {bool isNamed: false}) {
+    List<ResolutionDartType> typeVariables = element.typeVariables;
     LibraryElementX library = element.library;
     Map<String, MixinApplicationElementX> mixinApplicationClasses =
         library.mixinApplicationCache;
@@ -374,7 +375,7 @@
             var argument = type.typeArguments[i];
             String name;
             if (argument is ResolutionTypeVariableType) {
-              int index = element.typeVariables.indexOf(argument) ?? -1;
+              int index = typeVariables.indexOf(argument) ?? -1;
               if (index != -1) {
                 name = "#T${index}";
               }
@@ -413,8 +414,15 @@
       int index = 0;
       for (List<String> strings in currentSignatureParts) {
         for (String name in strings) {
-          variables[name] ??= new ResolutionTypeVariableType(
-              new TypeVariableElementX(name, cls, index++, node));
+          variables.putIfAbsent(name, () {
+            ResolutionTypeVariableType typeVariable =
+                new ResolutionTypeVariableType(
+                    new TypeVariableElementX(name, cls, index++, node));
+            TypeVariableElementX typeVariableElement = typeVariable.element;
+            typeVariableElement.typeCache = typeVariable;
+            typeVariableElement.boundCache = const ResolutionDynamicType();
+            return typeVariable;
+          });
         }
       }
       return variables;
@@ -436,7 +444,7 @@
       ResolutionInterfaceType createMixinApplication() {
         Map<String, ResolutionDartType> variables;
         MixinApplicationElementX mixinElement;
-        ResolutionInterfaceType mixinType;
+        ResolutionDartType mixinType;
         if (lastAndNamed) {
           mixinElement = element;
           variables = freeTypes;
@@ -488,8 +496,11 @@
       supertype = createMixinApplication();
     }
 
-    return new ResolutionInterfaceType(
-        supertype.element, freeTypes.values.toList());
+    if (!isNamed) {
+      typeVariables = freeTypes.values.toList();
+    }
+
+    return new ResolutionInterfaceType(supertype.element, typeVariables);
   }
 
   ResolutionDartType createMixins(ClassElement element, MixinApplication node,
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 99e4431..8f9bbcf 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -449,6 +449,19 @@
     if (!resolvedSuper) {
       constructorInvocation = resolveImplicitSuperConstructorSend();
     }
+    constructor.enclosingClass
+        .forEachInstanceField((ClassElement declarer, FieldElement field) {
+      if (declarer != constructor.enclosingClass) return;
+
+      if (!initialized.containsKey(field)) {
+        visitor.resolution.ensureResolved(field);
+        if (field.isFinal && field.initializer == null) {
+          registry.registerStaticUse(new StaticUse.fieldInit(field));
+          registry.registerConstantLiteral(new NullConstantExpression());
+        }
+      }
+    });
+
     if (isConst && isValidAsConstant) {
       constructor.enclosingClass.forEachInstanceField((_, FieldElement field) {
         if (!fieldInitializers.containsKey(field)) {
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index f0740c7..e6dff35 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -443,7 +443,8 @@
             element.constant = result.constant;
           }
         } else {
-          element.constant = new NullConstantExpression();
+          registry.registerConstantLiteral(
+              element.constant = new NullConstantExpression());
         }
       }
       VariableDefinitions variableDefinitions = parameterNodes.head;
diff --git a/pkg/compiler/lib/src/resolution/resolution_strategy.dart b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
index 83d4aaf..2c8c8b4 100644
--- a/pkg/compiler/lib/src/resolution/resolution_strategy.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
@@ -371,13 +371,15 @@
         : _spanFromTokens(currentElement, position, position, uri);
   }
 
-  SourceSpan spanFromSpannable(Spannable node, Entity currentElement) {
-    if (node is Node) {
-      return _spanFromNode(currentElement, node);
-    } else if (node is Element) {
-      return _spanFromElement(currentElement, node);
-    } else if (node is MetadataAnnotation) {
-      return node.sourcePosition;
+  SourceSpan spanFromSpannable(Spannable spannable, Entity currentElement) {
+    if (spannable is Node) {
+      return _spanFromNode(currentElement, spannable);
+    } else if (spannable is Element) {
+      return _spanFromElement(currentElement, spannable);
+    } else if (spannable is MetadataAnnotation) {
+      return spannable.sourcePosition;
+    } else if (spannable is LocalVariable) {
+      return spanFromSpannable(spannable.executableContext, currentElement);
     }
     return null;
   }
@@ -747,7 +749,9 @@
   @override
   ResolutionFunctionType getFunctionTypeOfTypedef(
       covariant TypedefElement typedef) {
-    return typedef.alias;
+    var result = typedef.alias;
+    if (result.isMalformed) return null;
+    return result;
   }
 }
 
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index 9d9009a..2279209 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -1050,15 +1050,24 @@
 /// Tests the equivalence of [impact1] and [impact2] using [strategy].
 bool testResolutionImpactEquivalence(
     ResolutionImpact impact1, ResolutionImpact impact2,
-    {TestStrategy strategy = const TestStrategy()}) {
+    {TestStrategy strategy = const TestStrategy(),
+    Iterable<ConstantExpression> filterConstantLiterals(
+        Iterable<ConstantExpression> constants,
+        {bool fromFirstImpact})}) {
   return strategy.testSets(impact1, impact2, 'constSymbolNames',
           impact1.constSymbolNames, impact2.constSymbolNames) &&
       strategy.testSets(
           impact1,
           impact2,
           'constantLiterals',
-          impact1.constantLiterals,
-          impact2.constantLiterals,
+          filterConstantLiterals != null
+              ? filterConstantLiterals(impact1.constantLiterals,
+                  fromFirstImpact: true)
+              : impact1.constantLiterals,
+          filterConstantLiterals != null
+              ? filterConstantLiterals(impact2.constantLiterals,
+                  fromFirstImpact: false)
+              : impact2.constantLiterals,
           areConstantsEquivalent) &&
       strategy.testSets(
           impact1,
@@ -1228,9 +1237,8 @@
       Node node1, Node node2, String property, JumpTarget a, JumpTarget b) {
     if (identical(a, b)) return true;
     if (a == null || b == null) return false;
-    return strategy.testElements(a, b, 'executableContext', a.executableContext,
-            b.executableContext) &&
-        strategy.test(a, b, 'nestingLevel', a.nestingLevel, b.nestingLevel) &&
+    return strategy.test(
+            a, b, 'nestingLevel', a.nestingLevel, b.nestingLevel) &&
         strategy.test(a, b, 'statement', indices1.nodeIndices[a.statement],
             indices2.nodeIndices[b.statement]) &&
         strategy.test(
diff --git a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
index 692a213..0e40512 100644
--- a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
@@ -192,7 +192,7 @@
   }
 
   /// Serialize [target] into [encoder].
-  void serializeJumpTarget(JumpTarget jumpTarget, ObjectEncoder encoder) {
+  void serializeJumpTarget(JumpTargetX jumpTarget, ObjectEncoder encoder) {
     encoder.setElement(Key.EXECUTABLE_CONTEXT, jumpTarget.executableContext);
     encoder.setInt(Key.NODE, nodeIndices[jumpTarget.statement]);
     encoder.setInt(Key.NESTING_LEVEL, jumpTarget.nestingLevel);
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index 6e78981..f09b4d6 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -21,10 +21,22 @@
 abstract class SourceFileProvider implements CompilerInput {
   bool isWindows = (Platform.operatingSystem == 'windows');
   Uri cwd = currentDirectory;
-  Map<Uri, api.Input> sourceFiles = <Uri, api.Input>{};
+  Map<Uri, api.Input> utf8SourceFiles = <Uri, api.Input>{};
+  Map<Uri, api.Input> binarySourceFiles = <Uri, api.Input>{};
   int dartCharactersRead = 0;
 
   Future<api.Input> readBytesFromUri(Uri resourceUri, api.InputKind inputKind) {
+    api.Input input;
+    switch (inputKind) {
+      case api.InputKind.utf8:
+        input = utf8SourceFiles[resourceUri];
+        break;
+      case api.InputKind.binary:
+        input = binarySourceFiles[resourceUri];
+        break;
+    }
+    if (input != null) return new Future.value(input);
+
     if (resourceUri.scheme == 'file') {
       return _readFromFile(resourceUri, inputKind);
     } else if (resourceUri.scheme == 'http' || resourceUri.scheme == 'https') {
@@ -49,14 +61,14 @@
     api.Input input;
     switch (inputKind) {
       case api.InputKind.utf8:
-        input = new CachingUtf8BytesSourceFile(
+        input = utf8SourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
             resourceUri, relativizeUri(resourceUri), source);
         break;
       case api.InputKind.binary:
-        input = new Binary(resourceUri, source);
+        input =
+            binarySourceFiles[resourceUri] = new Binary(resourceUri, source);
         break;
     }
-    sourceFiles[resourceUri] = input;
     return input;
   }
 
@@ -109,14 +121,14 @@
       api.Input input;
       switch (inputKind) {
         case api.InputKind.utf8:
-          input = new CachingUtf8BytesSourceFile(
+          input = utf8SourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
               resourceUri, resourceUri.toString(), result);
           break;
         case api.InputKind.binary:
-          input = new Binary(resourceUri, result);
+          input =
+              binarySourceFiles[resourceUri] = new Binary(resourceUri, result);
           break;
       }
-      sourceFiles[resourceUri] = input;
       return input;
     });
   }
@@ -129,8 +141,15 @@
 
   relativizeUri(Uri uri) => relativize(cwd, uri, isWindows);
 
-  SourceFile getSourceFile(Uri resourceUri) {
-    return sourceFiles[resourceUri];
+  SourceFile getUtf8SourceFile(Uri resourceUri) {
+    return utf8SourceFiles[resourceUri];
+  }
+
+  Iterable<Uri> getSourceUris() {
+    Set<Uri> uris = new Set<Uri>();
+    uris.addAll(utf8SourceFiles.keys);
+    uris.addAll(binarySourceFiles.keys);
+    return uris;
   }
 }
 
@@ -253,7 +272,7 @@
     if (uri == null) {
       print('${color(message)}');
     } else {
-      api.Input file = provider.sourceFiles[uri];
+      api.Input file = provider.getUtf8SourceFile(uri);
       if (file == null &&
           autoReadFileUri &&
           uri.scheme == 'file' &&
@@ -476,7 +495,14 @@
       }
     }
     api.Input result = await readBytesFromUri(resolvedUri, inputKind);
-    sourceFiles[uri] = sourceFiles[resolvedUri];
+    switch (inputKind) {
+      case InputKind.utf8:
+        utf8SourceFiles[uri] = utf8SourceFiles[resolvedUri];
+        break;
+      case InputKind.binary:
+        binarySourceFiles[uri] = binarySourceFiles[resolvedUri];
+        break;
+    }
     return result;
   }
 }
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 2e897ec..4caccb9 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -251,12 +251,11 @@
         this,
         target,
         target.memberContext,
-        target.contextClass,
-        null,
+        target.contextClass?.thisType,
         closedWorld.nativeData,
         closedWorld.interceptorData);
     loopHandler = new SsaLoopHandler(this);
-    typeBuilder = new TypeBuilder(this);
+    typeBuilder = new AstTypeBuilder(this);
   }
 
   MemberElement get targetElement => target;
@@ -837,8 +836,13 @@
       {ResolutionInterfaceType instanceType}) {
     ResolvedAst resolvedAst = function.resolvedAst;
     assert(resolvedAst != null);
-    localsHandler = new LocalsHandler(this, function, function.memberContext,
-        function.contextClass, instanceType, nativeData, interceptorData);
+    localsHandler = new LocalsHandler(
+        this,
+        function,
+        function.memberContext,
+        instanceType ?? function.contextClass?.thisType,
+        nativeData,
+        interceptorData);
     localsHandler.scopeInfo = closureDataLookup.getScopeInfo(function);
     returnLocal =
         new SyntheticLocal("result", function, function.memberContext);
@@ -1492,7 +1496,7 @@
           //
           //     class A {
           //       A(String foo) = A.b;
-          //       A(int foo) { print(foo); }
+          //       A.b(int foo) { print(foo); }
           //     }
           //     main() {
           //       new A(499);    // valid even in checked mode.
@@ -1886,9 +1890,10 @@
     ClassEntity closureClassEntity = closureInfo.closureClassEntity;
 
     List<HInstruction> capturedVariables = <HInstruction>[];
-    closureInfo.createdFieldEntities.forEach((Local field) {
-      assert(field != null);
-      capturedVariables.add(localsHandler.readLocal(field));
+    compiler.codegenWorldBuilder.forEachInstanceField(closureClassEntity,
+        (_, FieldEntity field) {
+      capturedVariables
+          .add(localsHandler.readLocal(closureInfo.getLocalForField(field)));
     });
 
     TypeMask type = new TypeMask.nonNullExact(closureClassEntity, closedWorld);
@@ -6861,3 +6866,52 @@
       this.oldElementInferenceResults)
       : super(function);
 }
+
+class AstTypeBuilder extends TypeBuilder {
+  AstTypeBuilder(GraphBuilder builder) : super(builder);
+
+  ClassTypeVariableAccess computeTypeVariableAccess(MemberEntity member) {
+    bool isClosure = member.enclosingClass.isClosure;
+    if (isClosure) {
+      ClosureClassElement closureClass = member.enclosingClass;
+      LocalFunctionElement localFunction = closureClass.methodElement;
+      member = localFunction.memberContext;
+    }
+    bool isInConstructorContext =
+        member.isConstructor || member is ConstructorBodyEntity;
+    if (isClosure) {
+      if ((member is ConstructorEntity && member.isFactoryConstructor) ||