Version 2.0.0-dev.59.0

Merge commit '1ca17b6d03d0fdf8778d45c486bb5ac617809df0' into dev
diff --git a/BUILD.gn b/BUILD.gn
index f4f9bec..d0cd1b5 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -139,6 +139,12 @@
   ]
 }
 
+group("observatory_archive") {
+  deps = [
+    "runtime/observatory:observatory_archive"
+  ]
+}
+
 # The rules below build a Fuchsia OS image that includes the Dart tree
 # under /system/test/dart.  To get this into the `user.bootfs` generated
 # by the Fuchsia build, add the GN build argument:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4d101527..36f7387 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,24 @@
+## 2.0.0-dev.59.0
+
+### Language
+
+The change to make bounds on generic functions invariant has landed in the
+analyzer.  The analyzer will now issue an invalid override error on the
+following program ([issue 29014][sdk#29014]).
+
+```dart
+class A {
+  void f<T extends int>() {}
+}
+
+class B extends A {
+  @override
+  void f<T extends num>() {}
+}
+```
+
+[sdk#29014]: https://github.com/dart-lang/sdk/issues/29014
+
 ## 2.0.0-dev.58.0
 
 ## 2.0.0-dev.57.0
@@ -58,6 +79,8 @@
 * `dart:io`
   * Added `X509Certificate.der`, `X509Certificate.pem`, and
     `X509Certificate.sha1`.
+  * Added `FileSystemEntity.fromRawPath` constructor to allow for
+    the creation of `FileSystemEntity` using `Uint8List` buffers.
 
 ### Tool Changes
 
diff --git a/DEPS b/DEPS
index 9f020fb..114668e 100644
--- a/DEPS
+++ b/DEPS
@@ -54,8 +54,8 @@
   "async_tag": "2.0.7",
   "bazel_worker_tag": "v0.1.9",
   "boolean_selector_tag" : "1.0.3",
-  "boringssl_gen_rev": "344f455fd13d46f054726638e76026156ea73aa9",
-  "boringssl_rev" : "672f6fc2486745d0cabc3aaeb4e0a3cd13b37b12",
+  "boringssl_gen_rev": "fc47eaa1a245d858bae462cd64d4155605b850ea",
+  "boringssl_rev" : "189270cd190267f5bd60cfe8f8ce7a61d07ba6f4",
   "charcode_tag": "v1.1.1",
   "chrome_rev" : "19997",
   "cli_util_tag" : "0.1.2+1",
@@ -79,7 +79,7 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
   "dart_style_tag": "1.0.14",  # Please see the note above before updating.
 
-  "dartdoc_tag" : "v0.19.0",
+  "dartdoc_tag" : "v0.19.1",
   "fixnum_tag": "0.10.5",
   "func_rev": "25eec48146a58967d75330075ab376b3838b18a8",
   "glob_tag": "1.1.5",
@@ -96,11 +96,11 @@
   "json_rpc_2_tag": "2.0.6",
   "linter_tag": "0.1.51",
   "logging_tag": "0.11.3+1",
-  "markdown_tag": "1.1.1",
+  "markdown_tag": "2.0.0",
   "matcher_tag": "0.12.1+4",
   "mime_tag": "0.9.6",
   "mockito_tag": "a92db054fba18bc2d605be7670aee74b7cadc00a",
-  "mustache4dart_tag" : "v2.1.1",
+  "mustache4dart_tag" : "v2.1.2",
   "oauth2_tag": "1.1.0",
   "observatory_pub_packages_rev": "d3a3aebefbd35aa30fe7bbc2889b772b398f7d7f",
   "package_config_tag": "1.0.3",
@@ -136,7 +136,7 @@
   "typed_data_tag": "1.1.3",
   "usage_tag": "3.3.0",
   "utf_tag": "0.9.0+4",
-  "watcher_tag": "0.9.7+7",
+  "watcher_tag": "0.9.7+8",
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
   "web_socket_channel_tag": "1.0.7",
   "WebCore_rev": "fb11e887f77919450e497344da570d780e078bc8",
diff --git a/build/toolchain/gcc_toolchain.gni b/build/toolchain/gcc_toolchain.gni
index b21a7d1..3689187 100644
--- a/build/toolchain/gcc_toolchain.gni
+++ b/build/toolchain/gcc_toolchain.gni
@@ -102,7 +102,7 @@
       depsformat = "gcc"
       description = "CC {{output}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
       ]
     }
 
@@ -112,7 +112,7 @@
       depsformat = "gcc"
       description = "CXX {{output}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
       ]
     }
 
@@ -123,7 +123,7 @@
       depsformat = "gcc"
       description = "ASM {{output}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
       ]
     }
 
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn
index 4ed409a..ef4b8a5 100644
--- a/build/toolchain/mac/BUILD.gn
+++ b/build/toolchain/mac/BUILD.gn
@@ -62,7 +62,7 @@
       depsformat = "gcc"
       description = "CC {{output}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
       ]
     }
 
@@ -72,7 +72,7 @@
       depsformat = "gcc"
       description = "CXX {{output}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
       ]
     }
 
@@ -83,7 +83,7 @@
       depsformat = "gcc"
       description = "ASM {{output}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
       ]
     }
 
@@ -93,7 +93,7 @@
       depsformat = "gcc"
       description = "OBJC {{output}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
       ]
     }
 
@@ -103,7 +103,7 @@
       depsformat = "gcc"
       description = "OBJCXX {{output}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.o",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
       ]
     }
 
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn
index 71c6595..b8d222a 100644
--- a/build/toolchain/win/BUILD.gn
+++ b/build/toolchain/win/BUILD.gn
@@ -76,7 +76,7 @@
       depsformat = "msvc"
       description = "CC {{output}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.obj",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
       ]
       rspfile_content = "{{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}"
     }
@@ -93,7 +93,7 @@
       depsformat = "msvc"
       description = "CXX {{output}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.obj",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
       ]
       rspfile_content = "{{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}"
     }
@@ -101,7 +101,7 @@
     tool("rc") {
       command = "$python_path $tool_wrapper_path rc-wrapper $env rc.exe {{defines}} {{include_dirs}} /fo{{output}} {{source}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.res",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.res",
       ]
       description = "RC {{output}}"
     }
@@ -117,7 +117,7 @@
       command = "$python_path $tool_wrapper_path asm-wrapper $env $ml $x64 {{defines}} {{include_dirs}} {{asmflags}} /c /Fo {{output}} {{source}}"
       description = "ASM {{output}}"
       outputs = [
-        "{{target_out_dir}}/{{target_output_name}}/{{source_name_part}}.obj",
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj",
       ]
     }
 
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 4ad9e1d..5e8b62c 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -1491,7 +1491,8 @@
 It is a static warning if a class has a setter named $v=$ with argument type $T$ and a getter named $v$ with return type $S$, and $T$ may not be assigned to $S$.
 
 \LMHash{}
-It is a static warning if a class declares a static setter named $v=$ and also has a non-static member named $v$.
+It is a static warning if a class declares a static setter named $v=$ and has an instance getter named $v$.
+It is a static warning if a class declares a setter named $v=$ and has a method named $v$.
 
 % We need not consider implicit declarations: If $v=$ is declared
 % implicitly then there is a static variable $v$, and then it is
@@ -2171,6 +2172,7 @@
 
 \LMHash{}
 It is a static warning if a class $C$ declares a static method named $n$ and has a setter named $n=$.
+It is a static warning if a class $C$ declares a static member named $n$ and has an instance member named $n$.
 
 
 \subsection{Static Variables}
diff --git a/docs/language/informal/extreme-upper-lower-bounds.md b/docs/language/informal/extreme-upper-lower-bounds.md
new file mode 100644
index 0000000..93babb8
--- /dev/null
+++ b/docs/language/informal/extreme-upper-lower-bounds.md
@@ -0,0 +1,254 @@
+# Feature Specification: Upper and Lower Bounds for Extreme Types
+
+**Owner**: eernst@
+
+**Status**: Under discussion.
+
+**Version**: 0.2 (2018-05-22)
+
+
+This document is a Dart 2 feature specification which specifies how to
+compute the standard upper bound and standard lower bound (`SUB` and `SLB`)
+of a pair of types when at least one of the operands is an extreme type:
+`Object`, `dynamic`, `void`, or `bottom`.
+
+
+## Motivation
+
+In order to motivate the rules for upper and lower bounds of a pair of
+types, we will focus on concrete examples that embody upper bounds very
+directly, namely conditional expressions, and extend that to lower bounds
+using functions.
+
+For example, can we use the result from the evaluation of `b ?
+print('Hello!') : 42`?  In Dart 2, an expression with static type `void` is
+considered to have a value which is not valid, and it is a compile-time
+error to use it in most situations. When it is one of two possible branches
+in a conditional expression (here: `print('Hello!')`) we would expect to
+consider the whole value to be not valid, because otherwise we could
+receive the value of "the void branch" and thus inadvertently use a value
+which is not valid. Based on this kind of reasoning we have chosen to give
+expressions like `b ? print('Hello!') : 42` the type `void`.
+
+Similarly, can we do `(b ? 42 : f()).isEven` if `f` has return type
+`dynamic`? In this case the result from evaluating the conditional
+expression (`?:`) may have any type whatsoever, so `isEven` cannot be
+assumed to exist in the interface of that object. On the other hand,
+`isEven` could be safely invoked on the result from the branch `42`, and
+the other branch would admit arbitrary member access operations (such as
+`f().isEven`), even though there is no static evidence for the existence of
+any particular members (except for a few members which are declared in
+`Object` and hence inherited or overridden for every object). So you could
+say "it is OK for both branches, so it must be OK for the expression as a
+whole."
+
+Then how about `(b ? 42 : f()).fooBar()` where `f` is again assumed to have
+the return type `dynamic`? In this situation we would accept `f().fooBar()`
+because `dynamic` receivers admit all member accesses, but `42.fooBar()`
+would be rejected. Hence, we might say that "it is not OK for both
+branches, hence it is not OK for the conditional expression".
+
+We could give `b ? 42 : f()` the type `int`, which would allow us to accept
+`(b ? 42 : f()).isEven` and reject `(b ? 42 : f()).fooBar()`. This would
+effectively mean that `dynamic` would be considered to be a subtype of all
+other types during computations of upper and lower bounds.
+
+However, we consider that to be such a serious anomaly relative to the rest
+of the Dart 2 type system that we have not taken that approach.
+
+Instead, we have chosen to accept that a `dynamic` branch in a conditional
+expression will make the whole conditional expression dynamic.
+
+A set of situations with the opposite polarity arise when we consider types
+in a contravariant position, e.g., `b ? (T1 t1) => e1 : (T2 t2) => e2`,
+where we need to consider various combinations of types as the values of
+`T1` and `T2` in order to compute the type of the whole expression.
+
+Ignoring "voidness" and "dynamicness" for a moment and focusing on the pure
+subtyping relationships, we apply the _standard upper bound_ function to
+the types of the two branches in the former situation (like `b ? e1 : e2`),
+and for the latter situation (where an intervening function literal
+reverses the polarity, that is, the types in question occur in
+contravariant locations) we use the _standard lower bound_ function.
+
+These bound functions take exactly two arguments, so we may also call them
+'operators' and the arguments 'operands'.  We call these functions
+'standard' rather than 'least' and 'greatest' because the Dart 2 type
+language cannot express a true least upper bound and greatest lower bound
+of all pairs of types, but it is still useful to choose an approximation
+thereof in many cases. We abbreviate the function names to `SUB` and `SLB`.
+
+As long as we are concerned with non-extreme types (everything except the
+top and bottom types), these bound functions deliver an approximation of
+the least upper bound and the greatest lower bound of its operands. For
+instance, `SUB(int, num)` is `num`, and `SLB(int, num)` is `int`, so we get
+the type `Object` for `b ? new Object() : 42`, and the type `num
+Function(int)` for `b ? (num n) => 41 : (int o) => 4.1`.
+
+This specification is concerned with combining the treatment of the pure
+subtyping related properties and the other properties like "dynamicness"
+and "voidness". We achieve that by means of a specification of the values
+of `SUB` and `SLB` when at least one of their operands is an extreme type.
+
+
+## Syntax
+
+The grammar is unaffected by this feature.
+
+
+## Static Analysis
+
+An _extreme type_ is one of the types `Object`, `dynamic`, `void`, and
+`bottom`.
+
+Consider a pair of types such that at least one of them is an extreme
+type. The value of the functions `SUB` and `SLB` on that pair of types is
+then determined by the following rules:
+
+```dart
+SUB(T, T) == T, for all T.
+SUB(S, T) == SUB(T, S), for all S, T.
+SUB(void, T) == void, for all T.
+SUB(dynamic, T) == dynamic, for all T != void.
+SUB(Object, T) == Object, for all T != void, dynamic.
+SUB(bottom, T) == T, for all T.
+
+SLB(T, T) == T, for all T.
+SLB(S, T) == SLB(T, S), for all S, T.
+SLB(void, T) == T, for all T.
+SLB(dynamic, T) == T, for all T != void.
+SLB(Object, T) == T, for all T != void, dynamic.
+SLB(bottom, T) == bottom, for all T.
+```
+
+*Note that this is the same outcome as we would have had if `Object` were a
+proper subtype of `dynamic` and `dynamic` were a proper subtype of
+`void`. Hence, an easy way to recall these rules would be to think `Object
+< dynamic < void`. Here, `<` is a "micro subtype" relationship which is
+able to distinguish between the top types, as opposed to the subtype
+relationship `<:` which considers the top types to be the same type. For
+any relationship involving a non-top type, `<` is the same thing as `<:`.*
+
+
+## Discussion
+
+We considered a different set of rules as well:
+
+```dart
+SUB(T, T) == T, for all T.
+SUB(S, T) == SUB(T, S), for all S, T.
+SUB(void, T) == void, for all T.
+SUB(dynamic, T) == Object, for all T != void, dynamic.
+SUB(Object, T) == Object, for all T != void.
+SUB(bottom, T) == T, for all T != dynamic.
+
+SLB(T, T) == T, for all T.
+SLB(S, T) == SLB(T, S), for all S, T.
+SLB(void, dynamic) == Object.
+SLB(void, T) == T, for all T != dynamic.
+SLB(dynamic, T) == T, for all T != void.
+SLB(Object, T) == T, for all T != void, dynamic.
+SLB(bottom, T) == bottom, for all T.
+```
+
+This set of rules cannot be reduced to any "micro subtype" relationship
+where we simply make a choice of how to order the top types and then get
+all other results as a consequence of that choice. These alternative rules
+are more strict on the propagation of "dynamicness" in a way which may be
+helpful for developers. Here is how it works:
+
+The 'Motivation' section mentioned a number of pragmatic reasons why it may
+be meaningful to let `SUB(dynamic, int)` be some other type than `dynamic`.
+
+If we take the stance that the relaxed type checks on member accesses that
+we apply to `dynamic` receivers are error-prone and hence shouldn't
+propagate very far implicitly, we may chose to eliminate the special
+treatment of `dynamic`, unless that type is present in all branches.
+
+This means that we would make the invocation `(b ? 42 : f()).isEven` a
+compile-time error: We could say that "it is not a dynamic invocation
+because some branches do not deliver a dynamic receiver, and there is no
+static guarantee that the `isEven` method exists, so the expression is a
+compile-time error". This is achieved by means of one of the rules shown
+above: `SUB(dynamic, T) == Object, for all T != void, dynamic`.
+
+In order to show that the alternative set of rules has an internal
+structure (as opposed to being a random mixture of decisions), we can
+describe them in the following manner. First we translate all types into a
+tuple-representation:
+
+```dart
+void      (1, 1, 0)
+dynamic   (1, 0, 1)
+Object    (1, 0, 0)
+T         (T, 0, 0), for all non-extreme types T
+bottom    (0, 0, 0)
+```
+
+In this tuple, the first component is the core type (where "voidness" and
+"dynamicness" have been erased), where `0` is bottom, `1` is top (that is,
+the types `Object`, `dynamic`, and `void`), and every other (non-extreme)
+type is itself, e.g., `int` is `int`.
+
+The second component is the "voidness": `1` means that the type is a void
+type (there is only `void`), and `0` means non-void.
+
+The third component is the "dynamicness": `1` means that the type is
+dynamic (there is only `dynamic`, at least for now), and `0` means
+non-dynamic.
+
+This means that the tuple contains one "core type" and two "bits" (boolean
+components). With that, we can compute the functions using simple
+operations:
+
+```dart
+SUB((t1, v1, d1), (t2, v2, d2)) = (lub(t1,t2), v1 || v2, d1 && d2)
+SLB((t1, v1, d1), (t2, v2, d2)) = (glb(t1,t2), v1 && v2, d1 && d2)
+
+```
+
+We may also specify the same thing more concisely in a curried form:
+
+```dart
+SUB = (lub, lub, glb)
+SLB = (glb, glb, glb)
+```
+
+where `lub` and `glb` are specialized for the domain of types and booleans,
+respectively, but are basically "least upper bound" and "greatest lower 
+bound": For types we rely on an underlying notion of upper and lower bounds
+for all non-extreme types, and for booleans it is simply the indicated 
+operators above (`||` and `&&`, respectively).
+
+It may seem tempting, for symmetry, to change the definitions such that we
+get `SLB = (glb, glb, lub)`, but this would introduce types of the form
+`(T, 0, 1)`, that is, types like `dynamic(int)` and 
+`dynamic(int Function(String))` that we have considered but not yet decided
+to introduce. Given that the only effect this change would have is to
+change some types in a contravariant location from `Object` to `dynamic`,
+and given that this is generally not detectable for clients (e.g., we don't
+care about, and actually can't even detect, the difference between calling
+a function of type `int Function(Object)` and a function of type `int
+Function(dynamic)`), so this choice is not likely to matter much. Also the
+fact that the use of `min` yields fewer occurrences of the type `dynamic`
+seems to be consistent with the nature of Dart 2 typing.
+
+Note that the operations are reflexive and symmetric by construction, and
+they are also likely to be associative, because both `lub` and `glb` are
+associative for booleans, and for types we will need to consider the actual
+underlying mechanism, but it ought to be associative if at all possible:
+
+```dart
+lub(lub(a,b),c) = lub(a,lub(b,c))
+glb(glb(a,b),c) = glb(a,glb(b,c))
+```
+
+## Updates
+
+*   May 22nd 2018, version 0.2: Adjusted to use `Object < dynamic < void`
+    as a "subtyping micro-structure" (which produces a simpler set of
+    rules) and mention the rules from version 0.1 merely as a possible
+    alternative ruleset.
+
+*   May 1st 2018, version 0.1: Initial version of this feature 
+    specification created, based on discussions in SDK issue 28513.
diff --git a/docs/language/informal/instantiate-to-bound.md b/docs/language/informal/instantiate-to-bound.md
index d182dcb..091c507 100644
--- a/docs/language/informal/instantiate-to-bound.md
+++ b/docs/language/informal/instantiate-to-bound.md
@@ -2,7 +2,7 @@
 
 **Author**: eernst@
 
-**Version**: 0.5 (2018-01-11)
+**Version**: 0.7 (2018-02-26)
 
 **Status**: Under implementation.
 
@@ -191,40 +191,41 @@
 on, every type variable in its bound, possibly including itself*).
 Let _==><sub>m</sub>_ be the transitive closure of _--><sub>m</sub>_.
 For each _m_, let _U<sub>i,m+1</sub>_, for _i_ in _1 .. k_, be determined
-as follows:
+by the following iterative process:
 
-- Let _j_ be the lowest number such that
-  _X<sub>j</sub> ==><sub>m</sub> X<sub>j</sub>_ (*that is, such that this
-  type variable is a member of a dependency cycle*).
-  Let _{Y<sub>1</sub> .. Y<sub>p</sub>}_ be the the maximal subset
-  containing _X<sub>j</sub>_ of _{X<sub>1</sub> .. X<sub>k</sub>}_ where
-  every pair is related: _Y<sub>q</sub> ==><sub>m</sub> Y<sub>r</sub>_, for
-  all _q, r_ in _1 .. p_ (*i.e., this subset is a strongly connected
-  component in the dependency graph containing _X<sub>j</sub>_*).
-  Then _U<sub>i,m+1</sub>_ is the result of substituting, in
-  _U<sub>i,m</sub>_, `Null` for every contravariant occurrence
-  of _X<sub>j</sub>_, and `dynamic` for every covariant occurrence of
-  _X<sub>j</sub>_, for all _i_ in _1 .. k_ such that _X<sub>i</sub>_ is a
-  member of _{Y<sub>1</sub> .. Y<sub>p</sub>}_; and _U<sub>i,m+1</sub>_ is
-  _U<sub>i,m</sub>_, for all other _i_ in _1 .. k_.
-  *That is, we update the bounds of type variables in the dependency cycle
-  such that the type variables in the dependency cycle are replaced by
-  `Null` or `dynamic`, depending on the variance of the location.*
+1. If there exists a _j_ in _1 .. k_ such that
+   _X<sub>j</sub> ==><sub>m</sub> X<sub>j</sub>_
+   (*that is, if the dependency graph has a cycle*)
+   let _M<sub>1</sub> .. M<sub>p</sub>_ be the strongly connected components
+   (SCCs) with respect to _--><sub>m</sub>_
+   (*that is, the maximal subsets of _X<sub>1</sub> .. X<sub>k</sub>_
+   where every pair of variables in each subset are related in both directions
+   by _==><sub>m</sub>_; note that the SCCs are pairwise disjoint; also, they
+   are uniquely defined up to reordering, and the order does not matter*).
+   Let _M_ be the union of _M<sub>1</sub> .. M<sub>p</sub>_
+   (*that is, all variables that participate in a dependency cycle*).
+   Let _i_ be in _1 .. k_.
+   If _X<sub>i</sub>_ does not belong to _M_ then
+   _U<sub>i,m+1</sub> = U<sub>i,m</sub>_.
+   Otherwise there exists a _q_ such that _X<sub>i</sub>_ belongs to
+   _M<sub>q</sub>_; _U<sub>i,m+1</sub>_ is then obtained from _U<sub>i,m</sub>_
+   by replacing every covariant occurrence of a variable in _M<sub>q</sub>_ by
+   `dynamic`, and replacing every contravariant occurence of a variable in
+   _M<sub>q</sub>_ by `Null`.
 
-- Otherwise, (*if no such dependency cycle exists*) let _j_ be the
-  lowest number such that _X<sub>j</sub>_ occurs in
-  _U<sub>p,m</sub>_ for some _p_ and
-  _X<sub>j</sub> -/-><sub>m</sub> X<sub>q</sub>_ for all _q_ in _1..k_
-  (*that is, _U<sub>j,m</sub>_ is closed, that is, the current bound of
-  _X<sub>j</sub>_ does not depend on any other type variables; but
-  _X<sub>j</sub>_ is being depended on by the bounds of some other type
-  variables*). Then _U<sub>i,m+1</sub>_ is the result of substituting, in
-  _U<sub>i,m</sub>_, `Null` for every contravariant occurrence
-  of _X<sub>j</sub>_, and _U<sub>j,m</sub>_ for every covariant occurrence
-  of _X<sub>j</sub>_, for all _i_ in _1 .. k_.
+2. Otherwise, (*if no dependency cycle exists*) let _j_ be the lowest number
+   such that _X<sub>j</sub>_ occurs in _U<sub>p,m</sub>_ for some _p_ and
+   _X<sub>j</sub> -/-><sub>m</sub> X<sub>q</sub>_ for all _q_ in _1..k_
+   (*that is, _U<sub>j,m</sub>_ is closed, that is, the current bound of
+   _X<sub>j</sub>_ does not contain any type variables; but _X<sub>j</sub>_ is
+   being depended on by the bound of some other type variable*).
+   Then, for all _i_ in _1 .. k_, _U<sub>i,m+1</sub>_ is obtained from
+   _U<sub>i,m</sub>_ by replacing every covariant occurrence of _X<sub>j</sub>_
+   by _U<sub>j,m</sub>_, and replacing every contravariant occurrence of
+   _X<sub>j</sub>_ by `Null`.
 
-- Otherwise, (*when no dependencies exist*) terminate with the result
-  _&lt;U<sub>1,m</sub> ..., U<sub>k,m</sub>&gt;_.
+3. Otherwise, (*when no dependencies exist*) terminate with the result
+   _&lt;U<sub>1,m</sub> ..., U<sub>k,m</sub>&gt;_.
 
 *This process will always terminate, because the total number of
 occurrences of type variables from _{X<sub>1</sub> .. X<sub>k</sub>}_ in
@@ -259,6 +260,13 @@
 
 ## Updates
 
+*   Feb 26th 2018, version 0.7: Revised cycle breaking algorithm for
+    F-bounded type variables to avoid specifying orderings that do not matter.
+
+*   Feb 22nd 2018, version 0.6: Revised cycle breaking algorithm for
+    F-bounded type variables to replace all members by an extreme type, not
+    just one of them.
+
 *   Jan 11th 2018, version 0.5: Revised treatment of variance based on
     strongly connected components in the dependency graph.
 
diff --git a/docs/language/informal/super-bounded-types.md b/docs/language/informal/super-bounded-types.md
index db2e46c..b7d19da 100644
--- a/docs/language/informal/super-bounded-types.md
+++ b/docs/language/informal/super-bounded-types.md
@@ -2,7 +2,7 @@
 
 **Author**: eernst@.
 
-**Version**: 0.5 (2018-01-11).
+**Version**: 0.6 (2018-05-25).
 
 **Status**: Under implementation.
 
@@ -348,6 +348,51 @@
 `void Function(A<Object>)` is well-bounded because `A<Object>` is
 super-bounded.*
 
+*Note that it is necessary to require that the right hand side of a type
+alias declaration is taken into account when determining that a given
+application of a type alias to an actual type argument list is correctly
+super-bounded. That is, we do not think that it is possible for a
+(reasonable) constraint specification mechanism on the formal type
+parameters of a type alias declaration to ensure that all arguments
+satisfying those constraints will also be suitable for the type on the
+right hand side. In particular, we may use simple upper bounds and
+F-bounded constraints (as we have always done), perform and pass the
+'correctly super-bounded' check on a given parameterized type based on a
+type alias, and still have a right hand side which is not well-bounded:*
+```dart
+class B<X extends List<num>> {}
+typedef H<Y extends num> = void Function(B<List<Y>>);
+typedef K<Y extends num> = B<List<Y>> Function(B<List<Y>>);
+
+H<Object> myH = null; // Error!
+```
+*`H<Object>` is a compile-time error because it is not regular-bounded
+(`Object <: num` does not hold), and it is also not correctly
+super-bounded: `Null` does satisfy the constraint in the declaration of
+`Y`, but `H<Object>` gives rise to the right hand side
+`void Function(B<List<Object>>)`, and that is not a well-bounded type:
+It is not regular-bounded (`List<Object> <: List<num>` does not hold),
+and it does not become a regular-bounded type by the type replacements
+(that yield `void Function(B<List<Object>>)` because that occurrence of
+`Object` is contravariant).*
+
+*Semantically, this failure may be motivated by the fact that `H<Object>`,
+were it allowed, would not be a supertype of `H<T>` for all the `T` where
+`H<T>` is regular-bounded. So it would not be capable of playing the role
+as a "default type" that abstracts over all the possible actual types that
+are expressible using `H`. For example, a variable declared like
+`List<H<Object>> x;` would not be allowed to hold a value of type
+`List<H<num>>` because the latter is not a subtype of the former.*
+
+*In the given situation it is possible to express such a default type:
+`H<Null>` is actually a common supertype of `H<T>` for all `T` such that
+`H<T>` is regular-bounded. However, `K` shows that this is not always the
+case: There is no type `S` such that `K<S>` is a common supertype of `K<T>`
+for all those `T` where `K<T>` is regular-bounded. Facing this situation,
+we prefer to bail out rather than implicitly allow some kind of
+super-bounded type (assuming that we amend the rules such that it is not an
+error) which would not abstract over all possible instantiations anyway.*
+
 *The subtype relations for super-bounded types follow directly from the
 extension of generic covariance to include actual type arguments that
 violate the declared bounds. For the example in the Motivation section, `D`
@@ -535,6 +580,9 @@
 
 ## Updates
 
+*   Version 0.6 (2018-05-25), added example showing why we must check the
+    right hand side of type aliases.
+
 *   Version 0.5 (2018-01-11), generalized to allow replacement of top types
     covariantly and bottom types contravariantly. Introduced checks on
     parameterized type aliases (such that bounds declared for the type
diff --git a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart b/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
index e0af23c..082517d 100644
--- a/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
+++ b/pkg/analysis_server/lib/plugin/edit/fix/fix_core.dart
@@ -49,6 +49,11 @@
    */
   Fix(this.kind, this.change);
 
+  /**
+   * Returns `true` if this fix is the union of multiple fixes.
+   */
+  bool isFixAllFix() => change.message == kind.appliedTogetherMessage;
+
   @override
   String toString() {
     return 'Fix(kind=$kind, change=$change)';
@@ -72,6 +77,12 @@
   AnalysisError get error;
 
   /**
+   * All of the errors in the file. This is used to compute additional fixes
+   * such "Fix all instances in file."
+   */
+  List<AnalysisError> get errors;
+
+  /**
    * The [ResourceProvider] to access files and folders.
    */
   ResourceProvider get resourceProvider;
diff --git a/pkg/analysis_server/lib/src/computer/computer_outline.dart b/pkg/analysis_server/lib/src/computer/computer_outline.dart
index 96432aa..4979f1e 100644
--- a/pkg/analysis_server/lib/src/computer/computer_outline.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_outline.dart
@@ -413,7 +413,12 @@
   @override
   visitMethodInvocation(MethodInvocation node) {
     SimpleIdentifier nameNode = node.methodName;
-    engine.ExecutableElement executableElement = nameNode.bestElement;
+
+    engine.Element nameElement = nameNode.bestElement;
+    if (nameElement is! engine.ExecutableElement) {
+      return;
+    }
+    engine.ExecutableElement executableElement = nameElement;
 
     String extractString(NodeList<Expression> arguments) {
       if (arguments != null && arguments.length > 0) {
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index db27347..05d4310 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -1129,8 +1129,9 @@
             pathContext.isWithin(includedPath, excludedPath))
         .toList();
     processOptionsForDriver(info, options, optionMap);
-    ContextRoot contextRoot =
-        new ContextRoot(pathContext, folder.path, containedExcludedPaths);
+    ContextRoot contextRoot = new ContextRoot(
+        folder.path, containedExcludedPaths,
+        pathContext: pathContext);
     if (optionsFile != null) {
       contextRoot.optionsFilePath = optionsFile.path;
     }
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 1af301c..86e8dce 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -526,12 +526,18 @@
       CompilationUnit unit = result.unit;
       LineInfo lineInfo = result.lineInfo;
       int requestLine = lineInfo.getLocation(offset).lineNumber;
+      List<engine.AnalysisError> errorsCopy = new List.from(result.errors);
       for (engine.AnalysisError error in result.errors) {
         int errorLine = lineInfo.getLocation(error.offset).lineNumber;
         if (errorLine == requestLine) {
           AstProvider astProvider = new AstProviderForDriver(driver);
           DartFixContext context = new _DartFixContextImpl(
-              server.resourceProvider, result.driver, astProvider, unit, error);
+              server.resourceProvider,
+              result.driver,
+              astProvider,
+              unit,
+              error,
+              errorsCopy);
           List<Fix> fixes =
               await new DefaultFixContributor().internalComputeFixes(context);
           if (fixes.isNotEmpty) {
@@ -679,8 +685,11 @@
   @override
   final engine.AnalysisError error;
 
+  @override
+  final List<engine.AnalysisError> errors;
+
   _DartFixContextImpl(this.resourceProvider, this.analysisDriver,
-      this.astProvider, this.unit, this.error);
+      this.astProvider, this.unit, this.error, this.errors);
 
   @override
   GetTopLevelDeclarations get getTopLevelDeclarations =>
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index cdcdc36..9603adb 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -212,8 +212,9 @@
       const FixKind('REMOVE_UNUSED_CATCH', 50, "Remove unused 'catch' clause");
   static const REMOVE_UNUSED_CATCH_STACK = const FixKind(
       'REMOVE_UNUSED_CATCH_STACK', 50, "Remove unused stack trace variable");
-  static const REMOVE_UNUSED_IMPORT =
-      const FixKind('REMOVE_UNUSED_IMPORT', 50, "Remove unused import");
+  static const REMOVE_UNUSED_IMPORT = const FixKind(
+      'REMOVE_UNUSED_IMPORT', 50, "Remove unused import",
+      appliedTogetherMessage: "Remove all unused imports in this file");
   static const RENAME_TO_CAMEL_CASE =
       const FixKind('RENAME_TO_CAMEL_CASE', 50, "Rename to '{0}'");
   static const REPLACE_BOOLEAN_WITH_BOOL = const FixKind(
@@ -266,10 +267,15 @@
   @override
   final AnalysisError error;
 
-  FixContextImpl(this.resourceProvider, this.analysisDriver, this.error);
+  @override
+  final List<AnalysisError> errors;
+
+  FixContextImpl(
+      this.resourceProvider, this.analysisDriver, this.error, this.errors);
 
   FixContextImpl.from(FixContext other)
       : resourceProvider = other.resourceProvider,
         analysisDriver = other.analysisDriver,
-        error = other.error;
+        error = other.error,
+        errors = other.errors;
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 3df2168..da9de25 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -84,11 +84,97 @@
     try {
       FixProcessor processor = new FixProcessor(context);
       List<Fix> fixes = await processor.compute();
-      return fixes;
+      List<Fix> fixAllFixes = await _computeFixAllFixes(context, fixes);
+      return new List.from(fixes)..addAll(fixAllFixes);
     } on CancelCorrectionException {
       return Fix.EMPTY_LIST;
     }
   }
+
+  Future<List<Fix>> _computeFixAllFixes(
+      DartFixContext context, List<Fix> fixes) async {
+    final AnalysisError analysisError = context.error;
+    final List<AnalysisError> allAnalysisErrors = context.errors;
+
+    // Validate inputs:
+    // - return if no fixes
+    // - return if no other analysis errors
+    if (fixes.isEmpty || allAnalysisErrors.length < 2) {
+      return Fix.EMPTY_LIST;
+    }
+
+    // Remove any analysis errors that don't have the expected error code name
+    allAnalysisErrors
+        .removeWhere((e) => analysisError.errorCode.name != e.errorCode.name);
+    if (allAnalysisErrors.length < 2) {
+      return Fix.EMPTY_LIST;
+    }
+
+    // A map between each FixKind and the List of associated fixes
+    final HashMap<FixKind, List<Fix>> map = new HashMap();
+
+    // Populate the HashMap by looping through all AnalysisErrors, creating a
+    // new FixProcessor to compute the other fixes that can be applied with this
+    // one.
+    // For each fix, put the fix into the HashMap.
+    for (int i = 0; i < allAnalysisErrors.length; i++) {
+      final FixContext fixContextI = new FixContextImpl(
+          context.resourceProvider,
+          context.analysisDriver,
+          allAnalysisErrors[i],
+          allAnalysisErrors);
+      final DartFixContextImpl dartFixContextI = new DartFixContextImpl(
+          fixContextI, context.astProvider, context.unit);
+      final FixProcessor processorI = new FixProcessor(dartFixContextI);
+      final List<Fix> fixesListI = await processorI.compute();
+      for (Fix f in fixesListI) {
+        if (!map.containsKey(f.kind)) {
+          map[f.kind] = new List<Fix>()..add(f);
+        } else {
+          map[f.kind].add(f);
+        }
+      }
+    }
+
+    // For each FixKind in the HashMap, union each list together, then return
+    // the set of unioned Fixes.
+    final List<Fix> result = new List<Fix>();
+    map.forEach((FixKind kind, List<Fix> fixesListJ) {
+      if (fixesListJ.first.kind.canBeAppliedTogether()) {
+        Fix unionFix = _unionFixList(fixesListJ);
+        if (unionFix != null) {
+          result.add(unionFix);
+        }
+      }
+    });
+    return result;
+  }
+
+  Fix _unionFixList(List<Fix> fixList) {
+    if (fixList == null || fixList.isEmpty) {
+      return null;
+    } else if (fixList.length == 1) {
+      return fixList[0];
+    }
+    final SourceChange sourceChange =
+        new SourceChange(fixList[0].kind.appliedTogetherMessage);
+    sourceChange.edits = new List.from(fixList[0].change.edits);
+    final List<SourceEdit> edits = new List<SourceEdit>();
+    edits.addAll(fixList[0].change.edits[0].edits);
+    sourceChange.linkedEditGroups =
+        new List.from(fixList[0].change.linkedEditGroups);
+    for (int i = 1; i < fixList.length; i++) {
+      edits.addAll(fixList[i].change.edits[0].edits);
+      sourceChange.linkedEditGroups..addAll(fixList[i].change.linkedEditGroups);
+    }
+    // Sort the list of SourceEdits so that when the edits are applied, they
+    // are applied from the end of the file to the top of the file.
+    edits.sort((s1, s2) => s2.offset - s1.offset);
+
+    sourceChange.edits[0].edits = edits;
+
+    return new Fix(fixList[0].kind, sourceChange);
+  }
 }
 
 /**
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 8060d58..f4b1cc7 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -137,8 +137,8 @@
         resourceProvider,
         new MemoryByteStore(),
         fileContentOverlay,
-        new ContextRoot(resourceProvider.pathContext,
-            resourceProvider.convertPath('/project'), []),
+        new ContextRoot(resourceProvider.convertPath('/project'), [],
+            pathContext: resourceProvider.pathContext),
         sourceFactory,
         new AnalysisOptionsImpl()..strongMode = true);
     scheduler.start();
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 62b0d84..dbd1ee2 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -100,6 +100,27 @@
     await _assertNoFix(kind, error);
   }
 
+  assertHasFixAllFix(ErrorCode errorCode, FixKind kind, String expected,
+      {String target}) async {
+    AnalysisError error = await _findErrorToFixOfType(errorCode);
+    fix = await _assertHasFix(kind, error, hasFixAllFix: true);
+    change = fix.change;
+
+    // apply to "file"
+    List<SourceFileEdit> fileEdits = change.edits;
+    expect(fileEdits, hasLength(1));
+
+    String fileContent = testCode;
+    if (target != null) {
+      expect(fileEdits.first.file, convertPath(target));
+      fileContent = getFile(target).readAsStringSync();
+    }
+
+    resultCode = SourceEdit.applySequence(fileContent, change.edits[0].edits);
+    // verify
+    expect(resultCode, expected);
+  }
+
   List<LinkedEditSuggestion> expectedSuggestions(
       LinkedEditSuggestionKind kind, List<String> values) {
     return values.map((value) {
@@ -115,14 +136,53 @@
   /**
    * Computes fixes and verifies that there is a fix of the given kind.
    */
-  Future<Fix> _assertHasFix(FixKind kind, AnalysisError error) async {
-    List<Fix> fixes = await _computeFixes(error);
-    for (Fix fix in fixes) {
-      if (fix.kind == kind) {
-        return fix;
+  Future<Fix> _assertHasFix(FixKind kind, AnalysisError error,
+      {bool hasFixAllFix: false}) async {
+    if (hasFixAllFix && !kind.canBeAppliedTogether()) {
+      fail(
+          'Expected to find and return fix-all FixKind for $kind, but kind.canBeAppliedTogether is ${kind.canBeAppliedTogether}');
+    }
+
+    // Compute the fixes for this AnalysisError
+    final List<Fix> fixes = await _computeFixes(error);
+
+    // If hasFixAllFix is false, assert that none of the fixes are a fix-all fix
+    if (!hasFixAllFix) {
+      for (Fix f in fixes) {
+        if (f.isFixAllFix()) {
+          fail("The boolean hasFixAllFix is false, but such a fix was found in "
+              "the computed set of fixes: $fixes, error: $error.");
+        }
       }
     }
-    fail('Expected to find fix $kind in\n${fixes.join('\n')}');
+    // If hasFixAllFix is true, assert that there exists such a fix in the list
+    else {
+      bool foundFixAllFix = false;
+      for (Fix f in fixes) {
+        if (f.isFixAllFix()) {
+          foundFixAllFix = true;
+          break;
+        }
+      }
+      if (!foundFixAllFix) {
+        fail("The boolean hasFixAllFix is true, but no fix-all fix was found "
+            "in the computed set of fixes: $fixes, error: $error.");
+      }
+    }
+
+    Fix foundFix = null;
+    if (!hasFixAllFix) {
+      foundFix =
+          fixes.firstWhere((fix) => fix.kind == kind && !fix.isFixAllFix());
+    } else {
+      foundFix =
+          fixes.lastWhere((fix) => fix.kind == kind && fix.isFixAllFix());
+    }
+    if (foundFix == null) {
+      fail('Expected to find fix $kind in\n${fixes.join('\n')}, hasFixAllFix = '
+          '$hasFixAllFix');
+    }
+    return foundFix;
   }
 
   void _assertLinkedGroup(LinkedEditGroup group, List<String> expectedStrings,
@@ -151,8 +211,13 @@
    * Computes fixes for the given [error] in [testUnit].
    */
   Future<List<Fix>> _computeFixes(AnalysisError error) async {
-    DartFixContext fixContext = new _DartFixContextImpl(resourceProvider,
-        driver, new AstProviderForDriver(driver), testUnit, error);
+    DartFixContext fixContext = new _DartFixContextImpl(
+        resourceProvider,
+        driver,
+        new AstProviderForDriver(driver),
+        testUnit,
+        error,
+        await _computeErrors());
     return await new DefaultFixContributor().internalComputeFixes(fixContext);
   }
 
@@ -189,6 +254,14 @@
     return errors[0];
   }
 
+  Future<AnalysisError> _findErrorToFixOfType(ErrorCode errorCode) async {
+    List<AnalysisError> errors = await _computeErrors();
+    if (errorFilter != null) {
+      errors = errors.where(errorFilter).toList();
+    }
+    return errors.firstWhere((error) => errorCode == error.errorCode);
+  }
+
   List<Position> _findResultPositions(List<String> searchStrings) {
     List<Position> positions = <Position>[];
     for (String search in searchStrings) {
@@ -5119,6 +5192,71 @@
 ''');
   }
 
+  test_removeUnusedImport_all() async {
+    await resolveTestUnit('''
+import 'dart:math';
+import 'dart:math';
+import 'dart:math';
+main() {
+}
+''');
+    await assertHasFixAllFix(
+        HintCode.UNUSED_IMPORT, DartFixKind.REMOVE_UNUSED_IMPORT, '''
+main() {
+}
+''');
+  }
+
+  test_removeUnusedImport_all_diverseImports() async {
+    await resolveTestUnit('''
+import 'dart:math';
+import 'dart:math';
+import 'dart:async';
+main() {
+}
+''');
+    await assertHasFixAllFix(
+        HintCode.UNUSED_IMPORT, DartFixKind.REMOVE_UNUSED_IMPORT, '''
+main() {
+}
+''');
+  }
+
+  test_removeUnusedImport_all_diverseImports2() async {
+    await resolveTestUnit('''
+import 'dart:async';
+import 'dart:math' as math;
+import 'dart:async';
+
+var tau = math.pi * 2;
+
+main() {
+}
+''');
+    await assertHasFixAllFix(
+        HintCode.UNUSED_IMPORT, DartFixKind.REMOVE_UNUSED_IMPORT, '''
+import 'dart:math' as math;
+
+var tau = math.pi * 2;
+
+main() {
+}
+''');
+  }
+
+  test_removeUnusedImport_all_singleLine() async {
+    await resolveTestUnit('''
+import 'dart:math'; import 'dart:math'; import 'dart:math';
+main() {
+}
+''');
+    await assertHasFixAllFix(
+        HintCode.UNUSED_IMPORT, DartFixKind.REMOVE_UNUSED_IMPORT, '''
+main() {
+}
+''');
+  }
+
   test_replaceVarWithDynamic() async {
     errorFilter = (AnalysisError error) {
       return error.errorCode == ParserErrorCode.VAR_AS_TYPE_NAME;
@@ -7923,8 +8061,11 @@
   @override
   final AnalysisError error;
 
+  @override
+  final List<AnalysisError> errors;
+
   _DartFixContextImpl(this.resourceProvider, this.analysisDriver,
-      this.astProvider, this.unit, this.error);
+      this.astProvider, this.unit, this.error, this.errors);
 
   @override
   GetTopLevelDeclarations get getTopLevelDeclarations =>
diff --git a/pkg/analysis_server/test/src/computer/outline_computer_test.dart b/pkg/analysis_server/test/src/computer/outline_computer_test.dart
index 67e9b9b..23079a7 100644
--- a/pkg/analysis_server/test/src/computer/outline_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/outline_computer_test.dart
@@ -546,6 +546,20 @@
     expect(outline, isNotNull);
   }
 
+  /**
+   * Code like this caused Dart2 failure in the past.
+   *
+   * https://github.com/dart-lang/sdk/issues/33228
+   */
+  test_invocation_ofParameter() async {
+    Outline outline = await _computeOutline('''
+main(p()) {
+  p();
+}
+''');
+    expect(outline, isNotNull);
+  }
+
   test_isTest_isTestGroup() async {
     addMetaPackageSource();
     Outline outline = await _computeOutline('''
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 5fd654d..f5cb609 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -34,7 +34,7 @@
 }
 
 ContextRoot _newContextRoot(String root, {List<String> exclude: const []}) {
-  return new ContextRoot(path.context, root, exclude);
+  return new ContextRoot(root, exclude, pathContext: path.context);
 }
 
 @reflectiveTest
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 0951011..694d46e 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
@@ -50,8 +50,8 @@
     newFile(
         '/pkg2/${PluginLocator.toolsFolderName}/${PluginLocator.defaultPluginFolderName}/bin/plugin.dart');
 
-    ContextRoot contextRoot =
-        new ContextRoot(resourceProvider.pathContext, pkg1Path, []);
+    ContextRoot contextRoot = new ContextRoot(pkg1Path, [],
+        pathContext: resourceProvider.pathContext);
     TestDriver driver = new TestDriver(resourceProvider, contextRoot);
     driver.analysisOptions.enabledPluginNames = ['pkg2'];
     watcher.addedDriver(driver, contextRoot);
@@ -80,8 +80,8 @@
     String pkg1Path = newFolder('/pkg1').path;
     newFile('/pkg1/lib/test1.dart');
 
-    ContextRoot contextRoot =
-        new ContextRoot(resourceProvider.pathContext, pkg1Path, []);
+    ContextRoot contextRoot = new ContextRoot(pkg1Path, [],
+        pathContext: resourceProvider.pathContext);
     TestDriver driver = new TestDriver(resourceProvider, contextRoot);
     driver.analysisOptions.enabledPluginNames = ['pkg3'];
     watcher.addedDriver(driver, contextRoot);
@@ -102,8 +102,8 @@
 
   test_removedDriver() {
     String pkg1Path = newFolder('/pkg1').path;
-    ContextRoot contextRoot =
-        new ContextRoot(resourceProvider.pathContext, pkg1Path, []);
+    ContextRoot contextRoot = new ContextRoot(pkg1Path, [],
+        pathContext: resourceProvider.pathContext);
     TestDriver driver = new TestDriver(resourceProvider, contextRoot);
     watcher.addedDriver(driver, contextRoot);
     watcher.removedDriver(driver);
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 8d9ed60..92c46dc 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 0.32.1-alpha.0
+
+* Add the ability to specify a pathContext when creating a ContextRoot (not part
+  of the officially supported API, but needed by some clients).
+* AnalysisSession now exports resourceProvider.
+* Function type parameters are now invariant. (#29014)
+* New logic to find source files generated by package:build when that build
+  system is detected.
+* Data stored by FileDataStore is now checked using CRC32.
+* Add ability for the angular plugin to set ErrorVerifier.enclosingClass.
+
 ## 0.32.0
 
 * Allow annotations on enum constants.
diff --git a/pkg/analyzer/lib/src/context/context_root.dart b/pkg/analyzer/lib/src/context/context_root.dart
index 1c32428..ebb208b7 100644
--- a/pkg/analyzer/lib/src/context/context_root.dart
+++ b/pkg/analyzer/lib/src/context/context_root.dart
@@ -38,7 +38,8 @@
   /**
    * Initialize a newly created context root.
    */
-  ContextRoot(this.pathContext, this.root, this.exclude);
+  ContextRoot(this.root, this.exclude, {path.Context pathContext})
+      : pathContext = pathContext ?? path.context;
 
   @override
   int get hashCode {
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
index 2d54d53..bf4d9ba 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
@@ -80,9 +80,8 @@
     builder.performanceLog = performanceLog;
 
     old.ContextRoot oldContextRoot = new old.ContextRoot(
-        resourceProvider.pathContext,
-        contextRoot.root.path,
-        contextRoot.excludedPaths.toList());
+        contextRoot.root.path, contextRoot.excludedPaths.toList(),
+        pathContext: resourceProvider.pathContext);
     AnalysisDriver driver = builder.buildDriver(oldContextRoot);
     DriverBasedAnalysisContext context =
         new DriverBasedAnalysisContext(resourceProvider, contextRoot, driver);
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 5d290be..5f36fcb 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -101,9 +101,8 @@
     List<AnalysisContext> contextList = <AnalysisContext>[];
     for (ContextRoot root in roots) {
       old.ContextRoot contextRoot = new old.ContextRoot(
-          resourceProvider.pathContext,
-          root.root.path,
-          root.excludedPaths.toList());
+          root.root.path, root.excludedPaths.toList(),
+          pathContext: resourceProvider.pathContext);
       AnalysisDriver driver = builder.buildDriver(contextRoot);
       DriverBasedAnalysisContext context =
           new DriverBasedAnalysisContext(resourceProvider, root, driver);
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 0d4084c..0563ff8 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -95,7 +95,7 @@
   /**
    * The version of data format, should be incremented on every format change.
    */
-  static const int DATA_VERSION = 59;
+  static const int DATA_VERSION = 60;
 
   /**
    * The number of exception contexts allowed to write. Once this field is
@@ -201,6 +201,13 @@
   final _requestedFiles = <String, List<Completer<AnalysisResult>>>{};
 
   /**
+   * The task that discovers available files.  If this field is not `null`,
+   * and the task is not completed, it should be performed and completed
+   * before any name searching task.
+   */
+  _DiscoverAvailableFilesTask _discoverAvailableFilesTask;
+
+  /**
    * The list of tasks to compute files defining a class member name.
    */
   final _definingClassMemberNameTasks = <_FilesDefiningClassMemberNameTask>[];
@@ -478,6 +485,10 @@
     if (_requestedFiles.isNotEmpty) {
       return AnalysisDriverPriority.interactive;
     }
+    if (_discoverAvailableFilesTask != null &&
+        !_discoverAvailableFilesTask.isCompleted) {
+      return AnalysisDriverPriority.interactive;
+    }
     if (_definingClassMemberNameTasks.isNotEmpty ||
         _referencingNameTasks.isNotEmpty) {
       return AnalysisDriverPriority.interactive;
@@ -650,6 +661,7 @@
    * define a class member with the given [name].
    */
   Future<List<String>> getFilesDefiningClassMemberName(String name) {
+    _discoverAvailableFiles();
     var task = new _FilesDefiningClassMemberNameTask(this, name);
     _definingClassMemberNameTasks.add(task);
     _scheduler.notify(this);
@@ -661,6 +673,7 @@
    * reference the given external [name].
    */
   Future<List<String>> getFilesReferencingName(String name) {
+    _discoverAvailableFiles();
     var task = new _FilesReferencingNameTask(this, name);
     _referencingNameTasks.add(task);
     _scheduler.notify(this);
@@ -793,6 +806,7 @@
    */
   Future<List<TopLevelDeclarationInSource>> getTopLevelNameDeclarations(
       String name) {
+    _discoverAvailableFiles();
     var task = new _TopLevelNameDeclarationsTask(this, name);
     _topLevelNameDeclarationsTasks.add(task);
     _scheduler.notify(this);
@@ -967,6 +981,13 @@
       return;
     }
 
+    // Discover available files.
+    if (_discoverAvailableFilesTask != null &&
+        !_discoverAvailableFilesTask.isCompleted) {
+      _discoverAvailableFilesTask.perform();
+      return;
+    }
+
     // Compute files defining a name.
     if (_definingClassMemberNameTasks.isNotEmpty) {
       _FilesDefiningClassMemberNameTask task =
@@ -1417,6 +1438,14 @@
   }
 
   /**
+   * If this has not been done yet, schedule discovery of all files that are
+   * potentially available, so that they are included in [knownFiles].
+   */
+  void _discoverAvailableFiles() {
+    _discoverAvailableFilesTask ??= new _DiscoverAvailableFilesTask(this);
+  }
+
+  /**
    * Fill [_salt] with data.
    */
   void _fillSalt() {
@@ -2223,6 +2252,79 @@
 }
 
 /**
+ * Task that discovers all files that are available to the driver, and makes
+ * them known.
+ */
+class _DiscoverAvailableFilesTask {
+  static const int _MS_WORK_INTERVAL = 5;
+
+  final AnalysisDriver driver;
+
+  bool isCompleted = false;
+
+  Iterator<Folder> folderIterator;
+  List<String> files;
+  int fileIndex = 0;
+
+  _DiscoverAvailableFilesTask(this.driver);
+
+  /**
+   * Perform the next piece of work, and set [isCompleted] to `true` to
+   * indicate that the task is done, or keeps it `false` to indicate that the
+   * task should continue to be run.
+   */
+  void perform() {
+    // Prepare the iterator of package/lib folders.
+    if (folderIterator == null) {
+      var packageMap = driver._sourceFactory.packageMap;
+      if (packageMap != null) {
+        folderIterator = packageMap.values.expand((f) => f).iterator;
+        files = <String>[];
+      } else {
+        isCompleted = true;
+        return;
+      }
+    }
+
+    // List each package/lib folder recursively.
+    Stopwatch timer = new Stopwatch()..start();
+    while (folderIterator.moveNext()) {
+      if (timer.elapsedMilliseconds > _MS_WORK_INTERVAL) {
+        return;
+      }
+      var folder = folderIterator.current;
+      _appendFilesRecursively(folder);
+    }
+
+    // Get know files one by one.
+    while (fileIndex < files.length) {
+      if (timer.elapsedMilliseconds > _MS_WORK_INTERVAL) {
+        return;
+      }
+      var file = files[fileIndex++];
+      driver._fsState.getFileForPath(file);
+    }
+
+    // The task is done, clean up.
+    isCompleted = true;
+    folderIterator = null;
+    files = null;
+  }
+
+  void _appendFilesRecursively(Folder folder) {
+    try {
+      for (var child in folder.getChildren()) {
+        if (child is File) {
+          files.add(child.path);
+        } else if (child is Folder) {
+          _appendFilesRecursively(child);
+        }
+      }
+    } catch (_) {}
+  }
+}
+
+/**
  * Information about an exception and its context.
  */
 class _ExceptionState {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index ac82f5f..822d245 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1281,7 +1281,7 @@
         if (_kernel.mixedInType != null) {
           _kernelMixins.add(_kernel.mixedInType);
         }
-        while (supertype.classNode.isSyntheticMixinImplementation) {
+        while (supertype.classNode.isAnonymousMixin) {
           var superNode = supertype.classNode;
           var substitute = kernel.Substitution.fromSupertype(supertype);
 
@@ -1855,7 +1855,7 @@
   List<ClassElement> get types {
     if (_kernelContext != null) {
       _types ??= _kernelContext.kernelUnit.classes
-          .where((k) => !k.isEnum && !k.isSyntheticMixinImplementation)
+          .where((k) => !k.isEnum && !k.isAnonymousMixin)
           .map((k) => new ClassElementImpl.forKernel(this, k))
           .toList(growable: false);
     }
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 5d91528..3ccdac9 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1175,8 +1175,8 @@
 
   /**
    * Compares two function types [t] and [s] to see if their corresponding
-   * parameter types match [parameterRelation] and their return types match
-   * [returnRelation].
+   * parameter types match [parameterRelation], return types match
+   * [returnRelation], and type parameter bounds match [boundsRelation].
    *
    * Used for the various relations on function types which have the same
    * structural rules for handling optional parameters and arity, but use their
@@ -1184,14 +1184,20 @@
    *
    * If [parameterRelation] is omitted, uses [returnRelation] for both. This
    * is convenient for Dart 1 type system methods.
+   *
+   * If [boundsRelation] is omitted, uses [returnRelation]. This is for
+   * backwards compatibility, and convenience for Dart 1 type system methods.
    */
   static bool relate(
       FunctionType t,
       DartType other,
       bool returnRelation(DartType t, DartType s),
       DartType instantiateToBounds(DartType t),
-      {bool parameterRelation(ParameterElement t, ParameterElement s)}) {
+      {bool parameterRelation(ParameterElement t, ParameterElement s),
+      bool boundsRelation(DartType bound2, DartType bound1,
+          TypeParameterElement formal2, TypeParameterElement formal1)}) {
     parameterRelation ??= (t, s) => returnRelation(t.type, s.type);
+    boundsRelation ??= (t, s, _, __) => returnRelation(t, s);
 
     // Trivial base cases.
     if (other == null) {
@@ -1208,8 +1214,7 @@
     // This type cast is safe, because we checked it above.
     FunctionType s = other as FunctionType;
     if (t.typeFormals.isNotEmpty) {
-      List<DartType> freshVariables =
-          relateTypeFormals(t, s, (s, t, _, __) => returnRelation(s, t));
+      List<DartType> freshVariables = relateTypeFormals(t, s, boundsRelation);
       if (freshVariables == null) {
         return false;
       }
diff --git a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
index 28b8ae0..94cbe97 100644
--- a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:front_end/src/fasta/kernel/body_builder.dart' show LabelTarget;
 import 'package:front_end/src/fasta/kernel/forest.dart';
 import 'package:kernel/ast.dart' as kernel;
 
@@ -103,6 +104,48 @@
   }
 
   @override
+  CatchClause catchClause(
+      Token onKeyword,
+      TypeAnnotation exceptionType,
+      Token catchKeyword,
+      SimpleIdentifier exceptionParameter,
+      SimpleIdentifier stackTraceParameter,
+      TypeAnnotation stackTraceType,
+      Statement body) {
+    // TODO(brianwilkerson) The following is not reliable in the presence of
+    // recovery. Consider passing the required tokens from the Parser to the
+    // BodyBuilder to here.
+    Token leftParenthesis;
+    if (catchKeyword != null) {
+      leftParenthesis = catchKeyword.next;
+    }
+    Token comma;
+    if (stackTraceParameter != null) {
+      comma = exceptionParameter.endToken.next;
+    }
+    Token rightParenthesis;
+    if (catchKeyword != null) {
+      if (stackTraceParameter != null) {
+        rightParenthesis = stackTraceParameter.endToken.next;
+      } else if (comma != null) {
+        rightParenthesis = comma.next;
+      } else {
+        rightParenthesis = exceptionParameter.endToken.next;
+      }
+    }
+    return astFactory.catchClause(
+        onKeyword,
+        exceptionType,
+        catchKeyword,
+        leftParenthesis,
+        exceptionParameter,
+        comma,
+        stackTraceParameter,
+        rightParenthesis,
+        body);
+  }
+
+  @override
   Expression checkLibraryIsLoaded(dependency) {
     // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
@@ -121,6 +164,16 @@
           continueKeyword, astFactory.simpleIdentifier(label.token), semicolon);
 
   @override
+  Generator<Expression, Statement, _Arguments> deferredAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token,
+      PrefixBuilder builder,
+      Generator<Expression, Statement, _Arguments> generator) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
   Statement doStatement(Token doKeyword, Statement body, Token whileKeyword,
           ParenthesizedExpression condition, Token semicolon) =>
       astFactory.doStatement(
@@ -148,7 +201,7 @@
           covariant initialization,
           Token leftSeparator,
           Expression condition,
-          Token rightSeparator,
+          Statement conditionStatement,
           List<Expression> updaters,
           Token rightParenthesis,
           Statement body) =>
@@ -159,7 +212,7 @@
           initialization,
           leftSeparator,
           condition,
-          rightSeparator,
+          getSemicolon(conditionStatement),
           updaters,
           rightParenthesis,
           body);
@@ -168,7 +221,13 @@
   Expression getExpressionFromExpressionStatement(Statement statement) =>
       (statement as ExpressionStatement).expression;
 
+  String getLabelName(Label label) => label.label.name;
+
   @override
+  int getLabelOffset(Label label) => label.offset;
+
+  /// Return the semicolon at the end of the given [statement], or `null` if the
+  /// statement is not terminated by a semicolon.
   Token getSemicolon(Statement statement) {
     if (statement is ExpressionStatement) {
       return statement.semicolon;
@@ -212,7 +271,7 @@
       Expression index,
       kernel.Procedure getter,
       kernel.Procedure setter) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
@@ -235,6 +294,9 @@
       statement is ExpressionStatement;
 
   @override
+  bool isLabel(covariant node) => node is Label;
+
+  @override
   bool isThisExpression(Object node) => node is ThisExpression;
 
   @override
@@ -242,6 +304,23 @@
       node is VariableDeclarationStatement && node.variables != 1;
 
   @override
+  Label label(Token identifier, Token colon) =>
+      astFactory.label(astFactory.simpleIdentifier(identifier), colon);
+
+  @override
+  Statement labeledStatement(
+          LabelTarget<Statement> target, Statement statement) =>
+      astFactory.labeledStatement(target.labels.cast<Label>(), statement);
+
+  @override
+  Generator<Expression, Statement, _Arguments> largeIntAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
   Expression literalBool(bool value, Token location) =>
       astFactory.booleanLiteral(location, value)
         ..staticType = _typeProvider?.boolType;
@@ -326,6 +405,15 @@
   }
 
   @override
+  Generator<Expression, Statement, _Arguments> loadLibraryGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token,
+      LoadLibraryBuilder builder) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
   Object mapEntry(Expression key, Token colon, Expression value) =>
       astFactory.mapLiteralEntry(key, colon, value);
 
@@ -346,7 +434,7 @@
       kernel.Member getter,
       kernel.Member setter,
       kernel.DartType type) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
@@ -364,7 +452,7 @@
       kernel.Name name,
       kernel.Member getter,
       kernel.Member setter) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
@@ -372,6 +460,16 @@
   int readOffset(AstNode node) => node.offset;
 
   @override
+  Generator<Expression, Statement, _Arguments> readOnlyAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token,
+      Expression expression,
+      String plainNameForRead) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
   void resolveBreak(Statement target, BreakStatement user) {
     user.target = target;
   }
@@ -397,18 +495,44 @@
       astFactory.returnStatement(returnKeyword, expression, semicolon);
 
   @override
+  void setParameterType(FormalParameter parameter, TypeAnnotation type) {
+    parameter.identifier.staticType = type.type;
+  }
+
+  @override
+  Generator<Expression, Statement, _Arguments> staticAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token,
+      kernel.Member getter,
+      kernel.Member setter) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
   Expression stringConcatenationExpression(
           List<Expression> strings, Token location) =>
       astFactory.adjacentStrings(strings.cast<StringLiteral>());
 
   @override
+  Generator<Expression, Statement, _Arguments> superIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token,
+      Expression index,
+      kernel.Member getter,
+      kernel.Member setter) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
   Generator<Expression, Statement, _Arguments> superPropertyAccessGenerator(
       ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
       Token token,
       kernel.Name name,
       kernel.Member getter,
       kernel.Member setter) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
@@ -426,7 +550,7 @@
       Expression index,
       kernel.Procedure getter,
       kernel.Procedure setter) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
@@ -437,7 +561,7 @@
       kernel.Name name,
       kernel.Member getter,
       kernel.Member setter) {
-    // TODO(brianwilkerson): Implement this.
+    // TODO(brianwilkerson) Implement this.
     throw new UnimplementedError();
   }
 
@@ -456,6 +580,18 @@
           tryKeyword, body, catchClauses, finallyKeyword, finallyBlock);
 
   @override
+  Generator<Expression, Statement, _Arguments> typeUseGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, _Arguments> helper,
+      Token token,
+      PrefixBuilder prefix,
+      int declarationReferenceOffset,
+      TypeDeclarationBuilder declaration,
+      String plainNameForRead) {
+    // TODO(brianwilkerson) Implement this.
+    throw new UnimplementedError();
+  }
+
+  @override
   VariableDeclarationStatement variablesDeclaration(
       List<VariableDeclaration> declarations, Uri uri) {
     // TODO(brianwilkerson) Implement this.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 185d6d3..6fdac95 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -76,17 +76,21 @@
       }
       Element element = nameScope.lookup(methodName, definingLibrary);
       if (element is ClassElement) {
+        ConstructorElement constructorElement = element.unnamedConstructor;
         AstFactory astFactory = new AstFactoryImpl();
         TypeName typeName = astFactory.typeName(methodName, node.typeArguments);
+        ConstructorName constructorName =
+            astFactory.constructorName(typeName, null, null);
         InstanceCreationExpression instanceCreationExpression =
             astFactory.instanceCreationExpression(
-                _getKeyword(node),
-                astFactory.constructorName(typeName, null, null),
-                node.argumentList);
+                _getKeyword(node), constructorName, node.argumentList);
         DartType type = _getType(element, node.typeArguments);
         methodName.staticElement = element;
         methodName.staticType = type;
         typeName.type = type;
+        constructorName.staticElement = constructorElement;
+        instanceCreationExpression.staticType = type;
+        instanceCreationExpression.staticElement = constructorElement;
         NodeReplacer.replace(node, instanceCreationExpression);
       }
     } else if (target is SimpleIdentifier) {
@@ -98,19 +102,22 @@
       Element element = nameScope.lookup(target, definingLibrary);
       if (element is ClassElement) {
         // Possible case: C.n()
-        if (element.getNamedConstructor(methodName.name) != null) {
+        var constructorElement = element.getNamedConstructor(methodName.name);
+        if (constructorElement != null) {
           AstFactory astFactory = new AstFactoryImpl();
           TypeName typeName = astFactory.typeName(target, node.typeArguments);
+          ConstructorName constructorName =
+              astFactory.constructorName(typeName, node.operator, methodName);
           InstanceCreationExpression instanceCreationExpression =
               astFactory.instanceCreationExpression(
-                  _getKeyword(node),
-                  astFactory.constructorName(
-                      typeName, node.operator, methodName),
-                  node.argumentList);
+                  _getKeyword(node), constructorName, node.argumentList);
           DartType type = _getType(element, node.typeArguments);
           methodName.staticElement = element;
           methodName.staticType = type;
           typeName.type = type;
+          constructorName.staticElement = constructorElement;
+          instanceCreationExpression.staticType = type;
+          instanceCreationExpression.staticElement = constructorElement;
           NodeReplacer.replace(node, instanceCreationExpression);
         }
       } else if (element is PrefixElement) {
@@ -122,18 +129,23 @@
             astFactory.simpleIdentifier(methodName.token));
         Element prefixedElement = nameScope.lookup(identifier, definingLibrary);
         if (prefixedElement is ClassElement) {
+          ConstructorElement constructorElement =
+              prefixedElement.unnamedConstructor;
           TypeName typeName = astFactory.typeName(
               astFactory.prefixedIdentifier(target, node.operator, methodName),
               node.typeArguments);
+          ConstructorName constructorName =
+              astFactory.constructorName(typeName, null, null);
           InstanceCreationExpression instanceCreationExpression =
               astFactory.instanceCreationExpression(
-                  _getKeyword(node),
-                  astFactory.constructorName(typeName, null, null),
-                  node.argumentList);
+                  _getKeyword(node), constructorName, node.argumentList);
           DartType type = _getType(prefixedElement, node.typeArguments);
           methodName.staticElement = element;
           methodName.staticType = type;
           typeName.type = type;
+          constructorName.staticElement = constructorElement;
+          instanceCreationExpression.staticType = type;
+          instanceCreationExpression.staticElement = constructorElement;
           NodeReplacer.replace(node, instanceCreationExpression);
         }
       }
@@ -143,19 +155,22 @@
       if (prefixElement is PrefixElement) {
         Element element = nameScope.lookup(target, definingLibrary);
         if (element is ClassElement) {
-          if (element.getNamedConstructor(methodName.name) != null) {
+          var constructorElement = element.getNamedConstructor(methodName.name);
+          if (constructorElement != null) {
             AstFactory astFactory = new AstFactoryImpl();
             TypeName typeName = astFactory.typeName(target, node.typeArguments);
+            ConstructorName constructorName =
+                astFactory.constructorName(typeName, node.operator, methodName);
             InstanceCreationExpression instanceCreationExpression =
                 astFactory.instanceCreationExpression(
-                    _getKeyword(node),
-                    astFactory.constructorName(
-                        typeName, node.operator, methodName),
-                    node.argumentList);
+                    _getKeyword(node), constructorName, node.argumentList);
             DartType type = _getType(element, node.typeArguments);
             methodName.staticElement = element;
             methodName.staticType = type;
             typeName.type = type;
+            constructorName.staticElement = constructorElement;
+            instanceCreationExpression.staticType = type;
+            instanceCreationExpression.staticElement = constructorElement;
             NodeReplacer.replace(node, instanceCreationExpression);
           }
         }
@@ -6748,6 +6763,9 @@
    */
   void _inferFunctionExpressionParametersTypes(
       Expression mayBeClosure, DartType mayByFunctionType) {
+    // TODO(mfairhurst): remove this code and callers. It's doing
+    // "propagated type" inference for the Dart 1 type system.
+    assert(!strongMode);
     // prepare closure
     if (mayBeClosure is! FunctionExpression) {
       return;
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index d693693..c7e14c8 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -272,6 +272,9 @@
  * An implementation of an non-existing [Source].
  */
 class NonExistingSource extends Source {
+  static final unknown = new NonExistingSource(
+      '/unknown.dart', pathos.toUri('/unknown.dart'), UriKind.FILE_URI);
+
   @override
   final String fullName;
 
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index d178f25..ab376a1 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -646,18 +646,14 @@
 
     if (t1 is FunctionType && t2 is FunctionType) {
       return FunctionTypeImpl.relate(
-          t1,
-          t2,
-          (t1, t2) {
-            // TODO(jmesserly): should we flip covariance when we're relating
-            // type formal bounds? They're more like parameters.
-            return matchSubtype(t1, t2);
-          },
-          _typeSystem.instantiateToBounds,
+          t1, t2, matchSubtype, _typeSystem.instantiateToBounds,
           parameterRelation: (p1, p2) {
             return _matchSubtypeOf(p2.type, p1.type, null, origin,
                 covariant: !covariant);
-          });
+          },
+          // Type parameter bounds are invariant.
+          boundsRelation: (t1, t2, p1, p2) =>
+              matchSubtype(t1, t2) && matchSubtype(t2, t1));
     }
 
     if (t1 is FunctionType && t2 == typeProvider.functionType) {
@@ -1181,7 +1177,10 @@
   /// - it allows opt-in covariant parameters.
   bool isOverrideSubtypeOf(FunctionType f1, FunctionType f2) {
     return FunctionTypeImpl.relate(f1, f2, isSubtypeOf, instantiateToBounds,
-        parameterRelation: isOverrideSubtypeOfParameter);
+        parameterRelation: isOverrideSubtypeOfParameter,
+        // Type parameter bounds are invariant.
+        boundsRelation: (t1, t2, p1, p2) =>
+            isSubtypeOf(t1, t2) && isSubtypeOf(t2, t1));
   }
 
   /// Check that parameter [p2] is a subtype of [p1], given that we are
@@ -1522,7 +1521,10 @@
   /// Check that [f1] is a subtype of [f2].
   bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2) {
     return FunctionTypeImpl.relate(f1, f2, isSubtypeOf, instantiateToBounds,
-        parameterRelation: (p1, p2) => isSubtypeOf(p2.type, p1.type));
+        parameterRelation: (p1, p2) => isSubtypeOf(p2.type, p1.type),
+        // Type parameter bounds are invariant.
+        boundsRelation: (t1, t2, p1, p2) =>
+            isSubtypeOf(t1, t2) && isSubtypeOf(t2, t1));
   }
 
   bool _isInterfaceSubtypeOf(
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 03cdb82..2a7256e 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.32.0
+version: 0.32.1-alpha.0
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -11,10 +11,10 @@
   collection: ^1.10.1
   convert: ^2.0.0
   crypto: '>=1.1.1 <3.0.0'
-  front_end: 0.1.0
+  front_end: 0.1.1-alpha.0
   glob: ^1.0.3
   html: '>=0.12.0 <1.14.0'
-  kernel: 0.3.0
+  kernel: 0.3.1-alpha.0
   meta: ^1.0.2
   package_config: '>=0.1.5 <2.0.0'
   path: '>=0.9.0 <2.0.0'
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 6ef150d..73c2001 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -4786,6 +4786,49 @@
     assertNoErrors(source);
   }
 
+  test_optionalNew_rewrite() async {
+    resetWith(
+        options: new AnalysisOptionsImpl()
+          ..previewDart2 = true
+          ..strongMode = true);
+    Source source = addSource(r'''
+import 'b.dart';
+main() {
+  const B.named1();
+  const B.named2();
+  const B.named3();
+  const B.named4();
+}
+''');
+    addNamedSource("/a.dart", r'''
+class A {
+  const A();
+  const A.named();
+}
+''');
+    addNamedSource("/b.dart", r'''
+import 'a.dart';
+import 'a.dart' as p;
+
+const _a1 = A();
+const _a2 = A.named();
+const _a3 = p.A();
+const _a4 = p.A.named();
+
+class B {
+  const B.named1({this.a: _a1}) : assert(a != null);
+  const B.named2({this.a: _a2}) : assert(a != null);
+  const B.named3({this.a: _a3}) : assert(a != null);
+  const B.named4({this.a: _a4}) : assert(a != null);
+
+  final A a;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   test_optionalParameterInOperator_required() async {
     Source source = addSource(r'''
 class A {
diff --git a/pkg/analyzer/test/generated/package_build_test.dart b/pkg/analyzer/test/generated/package_build_test.dart
index 1b2dedd..a731844 100644
--- a/pkg/analyzer/test/generated/package_build_test.dart
+++ b/pkg/analyzer/test/generated/package_build_test.dart
@@ -116,8 +116,9 @@
 
   Uri addPackageSource(String path, String uriStr, {bool create: true}) {
     Uri uri = Uri.parse(uriStr);
-    final File file =
-        create ? provider.newFile(_p(path), '') : provider.getResource(path);
+    final File file = create
+        ? provider.newFile(_p(path), '')
+        : provider.getResource(_p(path));
     final Source source = file.createSource(uri);
     when(packageUriResolver.resolveAbsolute(uri)).thenReturn(source);
     return uri;
@@ -226,7 +227,7 @@
 
     final libFile = provider.newFile(
         _p('/workspace/.dart_tool/build/generated/project/lib/file.dart'), '');
-    expect(workspace.builtFile('lib/file.dart', 'project'), libFile);
+    expect(workspace.builtFile(_p('lib/file.dart'), 'project'), libFile);
   }
 
   void test_builtFile_importedPackage() {
@@ -238,7 +239,7 @@
 
     final libFile = provider.newFile(
         _p('/workspace/.dart_tool/build/generated/foo/lib/file.dart'), '');
-    expect(workspace.builtFile('lib/file.dart', 'foo'), libFile);
+    expect(workspace.builtFile(_p('lib/file.dart'), 'foo'), libFile);
   }
 
   void test_builtFile_notInPackagesGetsHidden() {
@@ -382,7 +383,7 @@
         _createWorkspace('/workspace', ['project']);
 
     final binFile = provider.newFile(_p('/workspace/bin/file.dart'), '');
-    expect(workspace.findFile('/workspace/bin/file.dart'), binFile);
+    expect(workspace.findFile(_p('/workspace/bin/file.dart')), binFile);
   }
 
   void test_findFile_binGenerated() {
@@ -394,7 +395,7 @@
 
     final binFile = provider.newFile(
         _p('/workspace/.dart_tool/build/generated/project/bin/file.dart'), '');
-    expect(workspace.findFile('/workspace/bin/file.dart'), binFile);
+    expect(workspace.findFile(_p('/workspace/bin/file.dart')), binFile);
   }
 
   void test_findFile_libGenerated() {
@@ -406,7 +407,7 @@
 
     final libFile = provider.newFile(
         _p('/workspace/.dart_tool/build/generated/project/lib/file.dart'), '');
-    expect(workspace.findFile('/workspace/lib/file.dart'), libFile);
+    expect(workspace.findFile(_p('/workspace/lib/file.dart')), libFile);
   }
 
   void test_findFile_test() {
@@ -418,7 +419,7 @@
         _createWorkspace('/workspace', ['project']);
 
     final testFile = provider.newFile(_p('/workspace/test/file.dart'), '');
-    expect(workspace.findFile('/workspace/test/file.dart'), testFile);
+    expect(workspace.findFile(_p('/workspace/test/file.dart')), testFile);
   }
 
   void test_findFile_testGenerated() {
@@ -431,7 +432,7 @@
 
     final testFile = provider.newFile(
         _p('/workspace/.dart_tool/build/generated/project/test/file.dart'), '');
-    expect(workspace.findFile('/workspace/test/file.dart'), testFile);
+    expect(workspace.findFile(_p('/workspace/test/file.dart')), testFile);
   }
 
   void test_findFile_web() {
@@ -442,7 +443,7 @@
         _createWorkspace('/workspace', ['project']);
 
     final webFile = provider.newFile(_p('/workspace/web/file.dart'), '');
-    expect(workspace.findFile('/workspace/web/file.dart'), webFile);
+    expect(workspace.findFile(_p('/workspace/web/file.dart')), webFile);
   }
 
   void test_findFile_webGenerated() {
@@ -454,7 +455,7 @@
 
     final webFile = provider.newFile(
         _p('/workspace/.dart_tool/build/generated/project/web/file.dart'), '');
-    expect(workspace.findFile('/workspace/web/file.dart'), webFile);
+    expect(workspace.findFile(_p('/workspace/web/file.dart')), webFile);
   }
 
   PackageBuildWorkspace _createWorkspace(
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index e634c00..2ff080d 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -53,12 +53,6 @@
 @reflectiveTest
 class ClassMemberParserTest_Fasta extends FastaParserTestCase
     with ClassMemberParserTestMixin {
-  @failingTest
-  @override
-  void test_parseAwaitExpression_inSync() {
-    super.test_parseAwaitExpression_inSync();
-  }
-
   @override
   void test_parseClassMember_method_generic_comment_noReturnType() {
     // Ignored: Fasta does not support the generic comment syntax.
@@ -1318,13 +1312,6 @@
 
   @override
   @failingTest
-  void test_incompleteTypeArguments_field() {
-    // TODO(brianwilkerson) reportUnrecoverableErrorWithToken
-    super.test_incompleteTypeArguments_field();
-  }
-
-  @override
-  @failingTest
   void test_missingIdentifier_afterAnnotation() {
     // TODO(brianwilkerson) reportUnrecoverableErrorWithToken
     super.test_missingIdentifier_afterAnnotation();
diff --git a/pkg/analyzer/test/generated/parser_forest_test.dart b/pkg/analyzer/test/generated/parser_forest_test.dart
index 1ec29cc..5908df2 100644
--- a/pkg/analyzer/test/generated/parser_forest_test.dart
+++ b/pkg/analyzer/test/generated/parser_forest_test.dart
@@ -891,6 +891,16 @@
   }
 
   @failingTest
+  void test_constructorPartial2() {
+    super.test_constructorPartial();
+  }
+
+  @failingTest
+  void test_constructorPartial3() {
+    super.test_constructorPartial();
+  }
+
+  @failingTest
   void test_constructorWithReturnType() {
     super.test_constructorWithReturnType();
   }
@@ -4279,6 +4289,11 @@
   }
 
   @failingTest
+  void test_incompleteTypeParameters3() {
+    super.test_incompleteTypeParameters3();
+  }
+
+  @failingTest
   void test_invalidFunctionBodyModifier() {
     super.test_invalidFunctionBodyModifier();
   }
@@ -5045,21 +5060,11 @@
   }
 
   @failingTest
-  void test_parseBreakStatement_label() {
-    super.test_parseBreakStatement_label();
-  }
-
-  @failingTest
   void test_parseBreakStatement_noLabel() {
     super.test_parseBreakStatement_noLabel();
   }
 
   @failingTest
-  void test_parseContinueStatement_label() {
-    super.test_parseContinueStatement_label();
-  }
-
-  @failingTest
   void test_parseContinueStatement_noLabel() {
     super.test_parseContinueStatement_noLabel();
   }
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 7b529d3..35b6075 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -372,13 +372,22 @@
   }
 
   void test_parseAwaitExpression_inSync() {
-    // This test requires better error recovery than we currently have. In
-    // particular, we need to be able to distinguish between an await expression
-    // in the wrong context, and the use of 'await' as an identifier.
     createParser('m() { return await x + await y; }');
     MethodDeclaration method = parser.parseClassMember('C');
     expect(method, isNotNull);
-    assertNoErrors();
+    listener.assertErrors(usingFastaParser
+        ? [
+            expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 13, 5),
+            expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 23, 5)
+          ]
+        : [
+            // This test requires better error recovery than we currently have.
+            // In particular, we need to be able to distinguish
+            // between an await expression in the wrong context,
+            // and the use of 'await' as an identifier.
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 13, 5),
+            expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 29, 1)
+          ]);
     FunctionBody body = method.body;
     EngineTestCase.assertInstanceOf(
         (obj) => obj is BlockFunctionBody, BlockFunctionBody, body);
@@ -388,10 +397,13 @@
     Expression expression = (statement as ReturnStatement).expression;
     EngineTestCase.assertInstanceOf(
         (obj) => obj is BinaryExpression, BinaryExpression, expression);
-    EngineTestCase.assertInstanceOf((obj) => obj is AwaitExpression,
-        AwaitExpression, (expression as BinaryExpression).leftOperand);
-    EngineTestCase.assertInstanceOf((obj) => obj is AwaitExpression,
-        AwaitExpression, (expression as BinaryExpression).rightOperand);
+    if (!usingFastaParser) {
+      // TODO(danrubel): capture `await` keywords in fasta generated AST
+      EngineTestCase.assertInstanceOf((obj) => obj is AwaitExpression,
+          AwaitExpression, (expression as BinaryExpression).leftOperand);
+      EngineTestCase.assertInstanceOf((obj) => obj is AwaitExpression,
+          AwaitExpression, (expression as BinaryExpression).rightOperand);
+    }
   }
 
   void test_parseClassMember_constructor_withDocComment() {
@@ -2703,6 +2715,42 @@
           ]);
   }
 
+  void test_constructorPartial2() {
+    createParser('class C { C<@Foo }');
+    parser.parseCompilationUnit2();
+    listener.assertErrors(usingFastaParser
+        ? [
+            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 17, 1),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 17, 1),
+            expectedError(ParserErrorCode.MISSING_METHOD_PARAMETERS, 10, 1),
+            expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 17, 1)
+          ]
+        : [
+            expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 12, 1),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 1),
+            expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 12, 1),
+            expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 17, 1)
+          ]);
+  }
+
+  void test_constructorPartial3() {
+    createParser('class C { C<@Foo @Bar() }');
+    parser.parseCompilationUnit2();
+    listener.assertErrors(usingFastaParser
+        ? [
+            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 24, 1),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 24, 1),
+            expectedError(ParserErrorCode.MISSING_METHOD_PARAMETERS, 10, 1),
+            expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 24, 1)
+          ]
+        : [
+            expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 12, 1),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 12, 1),
+            expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 12, 1),
+            expectedError(ParserErrorCode.EXPECTED_CLASS_MEMBER, 24, 1)
+          ]);
+  }
+
   void test_constructorWithReturnType() {
     createParser('C C() {}');
     ClassMember member = parser.parseClassMember('C');
@@ -4420,12 +4468,15 @@
     // It doesn't try to advance past the invalid token `!` to find the
     // valid `>`. If it did we'd get less cascading errors, at least for this
     // particular example.
-    createParser('void m<E, hello!>() {}');
+    createParser('void m<E, hello!>() {}', expectedEndOffset: 6);
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
     listener.assertErrors(usingFastaParser
         ? [
-            expectedError(ParserErrorCode.EXPECTED_TOKEN, 15, 1) /*>*/
+            // TODO(danrubel): Improve recovery
+            expectedError(
+                ParserErrorCode.MISSING_METHOD_PARAMETERS, 5, 1) /*<*/,
+            expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 6, 1) /*E*/
           ]
         : [
             expectedError(ParserErrorCode.EXPECTED_TOKEN, 0, 0) /*>*/,
@@ -4436,8 +4487,10 @@
           ]);
     expect(member, new isInstanceOf<MethodDeclaration>());
     MethodDeclaration method = member;
-    expect(method.typeParameters.toString(), '<E, hello>',
-        reason: 'parser recovers what it can');
+    if (!usingFastaParser) {
+      expect(method.typeParameters.toString(), '<E, hello>',
+          reason: 'parser recovers what it can');
+    }
   }
 
   void test_missingAssignableSelector_identifiersAssigned() {
@@ -10000,7 +10053,7 @@
     listener ??= AnalysisErrorListener.NULL_LISTENER;
     Scanner scanner = new Scanner(null, new CharSequenceReader(code), listener);
     Token token = scanner.tokenize();
-    Parser parser = new Parser(null, listener);
+    Parser parser = new Parser(NonExistingSource.unknown, listener);
     parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
     CompilationUnit unit = parser.parseCompilationUnit(token);
     unit.lineInfo = new LineInfo(scanner.lineStarts);
@@ -11474,7 +11527,7 @@
     CompilationUnit unit = parseCompilationUnit(r'''
 class C {
   final List<int f;
-}''', codes: [ParserErrorCode.EXPECTED_TOKEN]);
+}''', errors: [expectedError(ParserErrorCode.EXPECTED_TOKEN, 27, 1)]);
     // one class
     List<CompilationUnitMember> declarations = unit.declarations;
     expect(declarations, hasLength(1));
@@ -11532,6 +11585,26 @@
     expect(token.isSynthetic, isTrue);
   }
 
+  void test_incompleteTypeParameters3() {
+    CompilationUnit unit = parseCompilationUnit(r'''
+class C<K extends L<T {
+}''', errors: [
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 22, 1),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 22, 1)
+    ]);
+    // one class
+    List<CompilationUnitMember> declarations = unit.declarations;
+    expect(declarations, hasLength(1));
+    ClassDeclaration classDecl = declarations[0] as ClassDeclaration;
+    // validate the type parameters
+    TypeParameterList typeParameters = classDecl.typeParameters;
+    expect(typeParameters.typeParameters, hasLength(1));
+    // synthetic '>'
+    Token token = typeParameters.endToken;
+    expect(token.type, TokenType.GT);
+    expect(token.isSynthetic, isTrue);
+  }
+
   void test_invalidFunctionBodyModifier() {
     parseCompilationUnit("f() sync {}",
         codes: [ParserErrorCode.MISSING_STAR_AFTER_SYNC]);
@@ -11543,14 +11616,7 @@
   G<int double> g;
 }''',
         errors: usingFastaParser
-            ? [
-                // TODO(danrubel): Improve missing comma recovery.
-                expectedError(ParserErrorCode.EXPECTED_TOKEN, 18, 6),
-                expectedError(ParserErrorCode.MISSING_METHOD_PARAMETERS, 12, 1),
-                expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 26, 1),
-                expectedError(
-                    ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 26, 1),
-              ]
+            ? [expectedError(ParserErrorCode.EXPECTED_TOKEN, 18, 6)]
             : [
                 expectedError(ParserErrorCode.EXPECTED_TOKEN, 18, 6),
                 expectedError(ParserErrorCode.EXPECTED_TOKEN, 18, 6),
@@ -11564,12 +11630,12 @@
     expect(declarations, hasLength(1));
     // validate members
     if (usingFastaParser) {
-//      ClassDeclaration classDecl = declarations[0] as ClassDeclaration;
-//      expect(classDecl.members, hasLength(1));
-//      FieldDeclaration fields = classDecl.members.first;
-//      expect(fields.fields.variables, hasLength(1));
-//      VariableDeclaration field = fields.fields.variables.first;
-//      expect(field.name.name, 'g');
+      ClassDeclaration classDecl = declarations[0] as ClassDeclaration;
+      expect(classDecl.members, hasLength(1));
+      FieldDeclaration fields = classDecl.members.first;
+      expect(fields.fields.variables, hasLength(1));
+      VariableDeclaration field = fields.fields.variables.first;
+      expect(field.name.name, 'g');
     }
   }
 
@@ -13107,7 +13173,7 @@
   }
 
   void test_Parser() {
-    expect(new Parser(null, null), isNotNull);
+    expect(new Parser(NonExistingSource.unknown, null), isNotNull);
   }
 
   void test_parseTypeName_parameterized_nullable() {
diff --git a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
index fdd3388..763d120 100644
--- a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
@@ -357,9 +357,18 @@
 
   @override
   @failingTest
-  test_genericMethod_override_invalidTypeParamBounds() async {
+  test_genericMethod_override_invalidCovariantTypeParamBounds() async {
     // Expected 1 errors of type StrongModeCode.STRONG_MODE_INVALID_METHOD_OVERRIDE, found 0
-    await super.test_genericMethod_override_invalidTypeParamBounds();
+    await super
+        .test_genericMethod_override_invalidContravariantTypeParamBounds();
+  }
+
+  @override
+  @failingTest
+  test_genericMethod_override_invalidContravariantTypeParamBounds() async {
+    // Expected 1 errors of type StrongModeCode.STRONG_MODE_INVALID_METHOD_OVERRIDE, found 0
+    await super
+        .test_genericMethod_override_invalidContravariantTypeParamBounds();
   }
 
   @override
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 6a0a0b3..ab24845 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -3407,13 +3407,17 @@
   test_genericMethod_override_bounds() async {
     await resolveTestUnit(r'''
 class A {}
-class B extends A {}
-class C {
-  T f<T extends B>(T x) => null;
-}
-class D extends C {
+class B {
   T f<T extends A>(T x) => null;
 }
+// override with the same bound is OK
+class C extends B {
+  T f<T extends A>(T x) => null;
+}
+// override with new name and the same bound is OK
+class D extends B {
+  Q f<Q extends A>(Q x) => null;
+}
 ''');
   }
 
@@ -3433,20 +3437,27 @@
     verify([source]);
   }
 
-  test_genericMethod_override_invalidReturnType() async {
+  test_genericMethod_override_differentContextsSameBounds() async {
     Source source = addSource(r'''
-class C {
-  Iterable<T> f<T>(T x) => null;
+        class GenericMethodBounds<T> {
+  Type get t => T;
+  GenericMethodBounds<E> foo<E extends T>() => new GenericMethodBounds<E>();
+  GenericMethodBounds<E> bar<E extends void Function(T)>() =>
+      new GenericMethodBounds<E>();
 }
-class D extends C {
-  String f<S>(S x) => null;
-}''');
+
+class GenericMethodBoundsDerived extends GenericMethodBounds<num> {
+  GenericMethodBounds<E> foo<E extends num>() => new GenericMethodBounds<E>();
+  GenericMethodBounds<E> bar<E extends void Function(num)>() =>
+      new GenericMethodBounds<E>();
+}
+''');
     await computeAnalysisResult(source);
-    assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]);
+    assertNoErrors(source);
     verify([source]);
   }
 
-  test_genericMethod_override_invalidTypeParamBounds() async {
+  test_genericMethod_override_invalidContravariantTypeParamBounds() async {
     Source source = addSource(r'''
 class A {}
 class B extends A {}
@@ -3461,6 +3472,34 @@
     verify([source]);
   }
 
+  test_genericMethod_override_invalidCovariantTypeParamBounds() async {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C {
+  T f<T extends B>(T x) => null;
+}
+class D extends C {
+  T f<T extends A>(T x) => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]);
+    verify([source]);
+  }
+
+  test_genericMethod_override_invalidReturnType() async {
+    Source source = addSource(r'''
+class C {
+  Iterable<T> f<T>(T x) => null;
+}
+class D extends C {
+  String f<S>(S x) => null;
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [StrongModeCode.INVALID_METHOD_OVERRIDE]);
+    verify([source]);
+  }
+
   test_genericMethod_override_invalidTypeParamCount() async {
     Source source = addSource(r'''
 class C {
@@ -3910,6 +3949,48 @@
 ''');
   }
 
+  @failingTest
+  test_notInstantiatedBound_class_error_recursion() async {
+    String code = r'''
+class A<T extends B> {} // points to a
+class B<T extends A> {} // points to b
+class C<T extends A> {} // points to a cyclical type
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+    ]);
+  }
+
+  @failingTest
+  test_notInstantiatedBound_class_error_recursion_less_direct() async {
+    String code = r'''
+class A<T extends B<A>> {}
+class B<T extends A<B>> {}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+    ]);
+  }
+
+  test_notInstantiatedBound_class_error_recursion_typedef() async {
+    String code = r'''
+typedef F(C value);
+class C<T extends F> {}
+class D<T extends C> {}
+''';
+    await resolveTestUnit(code, noErrors: false);
+    assertErrors(testSource, [
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      StrongModeCode.NOT_INSTANTIATED_BOUND,
+      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
+    ]);
+  }
+
   test_notInstantiatedBound_error_class_argument() async {
     String code = r'''
 class A<K, V extends List<K>> {}
@@ -3959,34 +4040,6 @@
     ]);
   }
 
-  @failingTest
-  test_notInstantiatedBound_class_error_recursion() async {
-    String code = r'''
-class A<T extends B> {} // points to a
-class B<T extends A> {} // points to b
-class C<T extends A> {} // points to a cyclical type
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-    ]);
-  }
-
-  @failingTest
-  test_notInstantiatedBound_class_error_recursion_less_direct() async {
-    String code = r'''
-class A<T extends B<A>> {}
-class B<T extends A<B>> {}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-    ]);
-  }
-
   test_notInstantiatedBound_error_typedef_argument() async {
     String code = r'''
 class A<K, V extends List<K>> {}
@@ -4014,20 +4067,6 @@
     assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
   }
 
-  test_notInstantiatedBound_class_error_recursion_typedef() async {
-    String code = r'''
-typedef F(C value);
-class C<T extends F> {}
-class D<T extends C> {}
-''';
-    await resolveTestUnit(code, noErrors: false);
-    assertErrors(testSource, [
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-      StrongModeCode.NOT_INSTANTIATED_BOUND,
-      CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
-    ]);
-  }
-
   test_notInstantiatedBound_ok_class() async {
     String code = r'''
 class A<T extends int> {}
@@ -4068,6 +4107,15 @@
     assertNoErrors(testSource);
   }
 
+  test_notInstantiatedBound_ok_class_function() async {
+    String code = r'''
+class A<T extends void Function<Z>()> {}
+class B<T extends A> {}
+''';
+    await resolveTestUnit(code);
+    assertNoErrors(testSource);
+  }
+
   test_notInstantiatedBound_ok_class_typedef() async {
     String code = r'''
 typedef void F<T extends int>();
@@ -4086,15 +4134,6 @@
     assertNoErrors(testSource);
   }
 
-  test_notInstantiatedBound_ok_class_function() async {
-    String code = r'''
-class A<T extends void Function<Z>()> {}
-class B<T extends A> {}
-''';
-    await resolveTestUnit(code);
-    assertNoErrors(testSource);
-  }
-
   test_objectMethodOnFunctions_Anonymous() async {
     String code = r'''
 void main() {
@@ -4403,7 +4442,7 @@
 }
 
 abstract class Override implements Base, BaseCopy {
-  f<E>(x) => null;
+  f<E extends int>(x) => null;
 }
 
 class C extends Override implements Base {}
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index c371ec8..a7ec816 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -2145,28 +2145,6 @@
     }
   }
 
-  void test_genericFunction_simple_fBounded() {
-    ClassElementImpl AClass = ElementFactory.classElement2('A', ["Q"]);
-    InterfaceType AType = AClass.type;
-    ClassElementImpl BClass = ElementFactory.classElement2('B', ["R"]);
-    BClass.supertype = AType.instantiate([BClass.typeParameters[0].type]);
-    InterfaceType BType = BClass.type;
-
-    DartType s = TypeBuilder.variable("S");
-    (s.element as TypeParameterElementImpl).bound = AType.instantiate([s]);
-    DartType t = TypeBuilder.variable("T", bound: s);
-    DartType u = TypeBuilder.variable("U");
-    (u.element as TypeParameterElementImpl).bound = BType.instantiate([u]);
-    DartType v = TypeBuilder.variable("V", bound: u);
-
-    _checkIsStrictSubtypeOf(
-        TypeBuilder.function(types: [s]), TypeBuilder.function(types: [u]));
-
-    _checkIsStrictSubtypeOf(
-        TypeBuilder.function(types: [s, t], required: [s], result: t),
-        TypeBuilder.function(types: [u, v], required: [u], result: v));
-  }
-
   void test_generics() {
     ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
     InterfaceType LType = LClass.type;
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index f960be0..010ae47 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1184,7 +1184,7 @@
     CharSequenceReader reader = new CharSequenceReader(code);
     Scanner scanner = new Scanner(null, reader, listener);
     Token token = scanner.tokenize();
-    Parser parser = new Parser(null, listener);
+    Parser parser = new Parser(NonExistingSource.unknown, listener);
     CompilationUnit unit = parser.parseCompilationUnit(token);
     expect(unit, isNotNull);
     listener.assertNoErrors();
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index dc970a1..558578c 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -891,7 +891,7 @@
     - empty_constructor_bodies
 ''');
 
-    ContextRoot root = new ContextRoot(pathContext, path, []);
+    ContextRoot root = new ContextRoot(path, [], pathContext: pathContext);
     builder.getAnalysisOptions(path, contextRoot: root);
     expect(root.optionsFilePath, equals(filePath));
   }
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index dacd732..373fd4b 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -94,7 +94,9 @@
           new DartUriResolver(sdk),
           generatedUriResolver,
           new PackageMapUriResolver(provider, <String, List<Folder>>{
-            'test': [provider.getFolder(testProject)]
+            'test': [provider.getFolder(testProject)],
+            'aaa': [provider.getFolder(_p('/aaa/lib'))],
+            'bbb': [provider.getFolder(_p('/bbb/lib'))],
           }),
           new ResourceUriResolver(provider)
         ], null, provider),
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 99871a4..cb583d2 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -1987,6 +1987,39 @@
         await driver.getTopLevelNameDeclarations('X'), [], []);
   }
 
+  test_getTopLevelNameDeclarations_discoverAvailable() async {
+    var t = _p('/test/lib/test.dart');
+    var a1 = _p('/aaa/lib/a1.dart');
+    var a2 = _p('/aaa/lib/src/a2.dart');
+    var b = _p('/bbb/lib/b.dart');
+    var c = _p('/ccc/lib/c.dart');
+
+    provider.newFile(t, 'class T {}');
+    provider.newFile(a1, 'class A1 {}');
+    provider.newFile(a2, 'class A2 {}');
+    provider.newFile(b, 'class B {}');
+    provider.newFile(c, 'class C {}');
+
+    driver.addFile(t);
+    // Don't add a1.dart, a2.dart, or b.dart - they should be discovered.
+    // And c.dart is not in .packages, so should not be discovered.
+
+    _assertTopLevelDeclarations(
+        await driver.getTopLevelNameDeclarations('T'), [t], [false]);
+
+    _assertTopLevelDeclarations(
+        await driver.getTopLevelNameDeclarations('A1'), [a1], [false]);
+
+    _assertTopLevelDeclarations(
+        await driver.getTopLevelNameDeclarations('A2'), [a2], [false]);
+
+    _assertTopLevelDeclarations(
+        await driver.getTopLevelNameDeclarations('B'), [b], [false]);
+
+    _assertTopLevelDeclarations(
+        await driver.getTopLevelNameDeclarations('C'), [], []);
+  }
+
   test_getTopLevelNameDeclarations_parts() async {
     var a = _p('/test/lib/a.dart');
     var b = _p('/test/lib/b.dart');
diff --git a/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart b/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
index 99320a1..74c0314 100644
--- a/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
+++ b/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
@@ -412,7 +412,7 @@
 //        print(problem.formatted);
       };
 
-    options = new ProcessedOptions(optionBuilder, false, [entryPoint]);
+    options = new ProcessedOptions(optionBuilder, [entryPoint]);
 
     UriTranslatorImpl uriTranslator = await options.getUriTranslator();
 
diff --git a/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart b/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
index 9d6e061..d312b78 100644
--- a/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
@@ -119,6 +119,24 @@
 ''');
   }
 
+  @failingTest
+  void test_initializerList_missingComma() {
+    // https://github.com/dart-lang/sdk/issues/33241
+    testRecovery('''
+class Test {
+  Test()
+    : assert(true)
+      assert(true);
+}
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+class Test {
+  Test()
+    : assert(true),
+      assert(true);
+}
+''');
+  }
+
   void test_asExpression_missingRight() {
     testRecovery('''
 convert(x) => x as ;
diff --git a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
index 1e2348b..b8145d1 100644
--- a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
@@ -84,7 +84,6 @@
 
   @failingTest
   void test_typeArguments_inner_last() {
-    // Parser crashes
     testRecovery('''
 List<List<int>
 ''', [ScannerErrorCode.EXPECTED_TOKEN], '''
@@ -92,9 +91,16 @@
 ''');
   }
 
+  void test_typeArguments_inner_last2() {
+    testRecovery('''
+List<List<int> f;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+List<List<int>> f;
+''');
+  }
+
   @failingTest
   void test_typeArguments_inner_notLast() {
-    // Parser crashes
     testRecovery('''
 Map<List<int, List<String>>
 ''', [ScannerErrorCode.EXPECTED_TOKEN], '''
@@ -102,9 +108,17 @@
 ''');
   }
 
+  void test_typeArguments_inner_notLast2() {
+    // TODO(danrubel): Investigate better recovery.
+    testRecovery('''
+Map<List<int, List<String>> f;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+Map<List<int, List<String>>> f;
+''');
+  }
+
   @failingTest
   void test_typeArguments_outer_last() {
-    // Parser crashes
     testRecovery('''
 List<int
 ''', [ScannerErrorCode.EXPECTED_TOKEN], '''
@@ -112,6 +126,22 @@
 ''');
   }
 
+  void test_typeArguments_outer_last2() {
+    testRecovery('''
+List<int f;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+List<int> f;
+''');
+  }
+
+  void test_typeArguments_missing_comma() {
+    testRecovery('''
+List<int double> f;
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+List<int, double> f;
+''');
+  }
+
   void test_typeParameters_last() {
     testRecovery('''
 f<T() => null;
@@ -284,13 +314,13 @@
 ''');
   }
 
-  @failingTest
   void test_parameterList_class() {
     // Parser crashes
     testRecovery('''
 f(x
 class C {}
-''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+''', [ScannerErrorCode.EXPECTED_TOKEN, ParserErrorCode.MISSING_FUNCTION_BODY],
+        '''
 f(x) {}
 class C {}
 ''');
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/instance_creation_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/instance_creation_test.dart
index 48660aa..826aa32 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/instance_creation_test.dart
@@ -29,7 +29,6 @@
           '$keyword',
           [
             ParserErrorCode.MISSING_IDENTIFIER,
-            ParserErrorCode.MISSING_IDENTIFIER,
             ParserErrorCode.EXPECTED_TOKEN,
           ],
           "$keyword _s_()"),
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
index 24b5890..17da7bc 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
@@ -34,8 +34,7 @@
                 ParserErrorCode.EXPECTED_STRING_LITERAL,
                 ParserErrorCode.EXPECTED_TOKEN
               ],
-              'part of "";',
-              failing: []),
+              'part of "";'),
         ],
         nonIdentifierSuffixes);
     buildTests(
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
index d9da37e..589b4c2 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
@@ -12,8 +12,6 @@
 
 class TryStatementTest extends PartialCodeTest {
   buildAll() {
-    final allExceptEof =
-        PartialCodeTest.statementSuffixes.map((ts) => ts.name).toList();
     buildTests(
         'try_statement',
         [
@@ -67,32 +65,57 @@
               [
                 ScannerErrorCode.EXPECTED_TOKEN,
                 ParserErrorCode.CATCH_SYNTAX,
+                ParserErrorCode.CATCH_SYNTAX,
+                ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.EXPECTED_TOKEN
               ],
               "try {} catch (e) {}",
-              failing: allExceptEof),
+              failing: [
+                'eof',
+                'block',
+                'labeled',
+                'localFunctionNonVoid',
+                'localFunctionVoid',
+                'localVariable'
+              ]),
           new TestDescriptor(
               'catch_identifier',
               'try {} catch (e',
-              [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
-              "try {} catch (e) {}",
-              failing: allExceptEof),
-          new TestDescriptor(
-              'catch_identifierComma',
-              'try {} catch (e, ',
               [
                 ParserErrorCode.CATCH_SYNTAX,
                 ParserErrorCode.EXPECTED_TOKEN,
                 ScannerErrorCode.EXPECTED_TOKEN
               ],
+              "try {} catch (e) {}",
+              failing: ['eof', 'block', 'labeled', 'localFunctionNonVoid']),
+          new TestDescriptor(
+              'catch_identifierComma',
+              'try {} catch (e, ',
+              [
+                ParserErrorCode.CATCH_SYNTAX,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ScannerErrorCode.EXPECTED_TOKEN
+              ],
               "try {} catch (e, _s_) {}",
-              failing: allExceptEof),
+              failing: [
+                'eof',
+                'block',
+                'labeled',
+                'localFunctionNonVoid',
+                'localFunctionVoid',
+                'localVariable'
+              ]),
           new TestDescriptor(
               'catch_identifierCommaIdentifier',
               'try {} catch (e, s',
-              [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
+              [
+                ParserErrorCode.CATCH_SYNTAX,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ScannerErrorCode.EXPECTED_TOKEN
+              ],
               "try {} catch (e, s) {}",
-              failing: allExceptEof),
+              failing: ['eof', 'block', 'labeled', 'localFunctionNonVoid']),
           new TestDescriptor('catch_rightParen', 'try {} catch (e, s)',
               [ParserErrorCode.EXPECTED_TOKEN], "try {} catch (e, s) {}",
               failing: ['block']),
@@ -110,33 +133,58 @@
               'try {} on A catch (',
               [
                 ParserErrorCode.CATCH_SYNTAX,
+                ParserErrorCode.CATCH_SYNTAX,
+                ParserErrorCode.MISSING_IDENTIFIER,
                 ParserErrorCode.EXPECTED_TOKEN,
                 ScannerErrorCode.EXPECTED_TOKEN
               ],
               "try {} on A catch (e) {}",
-              failing: allExceptEof),
+              failing: [
+                'eof',
+                'block',
+                'labeled',
+                'localFunctionNonVoid',
+                'localFunctionVoid',
+                'localVariable'
+              ]),
           new TestDescriptor(
               'on_catch_identifier',
               'try {} on A catch (e',
-              [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
-              "try {} on A catch (e) {}",
-              failing: allExceptEof),
-          new TestDescriptor(
-              'on_catch_identifierComma',
-              'try {} on A catch (e, ',
               [
                 ParserErrorCode.CATCH_SYNTAX,
                 ParserErrorCode.EXPECTED_TOKEN,
                 ScannerErrorCode.EXPECTED_TOKEN
               ],
+              "try {} on A catch (e) {}",
+              failing: ['eof', 'block', 'labeled', 'localFunctionNonVoid']),
+          new TestDescriptor(
+              'on_catch_identifierComma',
+              'try {} on A catch (e, ',
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.CATCH_SYNTAX,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ScannerErrorCode.EXPECTED_TOKEN
+              ],
               "try {} on A catch (e, _s_) {}",
-              failing: allExceptEof),
+              failing: [
+                'eof',
+                'block',
+                'labeled',
+                'localFunctionVoid',
+                'localFunctionNonVoid',
+                'localVariable'
+              ]),
           new TestDescriptor(
               'on_catch_identifierCommaIdentifier',
               'try {} on A catch (e, s',
-              [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
+              [
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.CATCH_SYNTAX,
+                ScannerErrorCode.EXPECTED_TOKEN
+              ],
               "try {} on A catch (e, s) {}",
-              failing: allExceptEof),
+              failing: ['eof', 'block', 'labeled', 'localFunctionNonVoid']),
           new TestDescriptor('on_catch_rightParen', 'try {} on A catch (e, s)',
               [ParserErrorCode.EXPECTED_TOKEN], "try {} on A catch (e, s) {}",
               failing: ['block']),
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart
index 29040d2..c13652f 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart
@@ -20,11 +20,12 @@
           'while',
           [
             ParserErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.MISSING_IDENTIFIER,
             ParserErrorCode.MISSING_IDENTIFIER,
             ParserErrorCode.EXPECTED_TOKEN
           ],
           "while (_s_)",
-          allFailing: true,
           expectedErrorsInValidCode: [
             ParserErrorCode.MISSING_IDENTIFIER,
             ParserErrorCode.EXPECTED_TOKEN
@@ -33,9 +34,13 @@
         new TestDescriptor(
           'leftParen',
           'while (',
-          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          [
+            ScannerErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.EXPECTED_TOKEN
+          ],
           "while (_s_)",
-          allFailing: true,
           expectedErrorsInValidCode: [
             ParserErrorCode.MISSING_IDENTIFIER,
             ParserErrorCode.EXPECTED_TOKEN
@@ -44,9 +49,12 @@
         new TestDescriptor(
           'condition',
           'while (a',
-          [ParserErrorCode.EXPECTED_TOKEN],
+          [
+            ScannerErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.EXPECTED_TOKEN
+          ],
           "while (a)",
-          allFailing: true,
           expectedErrorsInValidCode: [
             ParserErrorCode.MISSING_IDENTIFIER,
             ParserErrorCode.EXPECTED_TOKEN
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
index f95085b..d78d8a7 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
@@ -314,7 +314,8 @@
     Scanner scanner =
         new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER);
     Token token = scanner.tokenize();
-    Parser parser = new Parser(null, AnalysisErrorListener.NULL_LISTENER);
+    Parser parser = new Parser(
+        NonExistingSource.unknown, AnalysisErrorListener.NULL_LISTENER);
     CompilationUnit unit = parser.parseCompilationUnit(token);
     unit.lineInfo = new LineInfo(scanner.lineStarts);
     return unit;
diff --git a/pkg/analyzer/tool/summary/mini_ast.dart b/pkg/analyzer/tool/summary/mini_ast.dart
index 6866377..6dc47f7 100644
--- a/pkg/analyzer/tool/summary/mini_ast.dart
+++ b/pkg/analyzer/tool/summary/mini_ast.dart
@@ -178,13 +178,14 @@
   @override
   void endArguments(int count, Token beginToken, Token endToken) {
     debugEvent("Arguments");
-    push(popList(count));
+    push(popList(count, new List<dynamic>.filled(count, null, growable: true)));
   }
 
   @override
   void endClassBody(int memberCount, Token beginToken, Token endToken) {
     debugEvent("ClassBody");
-    push(popList(memberCount));
+    push(popList(memberCount,
+        new List<dynamic>.filled(memberCount, null, growable: true)));
   }
 
   @override
@@ -229,7 +230,9 @@
 
   void endEnum(Token enumKeyword, Token leftBrace, int count) {
     debugEvent("Enum");
-    List<EnumConstantDeclaration> constants = popList(count);
+    List<EnumConstantDeclaration> constants =
+        new List.filled(count, null, growable: true);
+    popList(count, constants);
     String name = pop();
     List<Annotation> metadata = pop();
     Comment comment = pop();
@@ -273,7 +276,7 @@
   @override
   void handleIdentifierList(int count) {
     debugEvent("IdentifierList");
-    push(popList(count));
+    push(popList(count, new List<dynamic>.filled(count, null, growable: true)));
   }
 
   @override
@@ -345,7 +348,9 @@
   @override
   void endMetadataStar(int count) {
     debugEvent("MetadataStar");
-    push(popList(count) ?? NullValue.Metadata);
+    push(
+        popList(count, new List<dynamic>.filled(count, null, growable: true)) ??
+            NullValue.Metadata);
   }
 
   void endMethod(
@@ -384,7 +389,8 @@
     // We ignore top level variable declarations; they are present just to make
     // the IDL analyze without warnings.
     debugEvent("TopLevelFields");
-    popList(count); // Fields
+    popList(
+        count, new List<dynamic>.filled(count, null, growable: true)); // Fields
     pop(); // Type
     pop(); // Metadata
     pop(); // Comment
@@ -393,7 +399,7 @@
   @override
   void endTypeArguments(int count, Token beginToken, Token endToken) {
     debugEvent("TypeArguments");
-    push(popList(count));
+    push(popList(count, new List<dynamic>.filled(count, null, growable: true)));
   }
 
   @override
diff --git a/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart b/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
index 865d169..3fc7fde7 100644
--- a/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
+++ b/pkg/analyzer_plugin/lib/utilities/fixes/fixes.dart
@@ -139,11 +139,30 @@
   final String message;
 
   /**
-   * Initialize a newly created kind of fix to have the given [name],
-   * [priority] and [message].
+   * A human-readable description of the changes that will be applied by this
+   * kind of 'applied together' fix.
    */
-  const FixKind(this.name, this.priority, this.message);
+  final String appliedTogetherMessage;
+
+  /**
+   * The change can be made with other fixes of this [FixKind].
+   */
+  bool canBeAppliedTogether() => appliedTogetherMessage != null;
+
+  /**
+   * Initialize a newly created kind of fix to have the given [name],
+   * [priority], [message], and optionally [canBeAppliedTogether] and
+   * [appliedTogetherMessage].
+   */
+  const FixKind(this.name, this.priority, this.message,
+      {this.appliedTogetherMessage: null});
 
   @override
   String toString() => name;
+
+  @override
+  bool operator ==(o) => o is FixKind && o.name == name;
+
+  @override
+  int get hashCode => name.hashCode;
 }
diff --git a/pkg/build_integration/lib/file_system/multi_root.dart b/pkg/build_integration/lib/file_system/multi_root.dart
index 1163d39..ed1bb8c 100644
--- a/pkg/build_integration/lib/file_system/multi_root.dart
+++ b/pkg/build_integration/lib/file_system/multi_root.dart
@@ -4,7 +4,7 @@
 
 import 'dart:async';
 
-import 'package:front_end/src/api_prototype/file_system.dart';
+import 'package:front_end/src/api_unstable/build_integration.dart';
 
 /// Wraps a file system to create an overlay of files from multiple roots.
 ///
@@ -76,7 +76,7 @@
   Future<String> readAsString() async => (await delegate).readAsString();
 }
 
-_normalize(root) {
+Uri _normalize(root) {
   Uri uri = root;
   return uri.path.endsWith('/') ? uri : uri.replace(path: '${uri.path}/');
 }
diff --git a/pkg/build_integration/lib/file_system/single_root.dart b/pkg/build_integration/lib/file_system/single_root.dart
new file mode 100644
index 0000000..175379d
--- /dev/null
+++ b/pkg/build_integration/lib/file_system/single_root.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:front_end/src/api_unstable/build_integration.dart';
+
+/// A [FileSystem] that resolves custom URIs to entities under a specified root
+/// folder on an underlying [FileSystem].
+///
+/// This abstraction lets packages like `package:front_end` use absolute URIs
+/// freely, while hiding machine-specific or user-specific details. In
+/// particular, this file-system is used to create a machine-independent .dill
+/// files in distributed build systems.
+///
+/// The resolution rules are as follows: if a given URI uses a special
+/// [markerScheme] it gets resolved under the given [root], while a given URI
+/// with any other scheme will produce an error.
+///
+/// For example, if [markerScheme] is `single-root`, and [root] is
+/// `file:///a/b/c/`, then, calling [entityForUri] will:
+///
+///   * resolve `single-root:///f1.dart` to `file:///a/b/c/f1.dart`.
+///   * resolve `single-root:///d/f2.dart` to `file:///a/b/c/d/f2.dart`.
+///   * throw on `other-custom-scheme:///d/f2.dart`.
+///   * throw on `file:///d/f2.dart`.
+class SingleRootFileSystem implements FileSystem {
+  final String markerScheme;
+  final Uri root;
+  final FileSystem original;
+
+  SingleRootFileSystem(this.markerScheme, Uri root, this.original)
+      : root = _normalize(root);
+
+  @override
+  FileSystemEntity entityForUri(Uri uri) {
+    if (uri.scheme != markerScheme) {
+      throw new FileSystemException(
+          uri,
+          "This SingleRootFileSystem only handles URIs with the '$markerScheme'"
+          " scheme and cannot handle URIs with scheme '${uri.scheme}': $uri");
+    }
+    if (!uri.path.startsWith('/')) {
+      throw new FileSystemException(
+          uri, "This SingleRootFileSystem only handles absolutes URIs: $uri");
+    }
+    var path = uri.path.substring(1);
+    return new SingleRootFileSystemEntity(
+        uri, original.entityForUri(root.resolve(path)));
+  }
+}
+
+/// [FileSystemEntity] with a URI of the `SingleRootFileSystem.markerScheme`,
+/// that delegates all operations to an underlying entity in the original
+/// `SingleRootFileSystem.filesystem`.
+class SingleRootFileSystemEntity implements FileSystemEntity {
+  final Uri uri;
+  final FileSystemEntity delegate;
+
+  SingleRootFileSystemEntity(this.uri, this.delegate);
+
+  @override
+  Future<bool> exists() async => delegate.exists();
+
+  @override
+  Future<List<int>> readAsBytes() async => delegate.readAsBytes();
+
+  @override
+  Future<String> readAsString() async => delegate.readAsString();
+}
+
+_normalize(root) {
+  Uri uri = root;
+  return uri.path.endsWith('/') ? uri : uri.replace(path: '${uri.path}/');
+}
diff --git a/pkg/build_integration/test/file_system/single_root_test.dart b/pkg/build_integration/test/file_system/single_root_test.dart
new file mode 100644
index 0000000..38ed4f8
--- /dev/null
+++ b/pkg/build_integration/test/file_system/single_root_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2018, 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:build_integration/file_system/single_root.dart';
+import 'package:front_end/src/api_unstable/build_integration.dart';
+import 'package:front_end/src/api_prototype/memory_file_system.dart';
+import 'package:test/test.dart';
+
+main() {
+  var root = Uri.parse('org-dartlang-test:///');
+  var fileSystem = new SingleRootFileSystem(
+      'single-root', root.resolve('A/B'), new MemoryFileSystem(root));
+
+  SingleRootFileSystemEntity entityOf(String uri) =>
+      fileSystem.entityForUri(Uri.parse(uri));
+
+  String effectiveUriOf(String uri) => '${entityOf(uri).delegate.uri}';
+
+  test('root is normalized', () {
+    expect(fileSystem.root.path, '/A/B/');
+  });
+
+  test('URIs with the marker scheme are converted', () {
+    expect(effectiveUriOf('single-root:///a/b/1.dart'),
+        'org-dartlang-test:///A/B/a/b/1.dart');
+  });
+
+  test('single-root expects absolute paths', () {
+    expect(effectiveUriOf('single-root:///a/8.dart'),
+        'org-dartlang-test:///A/B/a/8.dart');
+    expect(effectiveUriOf('single-root:///../B/a/8.dart'),
+        'org-dartlang-test:///A/B/B/a/8.dart');
+  });
+
+  test('URIs with other schemes are not supported', () {
+    expect(() => entityOf('foo-root:///a/b/1.dart'),
+        throwsA((e) => e is FileSystemException));
+
+    // The scheme of the underlying file system is also not supported
+    expect(() => entityOf('org-dartlang-test:///a/b/1.dart'),
+        throwsA((e) => e is FileSystemException));
+  });
+}
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index cd2101a..6eb3847 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -119,8 +119,8 @@
     return new Future.value();
   }
 
-  Future<Null> setupSdk() {
-    Future future = new Future.value(null);
+  Future setupSdk() {
+    var future = new Future.value(null);
     if (resolvedUriTranslator.isNotSet) {
       future = future.then((_) {
         return platform_configuration
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 0e83adc..884aadb 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -1118,6 +1118,9 @@
   FunctionEntity get instantiatedGenericFunctionType =>
       _findHelperFunction('instantiatedGenericFunctionType');
 
+  FunctionEntity get extractFunctionTypeObjectFromInternal =>
+      _findHelperFunction('extractFunctionTypeObjectFromInternal');
+
   // From dart:_internal
 
   ClassEntity _symbolImplementationClass;
@@ -1497,19 +1500,10 @@
   /// Returns the metadata constants declared on [cls].
   Iterable<ConstantValue> getClassMetadata(ClassEntity cls);
 
-  /// Returns the metadata constants declared on [typedef].
-  Iterable<ConstantValue> getTypedefMetadata(TypedefEntity typedef);
-
   /// Returns the metadata constants declared on [member].
   Iterable<ConstantValue> getMemberMetadata(MemberEntity member,
       {bool includeParameterMetadata: false});
 
-  /// Returns the function type that is an alias of a [typedef].
-  FunctionType getFunctionTypeOfTypedef(TypedefEntity typedef);
-
-  /// Returns the typedef type that is declared by a [typedef].
-  TypedefType getTypedefTypeOfTypedef(TypedefEntity typedef);
-
   /// Returns `true` if [cls] is a Dart enum class.
   bool isEnumClass(ClassEntity cls);
 }
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index a62b1a9..ca5e4ab 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -303,7 +303,6 @@
       resolutionEnqueuer = enqueuer.createResolutionEnqueuer();
       backend.onResolutionStart();
     }
-    resolutionEnqueuer.addDeferredActions(libraryLoader.pullDeferredActions());
     return resolutionEnqueuer;
   }
 
@@ -418,13 +417,13 @@
     phase = PHASE_DONE_RESOLVING;
 
     ClosedWorld closedWorld = resolutionWorldBuilder.closeWorld();
+    OutputUnitData result = deferredLoadTask.run(mainFunction, closedWorld);
     ClosedWorldRefiner closedWorldRefiner =
         backendStrategy.createClosedWorldRefiner(closedWorld);
     // Compute whole-program-knowledge that the backend needs. (This might
     // require the information computed in [world.closeWorld].)
     backend.onResolutionClosedWorld(closedWorld, closedWorldRefiner);
 
-    OutputUnitData result = deferredLoadTask.run(mainFunction, closedWorld);
     backend.onDeferredLoadComplete(result);
 
     // TODO(johnniwinther): Move this after rti computation but before
diff --git a/pkg/compiler/lib/src/constants/evaluation.dart b/pkg/compiler/lib/src/constants/evaluation.dart
index b647d48..fbeddd0 100644
--- a/pkg/compiler/lib/src/constants/evaluation.dart
+++ b/pkg/compiler/lib/src/constants/evaluation.dart
@@ -4,12 +4,13 @@
 
 library dart2js.constants.evaluation;
 
+import 'package:front_end/src/fasta/util/link.dart' show Link;
+
 import '../common.dart';
 import '../common_elements.dart' show CommonElements;
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../universe/call_structure.dart' show CallStructure;
-import '../util/util.dart' show Link;
 import 'constructors.dart';
 import 'expressions.dart';
 import 'values.dart';
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 0c6117c..e1a8e61 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -133,7 +133,7 @@
   bool showHints;
   bool enableColors;
   Uri platformBinaries = computePlatformBinariesLocation();
-  Map<String, dynamic> environment = new Map<String, dynamic>();
+  Map<String, String> environment = new Map<String, String>();
 
   void passThrough(String argument) => options.add(argument);
   void ignoreOption(String argument) {}
@@ -787,7 +787,7 @@
 
 Future<api.CompilationResult> internalMain(List<String> arguments,
     {fe.InitializedCompilerState kernelInitializedCompilerState}) {
-  Future onError(exception, trace) {
+  Future<api.CompilationResult> onError(exception, trace) {
     // If we are already trying to exit, just continue exiting.
     if (exception == _EXIT_SIGNAL) throw exception;
 
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 2064ae8..7418a1a 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -16,11 +16,9 @@
         ConstructedConstantValue,
         DeferredConstantValue,
         DeferredGlobalConstantValue,
-        InstantiationConstantValue,
-        TypeConstantValue;
+        InstantiationConstantValue;
 import 'elements/types.dart';
 import 'elements/entities.dart';
-import 'kernel/kelements.dart' show KLocalFunction;
 import 'universe/use.dart';
 import 'universe/world_impact.dart'
     show ImpactUseCase, WorldImpact, WorldImpactVisitorImpl;
@@ -111,8 +109,15 @@
   /// this map.
   final Map<ImportEntity, String> _importDeferName = <ImportEntity, String>{};
 
-  /// A mapping from elements and constants to their import set.
-  Map<Entity, ImportSet> _elementToSet = new Map<Entity, ImportSet>();
+  /// A mapping from classes to their import set.
+  Map<ClassEntity, ImportSet> _classToSet = new Map<ClassEntity, ImportSet>();
+
+  /// A mapping from members to their import set.
+  Map<MemberEntity, ImportSet> _memberToSet =
+      new Map<MemberEntity, ImportSet>();
+
+  /// A mapping from local functions to their import set.
+  Map<Local, ImportSet> _localFunctionToSet = new Map<Local, ImportSet>();
 
   /// A mapping from constants to their import set.
   Map<ConstantValue, ImportSet> _constantToSet =
@@ -180,69 +185,72 @@
   }
 
   /// Returns every [ImportEntity] that imports [element] into [library].
-  Iterable<ImportEntity> importsTo(Entity element, LibraryEntity library);
+  Iterable<ImportEntity> classImportsTo(
+      ClassEntity element, LibraryEntity library);
+
+  /// Returns every [ImportEntity] that imports [element] into [library].
+  Iterable<ImportEntity> memberImportsTo(
+      MemberEntity element, LibraryEntity library);
+
+  /// Collects all direct dependencies of [element].
+  ///
+  /// The collected dependent elements and constants are are added to
+  /// [elements] and [constants] respectively.
+  void _collectDirectMemberDependencies(
+      MemberEntity element, Dependencies dependencies) {
+    // TODO(sigurdm): We want to be more specific about this - need a better
+    // way to query "liveness".
+    if (!compiler.resolutionWorldBuilder.isMemberUsed(element)) {
+      return;
+    }
+    _collectDependenciesFromImpact(element, dependencies);
+    collectConstantsInBody(element, dependencies);
+  }
 
   /// Finds all elements and constants that [element] depends directly on.
   /// (not the transitive closure.)
   ///
   /// Adds the results to [elements] and [constants].
-  void _collectAllElementsAndConstantsResolvedFrom(Entity element,
-      Set<Entity> elements, Set<ConstantValue> constants, isMirrorUsage) {
-    /// Collects all direct dependencies of [element].
-    ///
-    /// The collected dependent elements and constants are are added to
-    /// [elements] and [constants] respectively.
-    void collectDependencies(Entity element) {
-      if (element is TypedefEntity) {
-        _collectTypeDependencies(
-            elementEnvironment.getTypedefTypeOfTypedef(element), elements);
-        return;
-      }
-
-      // TODO(sigurdm): We want to be more specific about this - need a better
-      // way to query "liveness".
-      if (!compiler.resolutionWorldBuilder.isMemberUsed(element)) {
-        return;
-      }
-      _collectDependenciesFromImpact(element, elements);
-      collectConstantsInBody(element, constants);
+  void _collectAllElementsAndConstantsResolvedFromClass(
+      ClassEntity element, Dependencies dependencies) {
+    // If we see a class, add everything its live instance members refer
+    // to.  Static members are not relevant, unless we are processing
+    // extra dependencies due to mirrors.
+    void addLiveInstanceMember(MemberEntity member) {
+      if (!compiler.resolutionWorldBuilder.isMemberUsed(member)) return;
+      if (!member.isInstanceMember) return;
+      dependencies.members.add(member);
+      _collectDirectMemberDependencies(member, dependencies);
     }
 
+    ClassEntity cls = element;
+    elementEnvironment.forEachLocalClassMember(cls, addLiveInstanceMember);
+    elementEnvironment.forEachSupertype(cls, (InterfaceType type) {
+      _collectTypeDependencies(type, dependencies);
+    });
+    dependencies.classes.add(cls);
+  }
+
+  /// Finds all elements and constants that [element] depends directly on.
+  /// (not the transitive closure.)
+  ///
+  /// Adds the results to [elements] and [constants].
+  void _collectAllElementsAndConstantsResolvedFromMember(
+      MemberEntity element, Dependencies dependencies) {
     if (element is FunctionEntity) {
       _collectTypeDependencies(
-          elementEnvironment.getFunctionType(element), elements);
+          elementEnvironment.getFunctionType(element), dependencies);
     }
-
-    if (element is ClassEntity) {
-      // If we see a class, add everything its live instance members refer
-      // to.  Static members are not relevant, unless we are processing
-      // extra dependencies due to mirrors.
-      void addLiveInstanceMember(_element) {
-        MemberEntity element = _element;
-        if (!compiler.resolutionWorldBuilder.isMemberUsed(element)) return;
-        if (!isMirrorUsage && !element.isInstanceMember) return;
-        elements.add(element);
-        collectDependencies(element);
-      }
-
-      ClassEntity cls = element;
-      elementEnvironment.forEachLocalClassMember(cls, addLiveInstanceMember);
-      elementEnvironment.forEachSupertype(cls, (InterfaceType type) {
-        _collectTypeDependencies(type, elements);
-      });
-      elements.add(cls);
-    } else if (element is MemberEntity &&
-        (element.isStatic || element.isTopLevel || element.isConstructor)) {
-      elements.add(element);
-      collectDependencies(element);
+    if (element.isStatic || element.isTopLevel || element.isConstructor) {
+      dependencies.members.add(element);
+      _collectDirectMemberDependencies(element, dependencies);
     }
     if (element is ConstructorEntity && element.isGenerativeConstructor) {
       // When instantiating a class, we record a reference to the
       // constructor, not the class itself.  We must add all the
       // instance members of the constructor's class.
       ClassEntity cls = element.enclosingClass;
-      _collectAllElementsAndConstantsResolvedFrom(
-          cls, elements, constants, isMirrorUsage);
+      _collectAllElementsAndConstantsResolvedFromClass(cls, dependencies);
     }
 
     // Other elements, in particular instance members, are ignored as
@@ -257,45 +265,55 @@
       Entity element, Set<ConstantValue> constants);
 
   /// Extract the set of constants that are used in the body of [element].
-  void collectConstantsInBody(Entity element, Set<ConstantValue> constants);
+  void collectConstantsInBody(MemberEntity element, Dependencies dependencies);
 
   /// Recursively collects all the dependencies of [type].
-  void _collectTypeDependencies(DartType type, Set<Entity> elements) {
+  void _collectTypeDependencies(DartType type, Dependencies dependencies) {
     // TODO(het): we would like to separate out types that are only needed for
     // rti from types that are needed for their members.
     if (type is FunctionType) {
       for (DartType argumentType in type.parameterTypes) {
-        _collectTypeDependencies(argumentType, elements);
+        _collectTypeDependencies(argumentType, dependencies);
       }
       for (DartType argumentType in type.optionalParameterTypes) {
-        _collectTypeDependencies(argumentType, elements);
+        _collectTypeDependencies(argumentType, dependencies);
       }
       for (DartType argumentType in type.namedParameterTypes) {
-        _collectTypeDependencies(argumentType, elements);
+        _collectTypeDependencies(argumentType, dependencies);
       }
-      _collectTypeDependencies(type.returnType, elements);
+      _collectTypeDependencies(type.returnType, dependencies);
     } else if (type is TypedefType) {
-      type.typeArguments.forEach((t) => _collectTypeDependencies(t, elements));
-      elements.add(type.element);
-      _collectTypeDependencies(type.unaliased, elements);
+      type.typeArguments
+          .forEach((t) => _collectTypeDependencies(t, dependencies));
+      _collectTypeDependencies(type.unaliased, dependencies);
     } else if (type is InterfaceType) {
-      type.typeArguments.forEach((t) => _collectTypeDependencies(t, elements));
-      elements.add(type.element);
+      type.typeArguments
+          .forEach((t) => _collectTypeDependencies(t, dependencies));
+      dependencies.classes.add(type.element);
     }
   }
 
   /// Extract any dependencies that are known from the impact of [element].
-  void _collectDependenciesFromImpact(Entity element, Set<Entity> elements) {
+  void _collectDependenciesFromImpact(
+      MemberEntity element, Dependencies dependencies) {
     WorldImpact worldImpact = compiler.impactCache[element];
     compiler.impactStrategy.visitImpact(
         element,
         worldImpact,
         new WorldImpactVisitorImpl(visitStaticUse: (StaticUse staticUse) {
-          elements.add(staticUse.element);
+          if (staticUse.element is MemberEntity) {
+            dependencies.members.add(staticUse.element);
+          } else {
+            assert(
+                staticUse.element is Local,
+                failedAt(
+                    staticUse.element, "Unexpected static use $staticUse."));
+            dependencies.localFunctions.add(staticUse.element);
+          }
           switch (staticUse.kind) {
             case StaticUseKind.CONSTRUCTOR_INVOKE:
             case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
-              _collectTypeDependencies(staticUse.type, elements);
+              _collectTypeDependencies(staticUse.type, dependencies);
               break;
             case StaticUseKind.INVOKE:
             case StaticUseKind.CLOSURE_CALL:
@@ -305,7 +323,7 @@
               List<DartType> typeArguments = staticUse.typeArguments;
               if (typeArguments != null) {
                 for (DartType typeArgument in typeArguments) {
-                  _collectTypeDependencies(typeArgument, elements);
+                  _collectTypeDependencies(typeArgument, dependencies);
                 }
               }
               break;
@@ -315,12 +333,9 @@
           DartType type = typeUse.type;
           switch (typeUse.kind) {
             case TypeUseKind.TYPE_LITERAL:
-              if (type.isTypedef) {
-                TypedefType typedef = type;
-                elements.add(typedef.element);
-              } else if (type.isInterfaceType) {
+              if (type.isInterfaceType) {
                 InterfaceType interface = type;
-                elements.add(interface.element);
+                dependencies.classes.add(interface.element);
               }
               break;
             case TypeUseKind.INSTANTIATION:
@@ -329,21 +344,21 @@
             case TypeUseKind.IS_CHECK:
             case TypeUseKind.AS_CAST:
             case TypeUseKind.CATCH_TYPE:
-              _collectTypeDependencies(type, elements);
+              _collectTypeDependencies(type, dependencies);
               break;
             case TypeUseKind.IMPLICIT_CAST:
               if (compiler.options.implicitDowncastCheckPolicy.isEmitted) {
-                _collectTypeDependencies(type, elements);
+                _collectTypeDependencies(type, dependencies);
               }
               break;
             case TypeUseKind.PARAMETER_CHECK:
               if (compiler.options.parameterCheckPolicy.isEmitted) {
-                _collectTypeDependencies(type, elements);
+                _collectTypeDependencies(type, dependencies);
               }
               break;
             case TypeUseKind.CHECKED_MODE_CHECK:
               if (compiler.options.assignmentCheckPolicy.isEmitted) {
-                _collectTypeDependencies(type, elements);
+                _collectTypeDependencies(type, dependencies);
               }
               break;
           }
@@ -353,7 +368,7 @@
           List<DartType> typeArguments = dynamicUse.typeArguments;
           if (typeArguments != null) {
             for (DartType typeArgument in typeArguments) {
-              _collectTypeDependencies(typeArgument, elements);
+              _collectTypeDependencies(typeArgument, dependencies);
             }
           }
         }),
@@ -380,18 +395,12 @@
       _constantToSet[constant] = newSet;
       if (constant is ConstructedConstantValue) {
         ClassEntity cls = constant.type.element;
-        _updateElementRecursive(cls, oldSet, newSet, queue);
-      }
-      if (constant is TypeConstantValue) {
-        var type = constant.representedType;
-        if (type is TypedefType) {
-          _updateElementRecursive(type.element, oldSet, newSet, queue);
-        }
+        _updateClassRecursive(cls, oldSet, newSet, queue);
       }
       if (constant is InstantiationConstantValue) {
         for (DartType type in constant.typeArguments) {
           if (type is InterfaceType) {
-            _updateElementRecursive(type.element, oldSet, newSet, queue);
+            _updateClassRecursive(type.element, oldSet, newSet, queue);
           }
         }
       }
@@ -421,77 +430,111 @@
     }
   }
 
-  /// Update the import set of all elements reachable from [element], as long as
-  /// they had the [oldSet]. As soon as we see an element with a different
-  /// import set, we stop and enqueue a new recursive update in [queue].
-  void _updateElementRecursive(
-      Entity element, ImportSet oldSet, ImportSet newSet, WorkQueue queue,
-      {bool isMirrorUsage: false}) {
+  void _updateClassRecursive(ClassEntity element, ImportSet oldSet,
+      ImportSet newSet, WorkQueue queue) {
     if (element == null) return;
-    var currentSet = _elementToSet[element];
+
+    ImportSet currentSet = _classToSet[element];
 
     // Already visited. We may visit some root nodes a second time with
     // [isMirrorUsage] in order to mark static members used reflectively.
-    if (currentSet == newSet && !isMirrorUsage) return;
+    if (currentSet == newSet) return;
 
     // Elements in the main output unit always remain there.
     if (currentSet == importSets.mainSet) return;
 
     if (currentSet == oldSet) {
       // Continue recursively updating from [oldSet] to [newSet].
-      _elementToSet[element] = newSet;
+      _classToSet[element] = newSet;
 
-      Set<Entity> dependentElements = new Set<Entity>();
-      Set<ConstantValue> dependentConstants = new Set<ConstantValue>();
-      _collectAllElementsAndConstantsResolvedFrom(
-          element, dependentElements, dependentConstants, isMirrorUsage);
-
-      // TODO(sigmund): split API to collect data about each kind of entity
-      // separately so we can avoid this ugly pattern.
-      LibraryEntity library;
-      if (element is ClassEntity) {
-        library = element.library;
-      } else if (element is MemberEntity) {
-        library = element.library;
-      } else if (element is TypedefEntity) {
-        library = element.library;
-      } else if (element is KLocalFunction) {
-        // TODO(sigmund): consider adding `Local.library`
-        library = element.memberContext.library;
-      } else {
-        assert(false, "Unexpected entity: ${element.runtimeType}");
-      }
-
-      for (Entity dependency in dependentElements) {
-        Iterable<ImportEntity> imports = importsTo(dependency, library);
-        if (_isExplicitlyDeferred(imports)) {
-          /// New deferred-imports are only discovered when we are visiting the
-          /// main output unit (size == 0) or code reachable from a deferred
-          /// import (size == 1). After that, we are rediscovering the
-          /// same nodes we have already seen.
-          if (newSet.length <= 1) {
-            for (ImportEntity deferredImport in imports) {
-              queue.addElement(
-                  dependency, importSets.singleton(deferredImport));
-            }
-          }
-        } else {
-          _updateElementRecursive(dependency, oldSet, newSet, queue);
-        }
-      }
-
-      for (ConstantValue dependency in dependentConstants) {
-        if (dependency is DeferredConstantValue) {
-          if (newSet.length <= 1) {
-            queue.addConstant(
-                dependency, importSets.singleton(dependency.import));
-          }
-        } else {
-          _updateConstantRecursive(dependency, oldSet, newSet, queue);
-        }
-      }
+      Dependencies dependencies = new Dependencies();
+      _collectAllElementsAndConstantsResolvedFromClass(element, dependencies);
+      LibraryEntity library = element.library;
+      _processDependencies(library, dependencies, oldSet, newSet, queue);
     } else {
-      queue.addElement(element, newSet);
+      queue.addClass(element, newSet);
+    }
+  }
+
+  void _updateMemberRecursive(MemberEntity element, ImportSet oldSet,
+      ImportSet newSet, WorkQueue queue) {
+    if (element == null) return;
+
+    ImportSet currentSet = _memberToSet[element];
+
+    // Already visited. We may visit some root nodes a second time with
+    // [isMirrorUsage] in order to mark static members used reflectively.
+    if (currentSet == newSet) return;
+
+    // Elements in the main output unit always remain there.
+    if (currentSet == importSets.mainSet) return;
+
+    if (currentSet == oldSet) {
+      // Continue recursively updating from [oldSet] to [newSet].
+      _memberToSet[element] = newSet;
+
+      Dependencies dependencies = new Dependencies();
+      _collectAllElementsAndConstantsResolvedFromMember(element, dependencies);
+
+      LibraryEntity library = element.library;
+      _processDependencies(library, dependencies, oldSet, newSet, queue);
+    } else {
+      queue.addMember(element, newSet);
+    }
+  }
+
+  void _processDependencies(LibraryEntity library, Dependencies dependencies,
+      ImportSet oldSet, ImportSet newSet, WorkQueue queue) {
+    for (ClassEntity cls in dependencies.classes) {
+      Iterable<ImportEntity> imports = classImportsTo(cls, library);
+      if (_isExplicitlyDeferred(imports)) {
+        /// New deferred-imports are only discovered when we are visiting the
+        /// main output unit (size == 0) or code reachable from a deferred
+        /// import (size == 1). After that, we are rediscovering the
+        /// same nodes we have already seen.
+        if (newSet.length <= 1) {
+          for (ImportEntity deferredImport in imports) {
+            queue.addClass(cls, importSets.singleton(deferredImport));
+          }
+        }
+      } else {
+        _updateClassRecursive(cls, oldSet, newSet, queue);
+      }
+    }
+
+    for (MemberEntity member in dependencies.members) {
+      Iterable<ImportEntity> imports = memberImportsTo(member, library);
+      if (_isExplicitlyDeferred(imports)) {
+        /// New deferred-imports are only discovered when we are visiting the
+        /// main output unit (size == 0) or code reachable from a deferred
+        /// import (size == 1). After that, we are rediscovering the
+        /// same nodes we have already seen.
+        if (newSet.length <= 1) {
+          for (ImportEntity deferredImport in imports) {
+            queue.addMember(member, importSets.singleton(deferredImport));
+          }
+        }
+      } else {
+        _updateMemberRecursive(member, oldSet, newSet, queue);
+      }
+    }
+
+    for (Local localFunction in dependencies.localFunctions) {
+      // Local function are not updated recursively because the dependencies are
+      // already visited as dependencies of the enclosing member, so we just
+      // assign the [newSet] to each local function.
+      _localFunctionToSet[localFunction] = newSet;
+    }
+
+    for (ConstantValue dependency in dependencies.constants) {
+      if (dependency is DeferredConstantValue) {
+        if (newSet.length <= 1) {
+          queue.addConstant(
+              dependency, importSets.singleton(dependency.import));
+        }
+      } else {
+        _updateConstantRecursive(dependency, oldSet, newSet, queue);
+      }
     }
   }
 
@@ -517,7 +560,9 @@
 
     // Generate an output unit for all import sets that are associated with an
     // element or constant.
-    _elementToSet.values.forEach(addUnit);
+    _classToSet.values.forEach(addUnit);
+    _memberToSet.values.forEach(addUnit);
+    _localFunctionToSet.values.forEach(addUnit);
     _constantToSet.values.forEach(addUnit);
 
     // Sort output units to make the output of the compiler more stable.
@@ -665,7 +710,7 @@
       // Add `main` and their recursive dependencies to the main output unit.
       // We do this upfront to avoid wasting time visiting these elements when
       // analyzing deferred imports.
-      queue.addElement(main, importSets.mainSet);
+      queue.addMember(main, importSets.mainSet);
 
       // Also add "global" dependencies to the main output unit.  These are
       // things that the backend needs but cannot associate with a particular
@@ -673,26 +718,17 @@
       // information.
       for (MemberEntity element
           in closedWorld.backendUsage.globalFunctionDependencies) {
-        queue.addElement(element, importSets.mainSet);
+        queue.addMember(element, importSets.mainSet);
       }
       for (ClassEntity element
           in closedWorld.backendUsage.globalClassDependencies) {
-        queue.addElement(element, importSets.mainSet);
+        queue.addClass(element, importSets.mainSet);
       }
 
       void emptyQueue() {
         while (queue.isNotEmpty) {
-          var item = queue.nextItem();
-          if (item.element != null) {
-            var oldSet = _elementToSet[item.element];
-            var newSet = importSets.union(oldSet, item.newSet);
-            _updateElementRecursive(item.element, oldSet, newSet, queue,
-                isMirrorUsage: item.isMirrorUsage);
-          } else if (item.value != null) {
-            var oldSet = _constantToSet[item.value];
-            var newSet = importSets.union(oldSet, item.newSet);
-            _updateConstantRecursive(item.value, oldSet, newSet, queue);
-          }
+          WorkItem item = queue.nextItem();
+          item.update(this, queue);
         }
       }
 
@@ -710,16 +746,29 @@
   OutputUnitData _buildResult() {
     _createOutputUnits();
     _setupHunksToLoad();
-    Map<Entity, OutputUnit> entityMap = <Entity, OutputUnit>{};
+    Map<ClassEntity, OutputUnit> classMap = <ClassEntity, OutputUnit>{};
+    Map<MemberEntity, OutputUnit> memberMap = <MemberEntity, OutputUnit>{};
+    Map<Local, OutputUnit> localFunctionMap = <Local, OutputUnit>{};
     Map<ConstantValue, OutputUnit> constantMap = <ConstantValue, OutputUnit>{};
-    _elementToSet.forEach((entity, s) => entityMap[entity] = s.unit);
+    _classToSet.forEach((cls, s) => classMap[cls] = s.unit);
+    _memberToSet.forEach((member, s) => memberMap[member] = s.unit);
+    _localFunctionToSet.forEach(
+        (localFunction, s) => localFunctionMap[localFunction] = s.unit);
     _constantToSet.forEach((constant, s) => constantMap[constant] = s.unit);
 
-    _elementToSet = null;
+    _classToSet = null;
+    _memberToSet = null;
+    _localFunctionToSet = null;
     _constantToSet = null;
     cleanup();
-    return new OutputUnitData(this.isProgramSplit && !disableProgramSplit,
-        this.mainOutputUnit, entityMap, constantMap, importSets);
+    return new OutputUnitData(
+        this.isProgramSplit && !disableProgramSplit,
+        this.mainOutputUnit,
+        classMap,
+        memberMap,
+        localFunctionMap,
+        constantMap,
+        importSets);
   }
 
   /// Frees up strategy-specific temporary data.
@@ -808,25 +857,31 @@
   String dump() {
     Map<OutputUnit, List<String>> elementMap = <OutputUnit, List<String>>{};
     Map<OutputUnit, List<String>> constantMap = <OutputUnit, List<String>>{};
-    _elementToSet.forEach((Entity element, ImportSet importSet) {
+    _classToSet.forEach((ClassEntity element, ImportSet importSet) {
       if (ignoreEntityInDump(element)) return;
       var elements = elementMap.putIfAbsent(importSet.unit, () => <String>[]);
       var id = element.name ?? '$element';
-      if (element is MemberEntity) {
-        var cls = element.enclosingClass?.name;
-        if (cls != null) id = '$cls.$id';
-        if (element.isSetter) id = '$id=';
-        id = '$id member';
-      } else if (element is ClassEntity) {
-        id = '$id cls';
-      } else if (element is TypedefEntity) {
-        id = '$id typedef';
-      } else if (element is Local) {
-        var context = (element as dynamic).memberContext.name;
-        id = element.name == null || element.name == '' ? '<anonymous>' : id;
-        id = '$context.$id';
-        id = '$id local';
-      }
+      id = '$id cls';
+      elements.add(id);
+    });
+    _memberToSet.forEach((MemberEntity element, ImportSet importSet) {
+      if (ignoreEntityInDump(element)) return;
+      var elements = elementMap.putIfAbsent(importSet.unit, () => <String>[]);
+      var id = element.name ?? '$element';
+      var cls = element.enclosingClass?.name;
+      if (cls != null) id = '$cls.$id';
+      if (element.isSetter) id = '$id=';
+      id = '$id member';
+      elements.add(id);
+    });
+    _localFunctionToSet.forEach((Local element, ImportSet importSet) {
+      if (ignoreEntityInDump(element)) return;
+      var elements = elementMap.putIfAbsent(importSet.unit, () => <String>[]);
+      var id = element.name ?? '$element';
+      var context = (element as dynamic).memberContext.name;
+      id = element.name == null || element.name == '' ? '<anonymous>' : id;
+      id = '$context.$id';
+      id = '$id local';
       elements.add(id);
     });
     _constantToSet.forEach((ConstantValue value, ImportSet importSet) {
@@ -1027,8 +1082,11 @@
   /// The actual queue of work that needs to be done.
   final Queue<WorkItem> queue = new Queue<WorkItem>();
 
-  /// An index to find work items in the queue corresponding to an entity.
-  final Map<Entity, WorkItem> pendingElements = <Entity, WorkItem>{};
+  /// An index to find work items in the queue corresponding to a class.
+  final Map<ClassEntity, WorkItem> pendingClasses = <ClassEntity, WorkItem>{};
+
+  /// An index to find work items in the queue corresponding to a member.
+  final Map<MemberEntity, WorkItem> pendingMembers = <MemberEntity, WorkItem>{};
 
   /// An index to find work items in the queue corresponding to a constant.
   final Map<ConstantValue, WorkItem> pendingConstants =
@@ -1045,26 +1103,37 @@
   /// Pop the next element in the queue.
   WorkItem nextItem() {
     assert(isNotEmpty);
-    var item = queue.removeFirst();
-    if (item.element != null) pendingElements.remove(item.element);
-    if (item.value != null) pendingConstants.remove(item.value);
-    return item;
+    return queue.removeFirst();
   }
 
   /// Add to the queue that [element] should be updated to include all imports
   /// in [importSet]. If there is already a work item in the queue for
   /// [element], this makes sure that the work item now includes the union of
   /// [importSet] and the existing work item's import set.
-  void addElement(Entity element, ImportSet importSet, {isMirrorUsage: false}) {
-    var item = pendingElements[element];
+  void addClass(ClassEntity element, ImportSet importSet) {
+    var item = pendingClasses[element];
     if (item == null) {
-      item = new WorkItem(element, importSet);
-      pendingElements[element] = item;
+      item = new ClassWorkItem(element, importSet);
+      pendingClasses[element] = item;
       queue.add(item);
     } else {
-      item.newSet = _importSets.union(item.newSet, importSet);
+      item.importsToAdd = _importSets.union(item.importsToAdd, importSet);
     }
-    if (isMirrorUsage) item.isMirrorUsage = true;
+  }
+
+  /// Add to the queue that [element] should be updated to include all imports
+  /// in [importSet]. If there is already a work item in the queue for
+  /// [element], this makes sure that the work item now includes the union of
+  /// [importSet] and the existing work item's import set.
+  void addMember(MemberEntity element, ImportSet importSet) {
+    var item = pendingMembers[element];
+    if (item == null) {
+      item = new MemberWorkItem(element, importSet);
+      pendingMembers[element] = item;
+      queue.add(item);
+    } else {
+      item.importsToAdd = _importSets.union(item.importsToAdd, importSet);
+    }
   }
 
   /// Add to the queue that [constant] should be updated to include all imports
@@ -1074,39 +1143,73 @@
   void addConstant(ConstantValue constant, ImportSet importSet) {
     var item = pendingConstants[constant];
     if (item == null) {
-      item = new WorkItem.constant(constant, importSet);
+      item = new ConstantWorkItem(constant, importSet);
       pendingConstants[constant] = item;
       queue.add(item);
     } else {
-      item.newSet = _importSets.union(item.newSet, importSet);
+      item.importsToAdd = _importSets.union(item.importsToAdd, importSet);
     }
   }
 }
 
-/// Summary of the work that needs to be done on an entity or constant.
-class WorkItem {
-  /// Entity to be recursively updated.
-  final Entity element;
-
-  /// Constant to be recursively updated.
-  final ConstantValue value;
-
+/// Summary of the work that needs to be done on a class, member, or constant.
+abstract class WorkItem {
   /// Additional imports that use [element] or [value] and need to be added by
   /// the algorithm.
   ///
   /// This is non-final in case we add more deferred imports to the set before
   /// the work item is applied (see [WorkQueue.addElement] and
   /// [WorkQueue.addConstant]).
-  ImportSet newSet;
+  ImportSet importsToAdd;
 
-  /// Whether [element] is used via mirrors.
-  ///
-  /// This is non-final in case we later discover that the same [element] is
-  /// used via mirrors (but before the work item is applied).
-  bool isMirrorUsage = false;
+  WorkItem(this.importsToAdd);
 
-  WorkItem(this.element, this.newSet) : value = null;
-  WorkItem.constant(this.value, this.newSet) : element = null;
+  void update(DeferredLoadTask task, WorkQueue queue);
+}
+
+/// Summary of the work that needs to be done on a class.
+class ClassWorkItem extends WorkItem {
+  /// Class to be recursively updated.
+  final ClassEntity cls;
+
+  ClassWorkItem(this.cls, ImportSet newSet) : super(newSet);
+
+  void update(DeferredLoadTask task, WorkQueue queue) {
+    queue.pendingClasses.remove(cls);
+    ImportSet oldSet = task._classToSet[cls];
+    ImportSet newSet = task.importSets.union(oldSet, importsToAdd);
+    task._updateClassRecursive(cls, oldSet, newSet, queue);
+  }
+}
+
+/// Summary of the work that needs to be done on a member.
+class MemberWorkItem extends WorkItem {
+  /// Member to be recursively updated.
+  final MemberEntity member;
+
+  MemberWorkItem(this.member, ImportSet newSet) : super(newSet);
+
+  void update(DeferredLoadTask task, WorkQueue queue) {
+    queue.pendingMembers.remove(member);
+    ImportSet oldSet = task._memberToSet[member];
+    ImportSet newSet = task.importSets.union(oldSet, importsToAdd);
+    task._updateMemberRecursive(member, oldSet, newSet, queue);
+  }
+}
+
+/// Summary of the work that needs to be done on a constant.
+class ConstantWorkItem extends WorkItem {
+  /// Constant to be recursively updated.
+  final ConstantValue constant;
+
+  ConstantWorkItem(this.constant, ImportSet newSet) : super(newSet);
+
+  void update(DeferredLoadTask task, WorkQueue queue) {
+    queue.pendingConstants.remove(constant);
+    ImportSet oldSet = task._constantToSet[constant];
+    ImportSet newSet = task.importSets.union(oldSet, importsToAdd);
+    task._updateConstantRecursive(constant, oldSet, newSet, queue);
+  }
 }
 
 /// Results of the deferred loading algorithm.
@@ -1118,57 +1221,63 @@
 class OutputUnitData {
   final bool isProgramSplit;
   final OutputUnit mainOutputUnit;
-  final Map<Entity, OutputUnit> _entityToUnit;
+  final Map<ClassEntity, OutputUnit> _classToUnit;
+  final Map<MemberEntity, OutputUnit> _memberToUnit;
+  final Map<Local, OutputUnit> _localFunctionToUnit;
   final Map<ConstantValue, OutputUnit> _constantToUnit;
   final ImportSetLattice _importSets;
 
-  OutputUnitData(this.isProgramSplit, this.mainOutputUnit, this._entityToUnit,
-      this._constantToUnit, this._importSets);
+  OutputUnitData(
+      this.isProgramSplit,
+      this.mainOutputUnit,
+      this._classToUnit,
+      this._memberToUnit,
+      this._localFunctionToUnit,
+      this._constantToUnit,
+      this._importSets);
 
   OutputUnitData.from(
       OutputUnitData other,
-      Map<Entity, OutputUnit> Function(Map<Entity, OutputUnit>)
-          convertEntityMap,
+      Map<ClassEntity, OutputUnit> Function(
+              Map<ClassEntity, OutputUnit>, Map<Local, OutputUnit>)
+          convertClassMap,
+      Map<MemberEntity, OutputUnit> Function(
+              Map<MemberEntity, OutputUnit>, Map<Local, OutputUnit>)
+          convertMemberMap,
       Map<ConstantValue, OutputUnit> Function(Map<ConstantValue, OutputUnit>)
           convertConstantMap)
       : isProgramSplit = other.isProgramSplit,
         mainOutputUnit = other.mainOutputUnit,
-        _entityToUnit = convertEntityMap(other._entityToUnit),
+        _memberToUnit =
+            convertMemberMap(other._memberToUnit, other._localFunctionToUnit),
+        _classToUnit =
+            convertClassMap(other._classToUnit, other._localFunctionToUnit),
+        _localFunctionToUnit = const <Local, OutputUnit>{},
         _constantToUnit = convertConstantMap(other._constantToUnit),
         _importSets = other._importSets;
 
-  /// Returns the [OutputUnit] where [element] belongs.
-  OutputUnit outputUnitForEntity(Entity entity) {
-    // TODO(johnniwinther): Support use of entities by splitting maps by
-    // entity kind.
+  /// Returns the [OutputUnit] where [cls] belongs.
+  OutputUnit outputUnitForClass(ClassEntity cls) {
     if (!isProgramSplit) return mainOutputUnit;
-    OutputUnit unit = _entityToUnit[entity];
+    OutputUnit unit = _classToUnit[cls];
+    return unit ?? mainOutputUnit;
+  }
+
+  /// Returns the [OutputUnit] where [member] belongs.
+  OutputUnit outputUnitForMember(MemberEntity member) {
+    if (!isProgramSplit) return mainOutputUnit;
+    OutputUnit unit = _memberToUnit[member];
     if (unit != null) return unit;
-    if (entity is MemberEntity && entity.isInstanceMember) {
-      return outputUnitForEntity(entity.enclosingClass);
+    if (member.isInstanceMember) {
+      return outputUnitForClass(member.enclosingClass);
     }
 
     return mainOutputUnit;
   }
 
-  /// Direct access to the output-unit to element relation used for testing.
-  OutputUnit outputUnitForEntityForTesting(Entity entity) {
-    return _entityToUnit[entity];
-  }
-
   /// Direct access to the output-unit to constants map used for testing.
   Iterable<ConstantValue> get constantsForTesting => _constantToUnit.keys;
 
-  /// Returns the [OutputUnit] where [element] belongs.
-  OutputUnit outputUnitForClass(ClassEntity element) {
-    return outputUnitForEntity(element);
-  }
-
-  /// Returns the [OutputUnit] where [element] belongs.
-  OutputUnit outputUnitForMember(MemberEntity element) {
-    return outputUnitForEntity(element);
-  }
-
   /// Returns the [OutputUnit] where [constant] belongs.
   OutputUnit outputUnitForConstant(ConstantValue constant) {
     if (!isProgramSplit) return mainOutputUnit;
@@ -1176,13 +1285,8 @@
   }
 
   /// Indicates whether [element] is deferred.
-  bool isDeferred(Entity element) {
-    return outputUnitForEntity(element) != mainOutputUnit;
-  }
-
-  /// Indicates whether [element] is deferred.
   bool isDeferredClass(ClassEntity element) {
-    return outputUnitForEntity(element) != mainOutputUnit;
+    return outputUnitForClass(element) != mainOutputUnit;
   }
 
   /// Returns `true` if element [to] is reachable from element [from] without
@@ -1191,9 +1295,9 @@
   /// For example, if we have two deferred libraries `A` and `B` that both
   /// import a library `C`, then even though elements from `A` and `C` end up in
   /// different output units, there is a non-deferred path between `A` and `C`.
-  bool hasOnlyNonDeferredImportPaths(Entity from, Entity to) {
-    OutputUnit outputUnitFrom = outputUnitForEntity(from);
-    OutputUnit outputUnitTo = outputUnitForEntity(to);
+  bool hasOnlyNonDeferredImportPaths(MemberEntity from, MemberEntity to) {
+    OutputUnit outputUnitFrom = outputUnitForMember(from);
+    OutputUnit outputUnitTo = outputUnitForMember(to);
     if (outputUnitTo == mainOutputUnit) return true;
     if (outputUnitFrom == mainOutputUnit) return false;
     return outputUnitTo._imports.containsAll(outputUnitFrom._imports);
@@ -1213,7 +1317,14 @@
   /// [existingEntity];
   void registerColocatedMembers(
       MemberEntity existingEntity, MemberEntity newEntity) {
-    assert(_entityToUnit[newEntity] == null);
-    _entityToUnit[newEntity] = outputUnitForMember(existingEntity);
+    assert(_memberToUnit[newEntity] == null);
+    _memberToUnit[newEntity] = outputUnitForMember(existingEntity);
   }
 }
+
+class Dependencies {
+  final Set<ClassEntity> classes = new Set<ClassEntity>();
+  final Set<MemberEntity> members = new Set<MemberEntity>();
+  final Set<Local> localFunctions = new Set<Local>();
+  final Set<ConstantValue> constants = new Set<ConstantValue>();
+}
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 75010fd..a723729 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -55,7 +55,6 @@
       result.constants.add(info);
     });
     environment.libraries.forEach(visitLibrary);
-    closedWorld.allTypedefs.forEach(visitTypedef);
   }
 
   /// Whether to emit information about [entity].
@@ -106,18 +105,6 @@
     return info;
   }
 
-  TypedefInfo visitTypedef(TypedefEntity typdef) {
-    var type = environment.getFunctionTypeOfTypedef(typdef);
-    TypedefInfo info =
-        new TypedefInfo(typdef.name, '$type', _unitInfoForEntity(typdef));
-    _entityToInfo[typdef] = info;
-    LibraryInfo lib = _entityToInfo[typdef.library];
-    lib.typedefs.add(info);
-    info.parent = lib;
-    result.typedefs.add(info);
-    return info;
-  }
-
   GlobalTypeInferenceMemberResult _resultOfMember(MemberEntity e) =>
       compiler.globalInference.results.resultOfMember(e);
 
@@ -147,7 +134,7 @@
         type: '${environment.getFieldType(field)}',
         inferredType: '$inferredType',
         code: code,
-        outputUnit: _unitInfoForEntity(field),
+        outputUnit: _unitInfoForMember(field),
         isConst: field.isConst);
     _entityToInfo[field] = info;
     if (codegenWorldBuilder.hasConstantFieldInitializer(field)) {
@@ -179,7 +166,7 @@
     ClassInfo classInfo = new ClassInfo(
         name: clazz.name,
         isAbstract: clazz.isAbstract,
-        outputUnit: _unitInfoForEntity(clazz));
+        outputUnit: _unitInfoForClass(clazz));
     _entityToInfo[clazz] = classInfo;
 
     int size = compiler.dumpInfoTask.sizeOf(clazz);
@@ -232,7 +219,7 @@
   ClosureInfo visitClosureClass(ClassEntity element) {
     ClosureInfo closureInfo = new ClosureInfo(
         name: element.name,
-        outputUnit: _unitInfoForEntity(element),
+        outputUnit: _unitInfoForClass(element),
         size: compiler.dumpInfoTask.sizeOf(element));
     _entityToInfo[element] = closureInfo;
 
@@ -313,7 +300,7 @@
         inlinedCount: inlinedCount,
         code: code,
         type: functionType.toString(),
-        outputUnit: _unitInfoForEntity(function));
+        outputUnit: _unitInfoForMember(function));
     _entityToInfo[function] = info;
 
     int closureSize = _addClosureInfo(info, function);
@@ -366,9 +353,14 @@
     });
   }
 
-  OutputUnitInfo _unitInfoForEntity(Entity entity) {
+  OutputUnitInfo _unitInfoForMember(MemberEntity entity) {
     return _infoFromOutputUnit(
-        compiler.backend.outputUnitData.outputUnitForEntity(entity));
+        compiler.backend.outputUnitData.outputUnitForMember(entity));
+  }
+
+  OutputUnitInfo _unitInfoForClass(ClassEntity entity) {
+    return _infoFromOutputUnit(
+        compiler.backend.outputUnitData.outputUnitForClass(entity));
   }
 
   OutputUnitInfo _unitInfoForConstant(ConstantValue constant) {
@@ -470,10 +462,11 @@
         entity,
         impact,
         new WorldImpactVisitorImpl(visitDynamicUse: (dynamicUse) {
+          TypeMask mask = dynamicUse.mask;
           selections.addAll(closedWorld
               // TODO(het): Handle `call` on `Closure` through
               // `world.includesClosureCall`.
-              .locateMembers(dynamicUse.selector, dynamicUse.mask)
+              .locateMembers(dynamicUse.selector, mask)
               .map((MemberEntity e) => new Selection(e, dynamicUse.mask)));
         }, visitStaticUse: (staticUse) {
           selections.add(new Selection(staticUse.element, null));
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 20264b1..dc244d9 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -562,17 +562,13 @@
 
   final List<FunctionTypeVariable> typeVariables;
 
-  /// The originating [TypedefType], if any.
-  final TypedefType typedefType;
-
   FunctionType(
       this.returnType,
       this.parameterTypes,
       this.optionalParameterTypes,
       this.namedParameters,
       this.namedParameterTypes,
-      this.typeVariables,
-      this.typedefType);
+      this.typeVariables);
 
   bool get containsTypeVariables {
     return typeVariables.any((type) => type.bound.containsTypeVariables) ||
@@ -665,8 +661,7 @@
           newOptionalParameterTypes,
           namedParameters,
           newNamedParameterTypes,
-          newTypeVariables,
-          typedefType);
+          newTypeVariables);
     }
     return this;
   }
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 0abf135..decc885 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -211,10 +211,6 @@
 
   final Queue<WorkItem> _queue = new Queue<WorkItem>();
 
-  /// Queue of deferred resolution actions to execute when the resolution queue
-  /// has been emptied.
-  final Queue<DeferredAction> _deferredQueue = new Queue<DeferredAction>();
-
   // If not `null` this is called when the queue has been emptied. It allows for
   // applying additional impacts before re-emptying the queue.
   void Function() onEmptyForTesting;
@@ -378,15 +374,9 @@
         }
         break;
       case TypeUseKind.TYPE_LITERAL:
-        TypedefType typedef;
-        if (type.isTypedef) {
-          typedef = type;
-        } else if (type is FunctionType) {
-          typedef = type.typedefType;
-        } else if (type is TypeVariableType) {
+        if (type is TypeVariableType) {
           _worldBuilder.registerTypeVariableTypeLiteral(type);
         }
-        if (typedef != null) worldBuilder.registerTypedef(typedef.element);
         break;
     }
   }
@@ -418,10 +408,8 @@
       if (!_onQueueEmpty(recents)) {
         _recentClasses.addAll(recents);
       }
-    } while (_queue.isNotEmpty ||
-        _recentClasses.isNotEmpty ||
-        _deferredQueue.isNotEmpty ||
-        _recentConstants);
+    } while (
+        _queue.isNotEmpty || _recentClasses.isNotEmpty || _recentConstants);
   }
 
   void forEach(void f(WorkItem work)) {
@@ -470,25 +458,6 @@
     _queue.add(workItem);
   }
 
-  /// Adds an action to the deferred task queue.
-  /// The action is performed the next time the resolution queue has been
-  /// emptied.
-  ///
-  /// The queue is processed in FIFO order.
-  void addDeferredAction(DeferredAction deferredAction) {
-    if (queueIsClosed) {
-      failedAt(
-          deferredAction.element,
-          "Resolution work list is closed. "
-          "Trying to add deferred action for ${deferredAction.element}");
-    }
-    _deferredQueue.add(deferredAction);
-  }
-
-  void addDeferredActions(Iterable<DeferredAction> deferredActions) {
-    deferredActions.forEach(addDeferredAction);
-  }
-
   /// [_onQueueEmpty] is called whenever the queue is drained. [recentClasses]
   /// contains the set of all classes seen for the first time since
   /// [_onQueueEmpty] was called last. A return value of [true] indicates that
@@ -496,19 +465,8 @@
   /// returned, [_onQueueEmpty] will be called once the queue is empty again (or
   /// still empty) and [recentClasses] will be a superset of the current value.
   bool _onQueueEmpty(Iterable<ClassEntity> recentClasses) {
-    _emptyDeferredQueue();
-
     return listener.onQueueEmpty(this, recentClasses);
   }
-
-  void emptyDeferredQueueForTesting() => _emptyDeferredQueue();
-
-  void _emptyDeferredQueue() {
-    while (!_deferredQueue.isEmpty) {
-      DeferredAction task = _deferredQueue.removeFirst();
-      _reporter.withCurrentElement(task.element, task.action);
-    }
-  }
 }
 
 /// Strategy used by the enqueuer to populate the world.
@@ -616,15 +574,6 @@
   }
 }
 
-typedef void DeferredActionFunction();
-
-class DeferredAction {
-  final Entity element;
-  final DeferredActionFunction action;
-
-  DeferredAction(this.element, this.action);
-}
-
 /// Interface for creating work items for enqueued member entities.
 abstract class WorkItemBuilder {
   WorkItem createWorkItem(covariant MemberEntity entity);
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index c995cfb..bb5ebdb 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -48,12 +48,12 @@
   final GlobalTypeInferenceElementData<ir.Node> _memberData;
   final bool _inGenerativeConstructor;
 
-  LocalsHandler _locals;
+  LocalsHandler<ir.Node> _locals;
   final SideEffectsBuilder _sideEffectsBuilder;
-  final Map<JumpTarget, List<LocalsHandler>> _breaksFor =
-      <JumpTarget, List<LocalsHandler>>{};
-  final Map<JumpTarget, List<LocalsHandler>> _continuesFor =
-      <JumpTarget, List<LocalsHandler>>{};
+  final Map<JumpTarget, List<LocalsHandler<ir.Node>>> _breaksFor =
+      <JumpTarget, List<LocalsHandler<ir.Node>>>{};
+  final Map<JumpTarget, List<LocalsHandler<ir.Node>>> _continuesFor =
+      <JumpTarget, List<LocalsHandler<ir.Node>>>{};
   TypeInformation _returnType;
   final Set<Local> _capturedVariables = new Set<Local>();
 
@@ -90,7 +90,7 @@
 
     FieldInitializationScope<ir.Node> fieldScope =
         _inGenerativeConstructor ? new FieldInitializationScope(_types) : null;
-    _locals = new LocalsHandler(
+    _locals = new LocalsHandler<ir.Node>(
         _inferrer, _types, _options, _analyzedNode, fieldScope);
   }
 
@@ -522,7 +522,7 @@
       continueTargets.forEach(_clearBreaksAndContinues);
     } else {
       LocalsHandler saved = _locals;
-      List<LocalsHandler> localsToMerge = <LocalsHandler>[];
+      List<LocalsHandler<ir.Node>> localsToMerge = <LocalsHandler<ir.Node>>[];
       bool hasDefaultCase = false;
 
       for (ir.SwitchCase switchCase in node.cases) {
@@ -580,8 +580,8 @@
   @override
   TypeInformation visitMapLiteral(ir.MapLiteral node) {
     return _inferrer.concreteTypes.putIfAbsent(node, () {
-      List keyTypes = [];
-      List valueTypes = [];
+      List keyTypes = <TypeInformation>[];
+      List valueTypes = <TypeInformation>[];
 
       for (ir.MapEntry entry in node.entries) {
         keyTypes.add(visit(entry.key));
@@ -944,8 +944,12 @@
 
   void _setupBreaksAndContinues(JumpTarget target) {
     if (target == null) return;
-    if (target.isContinueTarget) _continuesFor[target] = <LocalsHandler>[];
-    if (target.isBreakTarget) _breaksFor[target] = <LocalsHandler>[];
+    if (target.isContinueTarget) {
+      _continuesFor[target] = <LocalsHandler<ir.Node>>[];
+    }
+    if (target.isBreakTarget) {
+      _breaksFor[target] = <LocalsHandler<ir.Node>>[];
+    }
   }
 
   void _clearBreaksAndContinues(JumpTarget element) {
@@ -953,15 +957,15 @@
     _breaksFor.remove(element);
   }
 
-  List<LocalsHandler> _getBreaks(JumpTarget target) {
-    List<LocalsHandler> list = <LocalsHandler>[_locals];
+  List<LocalsHandler<ir.Node>> _getBreaks(JumpTarget target) {
+    List<LocalsHandler<ir.Node>> list = <LocalsHandler<ir.Node>>[_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];
+  List<LocalsHandler<ir.Node>> _getLoopBackEdges(JumpTarget target) {
+    List<LocalsHandler<ir.Node>> list = <LocalsHandler<ir.Node>>[_locals];
     if (target == null) return list;
     if (!target.isContinueTarget) return list;
     return list..addAll(_continuesFor[target]);
@@ -1463,7 +1467,7 @@
     // We don't put the closure in the work queue of the
     // inferrer, because it will share information with its enclosing
     // method, like for example the types of local variables.
-    LocalsHandler closureLocals =
+    LocalsHandler<ir.Node> closureLocals =
         new LocalsHandler.from(_locals, node, useOtherTryBlock: false);
     KernelTypeGraphBuilder visitor = new KernelTypeGraphBuilder(
         _options,
diff --git a/pkg/compiler/lib/src/io/source_file.dart b/pkg/compiler/lib/src/io/source_file.dart
index 8cfa41e..ff227ae 100644
--- a/pkg/compiler/lib/src/io/source_file.dart
+++ b/pkg/compiler/lib/src/io/source_file.dart
@@ -227,7 +227,7 @@
   }
 }
 
-class StringSourceFile extends SourceFile<String> {
+class StringSourceFile extends SourceFile<List<int>> {
   final Uri uri;
   final String filename;
   final String text;
@@ -240,7 +240,7 @@
   StringSourceFile.fromName(String filename, String text)
       : this(new Uri(path: filename), filename, text);
 
-  String get data => text;
+  List<int> get data => utf8.encode(text);
 
   int get length => text.length;
   set length(int v) {}
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 71bec0c..90bc21f 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -774,6 +774,7 @@
         _commonElements.instantiate2,
         _commonElements.instantiate3,
         _commonElements.instantiatedGenericFunctionType,
+        _commonElements.extractFunctionTypeObjectFromInternal,
       ], instantiatedClasses: [
         _commonElements.instantiation1Class,
         _commonElements.instantiation2Class,
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index 461bd279..bb430e2 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -155,6 +155,7 @@
         _customElementsAnalysis.registerTypeConstant(representedType.element);
       }
     } else if (constant is InstantiationConstantValue) {
+      // TODO(johnniwinther): Register these using `BackendImpact`.
       impactBuilder.registerTypeUse(new TypeUse.instantiation(
           _elementEnvironment
               .getThisType(_commonElements.instantiation1Class)));
@@ -167,6 +168,9 @@
       impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
           _commonElements.instantiatedGenericFunctionType,
           CallStructure.TWO_ARGS));
+      impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
+          _commonElements.extractFunctionTypeObjectFromInternal,
+          CallStructure.ONE_ARG));
     }
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
index 1869f4d..5e9c4cb 100644
--- a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
@@ -53,7 +53,6 @@
         new List<DartType>.filled(16, const DynamicType()),
         const <String>[],
         const <DartType>[],
-        const <FunctionTypeVariable>[],
-        null);
+        const <FunctionTypeVariable>[]);
   }
 }
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 4ce047a..1f202ed 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -1102,7 +1102,7 @@
   }
 
   jsAst.Name _disambiguateGlobalMember(MemberEntity element) {
-    return _disambiguateGlobal(element, _proposeNameForMember);
+    return _disambiguateGlobal<MemberEntity>(element, _proposeNameForMember);
   }
 
   jsAst.Name _disambiguateGlobalType(Entity element) {
@@ -1112,8 +1112,8 @@
   /// Returns the disambiguated name for a top-level or static element.
   ///
   /// The resulting name is unique within the global-member namespace.
-  jsAst.Name _disambiguateGlobal(
-      Entity element, String proposeName(Entity element)) {
+  jsAst.Name _disambiguateGlobal<T extends Entity>(
+      T element, String proposeName(T element)) {
     // TODO(asgerf): We can reuse more short names if we disambiguate with
     // a separate namespace for each of the global holder objects.
     jsAst.Name newName = userGlobals[element];
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 2364c42..1281eb9 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -1571,6 +1571,26 @@
       typeVariableTestsForTesting = typeVariableTests;
     }
 
+    /*print(typeVariableTests.dump());
+    print('------------------------------------------------------------------');
+    print('classesNeedingTypeArguments:');
+    classesNeedingTypeArguments.forEach((e) => print('  $e'));
+    print('------------------------------------------------------------------');
+    print('methodsNeedingSignature:');
+    methodsNeedingSignature.forEach((e) => print('  $e'));
+    print('------------------------------------------------------------------');
+    print('methodsNeedingTypeArguments:');
+    methodsNeedingTypeArguments.forEach((e) => print('  $e'));
+    print('------------------------------------------------------------------');
+    print('localFunctionsNeedingSignature:');
+    localFunctionsNeedingSignature.forEach((e) => print('  $e'));
+    print('------------------------------------------------------------------');
+    print('localFunctionsNeedingTypeArguments:');
+    localFunctionsNeedingTypeArguments.forEach((e) => print('  $e'));
+    print('------------------------------------------------------------------');
+    print('selectorsNeedingTypeArguments:');
+    selectorsNeedingTypeArguments.forEach((e) => print('  $e'));*/
+
     return _createRuntimeTypesNeed(
         _elementEnvironment,
         closedWorld.backendUsage,
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 ee51d11..3a54cf6 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
@@ -93,7 +93,7 @@
 
     jsAst.Name constructorName = namer.className(classElement);
     OutputUnit outputUnit =
-        compiler.backend.outputUnitData.outputUnitForEntity(classElement);
+        compiler.backend.outputUnitData.outputUnitForClass(classElement);
     emitter.assemblePrecompiledConstructor(
         outputUnit, constructorName, constructorAst, fieldNames);
   }
@@ -317,7 +317,7 @@
     ClassEntity cls = member.enclosingClass;
     jsAst.Name className = namer.className(cls);
     OutputUnit outputUnit =
-        compiler.backend.outputUnitData.outputUnitForEntity(member);
+        compiler.backend.outputUnitData.outputUnitForMember(member);
     emitter
         .cspPrecompiledFunctionFor(outputUnit)
         .add(js('#.prototype.# = #', [className, getterName, function]));
@@ -332,7 +332,7 @@
     ClassEntity cls = member.enclosingClass;
     jsAst.Name className = namer.className(cls);
     OutputUnit outputUnit =
-        compiler.backend.outputUnitData.outputUnitForEntity(member);
+        compiler.backend.outputUnitData.outputUnitForMember(member);
     emitter
         .cspPrecompiledFunctionFor(outputUnit)
         .add(js('#.prototype.# = #', [className, setterName, function]));
diff --git a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
index 865fc15..477ced0 100644
--- a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
@@ -104,18 +104,19 @@
   /// ```
   /// $signature:: function() {
   ///   return H.instantiatedGenericFunctionType(
-  ///       this._genericClosure.$signature(),
+  ///       H.extractFunctionTypeObjectFromInternal(this._genericClosure),
   ///       this.$ti);
   /// }
   /// ```
   ParameterStubMethod _generateSignatureStub(FieldEntity functionField) {
     jsAst.Name operatorSignature = _namer.asName(_namer.operatorSignature);
 
-    jsAst.Fun function = js('function() { return #(this.#.#(), this.#); }', [
+    jsAst.Fun function = js('function() { return #(#(this.#), this.#); }', [
       _emitter.staticFunctionAccess(
           _commonElements.instantiatedGenericFunctionType),
+      _emitter.staticFunctionAccess(
+          _commonElements.extractFunctionTypeObjectFromInternal),
       _namer.fieldPropertyName(functionField),
-      operatorSignature,
       _namer.rtiFieldJsName,
     ]);
     // TODO(sra): Generate source information for stub that has no member.
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 88f2c2d..905c3bd 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
@@ -616,7 +616,7 @@
     List<StaticMethod> statics = memberElements
         .where((e) => !e.isField)
         .cast<FunctionEntity>()
-        .map(_buildStaticMethod)
+        .map<StaticMethod>(_buildStaticMethod)
         .toList();
 
     if (library == _commonElements.interceptorsLibrary) {
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index 3615c8c..e76a39d 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -101,6 +101,7 @@
   final RuntimeTypesEncoder _rtiEncoder;
   final JsInteropAnalysis _jsInteropAnalysis;
   final bool _strongMode;
+  final _TypeContainedInOutputUnitVisitor _outputUnitVisitor;
 
   RuntimeTypeGenerator(
       this._commonElements,
@@ -111,7 +112,9 @@
       this._rtiChecks,
       this._rtiEncoder,
       this._jsInteropAnalysis,
-      this._strongMode);
+      this._strongMode)
+      : _outputUnitVisitor = new _TypeContainedInOutputUnitVisitor(
+            _commonElements, _outputUnitData);
 
   /**
    * Generate "is tests" for [cls] itself, and the "is tests" for the
@@ -145,19 +148,28 @@
       // signatures. We either need them for mirrors or because [type] is
       // potentially a subtype of a checked function. Currently we eagerly
       // generate a function type index or signature for all callable classes.
-      if (storeFunctionTypeInMetadata && !type.containsTypeVariables) {
-        // TODO(johnniwinther,efortuna): Should we use the scheme for Dart 2?
-        // TODO(sigmund): use output unit of `method` (Issue #31032)
-        OutputUnit outputUnit = _outputUnitData.mainOutputUnit;
-        result.functionTypeIndex =
-            emitterTask.metadataCollector.reifyType(type, outputUnit);
+      jsAst.Expression functionTypeIndex;
+      if (!type.containsTypeVariables) {
+        // TODO(sigmund): use output unit of [method] when the classes mentioned
+        // in [type] aren't in the main output unit. (Issue #31032)
+        OutputUnit mainOutputUnit = _outputUnitData.mainOutputUnit;
+        if (_outputUnitVisitor.isTypeContainedIn(type, mainOutputUnit)) {
+          functionTypeIndex =
+              emitterTask.metadataCollector.reifyType(type, mainOutputUnit);
+        }
+      }
+      if (storeFunctionTypeInMetadata && functionTypeIndex != null) {
+        result.functionTypeIndex = functionTypeIndex;
       } else {
         jsAst.Expression encoding =
             generatedCode[classFunctionType.signatureFunction];
-        if (classFunctionType.signatureFunction != null) {
-          // Use precomputed signature function if live.
-        } else {
-          assert(!_strongMode);
+        if (_strongMode) {
+          if (classFunctionType.signatureFunction == null) {
+            // The signature function isn't live.
+            return;
+          }
+          encoding = functionTypeIndex ?? encoding;
+        } else if (encoding == null) {
           // Generate the signature on the fly. This is only supported for
           // Dart 1.
 
@@ -240,3 +252,84 @@
     }
   }
 }
+
+/// Visitor that checks whether a type is contained within one output unit.
+class _TypeContainedInOutputUnitVisitor
+    implements DartTypeVisitor<bool, OutputUnit> {
+  final CommonElements _commonElements;
+  final OutputUnitData _outputUnitData;
+
+  _TypeContainedInOutputUnitVisitor(this._commonElements, this._outputUnitData);
+
+  /// Returns `true` if all classes mentioned in [type] are in [outputUnit].
+  bool isTypeContainedIn(DartType type, OutputUnit outputUnit) =>
+      visit(type, outputUnit);
+
+  @override
+  bool visit(DartType type, OutputUnit argument) => type.accept(this, argument);
+
+  bool visitList(List<DartType> types, OutputUnit argument) {
+    for (DartType type in types) {
+      if (!visit(type, argument)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @override
+  bool visitFutureOrType(FutureOrType type, OutputUnit argument) {
+    if (_outputUnitData.outputUnitForClass(_commonElements.functionClass) !=
+        argument) {
+      return false;
+    }
+    return visit(type.typeArgument, argument);
+  }
+
+  @override
+  bool visitDynamicType(DynamicType type, OutputUnit argument) => true;
+
+  @override
+  bool visitTypedefType(TypedefType type, OutputUnit argument) {
+    return visit(type.unaliased, argument);
+  }
+
+  @override
+  bool visitInterfaceType(InterfaceType type, OutputUnit argument) {
+    if (_outputUnitData.outputUnitForClass(type.element) != argument) {
+      return false;
+    }
+    return visitList(type.typeArguments, argument);
+  }
+
+  @override
+  bool visitFunctionType(FunctionType type, OutputUnit argument) {
+    bool result = visit(type.returnType, argument) &&
+        visitList(type.parameterTypes, argument) &&
+        visitList(type.optionalParameterTypes, argument) &&
+        visitList(type.namedParameterTypes, argument);
+    if (!result) return false;
+    for (FunctionTypeVariable typeVariable in type.typeVariables) {
+      if (!visit(typeVariable.bound, argument)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @override
+  bool visitFunctionTypeVariable(
+      FunctionTypeVariable type, OutputUnit argument) {
+    return true;
+  }
+
+  @override
+  bool visitTypeVariableType(TypeVariableType type, OutputUnit argument) {
+    return false;
+  }
+
+  @override
+  bool visitVoidType(VoidType type, OutputUnit argument) {
+    return true;
+  }
+}
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index c86157d..2641d69 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -286,8 +286,7 @@
         visitList(type.optionalParameterTypes, converter),
         type.namedParameters,
         visitList(type.namedParameterTypes, converter),
-        type.typeVariables,
-        visitTypedefType(type.typedefType, converter));
+        type.typeVariables);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 28e67b6..f624144 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -43,7 +43,6 @@
 import '../universe/class_set.dart';
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
-import '../util/emptyset.dart';
 import '../world.dart';
 import 'closure.dart';
 import 'elements.dart';
@@ -102,24 +101,51 @@
       return map.toBackendLibrary(entity);
     }
 
-    // Convert a front-end map containing K-entities keys to a backend map using
-    // J-entities as keys.
-    Map<Entity, OutputUnit> convertEntityMap(Map<Entity, OutputUnit> input) {
-      var result = <Entity, OutputUnit>{};
-      input.forEach((Entity entity, OutputUnit unit) {
-        // Closures have both a class and a call-method, we ensure both are
-        // included in the corresponding output unit.
+    // Convert front-end maps containing K-class and K-local function keys to a
+    // backend map using J-classes as keys.
+    Map<ClassEntity, OutputUnit> convertClassMap(
+        Map<ClassEntity, OutputUnit> classMap,
+        Map<Local, OutputUnit> localFunctionMap) {
+      var result = <ClassEntity, OutputUnit>{};
+      classMap.forEach((ClassEntity entity, OutputUnit unit) {
+        ClassEntity backendEntity = toBackendEntity(entity);
+        if (backendEntity != null) {
+          // If [entity] isn't used it doesn't have a corresponding backend
+          // entity.
+          result[backendEntity] = unit;
+        }
+      });
+      localFunctionMap.forEach((Local entity, OutputUnit unit) {
+        // Ensure closure classes are included in the output unit corresponding
+        // to the local function.
         if (entity is KLocalFunction) {
           var closureInfo = _closureDataLookup.getClosureInfo(entity.node);
           result[closureInfo.closureClassEntity] = unit;
+        }
+      });
+      return result;
+    }
+
+    // Convert front-end maps containing K-member and K-local function keys to
+    // a backend map using J-members as keys.
+    Map<MemberEntity, OutputUnit> convertMemberMap(
+        Map<MemberEntity, OutputUnit> memberMap,
+        Map<Local, OutputUnit> localFunctionMap) {
+      var result = <MemberEntity, OutputUnit>{};
+      memberMap.forEach((MemberEntity entity, OutputUnit unit) {
+        MemberEntity backendEntity = toBackendEntity(entity);
+        if (backendEntity != null) {
+          // If [entity] isn't used it doesn't have a corresponding backend
+          // entity.
+          result[backendEntity] = unit;
+        }
+      });
+      localFunctionMap.forEach((Local entity, OutputUnit unit) {
+        // Ensure closure call-methods are included in the output unit
+        // corresponding to the local function.
+        if (entity is KLocalFunction) {
+          var closureInfo = _closureDataLookup.getClosureInfo(entity.node);
           result[closureInfo.callMethod] = unit;
-        } else {
-          Entity backendEntity = toBackendEntity(entity);
-          if (backendEntity != null) {
-            // If [entity] isn't used it doesn't have a corresponding backend
-            // entity.
-            result[backendEntity] = unit;
-          }
         }
       });
       return result;
@@ -131,7 +157,8 @@
 
     return new OutputUnitData.from(
         data,
-        convertEntityMap,
+        convertClassMap,
+        convertMemberMap,
         (m) => convertMap<ConstantValue, OutputUnit>(
             m, toBackendConstant, (v) => v));
   }
@@ -363,9 +390,7 @@
         assignedInstanceMembers: assignedInstanceMembers,
         processedMembers: processedMembers,
         mixinUses: mixinUses,
-        typesImplementedBySubclasses: typesImplementedBySubclasses,
-        // TODO(johnniwinther): Support this:
-        allTypedefs: new ImmutableEmptySet<TypedefEntity>());
+        typesImplementedBySubclasses: typesImplementedBySubclasses);
   }
 
   BackendUsage _convertBackendUsage(
@@ -591,7 +616,6 @@
       Iterable<MemberEntity> liveInstanceMembers,
       Iterable<MemberEntity> assignedInstanceMembers,
       Iterable<MemberEntity> processedMembers,
-      Set<TypedefEntity> allTypedefs,
       Map<ClassEntity, Set<ClassEntity>> mixinUses,
       Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
       Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
@@ -610,7 +634,6 @@
             liveInstanceMembers,
             assignedInstanceMembers,
             processedMembers,
-            allTypedefs,
             mixinUses,
             typesImplementedBySubclasses,
             classHierarchyNodes,
@@ -758,9 +781,8 @@
     for (FunctionTypeVariable typeVariable in type.typeVariables) {
       _functionTypeVariables.remove(typeVariable);
     }
-    var typedefType = type.typedefType?.accept(this, null);
     return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
-        type.namedParameters, namedParameterTypes, typeVariables, typedefType);
+        type.namedParameters, namedParameterTypes, typeVariables);
   }
 
   DartType visitInterfaceType(InterfaceType type, _) {
diff --git a/pkg/compiler/lib/src/kernel/deferred_load.dart b/pkg/compiler/lib/src/kernel/deferred_load.dart
index f3f1a9c..b312027 100644
--- a/pkg/compiler/lib/src/kernel/deferred_load.dart
+++ b/pkg/compiler/lib/src/kernel/deferred_load.dart
@@ -20,37 +20,8 @@
 
   KernelDeferredLoadTask(Compiler compiler, this._elementMap) : super(compiler);
 
-  @override
-  Iterable<ImportEntity> importsTo(Entity element, LibraryEntity library) {
-    ir.NamedNode node;
-    String nodeName;
-    ir.Library enclosingLibrary;
-    if (element is ClassEntity) {
-      ClassDefinition definition = _elementMap.getClassDefinition(element);
-      if (definition.kind != ClassKind.regular) {
-        // You can't import closures.
-        return const <ImportEntity>[];
-      }
-      ir.Class _node = definition.node;
-      nodeName = _node.name;
-      enclosingLibrary = _node.enclosingLibrary;
-      node = _node;
-    } else if (element is MemberEntity) {
-      ir.Member _node = _elementMap.getMemberDefinition(element).node;
-      nodeName = _node.name.name;
-      enclosingLibrary = _node.enclosingLibrary;
-      node = _node;
-    } else if (element is Local ||
-        element is LibraryEntity ||
-        element is TypeVariableEntity) {
-      return const <ImportEntity>[];
-    } else if (element is TypedefEntity) {
-      throw new UnimplementedError("KernelDeferredLoadTask.importsTo typedef");
-    } else {
-      throw new UnsupportedError(
-          "KernelDeferredLoadTask.importsTo unexpected entity type: "
-          "${element.runtimeType}");
-    }
+  Iterable<ImportEntity> _findImportsTo(ir.NamedNode node, String nodeName,
+      ir.Library enclosingLibrary, LibraryEntity library) {
     List<ImportEntity> imports = [];
     ir.Library source = _elementMap.getLibraryNode(library);
     for (ir.LibraryDependency dependency in source.dependencies) {
@@ -65,6 +36,25 @@
   }
 
   @override
+  Iterable<ImportEntity> classImportsTo(
+      ClassEntity element, LibraryEntity library) {
+    ClassDefinition definition = _elementMap.getClassDefinition(element);
+    if (definition.kind != ClassKind.regular) {
+      // You can't import closures.
+      return const <ImportEntity>[];
+    }
+    ir.Class node = definition.node;
+    return _findImportsTo(node, node.name, node.enclosingLibrary, library);
+  }
+
+  @override
+  Iterable<ImportEntity> memberImportsTo(
+      Entity element, LibraryEntity library) {
+    ir.Member node = _elementMap.getMemberDefinition(element).node;
+    return _findImportsTo(node, node.name.name, node.enclosingLibrary, library);
+  }
+
+  @override
   void checkForDeferredErrorCases(LibraryEntity library) {
     // Nothing to do. The FE checks for error cases upfront.
   }
@@ -77,14 +67,13 @@
   }
 
   @override
-  void collectConstantsInBody(
-      covariant MemberEntity element, Set<ConstantValue> constants) {
+  void collectConstantsInBody(MemberEntity element, Dependencies dependencies) {
     ir.Member node = _elementMap.getMemberDefinition(element).node;
 
     // Fetch the internal node in order to skip annotations on the member.
     // TODO(sigmund): replace this pattern when the kernel-ast provides a better
     // way to skip annotations (issue 31565).
-    var visitor = new ConstantCollector(_elementMap, constants);
+    var visitor = new ConstantCollector(_elementMap, dependencies);
     if (node is ir.Field) {
       node.initializer?.accept(visitor);
       return;
@@ -135,9 +124,9 @@
 
 class ConstantCollector extends ir.RecursiveVisitor {
   final KernelToElementMapForImpact elementMap;
-  final Set<ConstantValue> constants;
+  final Dependencies dependencies;
 
-  ConstantCollector(this.elementMap, this.constants);
+  ConstantCollector(this.elementMap, this.dependencies);
 
   CommonElements get commonElements => elementMap.commonElements;
 
@@ -145,7 +134,7 @@
     ConstantValue constant =
         elementMap.getConstantValue(node, requireConstant: required);
     if (constant != null) {
-      constants.add(constant);
+      dependencies.constants.add(constant);
     }
   }
 
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index fe02b86..8154793 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -4,6 +4,7 @@
 
 library dart2js.kernel.element_map;
 
+import 'package:front_end/src/fasta/util/link.dart' show Link, LinkBuilder;
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/class_hierarchy.dart' as ir;
 import 'package:kernel/core_types.dart' as ir;
@@ -46,7 +47,6 @@
 import '../universe/class_set.dart';
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
-import '../util/util.dart' show Link, LinkBuilder;
 import '../world.dart';
 import 'element_map.dart';
 import 'element_map_mixins.dart';
@@ -311,11 +311,12 @@
         node.implementedTypes.forEach((ir.Supertype supertype) {
           linkBuilder.addLast(processSupertype(supertype));
         });
-        Link<InterfaceType> interfaces = linkBuilder.toLink();
+        Link<InterfaceType> interfaces =
+            linkBuilder.toLink(const Link<InterfaceType>());
         OrderedTypeSetBuilder setBuilder =
             new _KernelOrderedTypeSetBuilder(this, cls);
         data.orderedTypeSet = setBuilder.createOrderedTypeSet(
-            data.supertype, interfaces.reverse());
+            data.supertype, interfaces.reverse(const Link<InterfaceType>()));
         data.interfaces = new List<InterfaceType>.from(interfaces.toList());
       }
     }
@@ -479,7 +480,7 @@
     }
 
     return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
-        namedParameters, namedParameterTypes, typeVariables, null);
+        namedParameters, namedParameterTypes, typeVariables);
   }
 
   @override
@@ -614,15 +615,10 @@
             ..sort((a, b) => a.compareTo(b));
           List<DartType> namedParameterTypes =
               new List.filled(namedParameters.length, dynamic);
-          data.callType = new FunctionType(
-              dynamic,
-              requiredParameterTypes,
-              optionalParameterTypes,
-              namedParameters,
-              namedParameterTypes,
+          data.callType = new FunctionType(dynamic, requiredParameterTypes,
+              optionalParameterTypes, namedParameters, namedParameterTypes,
               // TODO(johnniwinther): Generate existential types here.
-              const <FunctionTypeVariable>[],
-              null);
+              const <FunctionTypeVariable>[]);
         } else {
           // The function type is not valid.
           data.callType = const DynamicType();
@@ -841,6 +837,9 @@
 
 /// Mixin that implements the abstract methods in [KernelToElementMapBase].
 abstract class ElementCreatorMixin implements KernelToElementMapBase {
+  /// Set to `true` before creating the J-World from the K-World to assert that
+  /// no entities are created late.
+  bool _envIsClosed = false;
   ProgramEnv get _env;
   EntityDataEnvMap<IndexedLibrary, LibraryData, LibraryEnv> get _libraries;
   EntityDataEnvMap<IndexedClass, ClassData, ClassEnv> get _classes;
@@ -885,6 +884,10 @@
 
   LibraryEntity _getLibrary(ir.Library node, [LibraryEnv libraryEnv]) {
     return _libraryMap.putIfAbsent(node, () {
+      assert(
+          !_envIsClosed,
+          "Environment of $this is closed. Trying to create "
+          "library for $node.");
       Uri canonicalUri = node.importUri;
       String name = node.name;
       if (name == null) {
@@ -900,6 +903,10 @@
 
   ClassEntity _getClass(ir.Class node, [ClassEnv classEnv]) {
     return _classMap.putIfAbsent(node, () {
+      assert(
+          !_envIsClosed,
+          "Environment of $this is closed. Trying to create "
+          "class for $node.");
       KLibrary library = _getLibrary(node.enclosingLibrary);
       if (classEnv == null) {
         classEnv = _libraries.getEnv(library).lookupClass(node.name);
@@ -913,6 +920,10 @@
 
   TypedefEntity _getTypedef(ir.Typedef node) {
     return _typedefMap.putIfAbsent(node, () {
+      assert(
+          !_envIsClosed,
+          "Environment of $this is closed. Trying to create "
+          "typedef for $node.");
       IndexedLibrary library = _getLibrary(node.enclosingLibrary);
       IndexedTypedef typedef = createTypedef(library, node.name);
       TypedefType typedefType = new TypedefType(
@@ -926,6 +937,10 @@
 
   TypeVariableEntity _getTypeVariable(ir.TypeParameter node) {
     return _typeVariableMap.putIfAbsent(node, () {
+      assert(
+          !_envIsClosed,
+          "Environment of $this is closed. Trying to create "
+          "type variable for $node.");
       if (node.parent is ir.Class) {
         ir.Class cls = node.parent;
         int index = cls.typeParameters.indexOf(node);
@@ -962,6 +977,10 @@
 
   ConstructorEntity _getConstructor(ir.Member node) {
     return _constructorMap.putIfAbsent(node, () {
+      assert(
+          !_envIsClosed,
+          "Environment of $this is closed. Trying to create "
+          "constructor for $node.");
       MemberDefinition definition;
       ir.FunctionNode functionNode;
       ClassEntity enclosingClass = _getClass(node.enclosingClass);
@@ -999,6 +1018,10 @@
 
   FunctionEntity _getMethod(ir.Procedure node) {
     return _methodMap.putIfAbsent(node, () {
+      assert(
+          !_envIsClosed,
+          "Environment of $this is closed. Trying to create "
+          "function for $node.");
       LibraryEntity library;
       ClassEntity enclosingClass;
       if (node.enclosingClass != null) {
@@ -1048,6 +1071,10 @@
 
   FieldEntity _getField(ir.Field node) {
     return _fieldMap.putIfAbsent(node, () {
+      assert(
+          !_envIsClosed,
+          "Environment of $this is closed. Trying to create "
+          "field for $node.");
       LibraryEntity library;
       ClassEntity enclosingClass;
       if (node.enclosingClass != null) {
@@ -1690,12 +1717,6 @@
   }
 
   @override
-  Iterable<ConstantValue> getTypedefMetadata(TypedefEntity typedef) {
-    // TODO(redemption): Support this.
-    throw new UnsupportedError('ElementEnvironment.getTypedefMetadata');
-  }
-
-  @override
   Iterable<ConstantValue> getMemberMetadata(covariant IndexedMember member,
       {bool includeParameterMetadata: false}) {
     // TODO(redemption): Support includeParameterMetadata.
@@ -1705,17 +1726,6 @@
   }
 
   @override
-  FunctionType getFunctionTypeOfTypedef(TypedefEntity typedef) {
-    // TODO(redemption): Support this.
-    throw new UnsupportedError('ElementEnvironment.getFunctionTypeOfTypedef');
-  }
-
-  @override
-  TypedefType getTypedefTypeOfTypedef(TypedefEntity typedef) {
-    return elementMap._typedefs.getData(typedef).rawType;
-  }
-
-  @override
   bool isEnumClass(ClassEntity cls) {
     assert(elementMap.checkFamily(cls));
     ClassData classData = elementMap._classes.getData(cls);
@@ -1795,9 +1805,6 @@
       }
     }
 
-    DartType typedefType =
-        node.typedef == null ? null : elementMap.getTypedefType(node.typedef);
-
     FunctionType type = new FunctionType(
         visitType(node.returnType),
         visitTypes(node.positionalParameters
@@ -1808,8 +1815,7 @@
             .toList()),
         node.namedParameters.map((n) => n.name).toList(),
         node.namedParameters.map((n) => visitType(n.type)).toList(),
-        typeVariables ?? const <FunctionTypeVariable>[],
-        typedefType);
+        typeVariables ?? const <FunctionTypeVariable>[]);
     for (ir.TypeParameter typeParameter in node.typeParameters) {
       currentFunctionTypeParameters.remove(typeParameter);
     }
@@ -2085,7 +2091,6 @@
       Iterable<MemberEntity> liveInstanceMembers,
       Iterable<MemberEntity> assignedInstanceMembers,
       Iterable<MemberEntity> processedMembers,
-      Set<TypedefEntity> allTypedefs,
       Map<ClassEntity, Set<ClassEntity>> mixinUses,
       Map<ClassEntity, Set<ClassEntity>> typesImplementedBySubclasses,
       Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
@@ -2104,7 +2109,6 @@
             liveInstanceMembers,
             assignedInstanceMembers,
             processedMembers,
-            allTypedefs,
             mixinUses,
             typesImplementedBySubclasses,
             classHierarchyNodes,
@@ -2370,6 +2374,11 @@
       assert(newTypeVariable.typeVariableIndex ==
           oldTypeVariable.typeVariableIndex);
     }
+    // TODO(johnniwinther): We should close the environment in the beginning of
+    // this constructor but currently we need the [MemberEntity] to query if the
+    // member is live, thus potentially creating the [MemberEntity] in the
+    // process. Avoid this.
+    _elementMap._envIsClosed = true;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index c9b9d93..dde76e85 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -297,7 +297,7 @@
   ClassEnvImpl.internal(this.cls, this._constructorMap, this._memberMap,
       this._setterMap, this._members);
 
-  bool get isUnnamedMixinApplication => cls.isSyntheticMixinImplementation;
+  bool get isUnnamedMixinApplication => cls.isAnonymousMixin;
 
   /// Copied from 'package:kernel/transformations/mixin_full_resolution.dart'.
   ir.Constructor _buildForwardingConstructor(
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 2124d1f..25e576b 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -7,6 +7,7 @@
 import 'dart:async';
 
 import 'package:front_end/src/api_unstable/dart2js.dart' as fe;
+import 'package:front_end/src/fasta/util/link.dart' show Link;
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
 import 'package:kernel/kernel.dart' hide LibraryDependency, Combinator;
@@ -19,10 +20,8 @@
 import 'common/tasks.dart' show CompilerTask, Measurer;
 import 'common.dart';
 import 'elements/entities.dart' show LibraryEntity;
-import 'enqueue.dart' show DeferredAction;
 import 'kernel/element_map_impl.dart' show KernelToElementMapForImpactImpl;
 import 'resolved_uri_translator.dart';
-import 'util/util.dart' show Link;
 
 /**
  * [CompilerTask] for loading libraries and setting up the import/export scopes.
@@ -131,47 +130,7 @@
   /// [LibraryElement] for the library and computes the import/export scope,
   /// loading and computing the import/export scopes of all required libraries
   /// in the process. The method handles cyclic dependency between libraries.
-  ///
-  /// If [skipFileWithPartOfTag] is `true`, `null` is returned if the
-  /// compilation unit for [resolvedUri] contains a `part of` tag. This is only
-  /// used for analysis through [Compiler.analyzeUri].
-  Future<LoadedLibraries> loadLibrary(Uri resolvedUri,
-      {bool skipFileWithPartOfTag: false});
-
-  // TODO(johnniwinther): Move these to a separate interface.
-  /// Register a deferred action to be performed during resolution.
-  void registerDeferredAction(DeferredAction action);
-
-  /// Returns the deferred actions registered since the last call to
-  /// [pullDeferredActions].
-  Iterable<DeferredAction> pullDeferredActions();
-
-  /// The locations of js patch-files relative to the sdk-descriptors.
-  static const _patchLocations = const <String, String>{
-    "async": "_internal/js_runtime/lib/async_patch.dart",
-    "cli": "_internal/js_runtime/lib/cli_patch.dart",
-    "collection": "_internal/js_runtime/lib/collection_patch.dart",
-    "convert": "_internal/js_runtime/lib/convert_patch.dart",
-    "core": "_internal/js_runtime/lib/core_patch.dart",
-    "developer": "_internal/js_runtime/lib/developer_patch.dart",
-    "io": "_internal/js_runtime/lib/io_patch.dart",
-    "isolate": "_internal/js_runtime/lib/isolate_patch.dart",
-    "math": "_internal/js_runtime/lib/math_patch.dart",
-    "mirrors": "_internal/js_runtime/lib/mirrors_patch.dart",
-    "typed_data": "_internal/js_runtime/lib/typed_data_patch.dart",
-    "_internal": "_internal/js_runtime/lib/internal_patch.dart",
-    "_js": "js/_js_client.dart",
-  };
-
-  /// Returns the location of the patch-file associated with [libraryName]
-  /// resolved from [plaformConfigUri].
-  ///
-  /// Returns null if there is none.
-  static Uri resolvePatchUri(String libraryName, Uri platformConfigUri) {
-    String patchLocation = _patchLocations[libraryName];
-    if (patchLocation == null) return null;
-    return platformConfigUri.resolve(patchLocation);
-  }
+  Future<LoadedLibraries> loadLibrary(Uri resolvedUri);
 }
 
 /// Interface for an entity that provide libraries.
@@ -223,8 +182,7 @@
   /// library, so this name is actually a bit of a misnomer).
   // TODO(efortuna): Rename this once the Element library loader class goes
   // away.
-  Future<LoadedLibraries> loadLibrary(Uri resolvedUri,
-      {bool skipFileWithPartOfTag: false}) {
+  Future<LoadedLibraries> loadLibrary(Uri resolvedUri) {
     return measure(() async {
       var isDill = resolvedUri.path.endsWith('.dill');
       ir.Component component;
@@ -303,13 +261,6 @@
   LibraryEntity lookupLibrary(Uri canonicalUri) {
     return _elementMap?.lookupLibrary(canonicalUri);
   }
-
-  void registerDeferredAction(DeferredAction action) {
-    throw new UnimplementedError(
-        'KernelLibraryLoaderTask.registerDeferredAction');
-  }
-
-  Iterable<DeferredAction> pullDeferredActions() => const <DeferredAction>[];
 }
 
 /// Information on the set libraries loaded as a result of a call to
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index dde23a9..cea1634 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -61,7 +61,7 @@
 
   /// Resolved constant "environment" values passed to the compiler via the `-D`
   /// flags.
-  Map<String, dynamic> environment = const <String, dynamic>{};
+  Map<String, String> environment = const <String, String>{};
 
   /// A possibly null state object for kernel compilation.
   fe.InitializedCompilerState kernelInitializedCompilerState;
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index 67c594a..e8d365b 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -4,13 +4,14 @@
 
 library ordered_typeset;
 
+import 'package:front_end/src/fasta/util/link.dart' show Link, LinkBuilder;
+import 'package:front_end/src/fasta/util/link_implementation.dart'
+    show LinkEntry;
+
 import 'common.dart';
 import 'diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
 import 'elements/entities.dart';
 import 'elements/types.dart';
-import 'util/util.dart' show Link, LinkBuilder;
-import 'package:front_end/src/fasta/util/link_implementation.dart'
-    show LinkEntry;
 
 /**
  * An ordered set of the supertypes of a class. The supertypes of a class are
@@ -283,7 +284,7 @@
       }
     }
     return new OrderedTypeSet.internal(
-        levels, levels.last, allSupertypes.toLink());
+        levels, levels.last, allSupertypes.toLink(const Link<InterfaceType>()));
   }
 
   String toString() {
@@ -291,13 +292,7 @@
     for (int depth = 0; depth <= maxDepth; depth++) {
       sb.write('$depth: ');
       LinkEntry<InterfaceType> first = map[depth];
-      if (first.isNotEmpty) {
-        sb.write('${first.head}');
-        while (first.tail.isNotEmpty) {
-          sb.write(', ${first.tail.head}');
-          first = first.tail;
-        }
-      }
+      first.printOn(sb, ", ");
       sb.write('\n');
     }
     return sb.toString();
diff --git a/pkg/compiler/lib/src/source_file_provider.dart b/pkg/compiler/lib/src/source_file_provider.dart
index e7c0f61..7b4f019 100644
--- a/pkg/compiler/lib/src/source_file_provider.dart
+++ b/pkg/compiler/lib/src/source_file_provider.dart
@@ -25,8 +25,9 @@
   Map<Uri, api.Input> binarySourceFiles = <Uri, api.Input>{};
   int dartCharactersRead = 0;
 
-  Future<api.Input> readBytesFromUri(Uri resourceUri, api.InputKind inputKind) {
-    api.Input input;
+  Future<api.Input<List<int>>> readBytesFromUri(
+      Uri resourceUri, api.InputKind inputKind) {
+    api.Input<List<int>> input;
     switch (inputKind) {
       case api.InputKind.UTF8:
         input = utf8SourceFiles[resourceUri];
@@ -84,8 +85,9 @@
     return null;
   }
 
-  Future<api.Input> _readFromFile(Uri resourceUri, api.InputKind inputKind) {
-    api.Input input;
+  Future<api.Input<List<int>>> _readFromFile(
+      Uri resourceUri, api.InputKind inputKind) {
+    api.Input<List<int>> input;
     try {
       input = _readFromFileSync(resourceUri, inputKind);
     } catch (e) {
@@ -94,7 +96,8 @@
     return new Future.value(input);
   }
 
-  Future<api.Input> _readFromHttp(Uri resourceUri, api.InputKind inputKind) {
+  Future<api.Input<List<int>>> _readFromHttp(
+      Uri resourceUri, api.InputKind inputKind) {
     assert(resourceUri.scheme == 'http');
     HttpClient client = new HttpClient();
     return client
@@ -118,7 +121,7 @@
         offset += contentPart.length;
       }
       dartCharactersRead += totalLength;
-      api.Input input;
+      api.Input<List<int>> input;
       switch (inputKind) {
         case api.InputKind.UTF8:
           input = utf8SourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
@@ -141,7 +144,7 @@
 
   relativizeUri(Uri uri) => relativize(cwd, uri, isWindows);
 
-  SourceFile getUtf8SourceFile(Uri resourceUri) {
+  SourceFile<List<int>> getUtf8SourceFile(Uri resourceUri) {
     return utf8SourceFiles[resourceUri];
   }
 
@@ -267,7 +270,7 @@
       throw 'Unknown kind: $kind (${kind.ordinal})';
     }
     if (!enableColors) {
-      color = (x) => x;
+      color = (String x) => x;
     }
     if (uri == null) {
       print('${color(message)}');
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index c8a203c..65e1636 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -2839,7 +2839,7 @@
       ConstantValue value = _elementMap.getFieldConstantValue(field);
       if (value != null) {
         if (!field.isAssignable) {
-          var unit = compiler.backend.outputUnitData.outputUnitForEntity(field);
+          var unit = compiler.backend.outputUnitData.outputUnitForMember(field);
           // TODO(sigmund): this is not equivalent to what the old FE does: if
           // there is no prefix the old FE wouldn't treat this in any special
           // way. Also, if the prefix points to a constant in the main output
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 1e94b01..4e299b0 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -4,6 +4,9 @@
 
 import 'dart:math' as math;
 import 'dart:collection' show Queue;
+
+import 'package:front_end/src/fasta/util/link.dart' show Link;
+
 import '../common.dart';
 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
 import '../common/tasks.dart' show CompilerTask;
@@ -31,7 +34,6 @@
 import '../universe/selector.dart' show Selector;
 import '../universe/use.dart'
     show ConstantUse, ConstrainedDynamicUse, StaticUse, TypeUse;
-import '../util/util.dart';
 import '../world.dart' show ClosedWorld;
 import 'codegen_helpers.dart';
 import 'nodes.dart';
@@ -2423,7 +2425,7 @@
   void generateThrowWithHelper(FunctionEntity helper, argument,
       {SourceInformation sourceInformation}) {
     js.Expression jsHelper = _emitter.staticFunctionAccess(helper);
-    List arguments = [];
+    List arguments = <js.Expression>[];
     if (argument is List) {
       argument.forEach((instruction) {
         use(instruction);
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 04c906f..cb3258d 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.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/util/link.dart' show Link;
+
 import '../closure.dart';
 import '../common.dart';
 import '../compiler.dart' show Compiler;
@@ -1555,7 +1557,7 @@
   /// we have to register the instantiated type in the code generator. The
   /// [instructionType] of this node is not enough, because we also need the
   /// type arguments. See also [SsaFromAstMixin.currentInlinedInstantiations].
-  List<DartType> instantiatedTypes;
+  List<InterfaceType> instantiatedTypes;
 
   /// If this node creates a closure class, [callMethod] is the call method of
   /// the closure class.
@@ -1759,7 +1761,7 @@
   /// contains the type(s) used in the (Dart) `New` expression(s). The
   /// [instructionType] of this node is not enough, because we also need the
   /// type arguments. See also [SsaFromAstMixin.currentInlinedInstantiations].
-  List<DartType> instantiatedTypes;
+  List<InterfaceType> instantiatedTypes;
 
   /** The first input must be the target. */
   HInvokeStatic(this.element, inputs, AbstractValue type, this.typeArguments,
diff --git a/pkg/compiler/lib/src/ssa/variable_allocator.dart b/pkg/compiler/lib/src/ssa/variable_allocator.dart
index 7575c22..3bb3c85 100644
--- a/pkg/compiler/lib/src/ssa/variable_allocator.dart
+++ b/pkg/compiler/lib/src/ssa/variable_allocator.dart
@@ -550,9 +550,9 @@
     if (instruction is HCheck) {
       // Special case this instruction to use the name of its
       // input if it has one.
-      var temp = instruction;
+      HInstruction temp = instruction;
       do {
-        temp = temp.checkedInput;
+        temp = (temp as HCheck).checkedInput;
         name = names.ownName[temp];
       } while (name == null && temp is HCheck);
       if (name != null) return addAllocatedName(instruction, name);
diff --git a/pkg/compiler/lib/src/types/abstract_value_domain.dart b/pkg/compiler/lib/src/types/abstract_value_domain.dart
index 6b35ca4..de04b3d 100644
--- a/pkg/compiler/lib/src/types/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/types/abstract_value_domain.dart
@@ -268,4 +268,14 @@
   /// Returns whether [selector] invoked on a [receiver] can hit a
   /// [noSuchMethod].
   bool needsNoSuchMethodHandling(AbstractValue receiver, Selector selector);
+
+  /// Returns `true` if the set of runtime values of [subset] are all in the set
+  /// of runtime values of [superset].
+  bool contains(AbstractValue superset, AbstractValue subset);
+
+  /// Returns the [MemberEntity] that is known to always be hit at runtime
+  /// [receiver].
+  ///
+  /// Returns `null` if 0 or more than 1 member can be hit at runtime.
+  MemberEntity locateSingleMember(AbstractValue receiver, Selector selector);
 }
diff --git a/pkg/compiler/lib/src/types/masks.dart b/pkg/compiler/lib/src/types/masks.dart
index 8e4916c..19455cc 100644
--- a/pkg/compiler/lib/src/types/masks.dart
+++ b/pkg/compiler/lib/src/types/masks.dart
@@ -442,4 +442,15 @@
       covariant TypeMask receiver, Selector selector) {
     return receiver.needsNoSuchMethodHandling(selector, _closedWorld);
   }
+
+  @override
+  bool contains(covariant TypeMask superset, covariant TypeMask subset) {
+    return superset.containsMask(subset, _closedWorld);
+  }
+
+  @override
+  MemberEntity locateSingleMember(
+      covariant TypeMask receiver, Selector selector) {
+    return receiver.locateSingleMember(selector, _closedWorld);
+  }
 }
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index 50bc096..d7c9c01 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -365,6 +365,5 @@
    * Returns the [element] that is known to always be hit at runtime
    * on this mask. Returns null if there is none.
    */
-  // TODO(johnniwinther): Move this method to [World].
   MemberEntity locateSingleMember(Selector selector, ClosedWorld closedWorld);
 }
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index 3dd5e16..e747c75 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -6,9 +6,10 @@
 
 import 'dart:collection' show IterableBase;
 
+import 'package:front_end/src/fasta/util/link.dart' show Link;
+
 import '../elements/entities.dart' show ClassEntity;
 import '../util/enumset.dart' show EnumSet;
-import '../util/util.dart' show Link;
 
 /// Enum for the different kinds of instantiation of a class.
 enum Instantiation {
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
index ed3c1b9..f408104 100644
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -384,8 +384,6 @@
   ClosedWorld _closedWorldCache;
   final Set<MemberEntity> _liveInstanceMembers = new Set<MemberEntity>();
 
-  final Set<TypedefEntity> _allTypedefs = new Set<TypedefEntity>();
-
   final Set<ConstantValue> _constantValues = new Set<ConstantValue>();
 
   final Set<Local> genericLocalFunctions = new Set<Local>();
@@ -888,10 +886,6 @@
     return uses != null ? uses : const <ClassEntity>[];
   }
 
-  void registerTypedef(TypedefEntity typdef) {
-    _allTypedefs.add(typdef);
-  }
-
   void registerUsedElement(MemberEntity element) {
     if (element.isInstanceMember && !element.isAbstract) {
       _liveInstanceMembers.add(element);
@@ -1063,7 +1057,6 @@
         liveInstanceMembers: _liveInstanceMembers,
         assignedInstanceMembers: computeAssignedInstanceMembers(),
         processedMembers: _processedMembers,
-        allTypedefs: _allTypedefs,
         mixinUses: classHierarchyBuilder.mixinUses,
         typesImplementedBySubclasses: typesImplementedBySubclasses,
         classHierarchyNodes: classHierarchyBuilder.classHierarchyNodes,
diff --git a/pkg/compiler/lib/src/util/maplet.dart b/pkg/compiler/lib/src/util/maplet.dart
index febfe5f..b9dc6744 100644
--- a/pkg/compiler/lib/src/util/maplet.dart
+++ b/pkg/compiler/lib/src/util/maplet.dart
@@ -157,7 +157,7 @@
           copyTo++;
         }
       } else {
-        Map map = new Map();
+        var map = new Map<K, V>();
         forEach((eachKey, eachValue) => map[eachKey] = eachValue);
         map[key] = value;
         _key = map;
diff --git a/pkg/compiler/lib/src/util/setlet.dart b/pkg/compiler/lib/src/util/setlet.dart
index 08195f0..62ccde0 100644
--- a/pkg/compiler/lib/src/util/setlet.dart
+++ b/pkg/compiler/lib/src/util/setlet.dart
@@ -138,7 +138,7 @@
         while (copyTo < CAPACITY) _contents[copyTo++] = null;
       } else {
         _contents = new Set<E>()
-          ..addAll(_contents)
+          ..addAll((_contents as List).cast<E>())
           ..add(element);
         _extra = _MARKER;
       }
diff --git a/pkg/compiler/lib/src/util/util.dart b/pkg/compiler/lib/src/util/util.dart
index 113a2ed..32944bb 100644
--- a/pkg/compiler/lib/src/util/util.dart
+++ b/pkg/compiler/lib/src/util/util.dart
@@ -10,7 +10,6 @@
 export 'emptyset.dart';
 export 'maplet.dart';
 export 'setlet.dart';
-export 'package:front_end/src/fasta/util/link.dart';
 
 part 'indentation.dart';
 
@@ -210,7 +209,7 @@
   if (isExternal) builder.addLast('external');
   if (isCovariant) builder.addLast('covariant');
   StringBuffer buffer = new StringBuffer();
-  builder.toLink().printOn(buffer, ', ');
+  builder.toLink(const Link<String>()).printOn(buffer, ', ');
   return buffer.toString();
 }
 
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 523bca7..9bd4e8a 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -5,6 +5,9 @@
 library dart2js.world;
 
 import 'dart:collection' show Queue;
+
+import 'package:front_end/src/fasta/util/link.dart' show Link;
+
 import 'common.dart';
 import 'common/names.dart';
 import 'common_elements.dart' show CommonElements, ElementEnvironment;
@@ -20,13 +23,12 @@
 import 'ordered_typeset.dart';
 import 'options.dart';
 import 'types/abstract_value_domain.dart';
-import 'types/masks.dart' show CommonMasks, TypeMask;
+import 'types/masks.dart' show CommonMasks;
 import 'universe/class_set.dart';
 import 'universe/function_set.dart' show FunctionSet;
 import 'universe/selector.dart' show Selector;
 import 'universe/side_effects.dart' show SideEffects, SideEffectsBuilder;
 import 'universe/world_builder.dart';
-import 'util/util.dart' show Link;
 
 /// Common superinterface for [OpenWorld] and [ClosedWorld].
 abstract class World {}
@@ -282,50 +284,50 @@
   /// Returns `true` if the field [element] is known to be effectively final.
   bool fieldNeverChanges(MemberEntity element);
 
-  /// Extends the receiver type [mask] for calling [selector] to take live
+  /// Extends the [receiver] type for calling [selector] to take live
   /// `noSuchMethod` handlers into account.
-  TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask);
+  AbstractValue extendMaskIfReachesAll(
+      Selector selector, AbstractValue receiver);
 
-  /// Returns all resolved typedefs.
-  Iterable<TypedefEntity> get allTypedefs;
-
-  /// Returns `true` if [selector] on [mask] can hit a `call` method on a
+  /// Returns `true` if [selector] on [receiver] can hit a `call` method on a
   /// subclass of `Closure`.
   ///
   /// Every implementation of `Closure` has a 'call' method with its own
   /// signature so it cannot be modelled by a [FunctionEntity]. Also,
   /// call-methods for tear-off are not part of the element model.
-  bool includesClosureCall(Selector selector, TypeMask mask);
+  bool includesClosureCall(Selector selector, AbstractValue receiver);
 
   /// Returns the mask for the potential receivers of a dynamic call to
-  /// [selector] on [mask].
+  /// [selector] on [receiver].
   ///
-  /// This will narrow the constraints of [mask] to a [TypeMask] of the
-  /// set of classes that actually implement the selected member or implement
-  /// the handling 'noSuchMethod' where the selected member is unimplemented.
-  TypeMask computeReceiverType(Selector selector, TypeMask mask);
+  /// This will narrow the constraints of [receiver] to an [AbstractValue] of
+  /// the set of classes that actually implement the selected member or
+  /// implement the handling 'noSuchMethod' where the selected member is
+  /// unimplemented.
+  AbstractValue computeReceiverType(Selector selector, AbstractValue receiver);
 
-  /// Returns all the instance members that may be invoked with the
-  /// [selector] on a receiver with the given [mask]. The returned elements may
-  /// include noSuchMethod handlers that are potential targets indirectly
-  /// through the noSuchMethod mechanism.
-  Iterable<MemberEntity> locateMembers(Selector selector, TypeMask mask);
+  /// Returns all the instance members that may be invoked with the [selector]
+  /// on the given [receiver]. The returned elements may include noSuchMethod
+  /// handlers that are potential targets indirectly through the noSuchMethod
+  /// mechanism.
+  Iterable<MemberEntity> locateMembers(
+      Selector selector, AbstractValue receiver);
 
-  /// Returns the single [MemberEntity] that matches a call to [selector] on a
-  /// receiver of type [mask]. If multiple targets exist, `null` is returned.
-  MemberEntity locateSingleMember(Selector selector, TypeMask mask);
+  /// Returns the single [MemberEntity] that matches a call to [selector] on the
+  /// [receiver]. If multiple targets exist, `null` is returned.
+  MemberEntity locateSingleMember(Selector selector, AbstractValue receiver);
 
-  /// Returns the single field that matches a call to [selector] on a
-  /// receiver of type [mask]. If multiple targets exist or the single target
-  /// is not a field, `null` is returned.
-  FieldEntity locateSingleField(Selector selector, TypeMask mask);
+  /// Returns the single field that matches a call to [selector] on the
+  /// [receiver]. If multiple targets exist or the single target is not a field,
+  /// `null` is returned.
+  FieldEntity locateSingleField(Selector selector, AbstractValue receiver);
 
   /// Returns the side effects of executing [element].
   SideEffects getSideEffectsOfElement(FunctionEntity element);
 
-  /// Returns the side effects of calling [selector] on a receiver of type
-  /// [mask].
-  SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask);
+  /// Returns the side effects of calling [selector] on the [receiver].
+  SideEffects getSideEffectsOfSelector(
+      Selector selector, AbstractValue receiver);
 
   /// Returns `true` if [element] is guaranteed not to throw an exception.
   bool getCannotThrow(FunctionEntity element);
@@ -386,7 +388,6 @@
 
 abstract class OpenWorld implements World {
   void registerUsedElement(MemberEntity element);
-  void registerTypedef(TypedefEntity typedef);
 
   ClosedWorld closeWorld();
 
@@ -431,8 +432,6 @@
 
   FunctionSet _allFunctions;
 
-  final Set<TypedefEntity> _allTypedefs;
-
   final Map<ClassEntity, Set<ClassEntity>> mixinUses;
   Map<ClassEntity, List<ClassEntity>> _liveMixinUses;
 
@@ -494,13 +493,11 @@
       this.liveInstanceMembers,
       this.assignedInstanceMembers,
       this.processedMembers,
-      Set<TypedefEntity> allTypedefs,
       this.mixinUses,
       this.typesImplementedBySubclasses,
       Map<ClassEntity, ClassHierarchyNode> classHierarchyNodes,
       Map<ClassEntity, ClassSet> classSets)
       : this._implementedClasses = implementedClasses,
-        this._allTypedefs = allTypedefs,
         this._classHierarchyNodes = classHierarchyNodes,
         this._classSets = classSets {
     _commonMasks = new CommonMasks(this);
@@ -1027,8 +1024,6 @@
     return _classSets[cls];
   }
 
-  Iterable<TypedefEntity> get allTypedefs => _allTypedefs;
-
   void _ensureFunctionSet() {
     if (_allFunctions == null) {
       // [FunctionSet] is created lazily because it is not used when we switch
@@ -1037,58 +1032,62 @@
     }
   }
 
-  /// Returns `true` if [selector] on [mask] can hit a `call` method on a
+  /// Returns `true` if [selector] on [receiver] can hit a `call` method on a
   /// subclass of `Closure`.
   ///
   /// Every implementation of `Closure` has a 'call' method with its own
   /// signature so it cannot be modelled by a [FunctionEntity]. Also,
   /// call-methods for tear-off are not part of the element model.
-  bool includesClosureCall(Selector selector, TypeMask mask) {
+  bool includesClosureCall(Selector selector, AbstractValue receiver) {
     return selector.name == Identifiers.call &&
-        (mask == null ||
-            mask.containsMask(abstractValueDomain.functionType, closedWorld));
+        (receiver == null ||
+            // TODO(johnniwinther): Should this have been `intersects` instead?
+            abstractValueDomain.contains(
+                receiver, abstractValueDomain.functionType));
   }
 
-  TypeMask computeReceiverType(Selector selector, TypeMask mask) {
+  AbstractValue computeReceiverType(Selector selector, AbstractValue receiver) {
     _ensureFunctionSet();
-    if (includesClosureCall(selector, mask)) {
+    if (includesClosureCall(selector, receiver)) {
       return abstractValueDomain.dynamicType;
     }
-    return _allFunctions.receiverType(selector, mask, abstractValueDomain);
+    return _allFunctions.receiverType(selector, receiver, abstractValueDomain);
   }
 
-  Iterable<MemberEntity> locateMembers(Selector selector, TypeMask mask) {
+  Iterable<MemberEntity> locateMembers(
+      Selector selector, AbstractValue receiver) {
     _ensureFunctionSet();
-    return _allFunctions.filter(selector, mask, abstractValueDomain);
+    return _allFunctions.filter(selector, receiver, abstractValueDomain);
   }
 
-  bool hasAnyUserDefinedGetter(Selector selector, TypeMask mask) {
+  bool hasAnyUserDefinedGetter(Selector selector, AbstractValue receiver) {
     _ensureFunctionSet();
     return _allFunctions
-        .filter(selector, mask, abstractValueDomain)
+        .filter(selector, receiver, abstractValueDomain)
         .any((each) => each.isGetter);
   }
 
-  FieldEntity locateSingleField(Selector selector, TypeMask mask) {
-    MemberEntity result = locateSingleMember(selector, mask);
+  FieldEntity locateSingleField(Selector selector, AbstractValue receiver) {
+    MemberEntity result = locateSingleMember(selector, receiver);
     return (result != null && result.isField) ? result : null;
   }
 
-  MemberEntity locateSingleMember(Selector selector, TypeMask mask) {
-    if (includesClosureCall(selector, mask)) {
+  MemberEntity locateSingleMember(Selector selector, AbstractValue receiver) {
+    if (includesClosureCall(selector, receiver)) {
       return null;
     }
-    mask ??= abstractValueDomain.dynamicType;
-    return mask.locateSingleMember(selector, this);
+    receiver ??= abstractValueDomain.dynamicType;
+    return abstractValueDomain.locateSingleMember(receiver, selector);
   }
 
-  TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
+  AbstractValue extendMaskIfReachesAll(
+      Selector selector, AbstractValue receiver) {
     bool canReachAll = true;
-    if (mask != null) {
+    if (receiver != null) {
       canReachAll = backendUsage.isInvokeOnUsed &&
-          mask.needsNoSuchMethodHandling(selector, this);
+          abstractValueDomain.needsNoSuchMethodHandling(receiver, selector);
     }
-    return canReachAll ? abstractValueDomain.dynamicType : mask;
+    return canReachAll ? abstractValueDomain.dynamicType : receiver;
   }
 
   bool fieldNeverChanges(MemberEntity element) {
@@ -1110,15 +1109,16 @@
     return false;
   }
 
-  SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask) {
+  SideEffects getSideEffectsOfSelector(
+      Selector selector, AbstractValue receiver) {
     // We're not tracking side effects of closures.
-    if (selector.isClosureCall || includesClosureCall(selector, mask)) {
+    if (selector.isClosureCall || includesClosureCall(selector, receiver)) {
       return new SideEffects();
     }
     SideEffects sideEffects = new SideEffects.empty();
     _ensureFunctionSet();
     for (MemberEntity e
-        in _allFunctions.filter(selector, mask, abstractValueDomain)) {
+        in _allFunctions.filter(selector, receiver, abstractValueDomain)) {
       if (e.isField) {
         if (selector.isGetter) {
           if (!fieldNeverChanges(e)) {
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 0a66690..a8478d6 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -522,7 +522,7 @@
 
   JS.Statement _emitClassDeclaration(Class c) {
     // Mixins are unrolled in _defineClass.
-    if (c.isSyntheticMixinImplementation) return null;
+    if (c.isAnonymousMixin) return null;
 
     // If this class is annotated with `@JS`, then there is nothing to emit.
     if (findAnnotation(c, isPublicJSAnnotation) != null) return null;
@@ -820,7 +820,7 @@
   /// Defines all constructors for this class as ES5 constructors.
   List<JS.Statement> _defineConstructors(Class c, JS.Expression className) {
     var body = <JS.Statement>[];
-    if (c.isSyntheticMixinImplementation || isMixinAliasClass(c)) {
+    if (c.isAnonymousMixin || isMixinAliasClass(c)) {
       // We already handled this when we defined the class.
       return body;
     }
@@ -1211,7 +1211,7 @@
       if (!emitMetadata && member.isStatic) continue;
 
       var name = member.name.name;
-      var reifiedType = _getMemberRuntimeType(member, c);
+      var reifiedType = _getMemberRuntimeType(member, c) as FunctionType;
 
       // Don't add redundant signatures for inherited methods whose signature
       // did not change.  If we are not overriding, or if the thing we are
@@ -1310,7 +1310,7 @@
         field.isFinal ? 'finalFieldType(#)' : 'fieldType(#)', [args]);
   }
 
-  FunctionType _getMemberRuntimeType(Member member, Class fromClass) {
+  DartType _getMemberRuntimeType(Member member, Class fromClass) {
     var f = member.function;
     if (f == null) {
       return (member as Field).type;
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index dc11518..44a8f0f 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -227,7 +227,7 @@
   if (mixedInClass != null) mixins.add(mixedInClass);
 
   var sc = c.superclass;
-  for (; sc.isSyntheticMixinImplementation; sc = sc.superclass) {
+  for (; sc.isAnonymousMixin; sc = sc.superclass) {
     mixins.add(sc.mixedInClass);
   }
   return sc;
diff --git a/pkg/dev_compiler/tool/build_pkgs.dart b/pkg/dev_compiler/tool/build_pkgs.dart
index 904aad3..c8b3bf12 100755
--- a/pkg/dev_compiler/tool/build_pkgs.dart
+++ b/pkg/dev_compiler/tool/build_pkgs.dart
@@ -189,7 +189,6 @@
     ..packagesFileUri = _uriInRepo(".packages")
     ..strongMode = true
     ..debugDump = true
-    ..chaseDependencies = true
     ..onError = errorHandler
     ..reportMessages = true
     ..target = new DevCompilerTarget();
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index a9faea8..a02b4cf 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -59,7 +59,7 @@
   ProcessResult runDdc(String command, List<String> args) {
     if (debug) {
       // Use unbuilt script.  This only works from a source checkout.
-      args.insertAll(0, ['--preview-dart-2', '-c', path.join(ddcPath, 'bin', '${command}.dart')]);
+      args.insertAll(0, ['--preview-dart-2', '--enable-asserts', path.join(ddcPath, 'bin', '${command}.dart')]);
       command = dartBinary;
     } else {
       // Use built snapshot.
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart
index 604c0c8..672eb0a 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart
@@ -16,12 +16,12 @@
   }
 
   @patch
-  static _setCurrent(_Namespace namespace, path) {
+  static _setCurrent(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("Directory_SetCurrent");
   }
 
   @patch
-  static _createTemp(_Namespace namespace, String path) {
+  static _createTemp(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("Directory._createTemp");
   }
 
@@ -31,22 +31,23 @@
   }
 
   @patch
-  static _exists(_Namespace namespace, String path) {
+  static _exists(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("Directory._exists");
   }
 
   @patch
-  static _create(_Namespace namespace, String path) {
+  static _create(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("Directory._create");
   }
 
   @patch
-  static _deleteNative(_Namespace namespace, String path, bool recursive) {
+  static _deleteNative(
+      _Namespace namespace, Uint8List rawPath, bool recursive) {
     throw new UnsupportedError("Directory._deleteNative");
   }
 
   @patch
-  static _rename(_Namespace namespace, String path, String newPath) {
+  static _rename(_Namespace namespace, Uint8List rawPath, String newPath) {
     throw new UnsupportedError("Directory._rename");
   }
 
@@ -54,7 +55,7 @@
   static void _fillWithDirectoryListing(
       _Namespace namespace,
       List<FileSystemEntity> list,
-      String path,
+      Uint8List rawPath,
       bool recursive,
       bool followLinks) {
     throw new UnsupportedError("Directory._fillWithDirectoryListing");
@@ -88,7 +89,8 @@
 @patch
 class FileSystemEntity {
   @patch
-  static _getTypeNative(_Namespace namespace, String path, bool followLinks) {
+  static _getTypeNative(
+      _Namespace namespace, Uint8List rawPath, bool followLinks) {
     throw new UnsupportedError("FileSystemEntity._getType");
   }
 
@@ -98,7 +100,7 @@
   }
 
   @patch
-  static _resolveSymbolicLinks(_Namespace namespace, String path) {
+  static _resolveSymbolicLinks(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("FileSystemEntity._resolveSymbolicLinks");
   }
 }
@@ -106,77 +108,77 @@
 @patch
 class _File {
   @patch
-  static _exists(_Namespace namespace, String path) {
+  static _exists(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("File._exists");
   }
 
   @patch
-  static _create(_Namespace namespace, String path) {
+  static _create(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("File._create");
   }
 
   @patch
-  static _createLink(_Namespace namespace, String path, String target) {
+  static _createLink(_Namespace namespace, Uint8List rawPath, String target) {
     throw new UnsupportedError("File._createLink");
   }
 
   @patch
-  static _linkTarget(_Namespace namespace, String path) {
+  static _linkTarget(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("File._linkTarget");
   }
 
   @patch
-  static _deleteNative(_Namespace namespace, String path) {
+  static _deleteNative(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("File._deleteNative");
   }
 
   @patch
-  static _deleteLinkNative(_Namespace namespace, String path) {
+  static _deleteLinkNative(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("File._deleteLinkNative");
   }
 
   @patch
-  static _rename(_Namespace namespace, String oldPath, String newPath) {
+  static _rename(_Namespace namespace, Uint8List oldPath, String newPath) {
     throw new UnsupportedError("File._rename");
   }
 
   @patch
-  static _renameLink(_Namespace namespace, String oldPath, String newPath) {
+  static _renameLink(_Namespace namespace, Uint8List oldPath, String newPath) {
     throw new UnsupportedError("File._renameLink");
   }
 
   @patch
-  static _copy(_Namespace namespace, String oldPath, String newPath) {
+  static _copy(_Namespace namespace, Uint8List oldPath, String newPath) {
     throw new UnsupportedError("File._copy");
   }
 
   @patch
-  static _lengthFromPath(_Namespace namespace, String path) {
+  static _lengthFromPath(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("File._lengthFromPath");
   }
 
   @patch
-  static _lastModified(_Namespace namespace, String path) {
+  static _lastModified(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("File._lastModified");
   }
 
   @patch
-  static _lastAccessed(_Namespace namespace, String path) {
+  static _lastAccessed(_Namespace namespace, Uint8List rawPath) {
     throw new UnsupportedError("File._lastAccessed");
   }
 
   @patch
-  static _setLastModified(_Namespace namespace, String path, int millis) {
+  static _setLastModified(_Namespace namespace, Uint8List rawPath, int millis) {
     throw new UnsupportedError("File._setLastModified");
   }
 
   @patch
-  static _setLastAccessed(_Namespace namespace, String path, int millis) {
+  static _setLastAccessed(_Namespace namespace, Uint8List rawPath, int millis) {
     throw new UnsupportedError("File._setLastAccessed");
   }
 
   @patch
-  static _open(_Namespace namespace, String path, int mode) {
+  static _open(_Namespace namespace, Uint8List rawPath, int mode) {
     throw new UnsupportedError("File._open");
   }
 
diff --git a/pkg/dev_compiler/tool/kernel_sdk.dart b/pkg/dev_compiler/tool/kernel_sdk.dart
index f2d5623..38e9e65 100755
--- a/pkg/dev_compiler/tool/kernel_sdk.dart
+++ b/pkg/dev_compiler/tool/kernel_sdk.dart
@@ -31,7 +31,6 @@
   var target = new DevCompilerTarget();
   var options = new CompilerOptions()
     ..compileSdk = true
-    ..chaseDependencies = true
     ..packagesFileUri = path.toUri(path.absolute('../../.packages'))
     ..sdkRoot = path.toUri(inputPath)
     ..target = target;
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index eea2ab4..4803de0 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -515,33 +515,35 @@
   }
 
   /**
-   * Calls the function [f] and verifies that it throws an exception.
+   * Calls the function [f] and verifies that it throws a `T`.
    * The optional [check] function can provide additional validation
-   * that the correct exception is being thrown.  For example, to check
-   * the type of the exception you could write this:
+   * that the correct object is being thrown.  For example, to check
+   * the content of the thrown boject you could write this:
    *
-   *     Expect.throws(myThrowingFunction, (e) => e is MyException);
+   *     Expect.throws<MyException>(myThrowingFunction,
+   *          (e) => e.myMessage.contains("WARNING"));
+   *
+   * The type variable can be omitted and the type checked in [check]
+   * instead. This was traditionally done before Dart had generic methods.
    *
    * If `f` fails an expectation (i.e., throws an [ExpectException]), that
    * exception is not caught by [Expect.throws]. The test is still considered
    * failing.
    */
-  static void throws(void f(), [bool check(Object error), String reason]) {
+  static void throws<T>(void f(), [bool check(T error), String reason]) {
     String msg = reason == null ? "" : "($reason)";
-    if (f is! _Nullary) {
+    if (f is! Function()) {
       // Only throws from executing the function body should count as throwing.
       // The failure to even call `f` should throw outside the try/catch.
       _fail("Expect.throws$msg: Function f not callable with zero arguments");
     }
     try {
       f();
-    } catch (e, s) {
+    } on Object catch (e, s) {
       // A test failure doesn't count as throwing.
       if (e is ExpectException) rethrow;
-      if (check != null && !check(e)) {
-        _fail("Expect.throws$msg: Unexpected '$e'\n$s");
-      }
-      return;
+      if (e is T && (check == null || check(e))) return;
+      _fail("Expect.throws$msg: Unexpected '$e'\n$s");
     }
     _fail('Expect.throws$msg fails: Did not throw');
   }
@@ -607,8 +609,9 @@
 /// Used in [Expect] because [Expect.identical] shadows the real [identical].
 bool _identical(a, b) => identical(a, b);
 
-typedef _Nullary(); // Expect.throws argument must be this type.
-
+/// Exception thrown on a failed expectation check.
+///
+/// Always recognized by [Expect.throws] as an unexpected error.
 class ExpectException implements Exception {
   final String message;
   ExpectException(this.message);
diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
index 57e667a..e624930 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -131,19 +131,7 @@
   /// When this option is `true`, [sdkSummary] must be null.
   bool compileSdk = false;
 
-  /// Whether the compiler should read files that are discovered as
-  /// dependencies, or only access the files listed explicitly.
-  ///
-  /// This option has different defaults depending on the API.
-  ///
-  /// For modular APIs like `kernelForComponent` and `summaryFor` the default
-  /// behavior is `false`. These APIs want to ensure that builds are hermetic,
-  /// where all files that will be compiled are listed explicitly and all other
-  /// dependencies are covered by summary files.
-  ///
-  /// For whole-program APIs like `kernelForProgram`, this option is true by
-  /// default, so they can treat any dependency that is not described in a
-  /// summary as if it was explicitly listed as an input.
+  @deprecated
   bool chaseDependencies;
 
   /// Whether to interpret Dart sources in strong-mode.
diff --git a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
index f10c806..8d4e803 100644
--- a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
@@ -21,7 +21,7 @@
   factory IncrementalKernelGenerator(CompilerOptions options, Uri entryPoint,
       [Uri initializeFromDillUri]) {
     return new IncrementalCompiler(
-        new CompilerContext(new ProcessedOptions(options, false, [entryPoint])),
+        new CompilerContext(new ProcessedOptions(options, [entryPoint])),
         initializeFromDillUri);
   }
 
diff --git a/pkg/front_end/lib/src/api_prototype/kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
index 94a6d0f..98d8ded 100644
--- a/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
@@ -43,7 +43,7 @@
 /// an error is reported.
 // TODO(sigmund): rename to kernelForScript?
 Future<Component> kernelForProgram(Uri source, CompilerOptions options) async {
-  var pOptions = new ProcessedOptions(options, false, [source]);
+  var pOptions = new ProcessedOptions(options, [source]);
   return await CompilerContext.runWithOptions(pOptions, (context) async {
     var component = (await generateKernelInternal())?.component;
     if (component == null) return null;
@@ -66,19 +66,10 @@
 /// dependencies, build unit dependencies must be acyclic.
 ///
 /// This API is intended for modular compilation. Dependencies to other build
-/// units are specified using [CompilerOptions.inputSummaries].
-///
-/// By default, the compilation process is hermetic, meaning that the only files
-/// which will be read are those listed in [sources],
-/// [CompilerOptions.inputSummaries], and [CompilerOptions.sdkSummary].  If a
-/// source file attempts to refer to a file which is not obtainable from these
-/// URIs, that will result in an error, even if the file exists on the
-/// filesystem.
-///
-/// When [CompilerOptions.chaseDependencies] is true, this default behavior
-/// changes, and any dependency of [sources] that is not listed in
-/// [CompilerOptions.inputSummaries] and [CompilerOptions.sdkSummary] is treated
-/// as an additional source file for the build unit.
+/// units are specified using [CompilerOptions.inputSummaries].  Any dependency
+/// of [sources] that is not listed in [CompilerOptions.inputSummaries] and
+/// [CompilerOptions.sdkSummary] is treated as an additional source file for the
+/// build unit.
 ///
 /// Any `part` declarations found in [sources] must refer to part files which
 /// are also listed in the build unit sources, otherwise an error results.  (It
@@ -89,6 +80,6 @@
 /// summaries.
 Future<Component> kernelForComponent(
     List<Uri> sources, CompilerOptions options) async {
-  return (await generateKernel(new ProcessedOptions(options, true, sources)))
+  return (await generateKernel(new ProcessedOptions(options, sources)))
       ?.component;
 }
diff --git a/pkg/front_end/lib/src/api_prototype/scheme_based_file_system.dart b/pkg/front_end/lib/src/api_prototype/scheme_based_file_system.dart
new file mode 100644
index 0000000..c992ea7
--- /dev/null
+++ b/pkg/front_end/lib/src/api_prototype/scheme_based_file_system.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, 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 'file_system.dart';
+
+/// A [FileSystem] that delegates to other file systems based on the URI scheme.
+class SchemeBasedFileSystem implements FileSystem {
+  final Map<String, FileSystem> fileSystemByScheme;
+
+  SchemeBasedFileSystem(this.fileSystemByScheme);
+
+  @override
+  FileSystemEntity entityForUri(Uri uri) {
+    FileSystem delegate = fileSystemByScheme[uri.scheme];
+    if (delegate == null) {
+      throw new FileSystemException(
+          uri,
+          "SchemeBasedFileSystem doesn't handle URIs with "
+          "scheme '${uri.scheme}': $uri");
+    }
+    return delegate.entityForUri(uri);
+  }
+}
diff --git a/pkg/front_end/lib/src/api_prototype/summary_generator.dart b/pkg/front_end/lib/src/api_prototype/summary_generator.dart
index 4a2974c..e230731 100644
--- a/pkg/front_end/lib/src/api_prototype/summary_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/summary_generator.dart
@@ -16,18 +16,7 @@
 ///
 /// Intended to be a part of a modular compilation process.
 ///
-/// [sources] should be the complete set of source files for a build unit
-/// (including both library and part files).
-///
-/// By default, the compilation process is hermetic, meaning that the only files
-/// which will be read are those listed in [sources],
-/// [CompilerOptions.inputSummaries], and [CompilerOptions.sdkSummary].  If a
-/// source file attempts to refer to a file which is not obtainable from these
-/// URIs, that will result in an error, even if the file exists on the
-/// filesystem.
-///
-/// When [CompilerOptions.chaseDependencies] is true, this default behavior
-/// changes, and any dependency of [sources] that is not listed in
+/// Any dependency of [sources] that is not listed in
 /// [CompilerOptions.inputSummaries] and [CompilerOptions.sdkSummary] is treated
 /// as an additional source file for the build unit.
 ///
@@ -42,7 +31,7 @@
 /// The return value is a list of bytes to write to the summary file.
 Future<List<int>> summaryFor(List<Uri> sources, CompilerOptions options,
     {bool truncate: false}) async {
-  return (await generateKernel(new ProcessedOptions(options, true, sources),
+  return (await generateKernel(new ProcessedOptions(options, sources),
           buildSummary: true, buildComponent: false, truncateSummary: truncate))
       ?.summary;
 }
diff --git a/pkg/front_end/lib/src/api_unstable/build_integration.dart b/pkg/front_end/lib/src/api_unstable/build_integration.dart
new file mode 100644
index 0000000..39fce75
--- /dev/null
+++ b/pkg/front_end/lib/src/api_unstable/build_integration.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2018, 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.
+
+export '../api_prototype/file_system.dart';
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index 666f32d..943eacf 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -47,7 +47,7 @@
     ..librariesSpecificationUri = librariesSpecificationUri
     ..packagesFileUri = packagesFileUri;
 
-  ProcessedOptions processedOpts = new ProcessedOptions(options, false, []);
+  ProcessedOptions processedOpts = new ProcessedOptions(options, []);
 
   return new InitializedCompilerState(options, processedOpts);
 }
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index 0b9545f..2fbff4f 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -66,10 +66,9 @@
     ..inputSummaries = inputSummaries
     ..target = target
     ..fileSystem = fileSystem ?? StandardFileSystem.instance
-    ..chaseDependencies = true
     ..reportMessages = true;
 
-  ProcessedOptions processedOpts = new ProcessedOptions(options, true, []);
+  ProcessedOptions processedOpts = new ProcessedOptions(options, []);
 
   return new InitializedCompilerState(options, processedOpts);
 }
diff --git a/pkg/front_end/lib/src/api_unstable/summary_worker.dart b/pkg/front_end/lib/src/api_unstable/summary_worker.dart
index 2fdc8e5..0d4bf9f 100644
--- a/pkg/front_end/lib/src/api_unstable/summary_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/summary_worker.dart
@@ -38,10 +38,9 @@
     ..packagesFileUri = packagesFile
     ..inputSummaries = inputSummaries
     ..target = target
-    ..fileSystem = fileSystem
-    ..chaseDependencies = true;
+    ..fileSystem = fileSystem;
 
-  ProcessedOptions processedOpts = new ProcessedOptions(options, true, []);
+  ProcessedOptions processedOpts = new ProcessedOptions(options, []);
 
   return new InitializedCompilerState(options, processedOpts);
 }
diff --git a/pkg/front_end/lib/src/base/libraries_specification.dart b/pkg/front_end/lib/src/base/libraries_specification.dart
index 2f9f553..2a25b30 100644
--- a/pkg/front_end/lib/src/base/libraries_specification.dart
+++ b/pkg/front_end/lib/src/base/libraries_specification.dart
@@ -164,9 +164,10 @@
         }
 
         var uri = checkAndResolve(data['uri']);
-        var patches;
+        List<Uri> patches;
         if (data['patches'] is List) {
-          patches = data['patches'].map(baseUri.resolve).toList();
+          patches =
+              data['patches'].map<Uri>((s) => baseUri.resolve(s)).toList();
         } else if (data['patches'] is String) {
           patches = [checkAndResolve(data['patches'])];
         } else if (data['patches'] == null) {
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 0c0dc02..c3072d9 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -172,15 +172,6 @@
 
   bool get throwOnNitsForDebugging => _raw.throwOnNitsForDebugging;
 
-  /// Like [CompilerOptions.chaseDependencies] but with the appropriate default
-  /// value filled in.
-  bool get chaseDependencies => _raw.chaseDependencies ?? !_modularApi;
-
-  /// Whether the compiler was invoked with a modular API.
-  ///
-  /// Used to determine the default behavior for [chaseDependencies].
-  final bool _modularApi;
-
   /// The entry-points provided to the compiler.
   final List<Uri> inputs;
 
@@ -189,7 +180,7 @@
 
   /// Initializes a [ProcessedOptions] object wrapping the given [rawOptions].
   ProcessedOptions(CompilerOptions rawOptions,
-      [this._modularApi = false, this.inputs = const [], this.output])
+      [this.inputs = const [], this.output])
       : this._raw = rawOptions,
         // TODO(sigmund, ahe): create ticker even earlier or pass in a stopwatch
         // collecting time since the start of the VM.
@@ -596,31 +587,8 @@
   }
 
   /// Create a [FileSystem] specific to the current options.
-  ///
-  /// If [chaseDependencies] is false, the resulting file system will be
-  /// hermetic.
   FileSystem _createFileSystem() {
-    var result = _raw.fileSystem;
-    if (!chaseDependencies) {
-      var allInputs = inputs.toSet();
-      allInputs.addAll(_raw.inputSummaries);
-      allInputs.addAll(_raw.linkedDependencies);
-
-      if (sdkSummary != null) allInputs.add(sdkSummary);
-
-      if (_raw.sdkRoot != null) {
-        // TODO(sigmund): refine this, we should be more explicit about when
-        // sdkRoot and libraries.json are allowed to be used.
-        allInputs.add(sdkRoot);
-        allInputs.add(sdkRoot.resolve("lib/libraries.json"));
-      }
-
-      /// Note: Searching the file-system for the package-config is not
-      /// supported in hermetic builds.
-      if (_raw.packagesFileUri != null) allInputs.add(_raw.packagesFileUri);
-      result = new HermeticFileSystem(allInputs, result);
-    }
-    return result;
+    return _raw.fileSystem;
   }
 
   String debugString() {
@@ -648,9 +616,6 @@
     writeList('Input Summaries', _raw.inputSummaries);
     writeList('Linked Dependencies', _raw.linkedDependencies);
 
-    sb.writeln('Modular: ${_modularApi}');
-    sb.writeln('Hermetic: ${!chaseDependencies} (provided: '
-        '${_raw.chaseDependencies == null ? null : !_raw.chaseDependencies})');
     sb.writeln('Packages uri: ${_raw.packagesFileUri}');
     sb.writeln('Packages: ${_packages}');
 
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index 1815328..304d87f 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -24,7 +24,6 @@
     show
         Builder,
         ClassBuilder,
-        DynamicTypeBuilder,
         ModifierBuilder,
         PrefixBuilder,
         Scope,
@@ -181,12 +180,7 @@
     return 0;
   }
 
-  void becomeCoreLibrary(dynamicType) {
-    if (scope.local["dynamic"] == null) {
-      addBuilder("dynamic",
-          new DynamicTypeBuilder<T, dynamic>(dynamicType, this, -1), -1);
-    }
-  }
+  void becomeCoreLibrary(dynamicType);
 
   void forEach(void f(String name, Builder builder)) {
     scope.forEach((String name, Builder builder) {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
index fc6df24..5febe96 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
@@ -66,8 +66,9 @@
     // So, if [arguments] is null, the default types should be retrieved from
     // [cls.typeParameters].
     if (arguments == null) {
-      List<DartType> result =
-          new List<DartType>.filled(cls.typeParameters.length, null);
+      List<DartType> result = new List<DartType>.filled(
+          cls.typeParameters.length, null,
+          growable: true);
       for (int i = 0; i < result.length; ++i) {
         result[i] = cls.typeParameters[i].defaultType;
       }
@@ -75,7 +76,8 @@
     }
 
     // [arguments] != null
-    List<DartType> result = new List<DartType>.filled(arguments.length, null);
+    List<DartType> result =
+        new List<DartType>.filled(arguments.length, null, growable: true);
     for (int i = 0; i < result.length; ++i) {
       result[i] = arguments[i].build(library);
     }
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
index 2b6c733..5a29dbe 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
@@ -9,6 +9,7 @@
 import 'package:kernel/ast.dart'
     show
         Class,
+        DartType,
         Field,
         Library,
         ListLiteral,
@@ -25,6 +26,7 @@
 import '../kernel/kernel_builder.dart'
     show
         Builder,
+        DynamicTypeBuilder,
         InvalidTypeBuilder,
         KernelInvalidTypeBuilder,
         KernelTypeBuilder,
@@ -65,6 +67,16 @@
   @override
   Library get target => library;
 
+  void becomeCoreLibrary(dynamicType) {
+    if (scope.local["dynamic"] == null) {
+      addBuilder(
+          "dynamic",
+          new DynamicTypeBuilder<KernelTypeBuilder, DartType>(
+              dynamicType, this, -1),
+          -1);
+    }
+  }
+
   void addClass(Class cls) {
     DillClassBuilder classBulder = new DillClassBuilder(cls, this);
     addBuilder(cls.name, classBulder, cls.fileOffset);
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_typedef_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_typedef_builder.dart
index f2666d8..a395dca 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_typedef_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_typedef_builder.dart
@@ -45,8 +45,9 @@
     // So, if [arguments] is null, the default types should be retrieved from
     // [cls.typeParameters].
     if (arguments == null) {
-      List<DartType> result =
-          new List<DartType>.filled(target.typeParameters.length, null);
+      List<DartType> result = new List<DartType>.filled(
+          target.typeParameters.length, null,
+          growable: true);
       for (int i = 0; i < result.length; ++i) {
         result[i] = target.typeParameters[i].defaultType;
       }
@@ -54,7 +55,8 @@
     }
 
     // [arguments] != null
-    List<DartType> result = new List<DartType>.filled(arguments.length, null);
+    List<DartType> result =
+        new List<DartType>.filled(arguments.length, null, growable: true);
     for (int i = 0; i < result.length; ++i) {
       result[i] = arguments[i].build(library);
     }
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index e1d7ba7..5f91fd5 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -128,17 +128,6 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeAnnotationOnEnumConstant = messageAnnotationOnEnumConstant;
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageAnnotationOnEnumConstant = const MessageCode(
-    "AnnotationOnEnumConstant",
-    analyzerCode: "ANNOTATION_ON_ENUM_CONSTANT",
-    dart2jsCode: "*fatal*",
-    message: r"""Enum constants can't have annotations.""",
-    tip: r"""Try removing the annotation.""");
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
         int
diff --git a/pkg/front_end/lib/src/fasta/get_dependencies.dart b/pkg/front_end/lib/src/fasta/get_dependencies.dart
index 37ee55e..4fa99af 100644
--- a/pkg/front_end/lib/src/fasta/get_dependencies.dart
+++ b/pkg/front_end/lib/src/fasta/get_dependencies.dart
@@ -37,7 +37,7 @@
     ..packagesFileUri = packages
     ..sdkSummary = platform
     ..sdkRoot = sdk;
-  var pOptions = new ProcessedOptions(options, false, <Uri>[script]);
+  var pOptions = new ProcessedOptions(options, <Uri>[script]);
   return await CompilerContext.runWithOptions(pOptions,
       (CompilerContext c) async {
     FileSystem fileSystem = c.options.fileSystem;
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 2fc31e8..b0297d0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -89,7 +89,7 @@
         SuperIndexedAccessGenerator,
         ThisAccessGenerator,
         ThisPropertyAccessGenerator,
-        TypeDeclarationAccessGenerator,
+        TypeUseGenerator,
         UnresolvedNameGenerator,
         VariableUseGenerator,
         buildIsNull;
@@ -445,7 +445,9 @@
   @override
   void endMetadataStar(int count) {
     debugEvent("MetadataStar");
-    push(popList(count) ?? NullValue.Metadata);
+    push(popList(
+            count, new List<Expression>.filled(count, null, growable: true)) ??
+        NullValue.Metadata);
   }
 
   @override
@@ -822,7 +824,9 @@
   @override
   void endArguments(int count, Token beginToken, Token endToken) {
     debugEvent("Arguments");
-    List arguments = popList(count) ?? <Expression>[];
+    List<dynamic> arguments =
+        new List<dynamic>.filled(count, null, growable: true);
+    popList(count, arguments);
     int firstNamedArgumentIndex = arguments.length;
     for (int i = 0; i < arguments.length; i++) {
       var node = arguments[i];
@@ -877,7 +881,9 @@
       }
       push(forest.arguments(positional, beginToken, named: named));
     } else {
-      push(forest.arguments(arguments, beginToken));
+      // TODO(kmillikin): Find a way to avoid allocating a second list in the
+      // case where there were no named arguments, which is a common one.
+      push(forest.arguments(new List<Expression>.from(arguments), beginToken));
     }
   }
 
@@ -938,13 +944,15 @@
     Expression expression = popForValue();
     if (expression is ShadowCascadeExpression) {
       push(expression);
-      push(new VariableUseGenerator(this, token, expression.variable));
+      push(new VariableUseGenerator<Expression, Statement, Arguments>(
+          this, token, expression.variable));
       expression.extend();
     } else {
       VariableDeclaration variable = new ShadowVariableDeclaration.forValue(
           toKernelExpression(expression), functionNestingLevel);
       push(new ShadowCascadeExpression(variable));
-      push(new VariableUseGenerator(this, token, variable));
+      push(new VariableUseGenerator<Expression, Statement, Arguments>(
+          this, token, variable));
     }
   }
 
@@ -1362,8 +1370,9 @@
         if (constantContext != ConstantContext.none || member.isField) {
           return new UnresolvedNameGenerator(this, token, n);
         }
-        return new ThisPropertyAccessGenerator(this, token, n,
-            lookupInstanceMember(n), lookupInstanceMember(n, isSetter: true));
+        return new ThisPropertyAccessGenerator<Expression, Statement,
+                Arguments>(this, token, n, lookupInstanceMember(n),
+            lookupInstanceMember(n, isSetter: true));
       } else if (ignoreMainInGetMainClosure &&
           name == "main" &&
           member?.name == "_getMainClosure") {
@@ -1378,11 +1387,12 @@
         deprecated_addCompileTimeError(
             charOffset, "Not a constant expression.");
       }
-      TypeDeclarationAccessGenerator generator =
-          new TypeDeclarationAccessGenerator(
+      TypeUseGenerator<Expression, Statement, Arguments> generator =
+          new TypeUseGenerator<Expression, Statement, Arguments>(
               this, token, prefix, charOffset, builder, name);
       return (prefix?.deferred == true)
-          ? new DeferredAccessGenerator(this, token, prefix, generator)
+          ? new DeferredAccessGenerator<Expression, Statement, Arguments>(
+              this, token, prefix, generator)
           : generator;
     } else if (builder.isLocal) {
       if (constantContext != ConstantContext.none &&
@@ -1399,14 +1409,15 @@
         var fact =
             typePromoter.getFactForAccess(builder.target, functionNestingLevel);
         var scope = typePromoter.currentScope;
-        return new ReadOnlyAccessGenerator(
+        return new ReadOnlyAccessGenerator<Expression, Statement, Arguments>(
             this,
             token,
-            new ShadowVariableGet(builder.target, fact, scope)
-              ..fileOffset = charOffset,
+            toExpression(new ShadowVariableGet(builder.target, fact, scope)
+              ..fileOffset = charOffset),
             name);
       } else {
-        return new VariableUseGenerator(this, token, builder.target);
+        return new VariableUseGenerator<Expression, Statement, Arguments>(
+            this, token, builder.target);
       }
     } else if (builder.isInstanceMember) {
       if (constantContext != ConstantContext.none &&
@@ -1429,13 +1440,16 @@
         getter = builder.target;
         setter = lookupInstanceMember(n, isSetter: true);
       }
-      return new ThisPropertyAccessGenerator(this, token, n, getter, setter);
+      return new ThisPropertyAccessGenerator<Expression, Statement, Arguments>(
+          this, token, n, getter, setter);
     } else if (builder.isRegularMethod) {
       assert(builder.isStatic || builder.isTopLevel);
-      StaticAccessGenerator generator =
-          new StaticAccessGenerator(this, token, builder.target, null);
+      StaticAccessGenerator<Expression, Statement, Arguments> generator =
+          new StaticAccessGenerator<Expression, Statement, Arguments>(
+              this, token, builder.target, null);
       return (prefix?.deferred == true)
-          ? new DeferredAccessGenerator(this, token, prefix, generator)
+          ? new DeferredAccessGenerator<Expression, Statement, Arguments>(
+              this, token, prefix, generator)
           : generator;
     } else if (builder is PrefixBuilder) {
       if (constantContext != ConstantContext.none && builder.deferred) {
@@ -1449,7 +1463,8 @@
       }
       return builder;
     } else if (builder is LoadLibraryBuilder) {
-      return new LoadLibraryGenerator(this, token, builder);
+      return new LoadLibraryGenerator<Expression, Statement, Arguments>(
+          this, token, builder);
     } else {
       if (builder.hasProblem && builder is! AccessErrorBuilder) return builder;
       Builder setter;
@@ -1460,8 +1475,9 @@
       } else if (builder.isField && !builder.isFinal) {
         setter = builder;
       }
-      StaticAccessGenerator generator =
-          new StaticAccessGenerator.fromBuilder(this, builder, token, setter);
+      StaticAccessGenerator<Expression, Statement, Arguments> generator =
+          new StaticAccessGenerator<Expression, Statement,
+              Arguments>.fromBuilder(this, builder, token, setter);
       if (constantContext != ConstantContext.none) {
         Member readTarget = generator.readTarget;
         if (!(readTarget is Field && readTarget.isConst ||
@@ -1472,7 +1488,8 @@
         }
       }
       return (prefix?.deferred == true)
-          ? new DeferredAccessGenerator(this, token, prefix, generator)
+          ? new DeferredAccessGenerator<Expression, Statement, Arguments>(
+              this, token, prefix, generator)
           : generator;
     }
   }
@@ -1505,7 +1522,9 @@
       String value = unescapeString(token.lexeme);
       push(forest.literalString(value, token));
     } else {
-      List parts = popList(1 + interpolationCount * 2);
+      var count = 1 + interpolationCount * 2;
+      List<Object> parts =
+          popList(count, new List<Object>.filled(count, null, growable: true));
       Token first = parts.first;
       Token last = parts.last;
       Quote quote = analyzeQuote(first.lexeme);
@@ -1581,7 +1600,8 @@
     debugEvent("LiteralInt");
     int value = int.parse(token.lexeme, onError: (_) => null);
     if (value == null) {
-      push(new LargeIntAccessGenerator(this, token));
+      push(new LargeIntAccessGenerator<Expression, Statement, Arguments>(
+          this, token));
     } else {
       push(forest.literalInt(value, token));
     }
@@ -1854,14 +1874,11 @@
       continueTarget.resolveContinues(forest, body);
     }
     Expression condition;
-    Token rightSeparator;
     if (forest.isExpressionStatement(conditionStatement)) {
       condition =
           forest.getExpressionFromExpressionStatement(conditionStatement);
-      rightSeparator = forest.getSemicolon(conditionStatement);
     } else {
       assert(forest.isEmptyStatement(conditionStatement));
-      rightSeparator = forest.getSemicolon(conditionStatement);
     }
     Statement result = forest.forStatement(
         forKeyword,
@@ -1870,7 +1887,7 @@
         variables,
         leftSeparator,
         condition,
-        rightSeparator,
+        conditionStatement,
         updates,
         leftParen.endGroup,
         body);
@@ -2032,7 +2049,8 @@
       if (prefix is PrefixBuilder) {
         name = scopeLookup(prefix.exportScope, suffix.name, beginToken,
             isQualified: true, prefix: prefix);
-      } else if (prefix is ErroneousExpressionGenerator) {
+      } else if (prefix
+          is ErroneousExpressionGenerator<Expression, Statement, Arguments>) {
         push(prefix.buildErroneousTypeNotAPrefix(suffix));
         return;
       } else {
@@ -2246,7 +2264,10 @@
     FormalParameterKind kind = optional("{", beginToken)
         ? FormalParameterKind.optionalNamed
         : FormalParameterKind.optionalPositional;
-    push(new OptionalFormals(kind, popList(count) ?? []));
+    var variables =
+        new List<VariableDeclaration>.filled(count, null, growable: true);
+    popList(count, variables);
+    push(new OptionalFormals(kind, variables));
   }
 
   @override
@@ -2346,45 +2367,47 @@
   @override
   void handleCatchBlock(Token onKeyword, Token catchKeyword, Token comma) {
     debugEvent("CatchBlock");
-    Block body = pop();
+    Statement body = pop();
     inCatchBlock = pop();
     if (catchKeyword != null) {
       exitLocalScope();
     }
     FormalParameters<Expression, Statement, Arguments> catchParameters =
         popIfNotNull(catchKeyword);
-    DartType type = popIfNotNull(onKeyword) ?? const DynamicType();
-    VariableDeclaration exception;
-    VariableDeclaration stackTrace;
+    Object type = popIfNotNull(onKeyword);
+    Object exception;
+    Object stackTrace;
     if (catchParameters != null) {
-      if (catchParameters.required.length > 0) {
+      int requiredCount = catchParameters.required.length;
+      if ((requiredCount == 1 || requiredCount == 2) &&
+          catchParameters.optional == null) {
         exception = catchParameters.required[0];
-        exception.type = type;
-      }
-      if (catchParameters.required.length > 1) {
-        stackTrace = catchParameters.required[1];
-        stackTrace.type = coreTypes.stackTraceClass.rawType;
-      }
-      if (catchParameters.required.length > 2 ||
-          catchParameters.optional != null) {
-        body = toKernelStatement(forest.block(
+        forest.setParameterType(exception, type);
+        if (requiredCount == 2) {
+          stackTrace = catchParameters.required[1];
+          forest.setParameterType(
+              stackTrace, coreTypes.stackTraceClass.rawType);
+        }
+      } else {
+        body = forest.block(
             catchKeyword,
             <Statement>[
               toStatement(compileTimeErrorInTry ??=
                   deprecated_buildCompileTimeErrorStatement(
                       "Invalid catch arguments.", catchKeyword.next.charOffset))
             ],
-            null));
+            null);
       }
     }
-    push(new Catch(exception, body, guard: type, stackTrace: stackTrace)
-      ..fileOffset = offsetForToken(onKeyword ?? catchKeyword));
+    push(forest.catchClause(onKeyword, type, catchKeyword, exception,
+        stackTrace, coreTypes.stackTraceClass.rawType, body));
   }
 
   @override
   void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
     Statement finallyBlock = popStatementIfNotNull(finallyKeyword);
-    Object catches = popList(catchCount);
+    Object catches = popList(
+        catchCount, new List<Catch>.filled(catchCount, null, growable: true));
     Statement tryBlock = popStatement();
     if (compileTimeErrorInTry == null) {
       push(forest.tryStatement(
@@ -2408,14 +2431,14 @@
     Expression index = popForValue();
     var receiver = pop();
     if (receiver is ThisAccessGenerator && receiver.isSuper) {
-      push(new SuperIndexedAccessGenerator(
+      push(new SuperIndexedAccessGenerator<Expression, Statement, Arguments>(
           this,
           openSquareBracket,
-          toKernelExpression(index),
+          index,
           lookupInstanceMember(indexGetName, isSuper: true),
           lookupInstanceMember(indexSetName, isSuper: true)));
     } else {
-      push(IndexedAccessGenerator.make(
+      push(IndexedAccessGenerator.make<Expression, Statement, Arguments>(
           this, openSquareBracket, toValue(receiver), index, null, null));
     }
   }
@@ -2431,7 +2454,8 @@
       if (optional("-", token)) {
         operator = "unary-";
 
-        if (receiver is LargeIntAccessGenerator) {
+        if (receiver
+            is LargeIntAccessGenerator<Expression, Statement, Arguments>) {
           int value =
               int.parse("-" + receiver.token.lexeme, onError: (_) => null);
           if (value != null) {
@@ -2542,7 +2566,7 @@
             prefix.exportScope, identifier.name, identifier.token,
             isQualified: true, prefix: prefix);
         identifier = null;
-      } else if (prefix is TypeDeclarationAccessGenerator) {
+      } else if (prefix is TypeUseGenerator<Expression, Statement, Arguments>) {
         type = prefix;
       } else if (prefix is Generator) {
         String name = suffix == null
@@ -2760,15 +2784,16 @@
     var type = pop();
     PrefixBuilder deferredPrefix;
     int checkOffset;
-    if (type is DeferredAccessGenerator) {
-      DeferredAccessGenerator generator = type;
+    if (type is DeferredAccessGenerator<Expression, Statement, Arguments>) {
+      DeferredAccessGenerator<Expression, Statement, Arguments> generator =
+          type;
       type = generator.generator;
       deferredPrefix = generator.builder;
       checkOffset = generator.token.charOffset;
     }
 
-    if (type is TypeDeclarationAccessGenerator) {
-      TypeDeclarationAccessGenerator generator = type;
+    if (type is TypeUseGenerator<Expression, Statement, Arguments>) {
+      TypeUseGenerator<Expression, Statement, Arguments> generator = type;
       if (generator.prefix != null) {
         nameToken = nameToken.next.next;
       }
@@ -2782,8 +2807,9 @@
       push(deferredPrefix != null
           ? wrapInDeferredCheck(expression, deferredPrefix, checkOffset)
           : expression);
-    } else if (type is ErroneousExpressionGenerator) {
-      push(type.buildError(forest.castArguments(arguments)));
+    } else if (type
+        is ErroneousExpressionGenerator<Expression, Statement, Arguments>) {
+      push(type.buildError(arguments));
     } else {
       push(throwNoSuchMethodError(storeOffset(forest.literalNull(null), offset),
           debugName(getNodeName(type), name), arguments, nameToken.charOffset));
@@ -2905,7 +2931,8 @@
   @override
   void endTypeArguments(int count, Token beginToken, Token endToken) {
     debugEvent("TypeArguments");
-    push(popList(count));
+    push(
+        popList(count, new List<DartType>.filled(count, null, growable: true)));
   }
 
   @override
@@ -3231,19 +3258,20 @@
   void handleLabel(Token token) {
     debugEvent("Label");
     Identifier identifier = pop();
-    push(new Label(identifier.name, identifier.token.charOffset));
+    push(forest.label(identifier.token, token));
   }
 
   @override
   void beginLabeledStatement(Token token, int labelCount) {
     debugEvent("beginLabeledStatement");
-    List<Label> labels = popList(
-        labelCount, new List<Label>.filled(labelCount, null, growable: true));
+    List<Object> labels =
+        new List<Object>.filled(labelCount, null, growable: true);
+    popList(labelCount, labels);
     enterLocalScope(null, scope.createNestedLabelScope());
     LabelTarget target = new LabelTarget<Statement>(
-        member, functionNestingLevel, token.charOffset);
-    for (Label label in labels) {
-      scope.declareLabel(label.name, target);
+        labels, member, functionNestingLevel, token.charOffset);
+    for (Object label in labels) {
+      scope.declareLabel(forest.getLabelName(label), target);
     }
     push(target);
   }
@@ -3260,9 +3288,7 @@
       }
       target.breakTarget.resolveBreaks(forest, statement);
     }
-    // TODO(brianwilkerson): Figure out how to get the labels that are part of
-    // the statement.
-//    statement = forest.labeledStatement(labels, statement);
+    statement = forest.labeledStatement(target, statement);
     if (target.continueTarget.hasUsers) {
       if (statement is! LabeledStatement) {
         statement = forest.syntheticLabeledStatement(statement);
@@ -3368,12 +3394,14 @@
   @override
   void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) {
     debugEvent("beginSwitchCase");
-    List labelsAndExpressions = popList(labelCount + expressionCount);
-    List<Label> labels = <Label>[];
+    var count = labelCount + expressionCount;
+    List<Object> labelsAndExpressions =
+        popList(count, new List<Object>.filled(count, null, growable: true));
+    List<Object> labels = <Object>[];
     List<Expression> expressions = <Expression>[];
     if (labelsAndExpressions != null) {
       for (var labelOrExpression in labelsAndExpressions) {
-        if (labelOrExpression is Label) {
+        if (forest.isLabel(labelOrExpression)) {
           labels.add(labelOrExpression);
         } else {
           expressions.add(labelOrExpression);
@@ -3381,18 +3409,19 @@
       }
     }
     assert(scope == switchScope);
-    for (Label label in labels) {
-      if (scope.hasLocalLabel(label.name)) {
+    for (Object label in labels) {
+      String labelName = forest.getLabelName(label);
+      if (scope.hasLocalLabel(labelName)) {
         // TODO(ahe): Should validate this is a goto target.
-        if (!scope.claimLabel(label.name)) {
+        if (!scope.claimLabel(labelName)) {
           addCompileTimeError(
               fasta.templateDuplicateLabelInSwitchStatement
-                  .withArguments(label.name),
-              label.charOffset,
-              label.name.length);
+                  .withArguments(labelName),
+              forest.getLabelOffset(label),
+              labelName.length);
         }
       } else {
-        scope.declareLabel(label.name, createGotoTarget(firstToken.charOffset));
+        scope.declareLabel(labelName, createGotoTarget(firstToken.charOffset));
       }
     }
     push(expressions);
@@ -3415,7 +3444,7 @@
     // check this switch case to see if it falls through to the next case.
     Statement block = popBlock(statementCount, firstToken, null);
     exitLocalScope();
-    List<Label> labels = pop();
+    List<Object> labels = pop();
     List<Expression> expressions = pop();
     List<int> expressionOffsets = <int>[];
     for (Expression expression in expressions) {
@@ -3453,10 +3482,10 @@
     List<SwitchCase> cases =
         new List<SwitchCase>.filled(caseCount, null, growable: true);
     for (int i = caseCount - 1; i >= 0; i--) {
-      List<Label> labels = pop();
+      List<Object> labels = pop();
       SwitchCase current = cases[i] = pop();
-      for (Label label in labels) {
-        JumpTarget target = switchScope.lookupLabel(label.name);
+      for (Object label in labels) {
+        JumpTarget target = switchScope.lookupLabel(forest.getLabelName(label));
         if (target != null) {
           target.resolveGotos(forest, current);
         }
@@ -3630,7 +3659,7 @@
     List<Expression> annotations = pop();
     KernelTypeVariableBuilder variable;
     Object inScope = scopeLookup(scope, name.name, token);
-    if (inScope is TypeDeclarationAccessGenerator) {
+    if (inScope is TypeUseGenerator<Expression, Statement, Arguments>) {
       variable = inScope.declaration;
     } else {
       // Something went wrong when pre-parsing the type variables.
@@ -3651,7 +3680,10 @@
   @override
   void endTypeVariables(int count, Token beginToken, Token endToken) {
     debugEvent("TypeVariables");
-    List<KernelTypeVariableBuilder> typeVariables = popList(count);
+    List<KernelTypeVariableBuilder> typeVariables = popList(
+        count,
+        new List<KernelTypeVariableBuilder>.filled(count, null,
+            growable: true));
     if (typeVariables != null) {
       if (library.loader.target.strongMode) {
         List<KernelTypeBuilder> calculatedBounds = calculateBounds(
@@ -4189,15 +4221,6 @@
   String toString() => "initialized-identifier($name, $initializer)";
 }
 
-class Label {
-  String name;
-  int charOffset;
-
-  Label(this.name, this.charOffset);
-
-  String toString() => "label($name)";
-}
-
 class JumpTarget<Statement> extends Builder {
   final List<Statement> users = <Statement>[];
 
@@ -4264,13 +4287,16 @@
 }
 
 class LabelTarget<Statement> extends Builder implements JumpTarget<Statement> {
+  final List<Object> labels;
+
   final JumpTarget breakTarget;
 
   final JumpTarget continueTarget;
 
   final int functionNestingLevel;
 
-  LabelTarget(MemberBuilder member, this.functionNestingLevel, int charOffset)
+  LabelTarget(this.labels, MemberBuilder member, this.functionNestingLevel,
+      int charOffset)
       : breakTarget = new JumpTarget<Statement>(
             JumpTargetKind.Break, functionNestingLevel, member, charOffset),
         continueTarget = new JumpTarget<Statement>(
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 92b3ac2..ad42775 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -10,17 +10,28 @@
 import '../constant_context.dart' show ConstantContext;
 
 import '../fasta_codes.dart'
-    show LocatedMessage, messageInvalidInitializer, templateNotAType;
+    show
+        LocatedMessage,
+        messageInvalidInitializer,
+        templateDeferredTypeAnnotation,
+        templateIntegerLiteralIsOutOfRange,
+        templateNotAType;
 
 import '../names.dart' show lengthName;
 
 import '../parser.dart' show lengthForToken, offsetForToken;
 
-import '../problems.dart' show unsupported;
+import '../problems.dart' show unhandled, unsupported;
 
 import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
 
-import 'forest.dart' show Forest;
+import 'forest.dart'
+    show
+        Forest,
+        Identifier,
+        LoadLibraryBuilder,
+        PrefixBuilder,
+        TypeDeclarationBuilder;
 
 import 'kernel_ast_api.dart'
     show
@@ -30,29 +41,32 @@
         Member,
         Name,
         Procedure,
+        TypeParameterType,
         VariableDeclaration;
 
+import 'kernel_builder.dart'
+    show
+        AccessErrorBuilder,
+        Builder,
+        BuiltinTypeBuilder,
+        FunctionTypeAliasBuilder,
+        KernelClassBuilder,
+        KernelFunctionTypeAliasBuilder,
+        KernelTypeVariableBuilder;
+
 import 'kernel_expression_generator.dart'
     show IncompleteSendGenerator, SendAccessGenerator;
 
 export 'kernel_expression_generator.dart'
     show
-        DeferredAccessGenerator,
         DelayedAssignment,
         DelayedPostfixIncrement,
-        ErroneousExpressionGenerator,
         IncompleteErrorGenerator,
         IncompletePropertyAccessGenerator,
         IncompleteSendGenerator,
-        LargeIntAccessGenerator,
-        LoadLibraryGenerator,
         ParenthesizedExpressionGenerator,
-        ReadOnlyAccessGenerator,
         SendAccessGenerator,
-        StaticAccessGenerator,
-        SuperIndexedAccessGenerator,
         ThisAccessGenerator,
-        TypeDeclarationAccessGenerator,
         UnresolvedNameGenerator,
         buildIsNull;
 
@@ -164,10 +178,10 @@
         offset);
   }
 
-  /* kernel.Expression | Generator | Initializer */ doInvocation(
+  /* Expression | Generator | Initializer */ doInvocation(
       int offset, Arguments arguments);
 
-  /* kernel.Expression | Generator */ buildPropertyAccess(
+  /* Expression | Generator */ buildPropertyAccess(
       IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
     if (send is SendAccessGenerator) {
       return helper.buildMethodInvocation(
@@ -201,7 +215,7 @@
   }
 
   @override
-  /* kernel.Expression | Generator */ buildThrowNoSuchMethodError(
+  /* Expression | Generator */ buildThrowNoSuchMethodError(
       Expression receiver, Arguments arguments,
       {bool isSuper: false,
       bool isGetter: false,
@@ -275,15 +289,10 @@
       return unsupported("ThisExpression", offsetForToken(token), helper.uri);
     } else {
       return isNullAware
-          ? new NullAwarePropertyAccessGenerator(
-              helper,
-              token,
-              receiver as dynamic /* TODO(ahe): Remove this cast. */,
-              name,
-              getter,
-              setter,
-              null)
-          : new PropertyAccessGenerator.internal(
+          ? new NullAwarePropertyAccessGenerator<Expression, Statement,
+              Arguments>(helper, token, receiver, name, getter, setter, null)
+          : new PropertyAccessGenerator<Expression, Statement,
+                  Arguments>.internal(
               helper, token, receiver, name, getter, setter);
     }
   }
@@ -372,11 +381,11 @@
           Procedure getter,
           Procedure setter) {
     if (helper.forest.isThisExpression(receiver)) {
-      return new ThisIndexedAccessGenerator(
+      return new ThisIndexedAccessGenerator<Expression, Statement, Arguments>(
           helper, token, index, getter, setter);
     } else {
-      return new IndexedAccessGenerator.internal(
-          helper, token, receiver, index, getter, setter);
+      return new IndexedAccessGenerator<Expression, Statement,
+          Arguments>.internal(helper, token, receiver, index, getter, setter);
     }
   }
 
@@ -413,3 +422,378 @@
   @override
   String get debugName => "ThisIndexedAccessGenerator";
 }
+
+abstract class SuperIndexedAccessGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory SuperIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression index,
+      Member getter,
+      Member setter) {
+    return helper.forest
+        .superIndexedAccessGenerator(helper, token, index, getter, setter);
+  }
+
+  String get plainNameForRead => "[]";
+
+  String get plainNameForWrite => "[]=";
+
+  String get debugName => "SuperIndexedAccessGenerator";
+}
+
+abstract class StaticAccessGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory StaticAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Member readTarget,
+      Member writeTarget) {
+    return helper.forest
+        .staticAccessGenerator(helper, token, readTarget, writeTarget);
+  }
+
+  factory StaticAccessGenerator.fromBuilder(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Builder builder,
+      Token token,
+      Builder builderSetter) {
+    if (builder is AccessErrorBuilder) {
+      AccessErrorBuilder error = builder;
+      builder = error.builder;
+      // We should only see an access error here if we've looked up a setter
+      // when not explicitly looking for a setter.
+      assert(builder.isSetter);
+    } else if (builder.target == null) {
+      return unhandled(
+          "${builder.runtimeType}",
+          "StaticAccessGenerator.fromBuilder",
+          offsetForToken(token),
+          helper.uri);
+    }
+    Member getter = builder.target.hasGetter ? builder.target : null;
+    Member setter = builder.target.hasSetter ? builder.target : null;
+    if (setter == null) {
+      if (builderSetter?.target?.hasSetter ?? false) {
+        setter = builderSetter.target;
+      }
+    }
+    return new StaticAccessGenerator<Expression, Statement, Arguments>(
+        helper, token, getter, setter);
+  }
+
+  Member get readTarget;
+
+  @override
+  String get debugName => "StaticAccessGenerator";
+}
+
+abstract class LoadLibraryGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory LoadLibraryGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      LoadLibraryBuilder builder) {
+    return helper.forest.loadLibraryGenerator(helper, token, builder);
+  }
+
+  @override
+  String get plainNameForRead => 'loadLibrary';
+
+  @override
+  String get debugName => "LoadLibraryGenerator";
+}
+
+abstract class DeferredAccessGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory DeferredAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      PrefixBuilder builder,
+      Generator<Expression, Statement, Arguments> generator) {
+    return helper.forest
+        .deferredAccessGenerator(helper, token, builder, generator);
+  }
+
+  PrefixBuilder get builder;
+
+  Generator<Expression, Statement, Arguments> get generator;
+
+  @override
+  buildPropertyAccess(
+      IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
+    var propertyAccess =
+        generator.buildPropertyAccess(send, operatorOffset, isNullAware);
+    if (propertyAccess is Generator) {
+      return new DeferredAccessGenerator<Expression, Statement, Arguments>(
+          helper, token, builder, propertyAccess);
+    } else {
+      Expression expression = propertyAccess;
+      return helper.wrapInDeferredCheck(expression, builder, token.charOffset);
+    }
+  }
+
+  @override
+  String get plainNameForRead {
+    return unsupported(
+        "deferredAccessor.plainNameForRead", offsetForToken(token), uri);
+  }
+
+  @override
+  String get debugName => "DeferredAccessGenerator";
+
+  @override
+  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
+      {bool nonInstanceAccessIsError: false}) {
+    helper.addProblem(
+        templateDeferredTypeAnnotation.withArguments(
+            generator.buildTypeWithBuiltArguments(arguments,
+                nonInstanceAccessIsError: nonInstanceAccessIsError),
+            builder.name),
+        offsetForToken(token),
+        lengthForToken(token));
+    return const InvalidType();
+  }
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    return helper.wrapInDeferredCheck(
+        generator.doInvocation(offset, arguments), builder, token.charOffset);
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", builder: ");
+    sink.write(builder);
+    sink.write(", generator: ");
+    sink.write(generator);
+  }
+}
+
+abstract class TypeUseGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory TypeUseGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      PrefixBuilder prefix,
+      int declarationReferenceOffset,
+      TypeDeclarationBuilder declaration,
+      String plainNameForRead) {
+    return helper.forest.typeUseGenerator(helper, token, prefix,
+        declarationReferenceOffset, declaration, plainNameForRead);
+  }
+
+  PrefixBuilder get prefix;
+
+  TypeDeclarationBuilder get declaration;
+
+  @override
+  String get debugName => "TypeUseGenerator";
+
+  @override
+  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
+      {bool nonInstanceAccessIsError: false}) {
+    if (arguments != null) {
+      int expected = 0;
+      if (declaration is KernelClassBuilder) {
+        expected = declaration.target.typeParameters.length;
+      } else if (declaration is FunctionTypeAliasBuilder) {
+        expected = declaration.target.typeParameters.length;
+      } else if (declaration is KernelTypeVariableBuilder) {
+        // Type arguments on a type variable - error reported elsewhere.
+      } else if (declaration is BuiltinTypeBuilder) {
+        // Type arguments on a built-in type, for example, dynamic or void.
+        expected = 0;
+      } else {
+        return unhandled("${declaration.runtimeType}",
+            "TypeUseGenerator.buildType", offsetForToken(token), helper.uri);
+      }
+      if (arguments.length != expected) {
+        helper.warnTypeArgumentsMismatch(
+            declaration.name, expected, offsetForToken(token));
+        // We ignore the provided arguments, which will in turn return the
+        // raw type below.
+        // TODO(sigmund): change to use an InvalidType and include the raw type
+        // as a recovery node once the IR can represent it (Issue #29840).
+        arguments = null;
+      }
+    }
+
+    DartType type;
+    if (arguments == null) {
+      TypeDeclarationBuilder typeDeclaration = declaration;
+      if (typeDeclaration is KernelClassBuilder) {
+        type = typeDeclaration.buildType(helper.library, null);
+      } else if (typeDeclaration is KernelFunctionTypeAliasBuilder) {
+        type = typeDeclaration.buildType(helper.library, null);
+      }
+    }
+    if (type == null) {
+      type =
+          declaration.buildTypesWithBuiltArguments(helper.library, arguments);
+    }
+    if (type is TypeParameterType) {
+      return helper.validatedTypeVariableUse(
+          type, offsetForToken(token), nonInstanceAccessIsError);
+    }
+    return type;
+  }
+}
+
+abstract class ReadOnlyAccessGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory ReadOnlyAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression expression,
+      String plainNameForRead) {
+    return helper.forest
+        .readOnlyAccessGenerator(helper, token, expression, plainNameForRead);
+  }
+
+  @override
+  String get debugName => "ReadOnlyAccessGenerator";
+}
+
+abstract class LargeIntAccessGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  factory LargeIntAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token) {
+    return helper.forest.largeIntAccessGenerator(helper, token);
+  }
+
+  // TODO(ahe): This should probably be calling unhandled.
+  @override
+  String get plainNameForRead => null;
+
+  @override
+  String get debugName => "LargeIntAccessGenerator";
+
+  Expression buildError() {
+    return helper.buildCompileTimeError(
+        templateIntegerLiteralIsOutOfRange.withArguments(token),
+        offsetForToken(token),
+        lengthForToken(token));
+  }
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    return buildError();
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", lexeme: ");
+    sink.write(token.lexeme);
+  }
+}
+
+abstract class ErroneousExpressionGenerator<Expression, Statement, Arguments>
+    implements Generator<Expression, Statement, Arguments> {
+  /// Pass [arguments] that must be evaluated before throwing an error.  At
+  /// most one of [isGetter] and [isSetter] should be true and they're passed
+  /// to [ExpressionGeneratorHelper.buildThrowNoSuchMethodError] if it is used.
+  Expression buildError(Arguments arguments,
+      {bool isGetter: false, bool isSetter: false, int offset});
+
+  DartType buildErroneousTypeNotAPrefix(Identifier suffix);
+
+  Name get name => unsupported("name", offsetForToken(token), uri);
+
+  @override
+  String get plainNameForRead => name.name;
+
+  withReceiver(Object receiver, int operatorOffset, {bool isNullAware}) => this;
+
+  @override
+  Initializer buildFieldInitializer(Map<String, int> initializedFields) {
+    return helper.buildInvalidInitializer(
+        buildError(forest.argumentsEmpty(token), isSetter: true));
+  }
+
+  @override
+  doInvocation(int offset, Arguments arguments) {
+    return buildError(arguments, offset: offset);
+  }
+
+  @override
+  buildPropertyAccess(
+      IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
+    return this;
+  }
+
+  @override
+  buildThrowNoSuchMethodError(Expression receiver, Arguments arguments,
+      {bool isSuper: false,
+      bool isGetter: false,
+      bool isSetter: false,
+      bool isStatic: false,
+      String name,
+      int offset,
+      LocatedMessage argMessage}) {
+    return this;
+  }
+
+  @override
+  Expression buildAssignment(Expression value, {bool voidContext: false}) {
+    return buildError(forest.arguments(<Expression>[value], token),
+        isSetter: true);
+  }
+
+  @override
+  Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+      {int offset: -1,
+      bool voidContext: false,
+      Procedure interfaceTarget,
+      bool isPreIncDec: false}) {
+    return buildError(forest.arguments(<Expression>[value], token),
+        isGetter: true);
+  }
+
+  @override
+  Expression buildPrefixIncrement(Name binaryOperator,
+      {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
+    // TODO(ahe): For the Analyzer, we probably need to build a prefix
+    // increment node that wraps an error.
+    return buildError(
+        forest.arguments(
+            <Expression>[storeOffset(forest.literalInt(1, null), offset)],
+            token),
+        isGetter: true);
+  }
+
+  @override
+  Expression buildPostfixIncrement(Name binaryOperator,
+      {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
+    // TODO(ahe): For the Analyzer, we probably need to build a post increment
+    // node that wraps an error.
+    return buildError(
+        forest.arguments(
+            <Expression>[storeOffset(forest.literalInt(1, null), offset)],
+            token),
+        isGetter: true);
+  }
+
+  @override
+  Expression buildNullAwareAssignment(
+      Expression value, DartType type, int offset,
+      {bool voidContext: false}) {
+    return buildError(forest.arguments(<Expression>[value], token),
+        isSetter: true);
+  }
+
+  @override
+  Expression buildSimpleRead() =>
+      buildError(forest.argumentsEmpty(token), isGetter: true);
+
+  @override
+  Expression makeInvalidRead() =>
+      buildError(forest.argumentsEmpty(token), isGetter: true);
+
+  @override
+  Expression makeInvalidWrite(Expression value) {
+    return buildError(forest.arguments(<Expression>[value], token),
+        isSetter: true);
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 1490aff..3acd9df 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -15,6 +15,7 @@
         Catch,
         ContinueSwitchStatement,
         DartType,
+        DynamicType,
         EmptyStatement,
         Expression,
         ExpressionStatement,
@@ -40,14 +41,23 @@
 
 import '../scanner.dart' show Token;
 
+import 'body_builder.dart' show LabelTarget;
+
 import 'kernel_expression_generator.dart'
     show
+        KernelDeferredAccessGenerator,
         KernelIndexedAccessGenerator,
+        KernelLargeIntAccessGenerator,
+        KernelLoadLibraryGenerator,
         KernelNullAwarePropertyAccessGenerator,
         KernelPropertyAccessGenerator,
+        KernelReadOnlyAccessGenerator,
+        KernelStaticAccessGenerator,
+        KernelSuperIndexedAccessGenerator,
         KernelSuperPropertyAccessGenerator,
         KernelThisIndexedAccessGenerator,
         KernelThisPropertyAccessGenerator,
+        KernelTypeUseGenerator,
         KernelVariableUseGenerator;
 
 import 'kernel_shadow_ast.dart'
@@ -90,7 +100,14 @@
         ShadowWhileStatement,
         ShadowYieldStatement;
 
-import 'forest.dart' show ExpressionGeneratorHelper, Forest;
+import 'forest.dart'
+    show
+        ExpressionGeneratorHelper,
+        Forest,
+        Generator,
+        LoadLibraryBuilder,
+        PrefixBuilder,
+        TypeDeclarationBuilder;
 
 /// A shadow tree factory.
 class Fangorn extends Forest<Expression, Statement, Token, Arguments> {
@@ -321,6 +338,21 @@
   }
 
   @override
+  Catch catchClause(
+      Token onKeyword,
+      DartType exceptionType,
+      Token catchKeyword,
+      VariableDeclaration exceptionParameter,
+      VariableDeclaration stackTraceParameter,
+      DartType stackTraceType,
+      Statement body) {
+    exceptionType ??= const DynamicType();
+    return new Catch(exceptionParameter, body,
+        guard: exceptionType, stackTrace: stackTraceParameter)
+      ..fileOffset = offsetForToken(onKeyword ?? catchKeyword);
+  }
+
+  @override
   Expression conditionalExpression(Expression condition, Token question,
       Expression thenExpression, Token colon, Expression elseExpression) {
     return new ShadowConditionalExpression(
@@ -359,7 +391,7 @@
       covariant initialization,
       Token leftSeparator,
       Expression condition,
-      Token rightSeparator,
+      Statement conditionStatement,
       List<Expression> updaters,
       Token rightParenthesis,
       Statement body) {
@@ -385,6 +417,16 @@
   }
 
   @override
+  Label label(Token identifier, Token colon) {
+    return new Label(identifier.lexeme, identifier.charOffset);
+  }
+
+  @override
+  Statement labeledStatement(
+          LabelTarget<Statement> target, Statement statement) =>
+      statement;
+
+  @override
   Expression notExpression(Expression operand, Token token) {
     return new ShadowNot(operand)..fileOffset = offsetForToken(token);
   }
@@ -489,7 +531,10 @@
   }
 
   @override
-  Token getSemicolon(Statement statement) => null;
+  String getLabelName(Label label) => label.name;
+
+  @override
+  int getLabelOffset(Label label) => label.charOffset;
 
   @override
   bool isBlock(Object node) => node is Block;
@@ -523,6 +568,9 @@
       statement is ExpressionStatement;
 
   @override
+  bool isLabel(covariant node) => node is Label;
+
+  @override
   bool isThisExpression(Object node) => node is ThisExpression;
 
   @override
@@ -545,6 +593,11 @@
   }
 
   @override
+  void setParameterType(VariableDeclaration parameter, DartType type) {
+    parameter.type = type ?? const DynamicType();
+  }
+
+  @override
   KernelVariableUseGenerator variableUseGenerator(
       ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
@@ -623,6 +676,72 @@
     return new KernelThisIndexedAccessGenerator(
         helper, token, index, getter, setter);
   }
+
+  @override
+  KernelSuperIndexedAccessGenerator superIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression index,
+      Member getter,
+      Member setter) {
+    return new KernelSuperIndexedAccessGenerator(
+        helper, token, index, getter, setter);
+  }
+
+  @override
+  KernelStaticAccessGenerator staticAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Member getter,
+      Member setter) {
+    return new KernelStaticAccessGenerator(helper, token, getter, setter);
+  }
+
+  @override
+  KernelLoadLibraryGenerator loadLibraryGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      LoadLibraryBuilder builder) {
+    return new KernelLoadLibraryGenerator(helper, token, builder);
+  }
+
+  @override
+  KernelDeferredAccessGenerator deferredAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      PrefixBuilder builder,
+      Generator<Expression, Statement, Arguments> generator) {
+    return new KernelDeferredAccessGenerator(helper, token, builder, generator);
+  }
+
+  @override
+  KernelTypeUseGenerator typeUseGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      PrefixBuilder prefix,
+      int declarationReferenceOffset,
+      TypeDeclarationBuilder declaration,
+      String plainNameForRead) {
+    return new KernelTypeUseGenerator(helper, token, prefix,
+        declarationReferenceOffset, declaration, plainNameForRead);
+  }
+
+  @override
+  KernelReadOnlyAccessGenerator readOnlyAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      Expression expression,
+      String plainNameForRead) {
+    return new KernelReadOnlyAccessGenerator(
+        helper, token, expression, plainNameForRead);
+  }
+
+  @override
+  KernelLargeIntAccessGenerator largeIntAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token) {
+    return new KernelLargeIntAccessGenerator(helper, token);
+  }
 }
 
 class _VariablesDeclaration extends Statement {
@@ -653,3 +772,14 @@
     unsupported("transformChildren", fileOffset, uri);
   }
 }
+
+/// A data holder used to hold the information about a label that is pushed on
+/// the stack.
+class Label {
+  String name;
+  int charOffset;
+
+  Label(this.name, this.charOffset);
+
+  String toString() => "label($name)";
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 2589526..8509c30 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -12,18 +12,24 @@
         Name,
         Procedure;
 
-import 'body_builder.dart' show Identifier;
+import 'body_builder.dart' show Identifier, LabelTarget;
 
 import 'expression_generator.dart' show Generator;
 
 import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
 
+import 'kernel_builder.dart'
+    show LoadLibraryBuilder, PrefixBuilder, TypeDeclarationBuilder;
+
 export 'body_builder.dart' show Identifier, Operator;
 
 export 'expression_generator.dart' show Generator;
 
 export 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
 
+export 'kernel_builder.dart'
+    show LoadLibraryBuilder, PrefixBuilder, TypeDeclarationBuilder;
+
 /// A tree factory.
 ///
 /// For now, the [Location] is always a token.
@@ -173,6 +179,16 @@
   Statement breakStatement(
       Location breakKeyword, Identifier label, Location semicolon);
 
+  /// Return a representation of a catch clause.
+  Object catchClause(
+      Location onKeyword,
+      covariant exceptionType,
+      Location catchKeyword,
+      covariant exceptionParameter,
+      covariant stackTraceParameter,
+      covariant stackTraceType,
+      Statement body);
+
   /// Return a representation of a conditional expression. The [condition] is
   /// the expression preceding the question mark. The [question] is the `?`. The
   /// [thenExpression] is the expression following the question mark. The
@@ -209,7 +225,7 @@
       covariant initialization,
       Location leftSeparator,
       Expression condition,
-      Location rightSeparator,
+      Statement conditionStatement,
       List<Expression> updaters,
       Location rightParenthesis,
       Statement body);
@@ -225,6 +241,15 @@
   Expression isExpression(Expression operand, Location isOperator,
       Location notOperator, covariant type);
 
+  /// Return a representation of the label consisting of the given [identifer]
+  /// followed by the given [colon].
+  Object label(Location identifier, Location colon);
+
+  /// Return a representation of a [statement] that has one or more labels (from
+  /// the [target]) associated with it.
+  Statement labeledStatement(
+      LabelTarget<Statement> target, Statement statement);
+
   Expression notExpression(Expression operand, Location location);
 
   /// Return a representation of a parenthesized condition consisting of the
@@ -286,9 +311,11 @@
   /// Return the expression from the given expression [statement].
   Expression getExpressionFromExpressionStatement(Statement statement);
 
-  /// Return the semicolon at the end of the given [statement], or `null` if the
-  /// statement is not terminated by a semicolon.
-  Location getSemicolon(Statement statement);
+  /// Return the name of the given [label].
+  String getLabelName(covariant label);
+
+  /// Return the offset of the given [label].
+  int getLabelOffset(covariant label);
 
   bool isBlock(Object node);
 
@@ -302,6 +329,9 @@
   /// expression statement.
   bool isExpressionStatement(Statement statement);
 
+  /// Return `true` if the given [node] is a label.
+  bool isLabel(covariant node);
+
   bool isThisExpression(Object node);
 
   bool isVariablesDeclaration(Object node);
@@ -319,6 +349,9 @@
   void resolveContinueInSwitch(
       covariant Object target, covariant Statement user);
 
+  /// Set the type of the [parameter] to the given [type].
+  void setParameterType(covariant parameter, covariant type);
+
   Generator<Expression, Statement, Arguments> variableUseGenerator(
       ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Location location,
@@ -371,6 +404,48 @@
       kernel.Procedure getter,
       kernel.Procedure setter);
 
+  Generator<Expression, Statement, Arguments> superIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location,
+      Expression index,
+      kernel.Member getter,
+      kernel.Member setter);
+
+  Generator<Expression, Statement, Arguments> staticAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location,
+      kernel.Member getter,
+      kernel.Member setter);
+
+  Generator<Expression, Statement, Arguments> loadLibraryGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location,
+      LoadLibraryBuilder builder);
+
+  Generator<Expression, Statement, Arguments> deferredAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location,
+      PrefixBuilder builder,
+      Generator<Expression, Statement, Arguments> generator);
+
+  Generator<Expression, Statement, Arguments> typeUseGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location,
+      PrefixBuilder prefix,
+      int declarationReferenceOffset,
+      TypeDeclarationBuilder declaration,
+      String plainNameForRead);
+
+  Generator<Expression, Statement, Arguments> readOnlyAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location,
+      Expression expression,
+      String plainNameForRead);
+
+  Generator<Expression, Statement, Arguments> largeIntAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Location location);
+
   // TODO(ahe): Remove this method when all users are moved here.
   kernel.Arguments castArguments(Arguments arguments) {
     dynamic a = arguments;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index 7272014..2e2c334 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -137,7 +137,7 @@
 
     if (arguments == null && typeVariables != null) {
       List<DartType> result =
-          new List<DartType>.filled(typeVariables.length, null);
+          new List<DartType>.filled(typeVariables.length, null, growable: true);
       for (int i = 0; i < result.length; ++i) {
         result[i] = typeVariables[i].defaultType.build(library);
       }
@@ -156,7 +156,8 @@
     }
 
     // arguments.length == typeVariables.length
-    List<DartType> result = new List<DartType>.filled(arguments.length, null);
+    List<DartType> result =
+        new List<DartType>.filled(arguments.length, null, growable: true);
     for (int i = 0; i < result.length; ++i) {
       result[i] = arguments[i].build(library);
     }
@@ -185,7 +186,8 @@
       return new Supertype(
           cls,
           new List<DartType>.filled(
-              cls.typeParameters.length, const UnknownType()));
+              cls.typeParameters.length, const UnknownType(),
+              growable: true));
     }
   }
 
@@ -215,9 +217,10 @@
                 // TODO(32049) If type arguments aren't specified, they should
                 // be inferred.  Currently, the inference is not performed.
                 // The code below is a workaround.
-                typeArguments = new List.filled(
+                typeArguments = new List<DartType>.filled(
                     targetBuilder.target.enclosingClass.typeParameters.length,
-                    const DynamicType());
+                    const DynamicType(),
+                    growable: true);
               }
               builder.setRedirectingFactoryBody(
                   targetBuilder.target, typeArguments);
@@ -227,9 +230,10 @@
                 // TODO(32049) If type arguments aren't specified, they should
                 // be inferred.  Currently, the inference is not performed.
                 // The code below is a workaround.
-                typeArguments = new List.filled(
+                typeArguments = new List<DartType>.filled(
                     targetBuilder.target.enclosingClass.typeParameters.length,
-                    const DynamicType());
+                    const DynamicType(),
+                    growable: true);
               }
               builder.setRedirectingFactoryBody(
                   targetBuilder.member, typeArguments);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
index 18cca9e..ef2a750 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
@@ -159,14 +159,15 @@
         charEndOffset);
     members["toString"] = toStringBuilder;
     String className = name;
-    for (int i = 0; i < constantNamesAndOffsetsAndDocs.length; i += 3) {
-      String name = constantNamesAndOffsetsAndDocs[i];
-      int charOffset = constantNamesAndOffsetsAndDocs[i + 1];
-      String documentationComment = constantNamesAndOffsetsAndDocs[i + 2];
+    for (int i = 0; i < constantNamesAndOffsetsAndDocs.length; i += 4) {
+      List<MetadataBuilder> metadata = constantNamesAndOffsetsAndDocs[i];
+      String name = constantNamesAndOffsetsAndDocs[i + 1];
+      int charOffset = constantNamesAndOffsetsAndDocs[i + 2];
+      String documentationComment = constantNamesAndOffsetsAndDocs[i + 3];
       if (members.containsKey(name)) {
         parent.addCompileTimeError(templateDuplicatedName.withArguments(name),
             charOffset, noLength, parent.fileUri);
-        constantNamesAndOffsetsAndDocs[i] = null;
+        constantNamesAndOffsetsAndDocs[i + 1] = null;
         continue;
       }
       if (name == className) {
@@ -175,11 +176,18 @@
             charOffset,
             noLength,
             parent.fileUri);
-        constantNamesAndOffsetsAndDocs[i] = null;
+        constantNamesAndOffsetsAndDocs[i + 1] = null;
         continue;
       }
-      KernelFieldBuilder fieldBuilder = new KernelFieldBuilder(null, selfType,
-          name, constMask | staticMask, parent, charOffset, null, true);
+      KernelFieldBuilder fieldBuilder = new KernelFieldBuilder(
+          metadata,
+          selfType,
+          name,
+          constMask | staticMask,
+          parent,
+          charOffset,
+          null,
+          true);
       metadataCollector?.setDocumentationComment(
           fieldBuilder.target, documentationComment);
       members[name] = fieldBuilder;
@@ -235,8 +243,8 @@
     toStringBuilder.body = new ReturnStatement(
         new DirectPropertyGet(new ThisExpression(), nameField));
     List<Expression> values = <Expression>[];
-    for (int i = 0; i < constantNamesAndOffsetsAndDocs.length; i += 3) {
-      String name = constantNamesAndOffsetsAndDocs[i];
+    for (int i = 0; i < constantNamesAndOffsetsAndDocs.length; i += 4) {
+      String name = constantNamesAndOffsetsAndDocs[i + 1];
       if (name != null) {
         KernelFieldBuilder builder = this[name];
         values.add(new StaticGet(builder.build(libraryBuilder)));
@@ -273,8 +281,8 @@
             ..parent = constructor);
     }
     int index = 0;
-    for (int i = 0; i < constantNamesAndOffsetsAndDocs.length; i += 3) {
-      String constant = constantNamesAndOffsetsAndDocs[i];
+    for (int i = 0; i < constantNamesAndOffsetsAndDocs.length; i += 4) {
+      String constant = constantNamesAndOffsetsAndDocs[i + 1];
       if (constant != null) {
         KernelFieldBuilder field = this[constant];
         field.build(libraryBuilder);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
index 218f9f9..e09b708 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
@@ -13,8 +13,6 @@
         LocatedMessage,
         messageLoadLibraryTakesNoArguments,
         messageSuperAsExpression,
-        templateDeferredTypeAnnotation,
-        templateIntegerLiteralIsOutOfRange,
         templateNotAPrefixInTypeAnnotation,
         templateUnresolvedPrefixInTypeAnnotation;
 
@@ -42,22 +40,28 @@
 
 import '../problems.dart' show unhandled, unsupported;
 
-import '../scope.dart' show AccessErrorBuilder;
-
 import 'body_builder.dart' show Identifier, noLocation;
 
 import 'constness.dart' show Constness;
 
 import 'expression_generator.dart'
     show
+        DeferredAccessGenerator,
+        ErroneousExpressionGenerator,
         ExpressionGenerator,
         Generator,
         IndexedAccessGenerator,
+        LargeIntAccessGenerator,
+        LoadLibraryGenerator,
         NullAwarePropertyAccessGenerator,
         PropertyAccessGenerator,
+        ReadOnlyAccessGenerator,
+        StaticAccessGenerator,
+        SuperIndexedAccessGenerator,
         SuperPropertyAccessGenerator,
         ThisIndexedAccessGenerator,
         ThisPropertyAccessGenerator,
+        TypeUseGenerator,
         VariableUseGenerator;
 
 import 'expression_generator_helper.dart' show ExpressionGeneratorHelper;
@@ -100,7 +104,6 @@
         Throw,
         TreeNode,
         TypeParameter,
-        TypeParameterType,
         VariableDeclaration,
         VariableGet,
         VariableSet;
@@ -108,12 +111,8 @@
 import 'kernel_builder.dart'
     show
         Builder,
-        BuiltinTypeBuilder,
-        FunctionTypeAliasBuilder,
         KernelClassBuilder,
-        KernelFunctionTypeAliasBuilder,
         KernelInvalidTypeBuilder,
-        KernelTypeVariableBuilder,
         LoadLibraryBuilder,
         PrefixBuilder,
         TypeDeclarationBuilder;
@@ -276,7 +275,7 @@
   final DartType promotedType;
 
   KernelVariableUseGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, Arguments> helper,
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
       this.variable,
       this.promotedType)
@@ -342,7 +341,7 @@
   VariableDeclaration _receiverVariable;
 
   KernelPropertyAccessGenerator.internal(
-      ExpressionGeneratorHelper<dynamic, dynamic, Arguments> helper,
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
       this.receiver,
       this.name,
@@ -510,7 +509,7 @@
   final DartType type;
 
   KernelNullAwarePropertyAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
       this.receiverExpression,
       this.name,
@@ -602,7 +601,7 @@
   final Member setter;
 
   KernelSuperPropertyAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
       this.name,
       this.getter,
@@ -831,7 +830,7 @@
   VariableDeclaration indexVariable;
 
   KernelThisIndexedAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
       Token token,
       this.index,
       this.getter,
@@ -944,6 +943,494 @@
   }
 }
 
+class KernelSuperIndexedAccessGenerator extends KernelGenerator
+    with SuperIndexedAccessGenerator<Expression, Statement, Arguments> {
+  final Expression index;
+
+  final Member getter;
+
+  final Member setter;
+
+  VariableDeclaration indexVariable;
+
+  KernelSuperIndexedAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      this.index,
+      this.getter,
+      this.setter)
+      : super(helper, token);
+
+  Expression indexAccess() {
+    indexVariable ??= new VariableDeclaration.forValue(index);
+    return new VariableGet(indexVariable);
+  }
+
+  Expression _makeWriteAndReturn(
+      Expression value, ShadowComplexAssignment complexAssignment) {
+    var valueVariable = new VariableDeclaration.forValue(value);
+    if (setter == null) {
+      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var write = new SuperMethodInvocation(
+        indexSetName,
+        forest.castArguments(forest.arguments(
+            <Expression>[indexAccess(), new VariableGet(valueVariable)],
+            token)),
+        setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    var dummy = new VariableDeclaration.forValue(write);
+    return makeLet(
+        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
+  }
+
+  @override
+  Expression _makeSimpleRead() {
+    if (getter == null) {
+      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
+          isSuper: true);
+    }
+    // TODO(ahe): Use [DirectMethodInvocation] when possible.
+    return new ShadowSuperMethodInvocation(
+        indexGetName,
+        forest.castArguments(forest.arguments(<Expression>[index], token)),
+        getter)
+      ..fileOffset = offsetForToken(token);
+  }
+
+  @override
+  Expression _makeSimpleWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    if (setter == null) {
+      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var write = new SuperMethodInvocation(
+        indexSetName,
+        forest
+            .castArguments(forest.arguments(<Expression>[index, value], token)),
+        setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  @override
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    if (getter == null) {
+      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var read = new SuperMethodInvocation(
+        indexGetName,
+        forest.castArguments(
+            forest.arguments(<Expression>[indexAccess()], token)),
+        getter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
+    if (setter == null) {
+      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
+          isSuper: true);
+    }
+    var write = new SuperMethodInvocation(
+        indexSetName,
+        forest.castArguments(
+            forest.arguments(<Expression>[indexAccess(), value], token)),
+        setter)
+      ..fileOffset = offsetForToken(token);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  @override
+  Expression _finish(
+      Expression body, ShadowComplexAssignment complexAssignment) {
+    return super._finish(makeLet(indexVariable, body), complexAssignment);
+  }
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildMethodInvocation(
+        buildSimpleRead(), callName, arguments, offset,
+        isImplicitCall: true);
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+      new ShadowIndexAssign(null, index, rhs, isSuper: true);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", index: ");
+    printNodeOn(index, sink, syntheticNames: syntheticNames);
+    sink.write(", getter: ");
+    printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
+    sink.write(", setter: ");
+    printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
+    sink.write(", indexVariable: ");
+    printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class KernelStaticAccessGenerator extends KernelGenerator
+    with StaticAccessGenerator<Expression, Statement, Arguments> {
+  @override
+  final Member readTarget;
+
+  final Member writeTarget;
+
+  KernelStaticAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      this.readTarget,
+      this.writeTarget)
+      : assert(readTarget != null || writeTarget != null),
+        super(helper, token);
+
+  @override
+  String get plainNameForRead => (readTarget ?? writeTarget).name.name;
+
+  @override
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    if (readTarget == null) {
+      return makeInvalidRead();
+    } else {
+      var read = helper.makeStaticGet(readTarget, token);
+      complexAssignment?.read = read;
+      return read;
+    }
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    Expression write;
+    if (writeTarget == null) {
+      write = makeInvalidWrite(value);
+    } else {
+      write = new StaticSet(writeTarget, value);
+      complexAssignment?.write = write;
+    }
+    write.fileOffset = offsetForToken(token);
+    return write;
+  }
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    if (helper.constantContext != ConstantContext.none &&
+        !helper.isIdentical(readTarget)) {
+      helper.deprecated_addCompileTimeError(
+          offset, "Not a constant expression.");
+    }
+    if (readTarget == null || isFieldOrGetter(readTarget)) {
+      return helper.buildMethodInvocation(buildSimpleRead(), callName,
+          arguments, offset + (readTarget?.name?.name?.length ?? 0),
+          // This isn't a constant expression, but we have checked if a
+          // constant expression error should be emitted already.
+          isConstantExpression: true,
+          isImplicitCall: true);
+    } else {
+      return helper.buildStaticInvocation(readTarget, arguments,
+          charOffset: offset);
+    }
+  }
+
+  @override
+  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+      new ShadowStaticAssignment(rhs);
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", readTarget: ");
+    printQualifiedNameOn(readTarget, sink, syntheticNames: syntheticNames);
+    sink.write(", writeTarget: ");
+    printQualifiedNameOn(writeTarget, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class KernelLoadLibraryGenerator extends KernelGenerator
+    with LoadLibraryGenerator<Expression, Statement, Arguments> {
+  final LoadLibraryBuilder builder;
+
+  KernelLoadLibraryGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      this.builder)
+      : super(helper, token);
+
+  @override
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    var read =
+        helper.makeStaticGet(builder.createTearoffMethod(helper.forest), token);
+    complexAssignment?.read = read;
+    return read;
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    Expression write = makeInvalidWrite(value);
+    write.fileOffset = offsetForToken(token);
+    return write;
+  }
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    if (forest.argumentsPositional(arguments).length > 0 ||
+        forest.argumentsNamed(arguments).length > 0) {
+      helper.addProblemErrorIfConst(
+          messageLoadLibraryTakesNoArguments, offset, 'loadLibrary'.length);
+    }
+    return builder.createLoadLibrary(offset, forest);
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    sink.write(", builder: ");
+    sink.write(builder);
+  }
+}
+
+class KernelDeferredAccessGenerator extends KernelGenerator
+    with DeferredAccessGenerator<Expression, Statement, Arguments> {
+  @override
+  final PrefixBuilder builder;
+
+  @override
+  final KernelGenerator generator;
+
+  KernelDeferredAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      this.builder,
+      this.generator)
+      : super(helper, token);
+
+  @override
+  Expression _makeSimpleRead() {
+    return helper.wrapInDeferredCheck(
+        generator._makeSimpleRead(), builder, token.charOffset);
+  }
+
+  @override
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    return helper.wrapInDeferredCheck(
+        generator._makeRead(complexAssignment), builder, token.charOffset);
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    return helper.wrapInDeferredCheck(
+        generator._makeWrite(value, voidContext, complexAssignment),
+        builder,
+        token.charOffset);
+  }
+}
+
+class KernelTypeUseGenerator extends KernelReadOnlyAccessGenerator
+    with TypeUseGenerator<Expression, Statement, Arguments> {
+  /// The import prefix preceding the [declaration] reference, or `null` if
+  /// the reference is not prefixed.
+  @override
+  final PrefixBuilder prefix;
+
+  /// The offset at which the [declaration] is referenced by this generator,
+  /// or `-1` if the reference is implicit.
+  final int declarationReferenceOffset;
+
+  @override
+  final TypeDeclarationBuilder declaration;
+
+  KernelTypeUseGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      this.prefix,
+      this.declarationReferenceOffset,
+      this.declaration,
+      String plainNameForRead)
+      : super(helper, token, null, plainNameForRead);
+
+  @override
+  Expression get expression {
+    if (super.expression == null) {
+      int offset = offsetForToken(token);
+      if (declaration is KernelInvalidTypeBuilder) {
+        KernelInvalidTypeBuilder declaration = this.declaration;
+        helper.addProblemErrorIfConst(
+            declaration.message.messageObject, offset, token.length);
+        super.expression =
+            new Throw(forest.literalString(declaration.message.message, token))
+              ..fileOffset = offset;
+      } else {
+        super.expression = forest.literalType(
+            buildTypeWithBuiltArguments(null, nonInstanceAccessIsError: true),
+            token);
+      }
+    }
+    return super.expression;
+  }
+
+  @override
+  Expression makeInvalidWrite(Expression value) {
+    return buildThrowNoSuchMethodError(
+        forest.literalNull(token),
+        storeOffset(
+            forest.arguments(<Expression>[value], null), value.fileOffset),
+        isSetter: true);
+  }
+
+  @override
+  buildPropertyAccess(
+      IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
+    // `SomeType?.toString` is the same as `SomeType.toString`, not
+    // `(SomeType).toString`.
+    isNullAware = false;
+
+    Name name = send.name;
+    Arguments arguments = send.arguments;
+
+    if (declaration is KernelClassBuilder) {
+      KernelClassBuilder declaration = this.declaration;
+      Builder builder = declaration.findStaticBuilder(
+          name.name, offsetForToken(token), uri, helper.library);
+
+      Generator generator;
+      if (builder == null) {
+        // If we find a setter, [builder] is an [AccessErrorBuilder], not null.
+        if (send is IncompletePropertyAccessGenerator) {
+          generator = new UnresolvedNameGenerator(helper, send.token, name);
+        } else {
+          return helper.buildConstructorInvocation(declaration, send.token,
+              arguments, name.name, null, token.charOffset, Constness.implicit);
+        }
+      } else {
+        Builder setter;
+        if (builder.isSetter) {
+          setter = builder;
+        } else if (builder.isGetter) {
+          setter = declaration.findStaticBuilder(
+              name.name, offsetForToken(token), uri, helper.library,
+              isSetter: true);
+        } else if (builder.isField && !builder.isFinal) {
+          setter = builder;
+        }
+        generator = new StaticAccessGenerator<Expression, Statement,
+            Arguments>.fromBuilder(helper, builder, send.token, setter);
+      }
+
+      return arguments == null
+          ? generator
+          : generator.doInvocation(offsetForToken(send.token), arguments);
+    } else {
+      return super.buildPropertyAccess(send, operatorOffset, isNullAware);
+    }
+  }
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildConstructorInvocation(declaration, token, arguments, "",
+        null, token.charOffset, Constness.implicit);
+  }
+}
+
+class KernelReadOnlyAccessGenerator extends KernelGenerator
+    with ReadOnlyAccessGenerator<Expression, Statement, Arguments> {
+  @override
+  final String plainNameForRead;
+
+  Expression expression;
+
+  VariableDeclaration value;
+
+  KernelReadOnlyAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token,
+      this.expression,
+      this.plainNameForRead)
+      : super(helper, token);
+
+  @override
+  Expression _makeSimpleRead() => expression;
+
+  @override
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    value ??= new VariableDeclaration.forValue(expression);
+    return new VariableGet(value);
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    var write = makeInvalidWrite(value);
+    complexAssignment?.write = write;
+    return write;
+  }
+
+  @override
+  Expression _finish(
+          Expression body, ShadowComplexAssignment complexAssignment) =>
+      super._finish(makeLet(value, body), complexAssignment);
+
+  @override
+  Expression doInvocation(int offset, Arguments arguments) {
+    return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
+        adjustForImplicitCall(plainNameForRead, offset),
+        isImplicitCall: true);
+  }
+
+  @override
+  void printOn(StringSink sink) {
+    NameSystem syntheticNames = new NameSystem();
+    sink.write(", expression: ");
+    printNodeOn(expression, sink, syntheticNames: syntheticNames);
+    sink.write(", plainNameForRead: ");
+    sink.write(plainNameForRead);
+    sink.write(", value: ");
+    printNodeOn(value, sink, syntheticNames: syntheticNames);
+  }
+}
+
+class KernelLargeIntAccessGenerator extends KernelGenerator
+    with LargeIntAccessGenerator<Expression, Statement, Arguments> {
+  KernelLargeIntAccessGenerator(
+      ExpressionGeneratorHelper<Expression, Statement, Arguments> helper,
+      Token token)
+      : super(helper, token);
+
+  @override
+  Expression _makeSimpleRead() => buildError();
+
+  @override
+  Expression _makeSimpleWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    return buildError();
+  }
+
+  @override
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    return buildError();
+  }
+
+  @override
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    return buildError();
+  }
+}
+
 Expression makeLet(VariableDeclaration variable, Expression body) {
   if (variable == null) return body;
   return new Let(variable, body);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
index 46e7b2a..e384183 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
@@ -15,579 +15,6 @@
 /// superclass should use the forest API in a factory method.
 part of 'kernel_expression_generator.dart';
 
-class SuperIndexedAccessGenerator extends KernelGenerator {
-  final Expression index;
-
-  final Member getter;
-
-  final Member setter;
-
-  VariableDeclaration indexVariable;
-
-  SuperIndexedAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Token token,
-      this.index,
-      this.getter,
-      this.setter)
-      : super(helper, token);
-
-  String get plainNameForRead => "[]";
-
-  String get plainNameForWrite => "[]=";
-
-  String get debugName => "SuperIndexedAccessGenerator";
-
-  indexAccess() {
-    indexVariable ??= new VariableDeclaration.forValue(index);
-    return new VariableGet(indexVariable);
-  }
-
-  Expression _makeSimpleRead() {
-    if (getter == null) {
-      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
-          isSuper: true);
-    }
-    // TODO(ahe): Use [DirectMethodInvocation] when possible.
-    return new ShadowSuperMethodInvocation(
-        indexGetName,
-        forest.castArguments(forest.arguments(<Expression>[index], token)),
-        getter)
-      ..fileOffset = offsetForToken(token);
-  }
-
-  Expression _makeSimpleWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    if (setter == null) {
-      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var write = new SuperMethodInvocation(
-        indexSetName,
-        forest
-            .castArguments(forest.arguments(<Expression>[index, value], token)),
-        setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    if (getter == null) {
-      helper.warnUnresolvedMethod(indexGetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var read = new SuperMethodInvocation(
-        indexGetName,
-        forest.castArguments(
-            forest.arguments(<Expression>[indexAccess()], token)),
-        getter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    if (!voidContext) return _makeWriteAndReturn(value, complexAssignment);
-    if (setter == null) {
-      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var write = new SuperMethodInvocation(
-        indexSetName,
-        forest.castArguments(
-            forest.arguments(<Expression>[indexAccess(), value], token)),
-        setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  _makeWriteAndReturn(
-      Expression value, ShadowComplexAssignment complexAssignment) {
-    var valueVariable = new VariableDeclaration.forValue(value);
-    if (setter == null) {
-      helper.warnUnresolvedMethod(indexSetName, offsetForToken(token),
-          isSuper: true);
-    }
-    var write = new SuperMethodInvocation(
-        indexSetName,
-        forest.castArguments(forest.arguments(
-            <Expression>[indexAccess(), new VariableGet(valueVariable)],
-            token)),
-        setter)
-      ..fileOffset = offsetForToken(token);
-    complexAssignment?.write = write;
-    var dummy = new VariableDeclaration.forValue(write);
-    return makeLet(
-        valueVariable, makeLet(dummy, new VariableGet(valueVariable)));
-  }
-
-  Expression _finish(
-      Expression body, ShadowComplexAssignment complexAssignment) {
-    return super._finish(makeLet(indexVariable, body), complexAssignment);
-  }
-
-  Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildMethodInvocation(
-        buildSimpleRead(), callName, arguments, offset,
-        isImplicitCall: true);
-  }
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
-      new ShadowIndexAssign(null, index, rhs, isSuper: true);
-
-  @override
-  void printOn(StringSink sink) {
-    NameSystem syntheticNames = new NameSystem();
-    sink.write(", index: ");
-    printNodeOn(index, sink, syntheticNames: syntheticNames);
-    sink.write(", getter: ");
-    printQualifiedNameOn(getter, sink, syntheticNames: syntheticNames);
-    sink.write(", setter: ");
-    printQualifiedNameOn(setter, sink, syntheticNames: syntheticNames);
-    sink.write(", indexVariable: ");
-    printNodeOn(indexVariable, sink, syntheticNames: syntheticNames);
-  }
-}
-
-class StaticAccessGenerator extends KernelGenerator {
-  final Member readTarget;
-
-  final Member writeTarget;
-
-  StaticAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Token token,
-      this.readTarget,
-      this.writeTarget)
-      : assert(readTarget != null || writeTarget != null),
-        super(helper, token);
-
-  factory StaticAccessGenerator.fromBuilder(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Builder builder,
-      Token token,
-      Builder builderSetter) {
-    if (builder is AccessErrorBuilder) {
-      AccessErrorBuilder error = builder;
-      builder = error.builder;
-      // We should only see an access error here if we've looked up a setter
-      // when not explicitly looking for a setter.
-      assert(builder.isSetter);
-    } else if (builder.target == null) {
-      return unhandled(
-          "${builder.runtimeType}",
-          "StaticAccessGenerator.fromBuilder",
-          offsetForToken(token),
-          helper.uri);
-    }
-    Member getter = builder.target.hasGetter ? builder.target : null;
-    Member setter = builder.target.hasSetter ? builder.target : null;
-    if (setter == null) {
-      if (builderSetter?.target?.hasSetter ?? false) {
-        setter = builderSetter.target;
-      }
-    }
-    return new StaticAccessGenerator(helper, token, getter, setter);
-  }
-
-  String get plainNameForRead => (readTarget ?? writeTarget).name.name;
-
-  String get debugName => "StaticAccessGenerator";
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    if (readTarget == null) {
-      return makeInvalidRead();
-    } else {
-      var read = helper.makeStaticGet(readTarget, token);
-      complexAssignment?.read = read;
-      return read;
-    }
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    Expression write;
-    if (writeTarget == null) {
-      write = makeInvalidWrite(value);
-    } else {
-      write = new StaticSet(writeTarget, value);
-      complexAssignment?.write = write;
-    }
-    write.fileOffset = offsetForToken(token);
-    return write;
-  }
-
-  Expression doInvocation(int offset, Arguments arguments) {
-    if (helper.constantContext != ConstantContext.none &&
-        !helper.isIdentical(readTarget)) {
-      helper.deprecated_addCompileTimeError(
-          offset, "Not a constant expression.");
-    }
-    if (readTarget == null || isFieldOrGetter(readTarget)) {
-      return helper.buildMethodInvocation(buildSimpleRead(), callName,
-          arguments, offset + (readTarget?.name?.name?.length ?? 0),
-          // This isn't a constant expression, but we have checked if a
-          // constant expression error should be emitted already.
-          isConstantExpression: true,
-          isImplicitCall: true);
-    } else {
-      return helper.buildStaticInvocation(readTarget, arguments,
-          charOffset: offset);
-    }
-  }
-
-  @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
-      new ShadowStaticAssignment(rhs);
-
-  @override
-  void printOn(StringSink sink) {
-    NameSystem syntheticNames = new NameSystem();
-    sink.write(", readTarget: ");
-    printQualifiedNameOn(readTarget, sink, syntheticNames: syntheticNames);
-    sink.write(", writeTarget: ");
-    printQualifiedNameOn(writeTarget, sink, syntheticNames: syntheticNames);
-  }
-}
-
-class LoadLibraryGenerator extends KernelGenerator {
-  final LoadLibraryBuilder builder;
-
-  LoadLibraryGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Token token,
-      this.builder)
-      : super(helper, token);
-
-  String get plainNameForRead => 'loadLibrary';
-
-  String get debugName => "LoadLibraryGenerator";
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    var read =
-        helper.makeStaticGet(builder.createTearoffMethod(helper.forest), token);
-    complexAssignment?.read = read;
-    return read;
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    Expression write = makeInvalidWrite(value);
-    write.fileOffset = offsetForToken(token);
-    return write;
-  }
-
-  Expression doInvocation(int offset, Arguments arguments) {
-    if (forest.argumentsPositional(arguments).length > 0 ||
-        forest.argumentsNamed(arguments).length > 0) {
-      helper.addProblemErrorIfConst(
-          messageLoadLibraryTakesNoArguments, offset, 'loadLibrary'.length);
-    }
-    return builder.createLoadLibrary(offset, forest);
-  }
-
-  @override
-  void printOn(StringSink sink) {
-    sink.write(", builder: ");
-    sink.write(builder);
-  }
-}
-
-class DeferredAccessGenerator extends KernelGenerator {
-  final PrefixBuilder builder;
-
-  final KernelGenerator generator;
-
-  DeferredAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Token token,
-      this.builder,
-      this.generator)
-      : super(helper, token);
-
-  String get plainNameForRead {
-    return unsupported(
-        "deferredAccessor.plainNameForRead", offsetForToken(token), uri);
-  }
-
-  String get debugName => "DeferredAccessGenerator";
-
-  Expression _makeSimpleRead() {
-    return helper.wrapInDeferredCheck(
-        generator._makeSimpleRead(), builder, token.charOffset);
-  }
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    return helper.wrapInDeferredCheck(
-        generator._makeRead(complexAssignment), builder, token.charOffset);
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    return helper.wrapInDeferredCheck(
-        generator._makeWrite(value, voidContext, complexAssignment),
-        builder,
-        token.charOffset);
-  }
-
-  buildPropertyAccess(
-      IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
-    var propertyAccess =
-        generator.buildPropertyAccess(send, operatorOffset, isNullAware);
-    if (propertyAccess is Generator) {
-      return new DeferredAccessGenerator(
-          helper, token, builder, propertyAccess);
-    } else {
-      Expression expression = propertyAccess;
-      return helper.wrapInDeferredCheck(expression, builder, token.charOffset);
-    }
-  }
-
-  @override
-  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
-      {bool nonInstanceAccessIsError: false}) {
-    helper.addProblem(
-        templateDeferredTypeAnnotation.withArguments(
-            generator.buildTypeWithBuiltArguments(arguments,
-                nonInstanceAccessIsError: nonInstanceAccessIsError),
-            builder.name),
-        offsetForToken(token),
-        lengthForToken(token));
-    return const InvalidType();
-  }
-
-  Expression doInvocation(int offset, Arguments arguments) {
-    return helper.wrapInDeferredCheck(
-        generator.doInvocation(offset, arguments), builder, token.charOffset);
-  }
-
-  @override
-  void printOn(StringSink sink) {
-    sink.write(", builder: ");
-    sink.write(builder);
-    sink.write(", generator: ");
-    sink.write(generator);
-  }
-}
-
-class ReadOnlyAccessGenerator extends KernelGenerator {
-  final String plainNameForRead;
-
-  Expression expression;
-
-  VariableDeclaration value;
-
-  ReadOnlyAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Token token,
-      this.expression,
-      this.plainNameForRead)
-      : super(helper, token);
-
-  String get debugName => "ReadOnlyAccessGenerator";
-
-  Expression _makeSimpleRead() => expression;
-
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    value ??= new VariableDeclaration.forValue(expression);
-    return new VariableGet(value);
-  }
-
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    var write = makeInvalidWrite(value);
-    complexAssignment?.write = write;
-    return write;
-  }
-
-  Expression _finish(
-          Expression body, ShadowComplexAssignment complexAssignment) =>
-      super._finish(makeLet(value, body), complexAssignment);
-
-  Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
-        adjustForImplicitCall(plainNameForRead, offset),
-        isImplicitCall: true);
-  }
-
-  @override
-  void printOn(StringSink sink) {
-    NameSystem syntheticNames = new NameSystem();
-    sink.write(", expression: ");
-    printNodeOn(expression, sink, syntheticNames: syntheticNames);
-    sink.write(", plainNameForRead: ");
-    sink.write(plainNameForRead);
-    sink.write(", value: ");
-    printNodeOn(value, sink, syntheticNames: syntheticNames);
-  }
-}
-
-class LargeIntAccessGenerator extends KernelGenerator {
-  LargeIntAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper, Token token)
-      : super(helper, token);
-
-  // TODO(ahe): This should probably be calling unhandled.
-  String get plainNameForRead => null;
-
-  String get debugName => "LargeIntAccessGenerator";
-
-  @override
-  Expression _makeSimpleRead() => buildError();
-
-  @override
-  Expression _makeSimpleWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    return buildError();
-  }
-
-  @override
-  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
-    return buildError();
-  }
-
-  @override
-  Expression _makeWrite(Expression value, bool voidContext,
-      ShadowComplexAssignment complexAssignment) {
-    return buildError();
-  }
-
-  Expression buildError() {
-    return helper.buildCompileTimeError(
-        templateIntegerLiteralIsOutOfRange.withArguments(token),
-        offsetForToken(token),
-        lengthForToken(token));
-  }
-
-  @override
-  Expression doInvocation(int offset, Arguments arguments) {
-    return buildError();
-  }
-
-  @override
-  void printOn(StringSink sink) {
-    sink.write(", lexeme: ");
-    sink.write(token.lexeme);
-  }
-}
-
-abstract class ErroneousExpressionGenerator implements KernelGenerator {
-  /// Pass [arguments] that must be evaluated before throwing an error.  At
-  /// most one of [isGetter] and [isSetter] should be true and they're passed
-  /// to [ExpressionGeneratorHelper.buildThrowNoSuchMethodError] if it is used.
-  Expression buildError(Arguments arguments,
-      {bool isGetter: false, bool isSetter: false, int offset});
-
-  DartType buildErroneousTypeNotAPrefix(Identifier suffix);
-
-  Name get name => unsupported("name", offsetForToken(token), uri);
-
-  @override
-  String get plainNameForRead => name.name;
-
-  withReceiver(Object receiver, int operatorOffset, {bool isNullAware}) => this;
-
-  @override
-  Initializer buildFieldInitializer(Map<String, int> initializedFields) {
-    return helper.buildInvalidInitializer(
-        buildError(forest.argumentsEmpty(noLocation), isSetter: true));
-  }
-
-  @override
-  doInvocation(int offset, Arguments arguments) {
-    return buildError(arguments, offset: offset);
-  }
-
-  @override
-  buildPropertyAccess(
-      IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
-    return this;
-  }
-
-  @override
-  buildThrowNoSuchMethodError(Expression receiver, Arguments arguments,
-      {bool isSuper: false,
-      bool isGetter: false,
-      bool isSetter: false,
-      bool isStatic: false,
-      String name,
-      int offset,
-      LocatedMessage argMessage}) {
-    return this;
-  }
-
-  @override
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
-    return buildError(forest.arguments(<Expression>[value], noLocation),
-        isSetter: true);
-  }
-
-  @override
-  Expression buildCompoundAssignment(Name binaryOperator, Expression value,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
-    return buildError(forest.arguments(<Expression>[value], token),
-        isGetter: true);
-  }
-
-  @override
-  Expression buildPrefixIncrement(Name binaryOperator,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget}) {
-    // TODO(ahe): For the Analyzer, we probably need to build a prefix
-    // increment node that wraps an error.
-    return buildError(
-        forest.arguments(
-            <Expression>[storeOffset(forest.literalInt(1, null), offset)],
-            noLocation),
-        isGetter: true);
-  }
-
-  @override
-  Expression buildPostfixIncrement(Name binaryOperator,
-      {int offset: TreeNode.noOffset,
-      bool voidContext: false,
-      Procedure interfaceTarget}) {
-    // TODO(ahe): For the Analyzer, we probably need to build a post increment
-    // node that wraps an error.
-    return buildError(
-        forest.arguments(
-            <Expression>[storeOffset(forest.literalInt(1, null), offset)],
-            noLocation),
-        isGetter: true);
-  }
-
-  @override
-  Expression buildNullAwareAssignment(
-      Expression value, DartType type, int offset,
-      {bool voidContext: false}) {
-    return buildError(forest.arguments(<Expression>[value], noLocation),
-        isSetter: true);
-  }
-
-  @override
-  Expression buildSimpleRead() =>
-      buildError(forest.argumentsEmpty(noLocation), isGetter: true);
-
-  @override
-  Expression makeInvalidRead() =>
-      buildError(forest.argumentsEmpty(noLocation), isGetter: true);
-
-  @override
-  Expression makeInvalidWrite(Expression value) {
-    return buildError(forest.arguments(<Expression>[value], noLocation),
-        isSetter: true);
-  }
-}
-
 class ThisAccessGenerator extends KernelGenerator {
   final bool isInitializer;
 
@@ -653,11 +80,11 @@
       Member setter =
           helper.lookupInstanceMember(name, isSuper: isSuper, isSetter: true);
       if (isSuper) {
-        return new SuperPropertyAccessGenerator(
-            helper, send.token, name, getter, setter);
+        return new SuperPropertyAccessGenerator<Expression, Statement,
+            Arguments>(helper, send.token, name, getter, setter);
       } else {
-        return new ThisPropertyAccessGenerator(
-            helper, send.token, name, getter, setter);
+        return new ThisPropertyAccessGenerator<Expression, Statement,
+            Arguments>(helper, send.token, name, getter, setter);
       }
     }
   }
@@ -791,7 +218,7 @@
 }
 
 class UnresolvedNameGenerator extends KernelGenerator
-    with ErroneousExpressionGenerator {
+    with ErroneousExpressionGenerator<Expression, Statement, Arguments> {
   @override
   final Name name;
 
@@ -849,7 +276,7 @@
 }
 
 class IncompleteErrorGenerator extends IncompleteSendGenerator
-    with ErroneousExpressionGenerator {
+    with ErroneousExpressionGenerator<Expression, Statement, Arguments> {
   final Message message;
 
   IncompleteErrorGenerator(
@@ -1017,7 +444,7 @@
           isQualified: true, prefix: prefix);
     }
 
-    return PropertyAccessGenerator.make(
+    return PropertyAccessGenerator.make<Expression, Statement, Arguments>(
         helper, token, helper.toValue(receiver), name, null, null, isNullAware);
   }
 
@@ -1053,7 +480,7 @@
   }
 }
 
-class ParenthesizedExpressionGenerator extends ReadOnlyAccessGenerator {
+class ParenthesizedExpressionGenerator extends KernelReadOnlyAccessGenerator {
   ParenthesizedExpressionGenerator(
       ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
       Token token,
@@ -1068,162 +495,6 @@
   }
 }
 
-// TODO(ahe): Rename to TypeUseGenerator.
-class TypeDeclarationAccessGenerator extends ReadOnlyAccessGenerator {
-  /// The import prefix preceding the [declaration] reference, or `null` if
-  /// the reference is not prefixed.
-  final PrefixBuilder prefix;
-
-  /// The offset at which the [declaration] is referenced by this generator,
-  /// or `-1` if the reference is implicit.
-  final int declarationReferenceOffset;
-
-  final TypeDeclarationBuilder declaration;
-
-  TypeDeclarationAccessGenerator(
-      ExpressionGeneratorHelper<dynamic, dynamic, dynamic> helper,
-      Token token,
-      this.prefix,
-      this.declarationReferenceOffset,
-      this.declaration,
-      String plainNameForRead)
-      : super(helper, token, null, plainNameForRead);
-
-  String get debugName => "TypeDeclarationAccessGenerator";
-
-  Expression get expression {
-    if (super.expression == null) {
-      int offset = offsetForToken(token);
-      if (declaration is KernelInvalidTypeBuilder) {
-        KernelInvalidTypeBuilder declaration = this.declaration;
-        helper.addProblemErrorIfConst(
-            declaration.message.messageObject, offset, token.length);
-        super.expression =
-            new Throw(forest.literalString(declaration.message.message, token))
-              ..fileOffset = offset;
-      } else {
-        super.expression = forest.literalType(
-            buildTypeWithBuiltArguments(null, nonInstanceAccessIsError: true),
-            token);
-      }
-    }
-    return super.expression;
-  }
-
-  Expression makeInvalidWrite(Expression value) {
-    return buildThrowNoSuchMethodError(
-        forest.literalNull(token),
-        storeOffset(
-            forest.arguments(<Expression>[value], null), value.fileOffset),
-        isSetter: true);
-  }
-
-  @override
-  buildPropertyAccess(
-      IncompleteSendGenerator send, int operatorOffset, bool isNullAware) {
-    // `SomeType?.toString` is the same as `SomeType.toString`, not
-    // `(SomeType).toString`.
-    isNullAware = false;
-
-    Name name = send.name;
-    Arguments arguments = send.arguments;
-
-    if (declaration is KernelClassBuilder) {
-      KernelClassBuilder declaration = this.declaration;
-      Builder builder = declaration.findStaticBuilder(
-          name.name, offsetForToken(token), uri, helper.library);
-
-      Generator generator;
-      if (builder == null) {
-        // If we find a setter, [builder] is an [AccessErrorBuilder], not null.
-        if (send is IncompletePropertyAccessGenerator) {
-          generator = new UnresolvedNameGenerator(helper, send.token, name);
-        } else {
-          return helper.buildConstructorInvocation(declaration, send.token,
-              arguments, name.name, null, token.charOffset, Constness.implicit);
-        }
-      } else {
-        Builder setter;
-        if (builder.isSetter) {
-          setter = builder;
-        } else if (builder.isGetter) {
-          setter = declaration.findStaticBuilder(
-              name.name, offsetForToken(token), uri, helper.library,
-              isSetter: true);
-        } else if (builder.isField && !builder.isFinal) {
-          setter = builder;
-        }
-        generator = new StaticAccessGenerator.fromBuilder(
-            helper, builder, send.token, setter);
-      }
-
-      return arguments == null
-          ? generator
-          : generator.doInvocation(offsetForToken(send.token), arguments);
-    } else {
-      return super.buildPropertyAccess(send, operatorOffset, isNullAware);
-    }
-  }
-
-  @override
-  DartType buildTypeWithBuiltArguments(List<DartType> arguments,
-      {bool nonInstanceAccessIsError: false}) {
-    if (arguments != null) {
-      int expected = 0;
-      if (declaration is KernelClassBuilder) {
-        expected = declaration.target.typeParameters.length;
-      } else if (declaration is FunctionTypeAliasBuilder) {
-        expected = declaration.target.typeParameters.length;
-      } else if (declaration is KernelTypeVariableBuilder) {
-        // Type arguments on a type variable - error reported elsewhere.
-      } else if (declaration is BuiltinTypeBuilder) {
-        // Type arguments on a built-in type, for example, dynamic or void.
-        expected = 0;
-      } else {
-        return unhandled(
-            "${declaration.runtimeType}",
-            "TypeDeclarationAccessGenerator.buildType",
-            offsetForToken(token),
-            helper.uri);
-      }
-      if (arguments.length != expected) {
-        helper.warnTypeArgumentsMismatch(
-            declaration.name, expected, offsetForToken(token));
-        // We ignore the provided arguments, which will in turn return the
-        // raw type below.
-        // TODO(sigmund): change to use an InvalidType and include the raw type
-        // as a recovery node once the IR can represent it (Issue #29840).
-        arguments = null;
-      }
-    }
-
-    DartType type;
-    if (arguments == null) {
-      TypeDeclarationBuilder typeDeclaration = declaration;
-      if (typeDeclaration is KernelClassBuilder) {
-        type = typeDeclaration.buildType(helper.library, null);
-      } else if (typeDeclaration is KernelFunctionTypeAliasBuilder) {
-        type = typeDeclaration.buildType(helper.library, null);
-      }
-    }
-    if (type == null) {
-      type =
-          declaration.buildTypesWithBuiltArguments(helper.library, arguments);
-    }
-    if (type is TypeParameterType) {
-      return helper.validatedTypeVariableUse(
-          type, offsetForToken(token), nonInstanceAccessIsError);
-    }
-    return type;
-  }
-
-  @override
-  Expression doInvocation(int offset, Arguments arguments) {
-    return helper.buildConstructorInvocation(declaration, token, arguments, "",
-        null, token.charOffset, Constness.implicit);
-  }
-}
-
 abstract class ContextAwareGenerator
     extends Generator<Expression, Statement, Arguments> {
   final Generator generator;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
index 99d686f..b83c6d6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
@@ -101,7 +101,7 @@
 
     if (arguments == null && typeVariables != null) {
       List<DartType> result =
-          new List<DartType>.filled(typeVariables.length, null);
+          new List<DartType>.filled(typeVariables.length, null, growable: true);
       for (int i = 0; i < result.length; ++i) {
         result[i] = typeVariables[i].defaultType.build(library);
       }
@@ -120,7 +120,8 @@
     }
 
     // arguments.length == typeVariables.length
-    List<DartType> result = new List<DartType>.filled(arguments.length, null);
+    List<DartType> result =
+        new List<DartType>.filled(arguments.length, null, growable: true);
     for (int i = 0; i < result.length; ++i) {
       result[i] = arguments[i].build(library);
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index b5f6854..c25088e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -53,6 +53,7 @@
         BuiltinTypeBuilder,
         ClassBuilder,
         ConstructorReferenceBuilder,
+        DynamicTypeBuilder,
         FormalParameterBuilder,
         InvalidTypeBuilder,
         KernelClassBuilder,
@@ -125,6 +126,16 @@
 
   Uri get uri => library.importUri;
 
+  void becomeCoreLibrary(dynamicType) {
+    if (scope.local["dynamic"] == null) {
+      addBuilder(
+          "dynamic",
+          new DynamicTypeBuilder<KernelTypeBuilder, DartType>(
+              dynamicType, this, -1),
+          -1);
+    }
+  }
+
   KernelTypeBuilder addNamedType(
       Object name, List<KernelTypeBuilder> arguments, int charOffset) {
     return addType(new KernelNamedTypeBuilder(name, arguments), charOffset);
@@ -138,7 +149,8 @@
 
   KernelTypeBuilder addVoidType(int charOffset) {
     return addNamedType("void", null, charOffset)
-      ..bind(new VoidTypeBuilder(const VoidType(), this, charOffset));
+      ..bind(new VoidTypeBuilder<KernelTypeBuilder, VoidType>(
+          const VoidType(), this, charOffset));
   }
 
   void addClass(
@@ -437,8 +449,7 @@
         // TODO(ahe, kmillikin): Should always be true?
         // pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart can't
         // handle that :(
-        application.cls.isSyntheticMixinImplementation =
-            !isNamedMixinApplication;
+        application.cls.isAnonymousMixin = !isNamedMixinApplication;
         addBuilder(fullname, application, charOffset);
         supertype =
             addNamedType(fullname, applicationTypeArguments, charOffset);
@@ -976,7 +987,8 @@
       boundlessTypeVariables.add(newVariable);
     }
     for (TypeBuilder newType in newTypes) {
-      declaration.addType(new UnresolvedType(newType, -1, null));
+      declaration
+          .addType(new UnresolvedType<KernelTypeBuilder>(newType, -1, null));
     }
     return copy;
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
index 787bc90..97944ad 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -158,47 +158,34 @@
   static const localFunctionDeclarationContinuation =
       const LocalFunctionDeclarationIdentifierContext.continuation();
 
-  /// Identifier is the name appearing in a function expression.
-  ///
-  /// TODO(paulberry,ahe): What is an example of valid Dart code where this
-  /// would occur?
-  static const functionExpressionName =
-      const IdentifierContext('functionExpressionName');
-
   /// Identifier is the start of a reference to a constructor declared
   /// elsewhere.
   static const constructorReference =
-      const IdentifierContext('constructorReference', isScopeReference: true);
+      const ConstructorReferenceIdentifierContext();
 
   /// Identifier is part of a reference to a constructor declared elsewhere, but
   /// it's not the first identifier of the reference.
-  static const constructorReferenceContinuation = const IdentifierContext(
-      'constructorReferenceContinuation',
-      isContinuation: true);
+  static const constructorReferenceContinuation =
+      const ConstructorReferenceIdentifierContext.continuation();
 
   /// Identifier is part of a reference to a constructor declared elsewhere, but
   /// it appears after type parameters (e.g. `foo` in `X<Y>.foo`).
   static const constructorReferenceContinuationAfterTypeArguments =
-      const IdentifierContext(
-          'constructorReferenceContinuationAfterTypeArguments',
-          isContinuation: true);
+      const ConstructorReferenceIdentifierContext
+          .continuationAfterTypeArguments();
 
   /// Identifier is the declaration of a label (i.e. it is followed by `:` and
   /// then a statement).
-  static const labelDeclaration =
-      const IdentifierContext('labelDeclaration', inDeclaration: true);
+  static const labelDeclaration = const LabelDeclarationIdentifierContext();
 
   /// Identifier is the start of a reference occurring in a literal symbol (e.g.
   /// `foo` in `#foo`).
-  static const literalSymbol =
-      const IdentifierContext('literalSymbol', inSymbol: true);
+  static const literalSymbol = const LiteralSymbolIdentifierContext();
 
   /// Identifier is part of a reference occurring in a literal symbol, but it's
   /// not the first identifier of the reference (e.g. `foo` in `#prefix.foo`).
-  static const literalSymbolContinuation = const IdentifierContext(
-      'literalSymbolContinuation',
-      inSymbol: true,
-      isContinuation: true);
+  static const literalSymbolContinuation =
+      const LiteralSymbolIdentifierContext.continuation();
 
   /// Identifier appears in an expression, and it does not immediately follow a
   /// `.`.
@@ -210,9 +197,8 @@
 
   /// Identifier is a reference to a named argument of a function or method
   /// invocation (e.g. `foo` in `f(foo: 0);`.
-  static const namedArgumentReference = const IdentifierContext(
-      'namedArgumentReference',
-      allowedInConstantExpression: true);
+  static const namedArgumentReference =
+      const NamedArgumentReferenceIdentifierContext();
 
   /// Identifier is a name being declared by a local variable declaration.
   static const localVariableDeclaration =
@@ -220,7 +206,7 @@
 
   /// Identifier is a reference to a label (e.g. `foo` in `break foo;`).
   /// Labels have their own scope.
-  static const labelReference = const IdentifierContext('labelReference');
+  static const labelReference = const LabelReferenceIdentifierContext();
 
   final String _name;
 
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index 18dd095..28e85b6 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -90,6 +90,40 @@
   }
 }
 
+/// See [IdentifierContext.constructorReference]
+/// and [IdentifierContext.constructorReferenceContinuation]
+/// and [IdentifierContext.constructorReferenceContinuationAfterTypeArguments].
+class ConstructorReferenceIdentifierContext extends IdentifierContext {
+  const ConstructorReferenceIdentifierContext()
+      : super('constructorReference', isScopeReference: true);
+
+  const ConstructorReferenceIdentifierContext.continuation()
+      : super('constructorReferenceContinuation', isContinuation: true);
+
+  const ConstructorReferenceIdentifierContext.continuationAfterTypeArguments()
+      : super('constructorReferenceContinuationAfterTypeArguments',
+            isContinuation: true);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.isIdentifier) {
+      return identifier;
+    }
+
+    // Recovery
+    if (!identifier.isKeywordOrIdentifier) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: fasta.templateExpectedIdentifier.withArguments(identifier));
+    } else {
+      parser.reportRecoverableErrorWithToken(
+          identifier, fasta.templateExpectedIdentifier);
+    }
+    return identifier;
+  }
+}
+
 /// See [IdentifierContext.dottedName].
 class DottedNameIdentifierContext extends IdentifierContext {
   const DottedNameIdentifierContext() : super('dottedName');
@@ -368,6 +402,28 @@
   }
 }
 
+class LiteralSymbolIdentifierContext extends IdentifierContext {
+  const LiteralSymbolIdentifierContext()
+      : super('literalSymbol', inSymbol: true);
+
+  const LiteralSymbolIdentifierContext.continuation()
+      : super('literalSymbolContinuation',
+            inSymbol: true, isContinuation: true);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.isIdentifier) {
+      return identifier;
+    }
+
+    // Recovery
+    return parser.insertSyntheticIdentifier(token, this,
+        message: fasta.templateExpectedIdentifier.withArguments(identifier));
+  }
+}
+
 /// See [IdentifierContext.localFunctionDeclaration]
 /// and [IdentifierContext.localFunctionDeclarationContinuation].
 class LocalFunctionDeclarationIdentifierContext extends IdentifierContext {
@@ -405,6 +461,66 @@
   }
 }
 
+/// See [IdentifierContext.labelDeclaration].
+class LabelDeclarationIdentifierContext extends IdentifierContext {
+  const LabelDeclarationIdentifierContext()
+      : super('labelDeclaration', inDeclaration: true);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.isIdentifier) {
+      return identifier;
+    }
+
+    // Recovery
+    if (isOneOfOrEof(identifier, const [':']) ||
+        looksLikeStartOfNextStatement(identifier)) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: fasta.templateExpectedIdentifier.withArguments(identifier));
+    } else {
+      parser.reportRecoverableErrorWithToken(
+          identifier, fasta.templateExpectedIdentifier);
+      if (!identifier.isKeywordOrIdentifier) {
+        // When in doubt, consume the token to ensure we make progress
+        // but insert a synthetic identifier to satisfy listeners.
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
+      }
+    }
+    return identifier;
+  }
+}
+
+/// See [IdentifierContext.labelReference].
+class LabelReferenceIdentifierContext extends IdentifierContext {
+  const LabelReferenceIdentifierContext() : super('labelReference');
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.isIdentifier) {
+      return identifier;
+    }
+
+    // Recovery
+    if (isOneOfOrEof(identifier, const [';'])) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: fasta.templateExpectedIdentifier.withArguments(identifier));
+    } else {
+      parser.reportRecoverableErrorWithToken(
+          identifier, fasta.templateExpectedIdentifier);
+      if (!identifier.isKeywordOrIdentifier) {
+        // When in doubt, consume the token to ensure we make progress
+        // but insert a synthetic identifier to satisfy listeners.
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
+      }
+    }
+    return identifier;
+  }
+}
+
 /// See [IdentifierContext.libraryName],
 /// and [IdentifierContext.libraryNameContinuation]
 /// and [IdentifierContext.partName],
@@ -576,6 +692,36 @@
   }
 }
 
+/// See [IdentifierContext.namedArgumentReference].
+class NamedArgumentReferenceIdentifierContext extends IdentifierContext {
+  const NamedArgumentReferenceIdentifierContext()
+      : super('namedArgumentReference', allowedInConstantExpression: true);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.isIdentifier) {
+      return identifier;
+    }
+
+    // Recovery
+    if (isOneOfOrEof(identifier, const [':'])) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: fasta.templateExpectedIdentifier.withArguments(identifier));
+    } else {
+      parser.reportRecoverableErrorWithToken(
+          identifier, fasta.templateExpectedIdentifier);
+      if (!identifier.isKeywordOrIdentifier) {
+        // When in doubt, consume the token to ensure we make progress
+        // but insert a synthetic identifier to satisfy listeners.
+        identifier = parser.rewriter.insertSyntheticIdentifier(identifier);
+      }
+    }
+    return identifier;
+  }
+}
+
 /// See [IdentifierContext.topLevelFunctionDeclaration]
 /// and [IdentifierContext.topLevelVariableDeclaration].
 class TopLevelDeclarationIdentifierContext extends IdentifierContext {
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 0b81640..1375174 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -90,14 +90,13 @@
         TypeParamOrArgInfo,
         computeMethodTypeArguments,
         computeType,
-        computeTypeParam,
         computeTypeParamOrArg,
         isGeneralizedFunctionType,
         isValidTypeReference,
         noType,
         noTypeParamOrArg;
 
-import 'util.dart' show optional;
+import 'util.dart' show findNonSyntheticToken, optional;
 
 /// An event generating parser of Dart programs. This parser expects all tokens
 /// in a linked list (aka a token stream).
@@ -1597,7 +1596,7 @@
 
   /// ```
   /// enumType:
-  ///   metadata 'enum' id '{' id [',' id]* [','] '}'
+  ///   metadata 'enum' id '{' metadata id [',' metadata id]* [','] '}'
   /// ;
   /// ```
   Token parseEnum(Token token) {
@@ -1619,10 +1618,6 @@
           break;
         }
         token = parseMetadataStar(token);
-        if (!identical(token.next, next)) {
-          listener.handleRecoverableError(
-              fasta.messageAnnotationOnEnumConstant, next, token);
-        }
         token = ensureIdentifier(token, IdentifierContext.enumValueDeclaration);
         next = token.next;
         count++;
@@ -1673,7 +1668,7 @@
     assert(optional('class', token));
     Token name =
         ensureIdentifier(token, IdentifierContext.classOrNamedMixinDeclaration);
-    token = computeTypeParam(name).parseVariables(name, this);
+    token = computeTypeParamOrArg(name, true).parseVariables(name, this);
     if (optional('=', token.next)) {
       listener.beginNamedMixinApplication(begin, abstractToken, name);
       return parseNamedMixinApplication(token, begin, classKeyword);
@@ -1918,72 +1913,14 @@
   /// an error, and return the synthetic identifier.
   Token ensureIdentifier(Token token, IdentifierContext context) {
     assert(context != null);
-    Token next = token.next;
-    if (next.kind == IDENTIFIER_TOKEN) {
-      listener.handleIdentifier(next, context);
-      return next;
-    }
-    Token identifier = context.ensureIdentifier(token, this);
-    // TODO(danrubel): Once refactoring is complete,
-    // context.ensureIdentifier should never return null.
-    if (identifier != null) {
+    Token identifier = token.next;
+    if (identifier.kind != IDENTIFIER_TOKEN) {
+      identifier = context.ensureIdentifier(token, this);
+      assert(identifier != null);
       assert(identifier.isKeywordOrIdentifier);
-      listener.handleIdentifier(identifier, context);
-      return identifier;
     }
-
-    // TODO(danrubel): Roll everything beyond this point into the
-    // ensureIdentifier methods in the various IdentifierContext subclasses.
-
-    if (!next.isIdentifier) {
-      if (next is ErrorToken) {
-        // TODO(brianwilkerson): This preserves the current semantics, but the
-        // listener should not be recovering from this case, so this needs to be
-        // reworked to recover in this method (probably inside the outermost
-        // if statement).
-        token =
-            reportUnrecoverableErrorWithToken(next, context.recoveryTemplate)
-                .next;
-      } else if (isIdentifierForRecovery(next, context)) {
-        reportRecoverableErrorWithToken(next, context.recoveryTemplate);
-        token = next;
-      } else if (isPostIdentifierForRecovery(next, context) ||
-          isStartOfNextSibling(next, context)) {
-        token = insertSyntheticIdentifier(token, context);
-      } else if (next.isKeywordOrIdentifier) {
-        reportRecoverableErrorWithToken(next, context.recoveryTemplate);
-        token = next;
-      } else {
-        reportRecoverableErrorWithToken(next, context.recoveryTemplate);
-        if (context == IdentifierContext.constructorReference) {
-          token = insertSyntheticIdentifier(token, context);
-        } else {
-          token = next;
-        }
-      }
-    } else if (next.type.isBuiltIn && !context.isBuiltInIdentifierAllowed) {
-      if (context.inDeclaration) {
-        reportRecoverableErrorWithToken(
-            next, fasta.templateBuiltInIdentifierInDeclaration);
-      } else if (!optional("dynamic", next)) {
-        reportRecoverableErrorWithToken(
-            next, fasta.templateBuiltInIdentifierAsType);
-      }
-      token = next;
-    } else if (!inPlainSync && next.type.isPseudo) {
-      if (optional('await', next)) {
-        reportRecoverableError(next, fasta.messageAwaitAsIdentifier);
-      } else if (optional('yield', next)) {
-        reportRecoverableError(next, fasta.messageYieldAsIdentifier);
-      } else if (optional('async', next)) {
-        reportRecoverableError(next, fasta.messageAsyncAsIdentifier);
-      }
-      token = next;
-    } else {
-      token = next;
-    }
-    listener.handleIdentifier(token, context);
-    return token;
+    listener.handleIdentifier(identifier, context);
+    return identifier;
   }
 
   /// Return `true` if the given [token] should be treated like the start of
@@ -2007,84 +1944,6 @@
       optional('++', next) ||
       optional('--', next);
 
-  /// Return `true` if the given [token] should be treated like an identifier in
-  /// the given [context] for the purposes of recovery.
-  bool isIdentifierForRecovery(Token token, IdentifierContext context) {
-    if (!token.type.isKeyword) {
-      return false;
-    }
-    return isPostIdentifierForRecovery(token.next, context);
-  }
-
-  /// Return `true` if the given [token] appears to be a token that would be
-  /// expected after an identifier in the given [context].
-  bool isPostIdentifierForRecovery(Token token, IdentifierContext context) {
-    if (token.isEof) {
-      return true;
-    }
-    List<String> followingValues;
-    if (context == IdentifierContext.combinator) {
-      followingValues = [';'];
-    } else if (context == IdentifierContext.constructorReferenceContinuation) {
-      followingValues = ['.', ',', '(', ')', '[', ']', '}', ';'];
-    } else if (context == IdentifierContext.labelDeclaration) {
-      followingValues = [':'];
-    } else if (context == IdentifierContext.literalSymbol ||
-        context == IdentifierContext.literalSymbolContinuation) {
-      followingValues = ['.', ';'];
-    } else {
-      return false;
-    }
-    for (String tokenValue in followingValues) {
-      if (optional(tokenValue, token)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /// Return `true` if the given [token] appears to be the start of a (virtual)
-  /// node that would be a sibling of the current node or one of its parents.
-  /// The type of the current node is suggested by the given [context].
-  bool isStartOfNextSibling(Token token, IdentifierContext context) {
-    if (!token.type.isKeyword) {
-      return false;
-    }
-
-    List<String> statementKeywords() => <String>[
-          'const',
-          'do',
-          'final',
-          'if',
-          'switch',
-          'try',
-          'var',
-          'void',
-          'while'
-        ];
-
-    // TODO(brianwilkerson): At the moment, this test is entirely based on data
-    // that can be represented declaratively. If that proves to be sufficient,
-    // then this data can be moved into a field in IdentifierContext and we
-    // could create a method to test whether a given token matches one of the
-    // patterns.
-    List<String> initialKeywords;
-    if (context == IdentifierContext.labelDeclaration) {
-      initialKeywords = statementKeywords();
-    } else if (context ==
-        IdentifierContext.localFunctionDeclarationContinuation) {
-      initialKeywords = statementKeywords();
-    } else {
-      return false;
-    }
-    for (String tokenValue in initialKeywords) {
-      if (optional(tokenValue, token)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
   Token expect(String string, Token token) {
     // TODO(danrubel): update all uses of expect(';'...) to ensureSemicolon
     // then add assert(!identical(';', string));
@@ -2445,7 +2304,7 @@
     }
 
     Token beforeType = token;
-    TypeInfo typeInfo = computeType(token, false);
+    TypeInfo typeInfo = computeType(token, false, true);
     token = typeInfo.skipType(token);
     next = token.next;
 
@@ -2530,8 +2389,8 @@
               varFinalOrConst, fasta.templateExtraneousModifier);
         }
       }
-      return parseTopLevelMethod(
-          beforeStart, externalToken, beforeType, typeInfo, getOrSet, token);
+      return parseTopLevelMethod(beforeStart, externalToken, beforeType,
+          typeInfo, getOrSet, token.next);
     }
 
     if (getOrSet != null) {
@@ -2539,7 +2398,7 @@
           getOrSet, fasta.templateExtraneousModifier);
     }
     return parseFields(beforeStart, externalToken, null, null, varFinalOrConst,
-        beforeType, typeInfo, token, true);
+        beforeType, typeInfo, token.next, true);
   }
 
   Token parseFields(
@@ -2550,7 +2409,7 @@
       Token varFinalOrConst,
       Token beforeType,
       TypeInfo typeInfo,
-      Token beforeName,
+      Token name,
       bool isTopLevel) {
     if (externalToken != null) {
       reportRecoverableError(externalToken, fasta.messageExternalField);
@@ -2563,8 +2422,7 @@
     }
     if (typeInfo == noType) {
       if (varFinalOrConst == null) {
-        reportRecoverableError(
-            beforeName.next, fasta.messageMissingConstFinalVarOrType);
+        reportRecoverableError(name, fasta.messageMissingConstFinalVarOrType);
       }
     } else {
       if (varFinalOrConst != null && optional('var', varFinalOrConst)) {
@@ -2572,16 +2430,16 @@
       }
     }
 
-    typeInfo.parseType(beforeType, this);
+    Token token = typeInfo.parseType(beforeType, this);
+    assert(token.next == name);
 
     IdentifierContext context = isTopLevel
         ? IdentifierContext.topLevelVariableDeclaration
         : IdentifierContext.fieldDeclaration;
-    Token name = ensureIdentifier(beforeName, context);
+    name = ensureIdentifier(token, context);
 
     int fieldCount = 1;
-    Token token =
-        parseFieldInitializerOpt(name, name, varFinalOrConst, isTopLevel);
+    token = parseFieldInitializerOpt(name, name, varFinalOrConst, isTopLevel);
     while (optional(',', token.next)) {
       name = ensureIdentifier(token.next, context);
       token = parseFieldInitializerOpt(name, name, varFinalOrConst, isTopLevel);
@@ -2599,17 +2457,17 @@
   }
 
   Token parseTopLevelMethod(Token beforeStart, Token externalToken,
-      Token beforeType, TypeInfo typeInfo, Token getOrSet, Token beforeName) {
+      Token beforeType, TypeInfo typeInfo, Token getOrSet, Token name) {
     listener.beginTopLevelMethod(beforeStart, externalToken);
 
-    typeInfo.parseType(beforeType, this);
-    Token name = ensureIdentifier(
-        beforeName, IdentifierContext.topLevelFunctionDeclaration);
+    Token token = typeInfo.parseType(beforeType, this);
+    assert(token.next == (getOrSet ?? name));
+    name = ensureIdentifier(
+        getOrSet ?? token, IdentifierContext.topLevelFunctionDeclaration);
 
-    Token token;
     bool isGetter = false;
     if (getOrSet == null) {
-      token = computeTypeParam(name).parseVariables(name, this);
+      token = computeTypeParamOrArg(name, true).parseVariables(name, this);
     } else {
       isGetter = optional("get", getOrSet);
       token = name;
@@ -3101,7 +2959,7 @@
     listener.beginMember();
 
     Token beforeType = token;
-    TypeInfo typeInfo = computeType(token, false);
+    TypeInfo typeInfo = computeType(token, false, true);
     token = typeInfo.skipType(token);
     next = token.next;
 
@@ -3136,7 +2994,7 @@
               beforeType,
               typeInfo,
               getOrSet,
-              token);
+              token.next);
           listener.endMember();
           return token;
         } else if (optional('===', next2) ||
@@ -3157,7 +3015,7 @@
               beforeType,
               typeInfo,
               getOrSet,
-              token);
+              token.next);
           listener.endMember();
           return token;
         }
@@ -3210,14 +3068,22 @@
           beforeType,
           typeInfo,
           getOrSet,
-          token);
+          token.next);
     } else {
       if (getOrSet != null) {
         reportRecoverableErrorWithToken(
             getOrSet, fasta.templateExtraneousModifier);
       }
-      token = parseFields(beforeStart, externalToken, staticToken,
-          covariantToken, varFinalOrConst, beforeType, typeInfo, token, false);
+      token = parseFields(
+          beforeStart,
+          externalToken,
+          staticToken,
+          covariantToken,
+          varFinalOrConst,
+          beforeType,
+          typeInfo,
+          token.next,
+          false);
     }
     listener.endMember();
     return token;
@@ -3232,8 +3098,8 @@
       Token beforeType,
       TypeInfo typeInfo,
       Token getOrSet,
-      Token beforeName) {
-    bool isOperator = getOrSet == null && optional('operator', beforeName.next);
+      Token name) {
+    bool isOperator = getOrSet == null && optional('operator', name);
 
     if (staticToken != null) {
       if (isOperator) {
@@ -3266,23 +3132,24 @@
 
     // TODO(danrubel): Consider parsing the name before calling beginMethod
     // rather than passing the name token into beginMethod.
-    listener.beginMethod(externalToken, staticToken, covariantToken,
-        varFinalOrConst, beforeName.next);
+    listener.beginMethod(
+        externalToken, staticToken, covariantToken, varFinalOrConst, name);
 
-    typeInfo.parseType(beforeType, this);
+    Token token = typeInfo.parseType(beforeType, this);
+    assert(token.next == (getOrSet ?? name));
+    token = getOrSet ?? token;
 
-    Token token;
     if (isOperator) {
-      token = parseOperatorName(beforeName);
+      token = parseOperatorName(token);
     } else {
-      token = ensureIdentifier(beforeName, IdentifierContext.methodDeclaration);
+      token = ensureIdentifier(token, IdentifierContext.methodDeclaration);
       token = parseQualifiedRestOpt(
           token, IdentifierContext.methodDeclarationContinuation);
     }
 
     bool isGetter = false;
     if (getOrSet == null) {
-      token = parseTypeVariablesOpt(token);
+      token = computeTypeParamOrArg(token, true).parseVariables(token, this);
     } else {
       isGetter = optional("get", getOrSet);
       listener.handleNoTypeVariables(token.next);
@@ -3291,7 +3158,7 @@
     MemberKind kind = staticToken != null
         ? MemberKind.StaticMethod
         : MemberKind.NonStaticMethod;
-    checkFormals(beforeName.next, isGetter, token.next, kind);
+    checkFormals(name, isGetter, token.next, kind);
     Token beforeParam = token;
     token = parseFormalParametersOpt(token, kind);
     token = parseInitializersOpt(token);
@@ -3875,12 +3742,9 @@
   /// ;
   /// ```
   Token parseLabel(Token token) {
-    // TODO(brianwilkerson): Enable this assert.
-    // `parseType` is allowing `void` to be a label.
-//    assert(token.next.isIdentifier);
-    assert(optional(':', token.next.next));
+    assert(token.next.isIdentifier);
     token = ensureIdentifier(token, IdentifierContext.labelDeclaration).next;
-    expect(':', token);
+    assert(optional(':', token));
     listener.handleLabel(token);
     return token;
   }
@@ -5959,7 +5823,7 @@
       Token covariantToken,
       Token varFinalOrConst,
       Token beforeType) {
-    TypeInfo typeInfo = computeType(beforeType, true);
+    TypeInfo typeInfo = computeType(beforeType, true, true);
 
     Token beforeName = typeInfo.skipType(beforeType);
     Token next = beforeName.next;
@@ -5973,12 +5837,6 @@
     }
 
     assert((next.isOperator && next.endGroup == null) || optional('===', next));
-    if (!next.isUserDefinableOperator) {
-      beforeName = next;
-      insertSyntheticIdentifier(beforeName, IdentifierContext.methodDeclaration,
-          message: fasta.templateInvalidOperator.withArguments(next),
-          messageOnToken: next);
-    }
 
     Token token = parseMethod(
         beforeStart,
@@ -5989,7 +5847,7 @@
         beforeType,
         typeInfo,
         null,
-        beforeName);
+        beforeName.next);
     listener.endMember();
     return token;
   }
@@ -6016,7 +5874,7 @@
       return reportAndSkipEnumInClass(next);
     } else if (identical(value, 'typedef')) {
       return reportAndSkipTypedefInClass(next);
-    } else if (next.isOperator) {
+    } else if (next.isOperator && next.endGroup == null) {
       return parseInvalidOperatorDeclaration(beforeStart, externalToken,
           staticToken, covariantToken, varFinalOrConst, beforeType);
     }
@@ -6034,7 +5892,7 @@
           beforeType,
           typeInfo,
           getOrSet,
-          token);
+          token.next);
     } else if (token == beforeStart) {
       // TODO(danrubel): Provide a more specific error message for extra ';'.
       reportRecoverableErrorWithToken(next, fasta.templateExpectedClassMember);
@@ -6044,8 +5902,16 @@
         token = next;
       }
     } else {
-      token = parseFields(beforeStart, externalToken, staticToken,
-          covariantToken, varFinalOrConst, beforeType, typeInfo, token, false);
+      token = parseFields(
+          beforeStart,
+          externalToken,
+          staticToken,
+          covariantToken,
+          varFinalOrConst,
+          beforeType,
+          typeInfo,
+          token.next,
+          false);
     }
 
     listener.endMember();
@@ -6078,6 +5944,8 @@
     if (token is ErrorToken) {
       reportErrorToken(token, true);
     } else {
+      // Find a non-synthetic token on which to report the error.
+      token = findNonSyntheticToken(token);
       listener.handleRecoverableError(message, token, token);
     }
   }
@@ -6099,6 +5967,8 @@
     if (token is ErrorToken) {
       reportErrorToken(token, true);
     } else {
+      // Find a non-synthetic token on which to report the error.
+      token = findNonSyntheticToken(token);
       listener.handleRecoverableError(
           template.withArguments(token), token, token);
     }
diff --git a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
index b8ab28e..529c38e 100644
--- a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
+++ b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
@@ -2,8 +2,6 @@
 // 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/util/link.dart';
-
 import '../../scanner/token.dart'
     show
         BeginToken,
@@ -41,49 +39,6 @@
   /// Initialize a newly created re-writer.
   TokenStreamRewriter();
 
-  /// For every `<` in [unbalancedLt] append a synthetic `>`.
-  /// Return the first `<`.
-  ///
-  /// [unbalancedLt] is a collection of `<` without closing `>` in the reverse
-  /// order from which they were encountered in the token stream.
-  Token balanceLt(final Token beforeLt, Token end, Link<Token> unbalancedLt) {
-    assert(optional('<', beforeLt.next));
-    assert(unbalancedLt.isNotEmpty);
-
-    BeginToken lt;
-    while (unbalancedLt.isNotEmpty) {
-      lt = unbalancedLt.head;
-      unbalancedLt = unbalancedLt.tail;
-      Token next = end.next;
-      Token gt;
-
-      if (optional('>', next)) {
-        gt = next;
-      } else if (optional('>>', next)) {
-        gt = new SimpleToken(TokenType.GT, next.charOffset)
-          ..setNext(new SimpleToken(TokenType.GT, next.charOffset + 1)
-            ..setNext(next.next));
-      } else if (optional('>=', next)) {
-        gt = new SimpleToken(TokenType.GT, next.charOffset)
-          ..setNext(new SimpleToken(TokenType.EQ, next.charOffset + 1)
-            ..setNext(next.next));
-      } else if (optional('>>=', next)) {
-        gt = new SimpleToken(TokenType.GT, next.charOffset)
-          ..setNext(new SimpleToken(TokenType.GT, next.charOffset + 1)
-            ..setNext(new SimpleToken(TokenType.EQ, next.charOffset + 2)
-              ..setNext(next.next)));
-      } else {
-        gt = new SyntheticToken(TokenType.GT, next.charOffset)..setNext(next);
-      }
-
-      lt.endGroup = gt;
-      end.setNext(gt);
-      end = gt;
-    }
-    assert(beforeLt.next == lt);
-    return lt;
-  }
-
   /// Insert a synthetic identifier after [token] and return the new identifier.
   Token insertSyntheticIdentifier(Token token) {
     Token identifier = new SyntheticStringToken(
@@ -136,31 +91,48 @@
     return replacementToken;
   }
 
-  /// Split a `>>` token into two separate `>` tokens and return the first `>`.
-  /// This sets [start].endGroup to the second `>` and updates the token stream,
-  /// but does not set the inner group's endGroup.
-  Token splitGtGt(BeginToken start) {
-    Token gtgt = start.endGroup;
-    assert(gtgt != null);
-    assert(optional('>>', gtgt));
+  /// Split a `>>` token into two separate `>` tokens, updates the token stream,
+  /// and returns the first `>`. If [start].endGroup is `>>` then sets
+  /// [start].endGroup to the second `>` but does not set the inner group's
+  /// endGroup, otherwise sets [start].endGroup to the first `>`.
+  Token splitEndGroup(BeginToken start, [Token end]) {
+    end ??= start.endGroup;
+    assert(end != null);
 
-    // A no-op rewriter could simply return `>>` here.
-
-    Token gt1 =
-        new SimpleToken(TokenType.GT, gtgt.charOffset, gtgt.precedingComments);
-    Token gt2 = gt1.setNext(new SimpleToken(TokenType.GT, gt1.charOffset + 1));
-    gt2.setNext(gtgt.next);
+    Token gt;
+    if (optional('>>', end)) {
+      gt = new SimpleToken(TokenType.GT, end.charOffset, end.precedingComments)
+        ..setNext(new SimpleToken(TokenType.GT, end.charOffset + 1)
+          ..setNext(end.next));
+    } else if (optional('>=', end)) {
+      gt = new SimpleToken(TokenType.GT, end.charOffset, end.precedingComments)
+        ..setNext(new SimpleToken(TokenType.EQ, end.charOffset + 1)
+          ..setNext(end.next));
+    } else if (optional('>>=', end)) {
+      gt = new SimpleToken(TokenType.GT, end.charOffset, end.precedingComments)
+        ..setNext(new SimpleToken(TokenType.GT, end.charOffset + 1)
+          ..setNext(new SimpleToken(TokenType.EQ, end.charOffset + 2)
+            ..setNext(end.next)));
+    } else {
+      gt = new SyntheticToken(TokenType.GT, end.charOffset)..setNext(end);
+    }
 
     Token token = start;
     Token next = token.next;
-    while (!identical(next, gtgt)) {
+    while (!identical(next, end)) {
       token = next;
       next = token.next;
     }
-    token.setNext(gt1);
+    token.setNext(gt);
 
-    start.endGroup = gt2;
-    return gt1;
+    if (start.endGroup != null) {
+      assert(optional('>>', start.endGroup));
+      start.endGroup = gt.next;
+    } else {
+      // Recovery
+      start.endGroup = gt;
+    }
+    return gt;
   }
 
   /// Given the [firstToken] in a chain of tokens to be inserted, return the
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info.dart b/pkg/front_end/lib/src/fasta/parser/type_info.dart
index 47f587f..c94e6f4 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info.dart
@@ -130,15 +130,19 @@
 /// Called by the parser to obtain information about a possible type reference
 /// that follows [token]. This does not modify the token stream.
 ///
+/// If [inDeclaration] is `true`, then this will more aggressively recover
+/// given unbalanced `<` `>` and invalid parameters or arguments.
+///
 /// If this method is called by [computeTypeParamOrArg] and the outer group ends
 /// with `>>`, then then [innerEndGroup] is set to either `>>` if the token
 /// has not been split or the first `>` if the `>>` token has been split.
-TypeInfo computeType(final Token token, bool required, [Token innerEndGroup]) {
+TypeInfo computeType(final Token token, bool required,
+    [bool inDeclaration = false, Token innerEndGroup]) {
   Token next = token.next;
   if (!isValidTypeReference(next)) {
     if (next.type.isBuiltIn) {
       TypeParamOrArgInfo typeParamOrArg =
-          computeTypeParamOrArg(next, innerEndGroup);
+          computeTypeParamOrArg(next, inDeclaration, innerEndGroup);
       if (typeParamOrArg != noTypeParamOrArg) {
         // Recovery: built-in `<` ... `>`
         if (required || looksLikeName(typeParamOrArg.skip(next).next)) {
@@ -159,7 +163,7 @@
     } else if (required && optional('.', next)) {
       // Recovery: looks like prefixed type missing the prefix
       return new ComplexTypeInfo(
-              token, computeTypeParamOrArg(next, innerEndGroup))
+              token, computeTypeParamOrArg(next, inDeclaration, innerEndGroup))
           .computePrefixedType(required);
     }
     return noType;
@@ -185,7 +189,7 @@
   // We've seen an identifier.
 
   TypeParamOrArgInfo typeParamOrArg =
-      computeTypeParamOrArg(next, innerEndGroup);
+      computeTypeParamOrArg(next, inDeclaration, innerEndGroup);
   if (typeParamOrArg != noTypeParamOrArg) {
     if (typeParamOrArg == simpleTypeArgument1) {
       // We've seen identifier `<` identifier `>`
@@ -215,7 +219,8 @@
     next = next.next;
     if (isValidTypeReference(next)) {
       // We've seen identifier `.` identifier
-      typeParamOrArg = computeTypeParamOrArg(next, innerEndGroup);
+      typeParamOrArg =
+          computeTypeParamOrArg(next, inDeclaration, innerEndGroup);
       next = next.next;
       if (typeParamOrArg == noTypeParamOrArg &&
           !isGeneralizedFunctionType(next)) {
@@ -233,7 +238,8 @@
     }
     // identifier `.` non-identifier
     if (required) {
-      typeParamOrArg = computeTypeParamOrArg(token.next.next, innerEndGroup);
+      typeParamOrArg =
+          computeTypeParamOrArg(token.next.next, inDeclaration, innerEndGroup);
       return new ComplexTypeInfo(token, typeParamOrArg)
           .computePrefixedType(required);
     }
@@ -255,47 +261,30 @@
 }
 
 /// Called by the parser to obtain information about a possible group of type
-/// parameters that follow [token] in a top level or class member declaration.
-/// It assumes that a leading `<` cannot be part of an expression, and thus
-/// tries to more aggressively recover given an unmatched '<'
-TypeParamOrArgInfo computeTypeParam(Token token) {
-  if (!optional('<', token.next)) {
-    return noTypeParamOrArg;
-  }
-  TypeParamOrArgInfo typeParam = computeTypeParamOrArgImpl(token);
-  if (typeParam != noTypeParamOrArg) {
-    return typeParam;
-  }
-
-  // Recovery
-  if (token.next.endGroup == null) {
-    // Attempt to find where the missing `>` should be inserted.
-    return new ComplexTypeParamOrArgInfo(token).computeRecovery();
-  } else {
-    // The `<` `>` are balanced but there's still a problem.
-    return noTypeParamOrArg;
-  }
-}
-
-/// Called by the parser to obtain information about a possible group of type
 /// parameters or type arguments that follow [token].
 /// This does not modify the token stream.
 ///
+/// If [inDeclaration] is `true`, then this will more aggressively recover
+/// given unbalanced `<` `>` and invalid parameters or arguments.
+///
 /// If this method is called by [computeType] and the outer group ends
 /// with `>>`, then then [innerEndGroup] is set to either `>>` if the token
 /// has not been split or the first `>` if the `>>` token has been split.
-TypeParamOrArgInfo computeTypeParamOrArg(Token token, [Token innerEndGroup]) {
-  return optional('<', token.next)
-      ? computeTypeParamOrArgImpl(token, innerEndGroup)
-      : noTypeParamOrArg;
-}
-
-TypeParamOrArgInfo computeTypeParamOrArgImpl(Token token,
-    [Token innerEndGroup]) {
+TypeParamOrArgInfo computeTypeParamOrArg(Token token,
+    [bool inDeclaration = false, Token innerEndGroup]) {
   Token next = token.next;
-  assert(optional('<', next));
+  if (!optional('<', next)) {
+    return noTypeParamOrArg;
+  }
   Token endGroup = next.endGroup ?? innerEndGroup;
   if (endGroup == null) {
+    if (inDeclaration) {
+      // Recovery
+      // Since the leading `<` cannot be part of an expression,
+      // try to more aggressively recover given an unbalanced '<'.
+      return new ComplexTypeParamOrArgInfo(token, inDeclaration)
+          .compute(innerEndGroup);
+    }
     return noTypeParamOrArg;
   }
   Token identifier = next.next;
@@ -306,7 +295,8 @@
     return simpleTypeArgument1;
   }
   // TODO(danrubel): Consider adding additional const for common situations.
-  return new ComplexTypeParamOrArgInfo(token).compute(innerEndGroup);
+  return new ComplexTypeParamOrArgInfo(token, inDeclaration)
+      .compute(innerEndGroup);
 }
 
 /// Called by the parser to obtain information about a possible group of type
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
index a18b898..461ebcc 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
@@ -4,7 +4,8 @@
 
 library fasta.parser.type_info_impl;
 
-import '../../scanner/token.dart' show BeginToken, Token;
+import '../../scanner/token.dart'
+    show BeginToken, SyntheticToken, Token, TokenType;
 
 import '../fasta_codes.dart' as fasta;
 
@@ -224,6 +225,19 @@
         // `typedef` is probably a separate declaration.
         (!optional('typedef', token) || !token.next.isIdentifier));
 
+/// When missing a comma, determine if the given token looks like it should
+/// be part of a collection of type parameters or arguments.
+bool looksLikeTypeParamOrArg(bool inDeclaration, Token token) {
+  if (inDeclaration && token.kind == IDENTIFIER_TOKEN) {
+    Token next = token.next;
+    if (next.kind == IDENTIFIER_TOKEN ||
+        isOneOf(next, const [',', '>', '>>'])) {
+      return true;
+    }
+  }
+  return false;
+}
+
 Token skipTypeVariables(Token token) {
   assert(optional('<', token));
   Token endGroup = token.endGroup;
@@ -358,9 +372,9 @@
     assert(identical(token, end) || optional('>', token));
 
     // During recovery, [token] may be a synthetic that was inserted in the
-    // middle of the type reference. In this situation, return [end] so that it
-    // matches [skipType], and so that the next token to be parsed is correct.
-    return token.isSynthetic ? end : token;
+    // middle of the type reference.
+    end = token;
+    return token;
   }
 
   @override
@@ -547,10 +561,12 @@
   @override
   Token skip(Token token) {
     token = token.next;
+    assert(optional('<', token));
     assert(token.endGroup != null ||
         (optional('>', token.next.next) || optional('>>', token.next.next)));
-    return token.endGroup ??
-        (optional('>>', token.next.next) ? token.next : token.next.next);
+    return (optional('>>', token.endGroup ?? token.next.next)
+        ? token.next
+        : token.next.next);
   }
 }
 
@@ -558,17 +574,18 @@
   /// The first token in the type var.
   final BeginToken start;
 
+  /// If [inDeclaration] is `true`, then this will more aggressively recover
+  /// given unbalanced `<` `>` and invalid parameters or arguments.
+  final bool inDeclaration;
+
   /// The last token in the group (typically `>`).
   /// If a `>>` has not yet been split, then this field will be
   /// `>>` for the outer group and the token before `>>` for the inner group.
   Token end;
 
-  /// A collection of `<` without closing `>` in the reverse order from which
-  /// they were encountered in the token stream.
-  Link<Token> unbalancedLt = const Link<Token>();
-
-  ComplexTypeParamOrArgInfo(Token token)
+  ComplexTypeParamOrArgInfo(Token token, this.inDeclaration)
       : assert(optional('<', token.next)),
+        assert(inDeclaration != null),
         start = token.next;
 
   /// Parse the tokens and return the receiver or [noTypeParamOrArg] if there
@@ -586,12 +603,12 @@
 
     Token token;
     Token next = start;
-    do {
-      TypeInfo typeInfo = computeType(next, true, innerEndGroup);
+    while (true) {
+      TypeInfo typeInfo = computeType(next, true, inDeclaration, innerEndGroup);
       if (typeInfo == noType) {
         while (typeInfo == noType && optional('@', next.next)) {
           next = skipMetadata(next);
-          typeInfo = computeType(next, true, innerEndGroup);
+          typeInfo = computeType(next, true, inDeclaration, innerEndGroup);
         }
         if (typeInfo == noType && !optional(',', next.next)) {
           token = next;
@@ -604,10 +621,17 @@
       token = typeInfo.skipType(next);
       next = token.next;
       if (optional('extends', next) || optional('super', next)) {
-        token = computeType(next, true, innerEndGroup).skipType(next);
+        token = computeType(next, true, inDeclaration, innerEndGroup)
+            .skipType(next);
         next = token.next;
       }
-    } while (optional(',', next));
+      if (!optional(',', next)) {
+        if (!looksLikeTypeParamOrArg(inDeclaration, next)) {
+          break;
+        }
+        // Recovery: Missing comma. Continue looping
+      }
+    }
 
     if (next == start.endGroup) {
       end = next;
@@ -616,96 +640,62 @@
       assert(optional('>', endGroup) || optional('>>', endGroup));
       // If `>>`, then the end or last consumed token is the token before `>>`.
       end = optional('>>', next) ? token : next;
+    } else if (inDeclaration && start.endGroup == null) {
+      // Recovery: Unbalanced `<`
+      end = token;
     } else {
       return noTypeParamOrArg;
     }
     return this;
   }
 
-  /// Parse the tokens and return the receiver or [noTypeParamOrArg] if there
-  /// are no type parameters or arguments. This does not modify the token
-  /// stream.
-  ///
-  /// This is called when parsing type parameters in a top level
-  /// or class member declaration. It assumes that a leading `<` cannot be part
-  /// of an expression, and thus tries to more aggressively recover
-  /// given an unmatched '<'.
-  ///
-  TypeParamOrArgInfo computeRecovery() {
-    assert(start.endGroup == null);
-    unbalancedLt = unbalancedLt.prepend(start);
-    Token token = start;
-    Token next = token.next;
-    while (!next.isEof) {
-      if (optional('Function', next)) {
-        next = next.next;
-        if (optional('<', next)) {
-          next = skipTypeVariables(next);
-          if (next == null) {
-            break;
-          }
-          next = next.next;
-        }
-        if (optional('(', next)) {
-          next = next.endGroup;
-        } else {
-          break;
-        }
-      } else if (optional('<', next)) {
-        Token endGroup = skipTypeVariables(next);
-        if (endGroup != null) {
-          next = endGroup;
-        } else {
-          unbalancedLt = unbalancedLt.prepend(next);
-        }
-      } else if (!isValidTypeReference(next) &&
-          !isOneOf(next, const ['.', ',', 'extends', 'super'])) {
-        break;
-      }
-      token = next;
-      next = token.next;
-    }
-
-    end = token;
-    return this;
-  }
-
   @override
   Token parseArguments(Token token, Parser parser) {
-    Token begin = balanceLt(token, parser);
-    Token next = begin;
-    Token innerEndGroup = processBeginGroup(begin, parser);
-    parser.listener.beginTypeArguments(begin);
+    Token next = start;
+    Token innerEndGroup = processBeginGroup(start, parser);
+    parser.listener.beginTypeArguments(start);
     int count = 0;
-    do {
-      TypeInfo typeInfo = computeType(next, true, innerEndGroup);
+    while (true) {
+      TypeInfo typeInfo = computeType(next, true, inDeclaration, innerEndGroup);
       if (typeInfo == noType) {
         // Recovery
         while (typeInfo == noType && optional('@', next.next)) {
           parser.reportRecoverableErrorWithToken(
               next.next, fasta.templateUnexpectedToken);
           next = skipMetadata(next);
-          typeInfo = computeType(next, true, innerEndGroup);
+          typeInfo = computeType(next, true, inDeclaration, innerEndGroup);
         }
         // Fall through to process type (if any) and consume `,`
       }
       token = typeInfo.ensureTypeOrVoid(next, parser);
       next = token.next;
       ++count;
-    } while (optional(',', next));
-    end = processEndGroup(token, begin, parser);
-    parser.listener.endTypeArguments(count, begin, end);
+      if (!optional(',', next)) {
+        if (!looksLikeTypeParamOrArg(inDeclaration, next)) {
+          break;
+        }
+
+        // Recovery: missing comma
+        parser.reportRecoverableError(
+            next, fasta.templateExpectedButGot.withArguments(','));
+        next = parser.rewriter
+            .insertTokenAfter(
+                token, new SyntheticToken(TokenType.COMMA, next.charOffset))
+            .next;
+      }
+    }
+    end = processEndGroup(token, start, parser);
+    parser.listener.endTypeArguments(count, start, end);
     return end;
   }
 
   @override
   Token parseVariables(Token token, Parser parser) {
-    Token begin = balanceLt(token, parser);
-    Token next = begin;
-    Token innerEndGroup = processBeginGroup(begin, parser);
-    parser.listener.beginTypeVariables(begin);
+    Token next = start;
+    Token innerEndGroup = processBeginGroup(start, parser);
+    parser.listener.beginTypeVariables(start);
     int count = 0;
-    do {
+    while (true) {
       parser.listener.beginTypeVariable(next.next);
       token = parser.parseMetadataStar(next);
       token = parser.ensureIdentifier(
@@ -714,7 +704,7 @@
       next = token.next;
       if (optional('extends', next) || optional('super', next)) {
         extendsOrSuper = next;
-        token = computeType(next, true, innerEndGroup)
+        token = computeType(next, true, inDeclaration, innerEndGroup)
             .ensureTypeOrVoid(next, parser);
         next = token.next;
       } else {
@@ -722,72 +712,67 @@
       }
       parser.listener.endTypeVariable(next, extendsOrSuper);
       ++count;
-    } while (optional(',', next));
-    end = processEndGroup(token, begin, parser);
-    parser.listener.endTypeVariables(count, begin, end);
+      if (!optional(',', next)) {
+        if (!looksLikeTypeParamOrArg(inDeclaration, next)) {
+          break;
+        }
+
+        // Recovery: missing comma
+        parser.reportRecoverableError(
+            next, fasta.templateExpectedButGot.withArguments(','));
+        next = parser.rewriter
+            .insertTokenAfter(
+                token, new SyntheticToken(TokenType.COMMA, next.charOffset))
+            .next;
+      }
+    }
+    end = processEndGroup(token, start, parser);
+    parser.listener.endTypeVariables(count, start, end);
     return end;
   }
 
   @override
   Token skip(Token token) => end;
-
-  /// For every unbalanced `<` append a synthetic `>`. Return the first `<`
-  Token balanceLt(Token token, Parser parser) {
-    assert(identical(start, token.next));
-    if (unbalancedLt.isEmpty) {
-      return start;
-    }
-    Token begin = parser.rewriter.balanceLt(token, end, unbalancedLt);
-    assert(begin.endGroup != null);
-    if (begin.endGroup.isSynthetic) {
-      parser.reportRecoverableError(
-          begin.endGroup.next, fasta.templateExpectedButGot.withArguments('>'));
-    }
-    return begin;
-  }
 }
 
 Token processBeginGroup(BeginToken start, Parser parser) {
-  Token innerEndGroup;
   if (start.endGroup != null && optional('>>', start.endGroup)) {
-    innerEndGroup = parser.rewriter.splitGtGt(start);
+    return parser.rewriter.splitEndGroup(start);
   }
-  return innerEndGroup;
+  return null;
 }
 
 Token processEndGroup(Token token, BeginToken start, Parser parser) {
   Token next = token.next;
   if (next == start.endGroup) {
     return next;
-  } else if (optional('>', next)) {
+  } else if (optional('>', next) && !next.isSynthetic) {
     // When `>>` is split, the inner group's endGroup updated here.
     assert(start.endGroup == null);
     start.endGroup = next;
     return next;
-  } else if (optional('>>', next)) {
-    // In this case, the last consumed token is the token before `>>`.
-    return token;
-  } else {
-    // Recovery
-    parser.reportRecoverableErrorWithToken(next, fasta.templateUnexpectedToken);
-    if (start.endGroup != null) {
-      return start.endGroup;
-    }
-    while (true) {
-      if (optional('>', next)) {
-        start.endGroup = next;
-        return next;
-      }
-      if (optional('>>', next)) {
-        // In this case, the last consumed token is the token before `>>`.
-        return token;
-      }
-      if (next.isEof) {
-        // Sanity check.
-        return next;
-      }
-      token = next;
-      next = token.next;
-    }
   }
+
+  // Recovery
+  if (start.endGroup != null) {
+    // Extraneous tokens between `<` and `>`.
+    parser.reportRecoverableErrorWithToken(next, fasta.templateUnexpectedToken);
+    return start.endGroup;
+  } else if (isOneOf(next, const ['>>', '>=', '>>='])) {
+    // Found single unbalanced `<`.
+    return parser.rewriter.splitEndGroup(start, next);
+  }
+  // Ensure that `>` is inserted after any newly inserted synthetic tokens.
+  while (next.isSynthetic && !next.isEof) {
+    token = next;
+    next = token.next;
+  }
+  // Unbalanced `<` `>`
+  parser.reportRecoverableError(
+      next, fasta.templateExpectedButGot.withArguments('>'));
+  start.endGroup = parser.rewriter
+      .insertTokenAfter(
+          token, new SyntheticToken(TokenType.GT, next.charOffset))
+      .next;
+  return start.endGroup;
 }
diff --git a/pkg/front_end/lib/src/fasta/parser/util.dart b/pkg/front_end/lib/src/fasta/parser/util.dart
index bbbd361..96495e7 100644
--- a/pkg/front_end/lib/src/fasta/parser/util.dart
+++ b/pkg/front_end/lib/src/fasta/parser/util.dart
@@ -33,6 +33,16 @@
   return token;
 }
 
+/// Return [token] if it is non-synthetic,
+/// otherwise find the next non-synthetic token.
+/// This may return EOF if there are no more non-synthetic tokens in the stream.
+Token findNonSyntheticToken(Token token) {
+  while (token.isSynthetic && !token.isEof) {
+    token = token.next;
+  }
+  return token;
+}
+
 /// A null-aware alternative to `token.offset`.  If [token] is `null`, returns
 /// `TreeNode.noOffset`.
 int offsetForToken(Token token) {
@@ -89,7 +99,7 @@
         next = token.next;
       }
     }
-    if (optional('(', next)) {
+    if (optional('(', next) && !next.endGroup.isSynthetic) {
       token = next.endGroup;
       next = token.next;
     }
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index b4639f1..58f6ebc 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -9,6 +9,7 @@
         AsyncMarker,
         Class,
         Expression,
+        Field,
         InterfaceType,
         Library,
         LibraryDependency,
@@ -33,8 +34,7 @@
 
 import '../kernel/kernel_body_builder.dart' show KernelBodyBuilder;
 
-import '../parser.dart'
-    show Assert, IdentifierContext, MemberKind, Parser, optional;
+import '../parser.dart' show Assert, MemberKind, Parser, optional;
 
 import '../problems.dart' show internalProblem, unexpected;
 
@@ -90,7 +90,9 @@
   @override
   void endMetadataStar(int count) {
     debugEvent("MetadataStar");
-    push(popList(count)?.first ?? NullValue.Metadata);
+    push(popList(count, new List<Token>.filled(count, null, growable: true))
+            ?.first ??
+        NullValue.Metadata);
   }
 
   @override
@@ -272,15 +274,6 @@
   }
 
   @override
-  void handleIdentifier(Token token, IdentifierContext context) {
-    if (context == IdentifierContext.enumValueDeclaration) {
-      // Discard the metadata.
-      pop();
-    }
-    super.handleIdentifier(token, context);
-  }
-
-  @override
   void handleQualified(Token period) {
     debugEvent("handleQualified");
     String suffix = pop();
@@ -574,7 +567,8 @@
   }
 
   void buildFields(int count, Token token, bool isTopLevel) {
-    List<String> names = popList(count);
+    List<String> names =
+        popList(count, new List<String>.filled(count, null, growable: true));
     Builder builder = lookupBuilder(token, null, names.first);
     Token metadata = pop();
     // TODO(paulberry): don't re-parse the field if we've already parsed it
@@ -640,11 +634,13 @@
   void endEnum(Token enumKeyword, Token leftBrace, int count) {
     debugEvent("Enum");
 
-    discard(count); // values
+    List metadataAndValues = new List.filled(count * 2, null, growable: true);
+    popList(count * 2, metadataAndValues);
+
     String name = pop();
     Token metadata = pop();
 
-    Builder enumBuilder = lookupBuilder(enumKeyword, null, name);
+    ClassBuilder enumBuilder = lookupBuilder(enumKeyword, null, name);
     Class target = enumBuilder.target;
     var metadataConstants = parseMetadata(enumBuilder, metadata);
     if (metadataConstants != null) {
@@ -652,6 +648,17 @@
         target.addAnnotation(metadataConstant);
       }
     }
+    for (int i = 0; i < metadataAndValues.length; i += 2) {
+      Token metadata = metadataAndValues[i];
+      String valueName = metadataAndValues[i + 1];
+      Builder builder = enumBuilder.scope.local[valueName];
+      if (metadata != null) {
+        Field field = builder.target;
+        for (var annotation in parseMetadata(builder, metadata)) {
+          field.addAnnotation(annotation);
+        }
+      }
+    }
 
     checkEmpty(enumKeyword.charOffset);
   }
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 8244fca..64f66b9 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -10,6 +10,8 @@
 
 import '../builder/builder.dart';
 
+import '../builder/metadata_builder.dart' show ExpressionMetadataBuilder;
+
 import '../combinator.dart' show Combinator;
 
 import '../fasta_codes.dart'
@@ -66,6 +68,13 @@
 
 import '../configuration.dart' show Configuration;
 
+import '../kernel/kernel_builder.dart'
+    show
+        KernelFormalParameterBuilder,
+        KernelNamedTypeBuilder,
+        KernelTypeBuilder,
+        KernelTypeVariableBuilder;
+
 enum MethodBody {
   Abstract,
   Regular,
@@ -129,7 +138,11 @@
   @override
   void endMetadataStar(int count) {
     debugEvent("MetadataStar");
-    push(popList(count) ?? NullValue.Metadata);
+    push(popList(
+            count,
+            new List<ExpressionMetadataBuilder<TypeBuilder>>.filled(count, null,
+                growable: true)) ??
+        NullValue.Metadata);
   }
 
   @override
@@ -155,7 +168,9 @@
   @override
   void endCombinators(int count) {
     debugEvent("Combinators");
-    push(popList(count) ?? NullValue.Combinators);
+    push(popList(
+            count, new List<Combinator>.filled(count, null, growable: true)) ??
+        NullValue.Combinators);
   }
 
   @override
@@ -202,7 +217,9 @@
   @override
   void endConditionalUris(int count) {
     debugEvent("EndConditionalUris");
-    push(popList(count) ?? NullValue.ConditionalUris);
+    push(popList(count,
+            new List<Configuration>.filled(count, null, growable: true)) ??
+        NullValue.ConditionalUris);
   }
 
   @override
@@ -259,8 +276,6 @@
   @override
   void handleIdentifier(Token token, IdentifierContext context) {
     if (context == IdentifierContext.enumValueDeclaration) {
-      // Discard the metadata.
-      pop();
       super.handleIdentifier(token, context);
       push(token.charOffset);
       String documentationComment = getDocumentationComment(token);
@@ -388,7 +403,11 @@
   @override
   void handleClassImplements(Token implementsKeyword, int interfacesCount) {
     debugEvent("handleClassImplements");
-    push(popList(interfacesCount) ?? NullValue.TypeBuilderList);
+    push(popList(
+            interfacesCount,
+            new List<KernelNamedTypeBuilder>.filled(interfacesCount, null,
+                growable: true)) ??
+        NullValue.TypeBuilderList);
   }
 
   @override
@@ -730,7 +749,9 @@
   @override
   void endTypeArguments(int count, Token beginToken, Token endToken) {
     debugEvent("TypeArguments");
-    push(popList(count) ?? NullValue.TypeArguments);
+    push(popList(count,
+            new List<KernelTypeBuilder>.filled(count, null, growable: true)) ??
+        NullValue.TypeArguments);
   }
 
   @override
@@ -750,13 +771,21 @@
   @override
   void endTypeList(int count) {
     debugEvent("TypeList");
-    push(popList(count) ?? NullValue.TypeList);
+    push(popList(
+            count,
+            new List<KernelNamedTypeBuilder>.filled(count, null,
+                growable: true)) ??
+        NullValue.TypeList);
   }
 
   @override
   void endTypeVariables(int count, Token beginToken, Token endToken) {
     debugEvent("TypeVariables");
-    push(popList(count) ?? NullValue.TypeVariables);
+    push(popList(
+            count,
+            new List<KernelTypeVariableBuilder>.filled(count, null,
+                growable: true)) ??
+        NullValue.TypeVariables);
   }
 
   @override
@@ -819,7 +848,9 @@
     // 0. It might be simpler if the parser didn't call this method in that
     // case, however, then [beginOptionalFormalParameters] wouldn't always be
     // matched by this method.
-    List parameters = popList(count) ?? [];
+    var parameters = new List<KernelFormalParameterBuilder>.filled(count, null,
+        growable: true);
+    popList(count, parameters);
     for (FormalParameterBuilder parameter in parameters) {
       parameter.kind = kind;
     }
@@ -910,7 +941,8 @@
   @override
   void endEnum(Token enumKeyword, Token leftBrace, int count) {
     String documentationComment = getDocumentationComment(enumKeyword);
-    List constantNamesAndOffsets = popList(count * 3);
+    List<Object> constantNamesAndOffsets = popList(
+        count * 4, new List<Object>.filled(count * 4, null, growable: true));
     int charOffset = pop();
     String name = pop();
     List<MetadataBuilder> metadata = pop();
@@ -1007,7 +1039,8 @@
   void endTopLevelFields(Token staticToken, Token covariantToken,
       Token varFinalOrConst, int count, Token beginToken, Token endToken) {
     debugEvent("endTopLevelFields");
-    List fieldsInfo = popList(count * 4);
+    List<Object> fieldsInfo = popList(
+        count * 4, new List<Object>.filled(count * 4, null, growable: true));
     TypeBuilder type = pop();
     int modifiers = (staticToken != null ? staticMask : 0) |
         (covariantToken != null ? covariantMask : 0) |
@@ -1023,7 +1056,8 @@
   void endFields(Token staticToken, Token covariantToken, Token varFinalOrConst,
       int count, Token beginToken, Token endToken) {
     debugEvent("Fields");
-    List fieldsInfo = popList(count * 4);
+    List<Object> fieldsInfo = popList(
+        count * 4, new List<Object>.filled(count * 4, null, growable: true));
     TypeBuilder type = pop();
     int modifiers = (staticToken != null ? staticMask : 0) |
         (covariantToken != null ? covariantMask : 0) |
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 5b02dc9..7507777 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -664,7 +664,7 @@
     TypeEnvironment env = new TypeEnvironment(coreTypes, hierarchy,
         strongMode: target.strongMode);
 
-    if (cls.isSyntheticMixinImplementation) return;
+    if (cls.isAnonymousMixin) return;
 
     if (env.isSubtypeOf(a.asInterfaceType, b.asInterfaceType)) return;
     addProblem(
diff --git a/pkg/front_end/lib/src/fasta/source/stack_listener.dart b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
index ef9eda1..dd5fc5d 100644
--- a/pkg/front_end/lib/src/fasta/source/stack_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
@@ -121,7 +121,7 @@
     return value == null ? null : pop();
   }
 
-  List popList(int n, [List list]) {
+  List popList(int n, List list) {
     if (n == 0) return null;
     return stack.popList(n, list);
   }
@@ -314,7 +314,9 @@
   @override
   void handleStringJuxtaposition(int literalCount) {
     debugEvent("StringJuxtaposition");
-    push(popList(literalCount).join(""));
+    push(popList(literalCount,
+            new List<Expression>.filled(literalCount, null, growable: true))
+        .join(""));
   }
 
   @override
@@ -396,16 +398,15 @@
     final table = array;
     final length = arrayLength;
 
-    final tailList = list ?? new List.filled(count, null, growable: true);
     final startIndex = length - count;
     for (int i = 0; i < count; i++) {
       final value = table[startIndex + i];
-      tailList[i] = value is NullValue ? null : value;
+      list[i] = value is NullValue ? null : value;
       table[startIndex + i] = null;
     }
     arrayLength -= count;
 
-    return tailList;
+    return list;
   }
 
   List get values {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 58c6532..361dd77 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -1634,7 +1634,7 @@
       Supertype baseType, Supertype mixinSupertype) {
     if (mixinSupertype.typeArguments.isEmpty) {
       // The supertype constraint isn't generic; it doesn't constrain anything.
-    } else if (mixinSupertype.classNode.isSyntheticMixinImplementation) {
+    } else if (mixinSupertype.classNode.isAnonymousMixin) {
       // We had a mixin M<X0, ..., Xn> with a superclass constraint of the form
       // S0 with M0 where S0 and M0 each possibly have type arguments.  That has
       // been compiled a named mixin application class of the form
diff --git a/pkg/front_end/lib/src/fasta/util/link.dart b/pkg/front_end/lib/src/fasta/util/link.dart
index 86c1c70..4debdc7 100644
--- a/pkg/front_end/lib/src/fasta/util/link.dart
+++ b/pkg/front_end/lib/src/fasta/util/link.dart
@@ -61,7 +61,7 @@
   bool get isEmpty => true;
   bool get isNotEmpty => false;
 
-  Link<T> reverse() => this;
+  Link<T> reverse(Link<T> tail) => this;
 
   Link<T> reversePrependAll(Link<T> from) {
     if (from.isEmpty) return this;
@@ -121,8 +121,6 @@
     return true;
   }
 
-  Link copyWithout(e) => this;
-
   //
   // Unsupported Iterable<T> methods.
   //
@@ -159,7 +157,7 @@
 
   /// Prepends all elements added to the builder to [tail]. The resulting list
   /// is returned and the builder is cleared.
-  Link<T> toLink([Link<T> tail = const Link()]);
+  Link<T> toLink(Link<T> tail);
 
   /// Creates a new fixed length containing all added elements. The
   /// resulting list is returned and the builder is cleared.
diff --git a/pkg/front_end/lib/src/fasta/util/link_implementation.dart b/pkg/front_end/lib/src/fasta/util/link_implementation.dart
index cc74c01..9849ecb 100644
--- a/pkg/front_end/lib/src/fasta/util/link_implementation.dart
+++ b/pkg/front_end/lib/src/fasta/util/link_implementation.dart
@@ -64,8 +64,7 @@
   final T head;
   Link<T> tail;
 
-  LinkEntry(this.head, [Link<T> tail])
-      : this.tail = ((tail == null) ? const Link() : tail);
+  LinkEntry(this.head, [Link<T> tail]) : tail = tail ?? const Link<Null>();
 
   Link<T> prepend(T element) {
     // TODO(ahe): Use new Link<T>, but this cost 8% performance on VM.
@@ -89,8 +88,9 @@
     return buffer.toString();
   }
 
-  Link<T> reverse() {
-    Link<T> result = const Link();
+  @override
+  Link<T> reverse(Link<T> tail) {
+    Link<T> result = tail;
     for (Link<T> link = this; link.isNotEmpty; link = link.tail) {
       result = result.prepend(link.head);
     }
@@ -147,17 +147,6 @@
     }
     return length;
   }
-
-  Link copyWithout(e) {
-    LinkBuilder copy = new LinkBuilder();
-    Link link = this;
-    for (; link.isNotEmpty; link = link.tail) {
-      if (link.head != e) {
-        copy.addLast(link.head);
-      }
-    }
-    return copy.toLink(link);
-  }
 }
 
 class LinkBuilderImplementation<T> implements LinkBuilder<T> {
@@ -167,7 +156,8 @@
 
   LinkBuilderImplementation();
 
-  Link<T> toLink([Link<T> tail = const Link()]) {
+  @override
+  Link<T> toLink(Link<T> tail) {
     if (head == null) return tail;
     lastLink.tail = tail;
     Link<T> link = head;
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 1e8e061..440aab5 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1940,12 +1940,6 @@
 ExpressionNotMetadata:
   template: "This can't be used as metadata; metadata should be a reference to a compile-time constant variable, or a call to a constant constructor."
 
-AnnotationOnEnumConstant:
-  template: "Enum constants can't have annotations."
-  tip: "Try removing the annotation."
-  analyzerCode: ANNOTATION_ON_ENUM_CONSTANT
-  dart2jsCode: "*fatal*"
-
 ExpectedAnInitializer:
   template: "Expected an initializer."
   analyzerCode: MISSING_INITIALIZER
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 90c0247..64cdab5 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,7 +1,7 @@
 name: front_end
 # Currently, front_end API is not stable and users should not
 # depend on semver semantics when depending on this package.
-version: 0.1.0
+version: 0.1.1-alpha.0
 author: Dart Team <misc@dartlang.org>
 description: Front end for compilation of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/front_end
@@ -11,7 +11,7 @@
   charcode: '^1.1.1'
   convert: '^2.0.1'
   crypto: '^2.0.2'
-  kernel: 0.3.0
+  kernel: 0.3.1-alpha.0
   meta: '^1.1.1'
   package_config: '^1.0.1'
   path: '^1.3.9'
diff --git a/pkg/front_end/test/fasta/expression_test.dart b/pkg/front_end/test/fasta/expression_test.dart
index ee97b9d..ee56f71 100644
--- a/pkg/front_end/test/fasta/expression_test.dart
+++ b/pkg/front_end/test/fasta/expression_test.dart
@@ -370,7 +370,7 @@
     };
 
   final ProcessedOptions options =
-      new ProcessedOptions(optionBuilder, false, [entryPoint]);
+      new ProcessedOptions(optionBuilder, [entryPoint]);
 
   final ExternalStateSnapshot snapshot =
       new ExternalStateSnapshot(await options.loadSdkSummary(null));
diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart
index 53b70fe..50c8ffc 100644
--- a/pkg/front_end/test/fasta/generator_to_string_test.dart
+++ b/pkg/front_end/test/fasta/generator_to_string_test.dart
@@ -53,27 +53,27 @@
 
 import 'package:front_end/src/fasta/kernel/kernel_expression_generator.dart'
     show
-        DeferredAccessGenerator,
         DelayedAssignment,
         DelayedPostfixIncrement,
         IncompleteErrorGenerator,
         IncompletePropertyAccessGenerator,
+        KernelDeferredAccessGenerator,
         KernelIndexedAccessGenerator,
+        KernelLargeIntAccessGenerator,
+        KernelLoadLibraryGenerator,
         KernelNullAwarePropertyAccessGenerator,
         KernelPropertyAccessGenerator,
+        KernelReadOnlyAccessGenerator,
+        KernelStaticAccessGenerator,
+        KernelSuperIndexedAccessGenerator,
         KernelSuperPropertyAccessGenerator,
         KernelThisIndexedAccessGenerator,
         KernelThisPropertyAccessGenerator,
+        KernelTypeUseGenerator,
         KernelVariableUseGenerator,
-        LargeIntAccessGenerator,
-        LoadLibraryGenerator,
         ParenthesizedExpressionGenerator,
-        ReadOnlyAccessGenerator,
         SendAccessGenerator,
-        StaticAccessGenerator,
-        SuperIndexedAccessGenerator,
         ThisAccessGenerator,
-        TypeDeclarationAccessGenerator,
         UnresolvedNameGenerator;
 
 import 'package:front_end/src/fasta/scanner.dart' show Token, scanString;
@@ -186,15 +186,16 @@
     check(
         "SuperIndexedAccessGenerator(offset: 4, index: index,"
         " getter: $uri::myGetter, setter: $uri::mySetter, indexVariable: null)",
-        new SuperIndexedAccessGenerator(helper, token, index, getter, setter));
+        new KernelSuperIndexedAccessGenerator(
+            helper, token, index, getter, setter));
     check(
         "StaticAccessGenerator(offset: 4, readTarget: $uri::myGetter,"
         " writeTarget: $uri::mySetter)",
-        new StaticAccessGenerator(helper, token, getter, setter));
+        new KernelStaticAccessGenerator(helper, token, getter, setter));
     check(
         "LoadLibraryGenerator(offset: 4,"
         " builder: Instance of 'LoadLibraryBuilder')",
-        new LoadLibraryGenerator(helper, token, loadLibraryBuilder));
+        new KernelLoadLibraryGenerator(helper, token, loadLibraryBuilder));
     check(
         "ThisAccessGenerator(offset: 4, isInitializer: false, isSuper: false)",
         new ThisAccessGenerator(helper, token, false));
@@ -205,25 +206,26 @@
     check("IncompletePropertyAccessGenerator(offset: 4, name: bar)",
         new IncompletePropertyAccessGenerator(helper, token, name));
     check(
-        "DeferredAccessGenerator(offset: 4, "
-        "builder: Instance of 'PrefixBuilder',"
+        "DeferredAccessGenerator(offset: 4,"
+        " builder: Instance of 'PrefixBuilder',"
         " generator: ThisAccessGenerator(offset: 4, isInitializer: false,"
         " isSuper: false))",
-        new DeferredAccessGenerator(helper, token, prefixBuilder, generator));
+        new KernelDeferredAccessGenerator(
+            helper, token, prefixBuilder, generator));
     check(
         "ReadOnlyAccessGenerator(offset: 4, expression: expression,"
         " plainNameForRead: foo, value: null)",
-        new ReadOnlyAccessGenerator(helper, token, expression, "foo"));
+        new KernelReadOnlyAccessGenerator(helper, token, expression, "foo"));
     check("LargeIntAccessGenerator(offset: 4, lexeme: myToken)",
-        new LargeIntAccessGenerator(helper, token));
+        new KernelLargeIntAccessGenerator(helper, token));
     check(
         "ParenthesizedExpressionGenerator(offset: 4, expression: expression,"
         " plainNameForRead: null, value: null)",
         new ParenthesizedExpressionGenerator(helper, token, expression));
     check(
-        "TypeDeclarationAccessGenerator(offset: 4, expression: T,"
+        "TypeUseGenerator(offset: 4, expression: T,"
         " plainNameForRead: foo, value: null)",
-        new TypeDeclarationAccessGenerator(
+        new KernelTypeUseGenerator(
             helper, token, prefixBuilder, -1, declaration, "foo"));
     check("UnresolvedNameGenerator(offset: 4, name: bar)",
         new UnresolvedNameGenerator(helper, token, name));
diff --git a/pkg/front_end/test/fasta/incremental_hello_test.dart b/pkg/front_end/test/fasta/incremental_hello_test.dart
index f096675..40fb9d3 100644
--- a/pkg/front_end/test/fasta/incremental_hello_test.dart
+++ b/pkg/front_end/test/fasta/incremental_hello_test.dart
@@ -50,7 +50,7 @@
   final Uri helloDart = Uri.base.resolve("pkg/front_end/testcases/hello.dart");
 
   final ProcessedOptions options =
-      new ProcessedOptions(optionBuilder, false, [helloDart]);
+      new ProcessedOptions(optionBuilder, [helloDart]);
 
   IncrementalCompiler compiler =
       new IncrementalCompiler(new CompilerContext(options));
diff --git a/pkg/front_end/test/fasta/incremental_test.dart b/pkg/front_end/test/fasta/incremental_test.dart
index 3d2fb2a..401d89b 100644
--- a/pkg/front_end/test/fasta/incremental_test.dart
+++ b/pkg/front_end/test/fasta/incremental_test.dart
@@ -227,7 +227,7 @@
     };
 
   final ProcessedOptions options =
-      new ProcessedOptions(optionBuilder, false, [entryPoint]);
+      new ProcessedOptions(optionBuilder, [entryPoint]);
 
   final ExternalStateSnapshot snapshot =
       new ExternalStateSnapshot(await options.loadSdkSummary(null));
diff --git a/pkg/front_end/test/fasta/link_test.dart b/pkg/front_end/test/fasta/link_test.dart
new file mode 100644
index 0000000..5fe7b42
--- /dev/null
+++ b/pkg/front_end/test/fasta/link_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:front_end/src/fasta/util/link.dart' show Link, LinkBuilder;
+
+import 'package:expect/expect.dart' show Expect;
+
+main() {
+  Link<String> strings = const Link<String>().prepend("B").prepend("A");
+  Expect.stringEquals("[ A, B ]", "${strings}");
+  Expect.stringEquals("[ B, A ]", "${strings.reverse(const Link<String>())}");
+
+  strings = (new LinkBuilder<String>()..addLast("A")..addLast("B"))
+      .toLink(const Link<String>());
+
+  Expect.stringEquals("[ A, B ]", "${strings}");
+  Expect.stringEquals("[ B, A ]", "${strings.reverse(const Link<String>())}");
+
+  strings = new LinkBuilder<String>()
+      .toLink(const Link<String>())
+      .prepend("B")
+      .prepend("A");
+
+  Expect.stringEquals("[ A, B ]", "${strings}");
+  Expect.stringEquals("[ B, A ]", "${strings.reverse(const Link<String>())}");
+
+  strings = const Link<String>()
+      .reverse(const Link<String>())
+      .prepend("B")
+      .prepend("A");
+  Expect.stringEquals("[ A, B ]", "${strings}");
+  Expect.stringEquals("[ B, A ]", "${strings.reverse(const Link<String>())}");
+
+  strings = (new LinkBuilder<String>()..addLast("A")..addLast("B"))
+      .toLink(const Link<String>());
+
+  Expect.stringEquals("[ A, B ]", "${strings}");
+  Expect.stringEquals("[ B, A ]", "${strings.reverse(const Link<String>())}");
+
+  Link<int> ints =
+      const Link<int>().prepend(1).reverse(const Link<int>()).tail.prepend(1);
+  Expect.stringEquals("[ 1 ]", "${ints}");
+}
diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart
index 4790175..d2d53a5 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:front_end/src/fasta/messages.dart';
 import 'package:front_end/src/fasta/parser.dart';
-import 'package:front_end/src/fasta/parser/token_stream_rewriter.dart';
+import 'package:front_end/src/fasta/parser/type_continuation.dart';
 import 'package:front_end/src/fasta/parser/type_info.dart';
 import 'package:front_end/src/fasta/parser/type_info_impl.dart';
 import 'package:front_end/src/fasta/scanner.dart';
@@ -229,47 +229,6 @@
         simpleTypeWith1Argument.parseType(start, new Parser(listener)));
   }
 
-  void test_simpleTypeArgumentsInfo2() {
-    final Token start = scanString('before S<C<T>> ;').tokens.next.next;
-    expect(start.lexeme, '<');
-    final Token expectedEnd = start.next.next.next;
-    expect(expectedEnd.next.lexeme, '>>');
-
-    expect(simpleTypeWith1Argument.skipType(start), expectedEnd);
-    expect(simpleTypeWith1Argument.couldBeExpression, isFalse);
-
-    TypeInfoListener listener;
-    assertResult(Token actualEnd) {
-      expect(actualEnd, expectedEnd);
-      expect(listener.calls, [
-        'handleIdentifier C typeReference',
-        'beginTypeArguments <',
-        'handleIdentifier T typeReference',
-        'handleNoTypeArguments >>',
-        'handleType T >>',
-        'endTypeArguments 1 < T',
-        'handleType C >>',
-      ]);
-      expect(listener.errors, isNull);
-    }
-
-    listener = new TypeInfoListener();
-    assertResult(
-        simpleTypeWith1Argument.ensureTypeNotVoid(start, new Parser(listener)));
-
-    listener = new TypeInfoListener();
-    assertResult(
-        simpleTypeWith1Argument.ensureTypeOrVoid(start, new Parser(listener)));
-
-    listener = new TypeInfoListener();
-    assertResult(
-        simpleTypeWith1Argument.parseTypeNotVoid(start, new Parser(listener)));
-
-    listener = new TypeInfoListener();
-    assertResult(
-        simpleTypeWith1Argument.parseType(start, new Parser(listener)));
-  }
-
   void test_computeType_basic() {
     expectInfo(noType, '');
     expectInfo(noType, ';');
@@ -564,23 +523,25 @@
     // TOOD(danrubel): dynamic, do, other keywords, malformed, recovery
     // <T>
 
-    // TODO(danrubel): Improve missing comma recovery
     expectTypeParamOrArg(noTypeParamOrArg, 'G<int double> g');
-    // expectComplexInfo('G<int double> g',
-    //     required: true,
-    //     tokenAfter: 'g',
-    //     expectedCalls: [
-    //       'handleIdentifier G typeReference',
-    //       'beginTypeArguments <',
-    //       'handleIdentifier int typeReference',
-    //       'handleNoTypeArguments double',
-    //       'handleType int double',
-    //       'endTypeArguments 1 < >',
-    //       'handleType G g',
-    //     ],
-    //     expectedErrors: [
-    //       error(codeExpectedToken, 6, 6)
-    //     ]);
+    expectComplexInfo('G<int double> g',
+        inDeclaration: true,
+        expectedAfter: 'g',
+        expectedCalls: [
+          'handleIdentifier G typeReference',
+          'beginTypeArguments <',
+          'handleIdentifier int typeReference',
+          'handleNoTypeArguments double' /* was , */,
+          'handleType int double' /* was , */,
+          'handleIdentifier double typeReference',
+          'handleNoTypeArguments >',
+          'handleType double >',
+          'endTypeArguments 2 < >',
+          'handleType G g',
+        ],
+        expectedErrors: [
+          error(codeExpectedButGot, 6, 6)
+        ]);
 
     expectInfo(noType, 'C<>', required: false);
     expectComplexInfo('C<>', required: true, expectedCalls: [
@@ -912,43 +873,6 @@
     expect(listener.errors, isNull);
   }
 
-  void test_simple_parseArguments2() {
-    final Token start = scanString('before <S<T>> after').tokens.next.next;
-    Token t = start.next.next;
-    expect(t.next.lexeme, '>>');
-    final TypeInfoListener listener = new TypeInfoListener();
-
-    expect(simpleTypeArgument1.parseArguments(start, new Parser(listener)), t);
-    expect(listener.calls, [
-      'beginTypeArguments <',
-      'handleIdentifier T typeReference',
-      'handleNoTypeArguments >>',
-      'handleType T >>',
-      'endTypeArguments 1 < T'
-    ]);
-    expect(listener.errors, isNull);
-  }
-
-  void test_simple_parseVariables2() {
-    final Token start = scanString('before <S<T>> after').tokens.next.next;
-    Token t = start.next.next;
-    expect(t.next.lexeme, '>>');
-    final TypeInfoListener listener = new TypeInfoListener();
-
-    expect(simpleTypeArgument1.parseVariables(start, new Parser(listener)), t);
-    expect(listener.calls, [
-      'beginTypeVariables <',
-      'beginTypeVariable T',
-      'beginMetadataStar T',
-      'endMetadataStar 0',
-      'handleIdentifier T typeVariableDeclaration',
-      'handleNoType T',
-      'endTypeVariable T null',
-      'endTypeVariables 1 < T',
-    ]);
-    expect(listener.errors, isNull);
-  }
-
   void test_computeTypeParamOrArg_basic() {
     expectTypeParamOrArg(noTypeParamOrArg, '');
     expectTypeParamOrArg(noTypeParamOrArg, 'a');
@@ -969,7 +893,7 @@
     Token gtgt = start.next.next.next;
     expect(gtgt.lexeme, '>>');
 
-    TypeParamOrArgInfo typeVarInfo = computeTypeParamOrArg(start, gtgt);
+    TypeParamOrArgInfo typeVarInfo = computeTypeParamOrArg(start, false, gtgt);
     expect(typeVarInfo, simpleTypeArgument1, reason: source);
   }
 
@@ -1017,17 +941,6 @@
       'handleType S >',
       'endTypeArguments 1 < >'
     ]);
-    expectComplexTypeArg('<S<T>>', splitGtGt: false, expectedCalls: [
-      'beginTypeArguments <',
-      'handleIdentifier S typeReference',
-      'beginTypeArguments <',
-      'handleIdentifier T typeReference',
-      'handleNoTypeArguments >>',
-      'handleType T >>',
-      'endTypeArguments 1 < T',
-      'handleType S >>',
-      'endTypeArguments 1 < >>'
-    ]);
     expectComplexTypeArg('<S<Function()>>', expectedCalls: [
       'beginTypeArguments <',
       'handleIdentifier S typeReference',
@@ -1042,20 +955,6 @@
       'handleType S >',
       'endTypeArguments 1 < >'
     ]);
-    expectComplexTypeArg('<S<Function()>>', splitGtGt: false, expectedCalls: [
-      'beginTypeArguments <',
-      'handleIdentifier S typeReference',
-      'beginTypeArguments <',
-      'handleNoTypeVariables (',
-      'beginFunctionType Function',
-      'handleNoType <',
-      'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
-      'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
-      'endFunctionType Function >>',
-      'endTypeArguments 1 < )',
-      'handleType S >>',
-      'endTypeArguments 1 < >>'
-    ]);
     expectComplexTypeArg('<S<void Function()>>', expectedCalls: [
       'beginTypeArguments <',
       'handleIdentifier S typeReference',
@@ -1070,22 +969,6 @@
       'handleType S >',
       'endTypeArguments 1 < >'
     ]);
-    expectComplexTypeArg('<S<void Function()>>',
-        splitGtGt: false,
-        expectedCalls: [
-          'beginTypeArguments <',
-          'handleIdentifier S typeReference',
-          'beginTypeArguments <',
-          'handleNoTypeVariables (',
-          'beginFunctionType void', // was 'beginFunctionType Function'
-          'handleVoidKeyword void', // was 'handleNoType <'
-          'beginFormalParameters ( MemberKind.GeneralizedFunctionType',
-          'endFormalParameters 0 ( ) MemberKind.GeneralizedFunctionType',
-          'endFunctionType Function >>',
-          'endTypeArguments 1 < )',
-          'handleType S >>',
-          'endTypeArguments 1 < >>'
-        ]);
   }
 
   void test_computeTypeArg_complex_recovery() {
@@ -1107,18 +990,6 @@
       'handleType S extends',
       'endTypeArguments 1 < >',
     ]);
-    expectComplexTypeArg('<S extends List<T>>',
-        splitGtGt: false,
-        expectedErrors: [
-          error(codeUnexpectedToken, 3, 7)
-        ],
-        expectedCalls: [
-          'beginTypeArguments <',
-          'handleIdentifier S typeReference',
-          'handleNoTypeArguments extends',
-          'handleType S extends',
-          'endTypeArguments 1 < >>',
-        ]);
     expectComplexTypeArg('<@A S,T>', expectedErrors: [
       error(codeUnexpectedToken, 1, 1)
     ], expectedCalls: [
@@ -1156,6 +1027,14 @@
       'handleType T >',
       'endTypeArguments 2 < >'
     ]);
+    expectComplexTypeArg('<S T>',
+        inDeclaration: true, expectedErrors: [error(codeExpectedButGot, 3, 1)]);
+    expectComplexTypeArg('<S',
+        inDeclaration: true, expectedErrors: [error(codeExpectedButGot, 2, 0)]);
+    expectComplexTypeArg('<@Foo S', inDeclaration: true, expectedErrors: [
+      error(codeUnexpectedToken, 1, 1),
+      error(codeExpectedButGot, 7, 0)
+    ]);
   }
 
   void test_computeTypeParam_complex() {
@@ -1215,24 +1094,6 @@
       'endTypeVariable > extends',
       'endTypeVariables 1 < >',
     ]);
-    expectComplexTypeParam('<S extends List<T>>',
-        splitGtGt: false,
-        expectedCalls: [
-          'beginTypeVariables <',
-          'beginTypeVariable S',
-          'beginMetadataStar S',
-          'endMetadataStar 0',
-          'handleIdentifier S typeVariableDeclaration',
-          'handleIdentifier List typeReference',
-          'beginTypeArguments <',
-          'handleIdentifier T typeReference',
-          'handleNoTypeArguments >>',
-          'handleType T >>',
-          'endTypeArguments 1 < T',
-          'handleType List >>',
-          'endTypeVariable >> extends',
-          'endTypeVariables 1 < >>',
-        ]);
     expectComplexTypeParam('<R, S extends void Function()>', expectedCalls: [
       'beginTypeVariables <',
       'beginTypeVariable R',
@@ -1364,21 +1225,14 @@
       'endTypeVariable < null',
       'endTypeVariables 1 < >',
     ]);
-    expectComplexTypeParam('<S<T>>',
-        expectedErrors: [
-          error(codeUnexpectedToken, 2, 1),
-        ],
-        splitGtGt: false,
-        expectedCalls: [
-          'beginTypeVariables <',
-          'beginTypeVariable S',
-          'beginMetadataStar S',
-          'endMetadataStar 0',
-          'handleIdentifier S typeVariableDeclaration',
-          'handleNoType S',
-          'endTypeVariable < null',
-          'endTypeVariables 1 < >>',
-        ]);
+    expectComplexTypeParam('<S T>', inDeclaration: true, expectedErrors: [
+      error(codeExpectedButGot, 3, 1),
+    ]);
+    expectComplexTypeParam('<S', inDeclaration: true, expectedErrors: [
+      error(codeExpectedButGot, 2, 0),
+    ]);
+    expectComplexTypeParam('<@Foo S',
+        inDeclaration: true, expectedErrors: [error(codeExpectedButGot, 7, 0)]);
   }
 }
 
@@ -1393,17 +1247,18 @@
 
 void expectComplexInfo(String source,
     {bool required,
+    bool inDeclaration = false,
     String expectedAfter,
     List<String> expectedCalls,
     List<ExpectedError> expectedErrors}) {
   if (required == null) {
-    computeComplex(source, scan(source), true, expectedAfter, expectedCalls,
-        expectedErrors);
-    computeComplex(source, scan(source), false, expectedAfter, expectedCalls,
-        expectedErrors);
+    computeComplex(source, scan(source), true, inDeclaration, expectedAfter,
+        expectedCalls, expectedErrors);
+    computeComplex(source, scan(source), false, inDeclaration, expectedAfter,
+        expectedCalls, expectedErrors);
   } else {
-    computeComplex(source, scan(source), required, expectedAfter, expectedCalls,
-        expectedErrors);
+    computeComplex(source, scan(source), required, inDeclaration, expectedAfter,
+        expectedCalls, expectedErrors);
   }
 }
 
@@ -1425,9 +1280,10 @@
 }
 
 TypeInfo compute(expectedInfo, String source, Token start, bool required,
-    {Token innerEndGroup}) {
+    {bool inDeclaration = false, Token innerEndGroup}) {
   int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
-  TypeInfo typeInfo = computeType(start, required, innerEndGroup);
+  TypeInfo typeInfo =
+      computeType(start, required, inDeclaration, innerEndGroup);
   expect(typeInfo, expectedInfo, reason: source);
   expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
       reason: 'computeType should not modify the token stream');
@@ -1438,12 +1294,14 @@
     String source,
     Token start,
     bool required,
+    bool inDeclaration,
     String expectedAfter,
     List<String> expectedCalls,
     List<ExpectedError> expectedErrors) {
   int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
-  ComplexTypeInfo typeInfo =
-      compute(const isInstanceOf<ComplexTypeInfo>(), source, start, required);
+  ComplexTypeInfo typeInfo = compute(
+      const isInstanceOf<ComplexTypeInfo>(), source, start, required,
+      inDeclaration: inDeclaration);
   expect(typeInfo.start, start.next, reason: source);
   expect(typeInfo.couldBeExpression, isFalse);
   expectEnd(expectedAfter, typeInfo.skipType(start));
@@ -1455,29 +1313,35 @@
 
   expectEnd(expectedAfter, actualEnd);
   if (expectedCalls != null) {
-    // TypeInfoListener listener2 = new TypeInfoListener();
-    // new Parser(listener2).parseType(start, TypeContinuation.Required);
-    // print('[');
-    // for (String call in listener2.calls) {
-    //   print("'$call',");
-    // }
-    // print(']');
-
-    expect(listener.calls, expectedCalls, reason: source);
+    try {
+      expect(listener.calls, expectedCalls, reason: source);
+    } catch (e) {
+      TypeInfoListener listener2 = new TypeInfoListener();
+      new Parser(listener2).parseType(start, TypeContinuation.Required);
+      print('[');
+      for (String call in listener2.calls) {
+        print("'$call',");
+      }
+      print(']');
+      rethrow;
+    }
   }
   expect(listener.errors, expectedErrors, reason: source);
   return typeInfo;
 }
 
 void expectComplexTypeArg(String source,
-    {bool splitGtGt: true,
+    {bool inDeclaration = false,
     String expectedAfter,
     List<String> expectedCalls,
     List<ExpectedError> expectedErrors}) {
   Token start = scan(source);
   int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
   ComplexTypeParamOrArgInfo typeVarInfo = computeVar(
-      const isInstanceOf<ComplexTypeParamOrArgInfo>(), source, start);
+      const isInstanceOf<ComplexTypeParamOrArgInfo>(),
+      source,
+      start,
+      inDeclaration);
 
   expect(typeVarInfo.start, start.next, reason: source);
   expectEnd(expectedAfter, typeVarInfo.skip(start));
@@ -1487,16 +1351,8 @@
 
   TypeInfoListener listener = new TypeInfoListener();
   Parser parser = new Parser(listener);
-  if (!splitGtGt) {
-    parser.cachedRewriter = new TokenStreamNonRewriter();
-  }
   Token actualEnd = typeVarInfo.parseArguments(start, parser);
   expectEnd(expectedAfter, actualEnd);
-  if (!splitGtGt) {
-    expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
-        reason: 'TypeParamOrArgInfo.parseArguments'
-            ' should not modify the token stream');
-  }
 
   if (expectedCalls != null) {
     try {
@@ -1516,14 +1372,17 @@
 }
 
 void expectComplexTypeParam(String source,
-    {bool splitGtGt: true,
+    {bool inDeclaration = false,
     String expectedAfter,
     List<String> expectedCalls,
     List<ExpectedError> expectedErrors}) {
   Token start = scan(source);
   int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
   ComplexTypeParamOrArgInfo typeVarInfo = computeVar(
-      const isInstanceOf<ComplexTypeParamOrArgInfo>(), source, start);
+      const isInstanceOf<ComplexTypeParamOrArgInfo>(),
+      source,
+      start,
+      inDeclaration);
 
   expect(typeVarInfo.start, start.next, reason: source);
   expectEnd(expectedAfter, typeVarInfo.skip(start));
@@ -1533,16 +1392,8 @@
 
   TypeInfoListener listener = new TypeInfoListener(metadataAllowed: true);
   Parser parser = new Parser(listener);
-  if (!splitGtGt) {
-    parser.cachedRewriter = new TokenStreamNonRewriter();
-  }
   Token actualEnd = typeVarInfo.parseVariables(start, parser);
   expectEnd(expectedAfter, actualEnd);
-  if (!splitGtGt) {
-    expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
-        reason: 'TypeParamOrArgInfo.parseVariables'
-            ' should not modify the token stream');
-  }
 
   if (expectedCalls != null) {
     try {
@@ -1562,17 +1413,18 @@
 }
 
 void expectTypeParamOrArg(expectedInfo, String source,
-    {bool splitGtGt: true,
+    {bool inDeclaration = false,
     String expectedAfter,
     List<String> expectedCalls,
     List<ExpectedError> expectedErrors}) {
   Token start = scan(source);
-  computeVar(expectedInfo, source, start);
+  computeVar(expectedInfo, source, start, inDeclaration);
 }
 
-TypeParamOrArgInfo computeVar(expectedInfo, String source, Token start) {
+TypeParamOrArgInfo computeVar(
+    expectedInfo, String source, Token start, bool inDeclaration) {
   int expectedGtGtAndNullEndCount = countGtGtAndNullEnd(start);
-  TypeParamOrArgInfo typeVarInfo = computeTypeParamOrArg(start);
+  TypeParamOrArgInfo typeVarInfo = computeTypeParamOrArg(start, inDeclaration);
   expect(typeVarInfo, expectedInfo, reason: source);
   expect(countGtGtAndNullEnd(start), expectedGtGtAndNullEndCount,
       reason: 'computeTypeParamOrArg should not modify the token stream');
@@ -1812,15 +1664,3 @@
   @override
   String toString() => 'error(${code.name}, $start, $length)';
 }
-
-class TokenStreamNonRewriter implements TokenStreamRewriter {
-  @override
-  Token splitGtGt(BeginToken start) {
-    Token gtgt = start.endGroup;
-    assert(gtgt != null);
-    assert(optional('>>', gtgt));
-    return gtgt;
-  }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
diff --git a/pkg/front_end/test/fasta/testing/analyzer_diet_listener.dart b/pkg/front_end/test/fasta/testing/analyzer_diet_listener.dart
index e0f5f3e..01ac3d2 100644
--- a/pkg/front_end/test/fasta/testing/analyzer_diet_listener.dart
+++ b/pkg/front_end/test/fasta/testing/analyzer_diet_listener.dart
@@ -58,7 +58,8 @@
 
   @override
   void buildFields(int count, Token token, bool isTopLevel) {
-    List<String> names = popList(count);
+    List<String> names =
+        popList(count, new List<String>.filled(count, null, growable: true));
     Builder builder = lookupBuilder(token, null, names.first);
     Token metadata = pop();
     AstBuilder listener =
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index ee0b49b..39f0bfc 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -247,7 +247,7 @@
     File generated = new File.fromUri(uri);
     StdioProcess process;
     try {
-      var args = [];
+      var args = <String>[];
       if (context.strongMode) {
         args.add('--strong');
         args.add('--reify-generic-functions');
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
index 5089798..156b814 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -444,9 +444,7 @@
 
   TestIncrementalCompiler(CompilerOptions options, Uri entryPoint,
       [Uri initializeFrom])
-      : super(
-            new CompilerContext(
-                new ProcessedOptions(options, false, [entryPoint])),
+      : super(new CompilerContext(new ProcessedOptions(options, [entryPoint])),
             initializeFrom);
 
   @override
diff --git a/pkg/front_end/test/incremental_utils.dart b/pkg/front_end/test/incremental_utils.dart
index c8480bf..ef4626a 100644
--- a/pkg/front_end/test/incremental_utils.dart
+++ b/pkg/front_end/test/incremental_utils.dart
@@ -33,7 +33,7 @@
   int empty = 0;
   for (Library lib in component.libraries) {
     for (Class c in lib.classes) {
-      if (c.isSyntheticMixinImplementation) {
+      if (c.isAnonymousMixin) {
         for (Procedure p in c.procedures) {
           if (p.function.body is EmptyStatement) {
             empty++;
diff --git a/pkg/front_end/test/kernel_generator_test.dart b/pkg/front_end/test/kernel_generator_test.dart
index 736cb2f..2ad6012 100644
--- a/pkg/front_end/test/kernel_generator_test.dart
+++ b/pkg/front_end/test/kernel_generator_test.dart
@@ -177,26 +177,9 @@
       expect(errors, isEmpty);
     });
 
-    test('compiler by default is hermetic', () async {
+    test('compiler is not hermetic by default', () async {
       var errors = [];
       var options = new CompilerOptions()..onError = (e) => errors.add(e);
-      var sources = {
-        'a.dart': 'import "b.dart"; a() => print("hi");',
-        'b.dart': ''
-      };
-      await compileUnit(['a.dart'], sources, options: options);
-      expect(errors.first.message, contains('Invalid access'));
-      errors.clear();
-
-      await compileUnit(['a.dart', 'b.dart'], sources, options: options);
-      expect(errors, isEmpty);
-    });
-
-    test('chaseDependencies=true removes hermetic restriction', () async {
-      var errors = [];
-      var options = new CompilerOptions()
-        ..chaseDependencies = true
-        ..onError = (e) => errors.add(e);
       await compileUnit([
         'a.dart'
       ], {
diff --git a/pkg/front_end/test/scheme_based_file_system_test.dart b/pkg/front_end/test/scheme_based_file_system_test.dart
new file mode 100644
index 0000000..be40f65
--- /dev/null
+++ b/pkg/front_end/test/scheme_based_file_system_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:front_end/src/api_prototype/file_system.dart';
+import 'package:front_end/src/api_prototype/scheme_based_file_system.dart';
+
+import 'package:test/test.dart';
+
+main() {
+  test('lookup of registered schemes is handled', () {
+    var fs1 = new MockFileSystem('scheme1');
+    var fs2 = new MockFileSystem('scheme2');
+    var fileSystem =
+        new SchemeBasedFileSystem({'scheme1': fs1, 'scheme2': fs2});
+
+    MockFileSystemEntity e1 =
+        fileSystem.entityForUri(Uri.parse('scheme1:a.dart'));
+    MockFileSystemEntity e2 =
+        fileSystem.entityForUri(Uri.parse('scheme2:a.dart'));
+    expect(e1.fileSystem, fs1);
+    expect(e2.fileSystem, fs2);
+  });
+
+  test('lookup of an unregistered scheme will throw', () {
+    var fileSystem =
+        new SchemeBasedFileSystem({'scheme1': new MockFileSystem('scheme1')});
+    expect(() => fileSystem.entityForUri(Uri.parse('scheme2:a.dart')),
+        throwsA((e) => e is FileSystemException));
+  });
+}
+
+class MockFileSystem implements FileSystem {
+  String scheme;
+  MockFileSystem(this.scheme);
+
+  @override
+  FileSystemEntity entityForUri(Uri uri) {
+    if (uri.scheme != scheme) throw "unsupported";
+    return new MockFileSystemEntity(uri, this);
+  }
+}
+
+class MockFileSystemEntity implements FileSystemEntity {
+  final Uri uri;
+  final FileSystem fileSystem;
+  MockFileSystemEntity(this.uri, this.fileSystem);
+
+  noSuchMethod(m) => super.noSuchMethod(m);
+}
diff --git a/pkg/front_end/test/src/base/processed_options_test.dart b/pkg/front_end/test/src/base/processed_options_test.dart
index 2ce4498..8d29cbe 100644
--- a/pkg/front_end/test/src/base/processed_options_test.dart
+++ b/pkg/front_end/test/src/base/processed_options_test.dart
@@ -239,8 +239,8 @@
         .entityForUri(Uri.parse('org-dartlang-test:///base/location/.packages'))
         .writeAsStringSync('foo:baz\n');
     var raw = new CompilerOptions()..fileSystem = fileSystem;
-    var processed = new ProcessedOptions(raw, false,
-        [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
+    var processed = new ProcessedOptions(
+        raw, [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
     var uriTranslator = await processed.getUriTranslator();
     checkPackageExpansion('foo', 'base/location/baz', uriTranslator.packages);
   }
@@ -259,8 +259,8 @@
         .entityForUri(Uri.parse('org-dartlang-test:///base/.packages'))
         .writeAsStringSync('foo:baz\n');
     var raw = new CompilerOptions()..fileSystem = fileSystem;
-    var processed = new ProcessedOptions(raw, false,
-        [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
+    var processed = new ProcessedOptions(
+        raw, [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
     var uriTranslator = await processed.getUriTranslator();
     checkPackageExpansion('foo', 'base/baz', uriTranslator.packages);
   }
@@ -282,8 +282,8 @@
         .entityForUri(Uri.parse('org-dartlang-test:///base/.packages'))
         .writeAsStringSync('foo:baz\n');
     var raw = new CompilerOptions()..fileSystem = fileSystem;
-    var processed = new ProcessedOptions(raw, false,
-        [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
+    var processed = new ProcessedOptions(
+        raw, [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
     var uriTranslator = await processed.getUriTranslator();
     checkPackageExpansion(
         'foo', 'base/location/packages/foo', uriTranslator.packages);
@@ -299,8 +299,8 @@
     var raw = new CompilerOptions()
       ..fileSystem = fileSystem
       ..onError = (e) => errors.add(e);
-    var processed = new ProcessedOptions(raw, false,
-        [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
+    var processed = new ProcessedOptions(
+        raw, [Uri.parse('org-dartlang-test:///base/location/script.dart')]);
     var uriTranslator = await processed.getUriTranslator();
     expect(errors, isEmpty);
     expect(uriTranslator.packages.asMap(), isEmpty);
@@ -342,7 +342,7 @@
     var raw = new CompilerOptions()
       ..fileSystem = fileSystem
       ..onError = (e) => errors.add(e);
-    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
+    var options = new ProcessedOptions(raw, [Uri.parse('foo.dart')]);
     var result = await options.validateOptions();
     expect(errors.single.message,
         startsWith(_stringPrefixOf(templateInputFileNotFound)));
@@ -368,7 +368,7 @@
       ..sdkRoot = sdkRoot
       ..fileSystem = fileSystem
       ..onError = (e) => errors.add(e);
-    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
+    var options = new ProcessedOptions(raw, [Uri.parse('foo.dart')]);
     var result = await options.validateOptions();
     // Note: we check this first so test failures show the cause directly.
     expect(errors, isEmpty);
@@ -385,7 +385,7 @@
       ..sdkRoot = sdkRoot
       ..fileSystem = fileSystem
       ..onError = (e) => errors.add(e);
-    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
+    var options = new ProcessedOptions(raw, [Uri.parse('foo.dart')]);
     expect(await options.validateOptions(), isFalse);
     expect(errors.first.message,
         startsWith(_stringPrefixOf(templateSdkRootNotFound)));
@@ -403,7 +403,7 @@
       ..sdkSummary = sdkSummary
       ..fileSystem = fileSystem
       ..onError = (e) => errors.add(e);
-    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
+    var options = new ProcessedOptions(raw, [Uri.parse('foo.dart')]);
     var result = await options.validateOptions();
     expect(errors, isEmpty);
     expect(result, isTrue);
@@ -419,7 +419,7 @@
       ..sdkSummary = sdkSummary
       ..fileSystem = fileSystem
       ..onError = (e) => errors.add(e);
-    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
+    var options = new ProcessedOptions(raw, [Uri.parse('foo.dart')]);
     expect(await options.validateOptions(), isFalse);
     expect(errors.single.message,
         startsWith(_stringPrefixOf(templateSdkSummaryNotFound)));
@@ -440,7 +440,7 @@
       ..sdkRoot = sdkRoot
       ..fileSystem = fileSystem
       ..onError = (e) => errors.add(e);
-    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
+    var options = new ProcessedOptions(raw, [Uri.parse('foo.dart')]);
     var result = await options.validateOptions();
     expect(errors, isEmpty);
     expect(result, isTrue);
@@ -458,7 +458,7 @@
       ..sdkSummary = sdkSummary
       ..fileSystem = fileSystem
       ..onError = (e) => errors.add(e);
-    var options = new ProcessedOptions(raw, false, [Uri.parse('foo.dart')]);
+    var options = new ProcessedOptions(raw, [Uri.parse('foo.dart')]);
     expect(await options.validateOptions(), isFalse);
     expect(errors.single.message,
         startsWith(_stringPrefixOf(templateSdkSummaryNotFound)));
diff --git a/pkg/front_end/test/src/incremental/kernel_driver_test.dart b/pkg/front_end/test/src/incremental/kernel_driver_test.dart
index 7568239..0b33811 100644
--- a/pkg/front_end/test/src/incremental/kernel_driver_test.dart
+++ b/pkg/front_end/test/src/incremental/kernel_driver_test.dart
@@ -987,7 +987,6 @@
       ..fileSystem = fileSystem
       ..sdkRoot = Uri.parse('org-dartlang-test:///sdk/')
       ..compileSdk = true
-      ..chaseDependencies = true
       ..strongMode = true
       ..target = new NoneTarget(new TargetFlags(strongMode: true));
     var inputs = [Uri.parse('dart:core')];
diff --git a/pkg/front_end/test/summary_generator_test.dart b/pkg/front_end/test/summary_generator_test.dart
index 435e5ec..3588ea8 100644
--- a/pkg/front_end/test/summary_generator_test.dart
+++ b/pkg/front_end/test/summary_generator_test.dart
@@ -118,14 +118,10 @@
         component.libraries.single.importUri.path.endsWith('b.dart'), isTrue);
   });
 
-  test('summarization by default is hermetic', () async {
+  test('summarization by default is not hermetic', () async {
     var errors = [];
     var options = new CompilerOptions()..onError = (e) => errors.add(e);
     await summarize(['b.dart'], allSources, options: options);
-    expect(errors.first.toString(), contains('Invalid access'));
-    errors.clear();
-
-    await summarize(['a.dart', 'b.dart'], allSources, options: options);
     expect(errors, isEmpty);
   });
 
diff --git a/pkg/front_end/testcases/annotation_on_enum_values.dart b/pkg/front_end/testcases/annotation_on_enum_values.dart
new file mode 100644
index 0000000..29dba81
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_on_enum_values.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This test checks that annotations on enum values are preserved by the
+// compiler.
+
+const int hest = 42;
+
+class Fisk<T> {
+  final T x;
+  const Fisk.fisk(this.x);
+}
+
+enum Foo {
+  @hest bar,
+  @Fisk.fisk(hest) baz,
+  cafebabe,
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/annotation_on_enum_values.dart.direct.expect b/pkg/front_end/testcases/annotation_on_enum_values.dart.direct.expect
new file mode 100644
index 0000000..246f4cb
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_on_enum_values.dart.direct.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Fisk<T extends core::Object = dynamic> extends core::Object {
+  final field self::Fisk::T x;
+  const constructor fisk(self::Fisk::T x) → void
+    : self::Fisk::x = x, super core::Object::•()
+    ;
+}
+class Foo extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::Foo> values = const <self::Foo>[self::Foo::bar, self::Foo::baz, self::Foo::cafebabe];
+  @self::hest
+  static const field self::Foo bar = const self::Foo::•(0, "Foo.bar");
+  @self::Fisk::fisk<dynamic>(self::hest)
+  static const field self::Foo baz = const self::Foo::•(1, "Foo.baz");
+  static const field self::Foo cafebabe = const self::Foo::•(2, "Foo.cafebabe");
+  const constructor •(core::int index, core::String _name) → void
+    : self::Foo::index = index, self::Foo::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::Foo::_name};
+}
+static const field core::int hest = 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/annotation_on_enum_values.dart.direct.transformed.expect b/pkg/front_end/testcases/annotation_on_enum_values.dart.direct.transformed.expect
new file mode 100644
index 0000000..246f4cb
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_on_enum_values.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Fisk<T extends core::Object = dynamic> extends core::Object {
+  final field self::Fisk::T x;
+  const constructor fisk(self::Fisk::T x) → void
+    : self::Fisk::x = x, super core::Object::•()
+    ;
+}
+class Foo extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::Foo> values = const <self::Foo>[self::Foo::bar, self::Foo::baz, self::Foo::cafebabe];
+  @self::hest
+  static const field self::Foo bar = const self::Foo::•(0, "Foo.bar");
+  @self::Fisk::fisk<dynamic>(self::hest)
+  static const field self::Foo baz = const self::Foo::•(1, "Foo.baz");
+  static const field self::Foo cafebabe = const self::Foo::•(2, "Foo.cafebabe");
+  const constructor •(core::int index, core::String _name) → void
+    : self::Foo::index = index, self::Foo::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::Foo::_name};
+}
+static const field core::int hest = 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/annotation_on_enum_values.dart.outline.expect b/pkg/front_end/testcases/annotation_on_enum_values.dart.outline.expect
new file mode 100644
index 0000000..02c5c32
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_on_enum_values.dart.outline.expect
@@ -0,0 +1,25 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Fisk<T extends core::Object = dynamic> extends core::Object {
+  final field self::Fisk::T x;
+  const constructor fisk(self::Fisk::T x) → void
+    ;
+}
+class Foo extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::Foo> values = const <self::Foo>[self::Foo::bar, self::Foo::baz, self::Foo::cafebabe];
+  static const field self::Foo bar = const self::Foo::•(0, "Foo.bar");
+  static const field self::Foo baz = const self::Foo::•(1, "Foo.baz");
+  static const field self::Foo cafebabe = const self::Foo::•(2, "Foo.cafebabe");
+  const constructor •(core::int index, core::String _name) → void
+    : self::Foo::index = index, self::Foo::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::Foo::_name};
+}
+static const field core::int hest;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/annotation_on_enum_values.dart.strong.expect b/pkg/front_end/testcases/annotation_on_enum_values.dart.strong.expect
new file mode 100644
index 0000000..2c026ab
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_on_enum_values.dart.strong.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Fisk<T extends core::Object = dynamic> extends core::Object {
+  final field self::Fisk::T x;
+  const constructor fisk(self::Fisk::T x) → void
+    : self::Fisk::x = x, super core::Object::•()
+    ;
+}
+class Foo extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::Foo> values = const <self::Foo>[self::Foo::bar, self::Foo::baz, self::Foo::cafebabe];
+  @self::hest
+  static const field self::Foo bar = const self::Foo::•(0, "Foo.bar");
+  @self::Fisk::fisk<core::int>(self::hest)
+  static const field self::Foo baz = const self::Foo::•(1, "Foo.baz");
+  static const field self::Foo cafebabe = const self::Foo::•(2, "Foo.cafebabe");
+  const constructor •(core::int index, core::String _name) → void
+    : self::Foo::index = index, self::Foo::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::Foo::_name};
+}
+static const field core::int hest = 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/annotation_on_enum_values.dart.strong.transformed.expect b/pkg/front_end/testcases/annotation_on_enum_values.dart.strong.transformed.expect
new file mode 100644
index 0000000..2c026ab
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_on_enum_values.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Fisk<T extends core::Object = dynamic> extends core::Object {
+  final field self::Fisk::T x;
+  const constructor fisk(self::Fisk::T x) → void
+    : self::Fisk::x = x, super core::Object::•()
+    ;
+}
+class Foo extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::Foo> values = const <self::Foo>[self::Foo::bar, self::Foo::baz, self::Foo::cafebabe];
+  @self::hest
+  static const field self::Foo bar = const self::Foo::•(0, "Foo.bar");
+  @self::Fisk::fisk<core::int>(self::hest)
+  static const field self::Foo baz = const self::Foo::•(1, "Foo.baz");
+  static const field self::Foo cafebabe = const self::Foo::•(2, "Foo.cafebabe");
+  const constructor •(core::int index, core::String _name) → void
+    : self::Foo::index = index, self::Foo::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::Foo::_name};
+}
+static const field core::int hest = 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/ast_builder.status b/pkg/front_end/testcases/ast_builder.status
index 1301285..6e166ec 100644
--- a/pkg/front_end/testcases/ast_builder.status
+++ b/pkg/front_end/testcases/ast_builder.status
@@ -4,6 +4,7 @@
 
 # Status file for the ast_builder_test.dart test suite. This is testing
 # generating analyzer ASTs and connecting up type inference information.
+annotation_on_enum_values: Crash
 annotation_top: Crash
 argument_mismatch: Fail
 bug32629: Fail
diff --git a/pkg/front_end/testcases/bug33196.dart b/pkg/front_end/testcases/bug33196.dart
new file mode 100644
index 0000000..e2f01f1
--- /dev/null
+++ b/pkg/front_end/testcases/bug33196.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2018, 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';
+
+main() {
+  var result = returnsString();
+  print(result.runtimeType);
+}
+
+FutureOr<String> returnsString() async {
+  return "oh no";
+}
diff --git a/pkg/front_end/testcases/bug33196.dart.direct.expect b/pkg/front_end/testcases/bug33196.dart.direct.expect
new file mode 100644
index 0000000..4baad60
--- /dev/null
+++ b/pkg/front_end/testcases/bug33196.dart.direct.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method main() → dynamic {
+  dynamic result = self::returnsString();
+  core::print(result.runtimeType);
+}
+static method returnsString() → asy::FutureOr<core::String> async {
+  return "oh no";
+}
diff --git a/pkg/front_end/testcases/bug33196.dart.direct.transformed.expect b/pkg/front_end/testcases/bug33196.dart.direct.transformed.expect
new file mode 100644
index 0000000..4fbc43e
--- /dev/null
+++ b/pkg/front_end/testcases/bug33196.dart.direct.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method main() → dynamic {
+  dynamic result = self::returnsString();
+  core::print(result.runtimeType);
+}
+static method returnsString() → asy::FutureOr<core::String> /* originally async */ {
+  final asy::Completer<core::String> :async_completer = asy::Completer::sync<core::String>();
+  asy::FutureOr<core::String> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = "oh no";
+        break #L1;
+      }
+      :async_completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/bug33196.dart.outline.expect b/pkg/front_end/testcases/bug33196.dart.outline.expect
new file mode 100644
index 0000000..e640af1
--- /dev/null
+++ b/pkg/front_end/testcases/bug33196.dart.outline.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic
+  ;
+static method returnsString() → asy::FutureOr<core::String>
+  ;
diff --git a/pkg/front_end/testcases/bug33196.dart.strong.expect b/pkg/front_end/testcases/bug33196.dart.strong.expect
new file mode 100644
index 0000000..d8e9475
--- /dev/null
+++ b/pkg/front_end/testcases/bug33196.dart.strong.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  asy::FutureOr<core::String> result = self::returnsString();
+  core::print(result.{core::Object::runtimeType});
+}
+static method returnsString() → asy::FutureOr<core::String> async {
+  return "oh no";
+}
diff --git a/pkg/front_end/testcases/bug33196.dart.strong.transformed.expect b/pkg/front_end/testcases/bug33196.dart.strong.transformed.expect
new file mode 100644
index 0000000..2a550b1
--- /dev/null
+++ b/pkg/front_end/testcases/bug33196.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  asy::FutureOr<core::String> result = self::returnsString();
+  core::print(result.{core::Object::runtimeType});
+}
+static method returnsString() → asy::FutureOr<core::String> /* originally async */ {
+  final asy::Completer<core::String> :async_completer = asy::Completer::sync<core::String>();
+  asy::FutureOr<core::String> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = "oh no";
+        break #L1;
+      }
+      :async_completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/bug33206.dart b/pkg/front_end/testcases/bug33206.dart
new file mode 100644
index 0000000..79892c5
--- /dev/null
+++ b/pkg/front_end/testcases/bug33206.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+class X {
+  final x;
+  final y;
+
+  X(this.x, this.y);
+
+  toString() => "X($x, $y)";
+}
+
+class Y {
+  f(_) {}
+}
+
+Future<List<Object>> f1() async {
+  return [1];
+}
+
+List<Object> f2() => [2];
+
+Future<Object> f3() async {
+  return 3;
+}
+
+Future<X> foo() async {
+  return X(Y()..f(await f1())..f(f2()), await f3());
+}
+
+Future<void> main() async {
+  print(await foo());
+}
diff --git a/pkg/front_end/testcases/bug33206.dart.direct.expect b/pkg/front_end/testcases/bug33206.dart.direct.expect
new file mode 100644
index 0000000..45898a6
--- /dev/null
+++ b/pkg/front_end/testcases/bug33206.dart.direct.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class X extends core::Object {
+  final field dynamic x;
+  final field dynamic y;
+  constructor •(dynamic x, dynamic y) → void
+    : self::X::x = x, self::X::y = y, super core::Object::•()
+    ;
+  method toString() → dynamic
+    return "X(${this.{self::X::x}}, ${this.{self::X::y}})";
+}
+class Y extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(dynamic _) → dynamic {}
+}
+static method f1() → asy::Future<core::List<core::Object>> async {
+  return <dynamic>[1];
+}
+static method f2() → core::List<core::Object>
+  return <dynamic>[2];
+static method f3() → asy::Future<core::Object> async {
+  return 3;
+}
+static method foo() → asy::Future<self::X> async {
+  return new self::X::•(let final dynamic #t1 = new self::Y::•() in let final dynamic #t2 = #t1.f(await self::f1()) in let final dynamic #t3 = #t1.f(self::f2()) in #t1, await self::f3());
+}
+static method main() → asy::Future<void> async {
+  core::print(await self::foo());
+}
diff --git a/pkg/front_end/testcases/bug33206.dart.direct.transformed.expect b/pkg/front_end/testcases/bug33206.dart.direct.transformed.expect
new file mode 100644
index 0000000..9d44bff
--- /dev/null
+++ b/pkg/front_end/testcases/bug33206.dart.direct.transformed.expect
@@ -0,0 +1,137 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class X extends core::Object {
+  final field dynamic x;
+  final field dynamic y;
+  constructor •(dynamic x, dynamic y) → void
+    : self::X::x = x, self::X::y = y, super core::Object::•()
+    ;
+  method toString() → dynamic
+    return "X(${this.{self::X::x}}, ${this.{self::X::y}})";
+}
+class Y extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(dynamic _) → dynamic {}
+}
+static method f1() → asy::Future<core::List<core::Object>> /* originally async */ {
+  final asy::Completer<core::List<core::Object>> :async_completer = asy::Completer::sync<core::List<core::Object>>();
+  asy::FutureOr<core::List<core::Object>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = <dynamic>[1];
+        break #L1;
+      }
+      :async_completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method f2() → core::List<core::Object>
+  return <dynamic>[2];
+static method f3() → asy::Future<core::Object> /* originally async */ {
+  final asy::Completer<core::Object> :async_completer = asy::Completer::sync<core::Object>();
+  asy::FutureOr<core::Object> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = 3;
+        break #L2;
+      }
+      :async_completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method foo() → asy::Future<self::X> /* originally async */ {
+  final asy::Completer<self::X> :async_completer = asy::Completer::sync<self::X>();
+  asy::FutureOr<self::X> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L3:
+      {
+        final dynamic #t1 = new self::Y::•();
+        [yield] let dynamic #t2 = asy::_awaitHelper(self::f1(), :async_op_then, :async_op_error, :async_op) in null;
+        final dynamic #t3 = #t1.f(:result);
+        final dynamic #t4 = #t1.f(self::f2());
+        [yield] let dynamic #t5 = asy::_awaitHelper(self::f3(), :async_op_then, :async_op_error, :async_op) in null;
+        :return_value = new self::X::•(#t1, :result);
+        break #L3;
+      }
+      :async_completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method main() → asy::Future<void> /* originally async */ {
+  final asy::Completer<void> :async_completer = asy::Completer::sync<void>();
+  asy::FutureOr<void> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L4:
+      {
+        [yield] let dynamic #t6 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
+        core::print(:result);
+      }
+      :async_completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/bug33206.dart.outline.expect b/pkg/front_end/testcases/bug33206.dart.outline.expect
new file mode 100644
index 0000000..bc0040e
--- /dev/null
+++ b/pkg/front_end/testcases/bug33206.dart.outline.expect
@@ -0,0 +1,29 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class X extends core::Object {
+  final field dynamic x;
+  final field dynamic y;
+  constructor •(dynamic x, dynamic y) → void
+    ;
+  method toString() → dynamic
+    ;
+}
+class Y extends core::Object {
+  synthetic constructor •() → void
+    ;
+  method f(dynamic _) → dynamic
+    ;
+}
+static method f1() → asy::Future<core::List<core::Object>>
+  ;
+static method f2() → core::List<core::Object>
+  ;
+static method f3() → asy::Future<core::Object>
+  ;
+static method foo() → asy::Future<self::X>
+  ;
+static method main() → asy::Future<void>
+  ;
diff --git a/pkg/front_end/testcases/bug33206.dart.strong.expect b/pkg/front_end/testcases/bug33206.dart.strong.expect
new file mode 100644
index 0000000..027b1f8
--- /dev/null
+++ b/pkg/front_end/testcases/bug33206.dart.strong.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class X extends core::Object {
+  final field dynamic x;
+  final field dynamic y;
+  constructor •(dynamic x, dynamic y) → void
+    : self::X::x = x, self::X::y = y, super core::Object::•()
+    ;
+  method toString() → core::String
+    return "X(${this.{self::X::x}}, ${this.{self::X::y}})";
+}
+class Y extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(dynamic _) → dynamic {}
+}
+static method f1() → asy::Future<core::List<core::Object>> async {
+  return <core::Object>[1];
+}
+static method f2() → core::List<core::Object>
+  return <core::Object>[2];
+static method f3() → asy::Future<core::Object> async {
+  return 3;
+}
+static method foo() → asy::Future<self::X> async {
+  return new self::X::•(let final self::Y #t1 = new self::Y::•() in let final dynamic #t2 = #t1.{self::Y::f}(await self::f1()) in let final dynamic #t3 = #t1.{self::Y::f}(self::f2()) in #t1, await self::f3());
+}
+static method main() → asy::Future<void> async {
+  core::print(await self::foo());
+}
diff --git a/pkg/front_end/testcases/bug33206.dart.strong.transformed.expect b/pkg/front_end/testcases/bug33206.dart.strong.transformed.expect
new file mode 100644
index 0000000..cf29898
--- /dev/null
+++ b/pkg/front_end/testcases/bug33206.dart.strong.transformed.expect
@@ -0,0 +1,137 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class X extends core::Object {
+  final field dynamic x;
+  final field dynamic y;
+  constructor •(dynamic x, dynamic y) → void
+    : self::X::x = x, self::X::y = y, super core::Object::•()
+    ;
+  method toString() → core::String
+    return "X(${this.{self::X::x}}, ${this.{self::X::y}})";
+}
+class Y extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(dynamic _) → dynamic {}
+}
+static method f1() → asy::Future<core::List<core::Object>> /* originally async */ {
+  final asy::Completer<core::List<core::Object>> :async_completer = asy::Completer::sync<core::List<core::Object>>();
+  asy::FutureOr<core::List<core::Object>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = <core::Object>[1];
+        break #L1;
+      }
+      :async_completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method f2() → core::List<core::Object>
+  return <core::Object>[2];
+static method f3() → asy::Future<core::Object> /* originally async */ {
+  final asy::Completer<core::Object> :async_completer = asy::Completer::sync<core::Object>();
+  asy::FutureOr<core::Object> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = 3;
+        break #L2;
+      }
+      :async_completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method foo() → asy::Future<self::X> /* originally async */ {
+  final asy::Completer<self::X> :async_completer = asy::Completer::sync<self::X>();
+  asy::FutureOr<self::X> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L3:
+      {
+        final self::Y #t1 = new self::Y::•();
+        [yield] let dynamic #t2 = asy::_awaitHelper(self::f1(), :async_op_then, :async_op_error, :async_op) in null;
+        final dynamic #t3 = #t1.{self::Y::f}(:result);
+        final dynamic #t4 = #t1.{self::Y::f}(self::f2());
+        [yield] let dynamic #t5 = asy::_awaitHelper(self::f3(), :async_op_then, :async_op_error, :async_op) in null;
+        :return_value = new self::X::•(#t1, :result);
+        break #L3;
+      }
+      :async_completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
+static method main() → asy::Future<void> /* originally async */ {
+  final asy::Completer<void> :async_completer = asy::Completer::sync<void>();
+  asy::FutureOr<void> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L4:
+      {
+        [yield] let dynamic #t6 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
+        core::print(:result);
+      }
+      :async_completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :async_completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :async_completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/tool/_fasta/bulk_compile.dart b/pkg/front_end/tool/_fasta/bulk_compile.dart
index fd4e09b..770ad9d 100644
--- a/pkg/front_end/tool/_fasta/bulk_compile.dart
+++ b/pkg/front_end/tool/_fasta/bulk_compile.dart
@@ -43,7 +43,6 @@
               ..fileSystem = (new FileBackedMemoryFileSystem()
                 ..entities[mainUri.path] =
                     (new MemoryFileSystemEntity(mainUri)..bytes = <int>[])),
-            false,
             <Uri>[mainUri]);
 
   Future<Null> compile(String source) {
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index c504e29..c804b1e 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -300,7 +300,6 @@
           ..sdkSummary = options["--platform"]
           ..librariesSpecificationUri = resolveFile(arguments[1])
           ..setExitCodeOnProblem = true
-          ..chaseDependencies = true
           ..packagesFileUri = packages
           ..strongMode = strongMode
           ..target = target
@@ -311,7 +310,6 @@
           ..debugDump = dumpIr
           ..verbose = verbose
           ..verify = verify,
-        false,
         <Uri>[Uri.parse(arguments[0])],
         resolveFile(arguments[2]));
   } else if (arguments.isEmpty) {
@@ -352,7 +350,7 @@
       inputs.add(resolveFile(argument));
     }
   }
-  return new ProcessedOptions(compilerOptions, false, inputs, output);
+  return new ProcessedOptions(compilerOptions, inputs, output);
 }
 
 dynamic withGlobalOptions(
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index a8b6a15..026bccd 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -129,8 +129,7 @@
 
   Future<bool> batchCompile(CompilerOptions options, Uri input, Uri output) {
     return CompilerContext.runWithOptions(
-        new ProcessedOptions(options, false, <Uri>[input], output),
-        batchCompileImpl);
+        new ProcessedOptions(options, <Uri>[input], output), batchCompileImpl);
   }
 
   Future<bool> batchCompileImpl(CompilerContext c) async {
diff --git a/pkg/front_end/tool/_fasta/generate_messages_test.dart b/pkg/front_end/tool/_fasta/generate_messages_test.dart
index f242f01..d351316 100644
--- a/pkg/front_end/tool/_fasta/generate_messages_test.dart
+++ b/pkg/front_end/tool/_fasta/generate_messages_test.dart
@@ -14,7 +14,8 @@
   asyncTest(() async {
     Uri generatedFile = await computeGeneratedFile();
     String generated = await generateMessagesFile();
-    String actual = await new File.fromUri(generatedFile).readAsString();
+    String actual = (await new File.fromUri(generatedFile).readAsString())
+        .replaceAll('\r\n', '\n');
     Expect.stringEquals(
         generated, actual, "${generatedFile.path} is out of date");
   });
diff --git a/pkg/front_end/tool/fasta_perf.dart b/pkg/front_end/tool/fasta_perf.dart
index de09e9a..75a58f7 100644
--- a/pkg/front_end/tool/fasta_perf.dart
+++ b/pkg/front_end/tool/fasta_perf.dart
@@ -233,7 +233,6 @@
     ..onError = onErrorHandler(strongMode)
     ..strongMode = strongMode
     ..target = createTarget(isFlutter: false, strongMode: strongMode)
-    ..chaseDependencies = true
     ..packagesFileUri = Uri.base.resolve('.packages')
     ..compileSdk = compileSdk;
   if (!compileSdk) {
diff --git a/pkg/front_end/tool/incremental_perf.dart b/pkg/front_end/tool/incremental_perf.dart
index 02a4bb7..0f8f161 100644
--- a/pkg/front_end/tool/incremental_perf.dart
+++ b/pkg/front_end/tool/incremental_perf.dart
@@ -127,8 +127,7 @@
   var dir = Directory.systemTemp.createTempSync("ikg-cache");
   compilerOptions.byteStore = createByteStore(cache, dir.path);
 
-  final processedOptions =
-      new ProcessedOptions(compilerOptions, false, [entryUri]);
+  final processedOptions = new ProcessedOptions(compilerOptions, [entryUri]);
   final UriTranslator uriTranslator = await processedOptions.getUriTranslator();
 
   collector.start("Initial compilation");
diff --git a/pkg/js_ast/lib/src/builder.dart b/pkg/js_ast/lib/src/builder.dart
index 8366dd0..1de3981 100644
--- a/pkg/js_ast/lib/src/builder.dart
+++ b/pkg/js_ast/lib/src/builder.dart
@@ -1254,7 +1254,7 @@
 
   VariableDeclarationList finishVariableDeclarationList(
       Declaration firstVariable) {
-    var initialization = [];
+    var initialization = <VariableInitialization>[];
 
     void declare(Declaration declaration) {
       Expression initializer = null;
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 13b28bf..d94fb18 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -131,7 +131,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 6;
+  UInt32 formatVersion = 7;
   Library[] libraries;
   UriSource sourceMap;
   List<CanonicalName> canonicalNames;
@@ -286,11 +286,14 @@
   UriReference fileUri;
   FileOffset fileOffset;
   FileOffset fileEndOffset;
-  Byte flags (isAbstract, isEnum, xx); // Where xx is index into ClassLevel
+  Byte flags (levelBit0, levelBit1, isAbstract, isEnum, isAnonymousMixin,
+              isEliminatedMixin); // Where level is index into ClassLevel
   StringReference name;
   List<Expression> annotations;
   List<TypeParameter> typeParameters;
   Option<DartType> superClass;
+  // For transformed mixin application classes (isEliminatedMixin),
+  // original mixedInType is pulled into the end of implementedClasses.
   Option<DartType> mixedInType;
   List<DartType> implementedClasses;
   List<Field> fields;
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index afe96c6..f7367b9 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -696,10 +696,28 @@
   /// applications.
   @coq
   String name;
-  bool isAbstract;
+
+  // Must match serialized bit positions.
+  static const int LevelMask = 0x3; // Bits 0 and 1.
+  static const int FlagAbstract = 1 << 2;
+  static const int FlagEnum = 1 << 3;
+  static const int FlagAnonymousMixin = 1 << 4;
+  static const int FlagEliminatedMixin = 1 << 5;
+
+  int flags = 0;
+
+  bool get isAbstract => flags & FlagAbstract != 0;
+
+  void set isAbstract(bool value) {
+    flags = value ? (flags | FlagAbstract) : (flags & ~FlagAbstract);
+  }
 
   /// Whether this class is an enum.
-  bool isEnum = false;
+  bool get isEnum => flags & FlagEnum != 0;
+
+  void set isEnum(bool value) {
+    flags = value ? (flags | FlagEnum) : (flags & ~FlagEnum);
+  }
 
   /// Whether this class is a synthetic implementation created for each
   /// mixed-in class. For example the following code:
@@ -714,7 +732,22 @@
   /// abstract class A&B&C&D extends A&B&C mixedIn D {}
   /// class Z extends A&B&C&D {}
   /// All X&Y classes are marked as synthetic.
-  bool isSyntheticMixinImplementation;
+  bool get isAnonymousMixin => flags & FlagAnonymousMixin != 0;
+
+  void set isAnonymousMixin(bool value) {
+    flags =
+        value ? (flags | FlagAnonymousMixin) : (flags & ~FlagAnonymousMixin);
+  }
+
+  /// Whether this class was transformed from a mixin application.
+  /// In such case, its mixed-in type was pulled into the end of implemented
+  /// types list.
+  bool get isEliminatedMixin => flags & FlagEliminatedMixin != 0;
+
+  void set isEliminatedMixin(bool value) {
+    flags =
+        value ? (flags | FlagEliminatedMixin) : (flags & ~FlagEliminatedMixin);
+  }
 
   /// The URI of the source file this class was loaded from.
   Uri fileUri;
@@ -750,8 +783,8 @@
 
   Class(
       {this.name,
-      this.isAbstract: false,
-      this.isSyntheticMixinImplementation: false,
+      bool isAbstract: false,
+      bool isAnonymousMixin: false,
       this.supertype,
       this.mixedInType,
       List<TypeParameter> typeParameters,
@@ -775,6 +808,8 @@
     setParents(this.procedures, this);
     setParents(this.fields, this);
     setParents(this.redirectingFactoryConstructors, this);
+    this.isAbstract = isAbstract;
+    this.isAnonymousMixin = isAnonymousMixin;
   }
 
   void computeCanonicalNames() {
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index b75a3a3..5e01828 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -847,10 +847,8 @@
     node.fileOffset = readOffset();
     node.fileEndOffset = readOffset();
     int flags = readByte();
-    node.isAbstract = flags & 0x1 != 0;
-    node.isEnum = flags & 0x2 != 0;
-    node.isSyntheticMixinImplementation = flags & 0x4 != 0;
-    int levelIndex = (flags >> 3) & 0x3;
+    node.flags = flags & ~Class.LevelMask;
+    int levelIndex = flags & Class.LevelMask;
     var level = ClassLevel.values[levelIndex + 1];
     if (level.index >= node.level.index) {
       node.level = level;
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 156d80b..ed89e92 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -725,25 +725,18 @@
     }
   }
 
-  int _encodeClassFlags(bool isAbstract, bool isEnum,
-      bool isSyntheticMixinImplementation, ClassLevel level) {
-    int abstractFlag = isAbstract ? 1 : 0;
-    int isEnumFlag = isEnum ? 2 : 0;
-    int isSyntheticMixinImplementationFlag =
-        isSyntheticMixinImplementation ? 4 : 0;
-    int levelFlags = (level.index - 1) << 3;
-    return abstractFlag |
-        isEnumFlag |
-        isSyntheticMixinImplementationFlag |
-        levelFlags;
+  int _encodeClassFlags(int flags, ClassLevel level) {
+    assert((flags & Class.LevelMask) == 0);
+    final levelIndex = level.index - 1;
+    assert((levelIndex & Class.LevelMask) == levelIndex);
+    return flags | levelIndex;
   }
 
   @override
   void visitClass(Class node) {
     classOffsets.add(getBufferOffset());
 
-    int flags = _encodeClassFlags(node.isAbstract, node.isEnum,
-        node.isSyntheticMixinImplementation, node.level);
+    int flags = _encodeClassFlags(node.flags, node.level);
     if (node.canonicalName == null) {
       throw 'Missing canonical name for $node';
     }
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 1d016af..9bb574b0 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -135,7 +135,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
-  static const int BinaryFormatVersion = 6;
+  static const int BinaryFormatVersion = 7;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 3a9a036..ab527e5 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -23,7 +23,7 @@
       {HandleAmbiguousSupertypes onAmbiguousSupertypes,
       MixinInferrer mixinInferrer}) {
     onAmbiguousSupertypes ??= (Class cls, Supertype a, Supertype b) {
-      if (!cls.isSyntheticMixinImplementation) {
+      if (!cls.isAnonymousMixin) {
         // See https://github.com/dart-lang/sdk/issues/32091
         throw "$cls can't implement both $a and $b";
       }
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index 5553fd03..3a461aa1 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -52,7 +52,7 @@
     return _activeFileUri == null ? TreeNode.noOffset : fileOffset;
   }
 
-  TreeNode clone(TreeNode node) {
+  T clone<T extends TreeNode>(T node) {
     final Uri activeFileUriSaved = _activeFileUri;
     if (node is FileUriNode) _activeFileUri = node.fileUri ?? _activeFileUri;
     final TreeNode result = node.accept(this)
diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart
index 72a0d20..21da8d9 100644
--- a/pkg/kernel/lib/transformations/async.dart
+++ b/pkg/kernel/lib/transformations/async.dart
@@ -454,15 +454,12 @@
   }
 
   TreeNode visitLet(Let expr) {
-    var shouldName = seenAwait;
-
-    seenAwait = false;
     var body = expr.body.accept(this);
 
     VariableDeclaration variable = expr.variable;
     if (seenAwait) {
-      // The body in `let var x = initializer in body` contained an await.  We
-      // will produce the sequence of statements:
+      // There is an await in the body of `let var x = initializer in body` or
+      // to its right.  We will produce the sequence of statements:
       //
       // <initializer's statements>
       // var x = <initializer's value>
@@ -488,7 +485,6 @@
     } else {
       // The body in `let x = initializer in body` did not contain an await.  We
       // can leave a let expression.
-      seenAwait = shouldName;
       return transform(expr, () {
         // The body has already been translated.
         expr.body = body..parent = expr;
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index d31f70a..05b814d 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -956,12 +956,15 @@
   FunctionNode rewrite() {
     var statements = <Statement>[];
 
-    // The original function return type should be Future<T> because the
-    // function is async. If it was, we make a Completer<T>.  Otherwise
-    // We will make a malformed type.
-    // In an "Future<FooBar> foo() async {}" function the body can either return
-    // a "FooBar" or a "Future<FooBar>" => a "FutureOr<FooBar>".
-    final DartType valueType = elementTypeFromReturnType(helper.futureClass);
+    // The original function return type should be Future<T> or FutureOr<T>
+    // because the function is async. If it was, we make a Completer<T>,
+    // otherwise we make a malformed type.  In a "Future<T> foo() async {}"
+    // function the body can either return a "T" or a "Future<T>" => a
+    // "FutureOr<T>".
+    DartType valueType = elementTypeFromReturnType(helper.futureClass);
+    if (valueType == const DynamicType()) {
+      valueType = elementTypeFromReturnType(helper.futureOrClass);
+    }
     final DartType returnType =
         new InterfaceType(helper.futureOrClass, <DartType>[valueType]);
     var completerTypeArguments = <DartType>[valueType];
diff --git a/pkg/kernel/lib/transformations/mixin_full_resolution.dart b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
index a2f392620..d546fe4 100644
--- a/pkg/kernel/lib/transformations/mixin_full_resolution.dart
+++ b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
@@ -232,11 +232,15 @@
       }
     }
 
-    // This class implements the mixin type.
+    // This class implements the mixin type. Also, backends rely on the fact
+    // that eliminated mixin is appended into the end of interfaces list.
     class_.implementedTypes.add(class_.mixedInType);
 
     // This class is now a normal class.
     class_.mixedInType = null;
+
+    // Leave breadcrumbs for backends (e.g. for dart:mirrors implementation).
+    class_.isEliminatedMixin = true;
   }
 
   Constructor buildForwardingConstructor(
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index d84856f..db043a8 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,7 +1,7 @@
 name: kernel
 # Currently, kernel API is not stable and users should
 # not depend on semver semantics when depending on this package.
-version: 0.3.0
+version: 0.3.1-alpha.0
 author: Dart Team <misc@dartlang.org>
 description: Dart IR (Intermediate Representation)
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
@@ -14,7 +14,7 @@
   package_config: ^1.0.0
 dev_dependencies:
   analyzer: '>=0.31.0 <0.33.0'
-  front_end: 0.1.0
+  front_end: 0.1.1-alpha.0
   test: ^0.12.15+6
   stack_trace: ^1.6.6
   ansicolor: ^0.0.9
diff --git a/pkg/testing/lib/src/analyze.dart b/pkg/testing/lib/src/analyze.dart
index 4471201..f9a23ee 100644
--- a/pkg/testing/lib/src/analyze.dart
+++ b/pkg/testing/lib/src/analyze.dart
@@ -46,18 +46,23 @@
     String optionsPath = json["options"];
     Uri optionsUri = optionsPath == null ? null : base.resolve(optionsPath);
 
-    List<Uri> uris = new List<Uri>.from(
-        json["uris"].map((String relative) => base.resolve(relative)));
+    List<Uri> uris = json["uris"].map<Uri>((relative) {
+      String r = relative;
+      return base.resolve(r);
+    }).toList();
 
     List<RegExp> exclude =
-        new List<RegExp>.from(json["exclude"].map((String p) => new RegExp(p)));
+        json["exclude"].map<RegExp>((p) => new RegExp(p)).toList();
 
     Map gitGrep = json["git grep"];
     List<String> gitGrepPathspecs;
     List<String> gitGrepPatterns;
     if (gitGrep != null) {
-      gitGrepPathspecs = gitGrep["pathspecs"] ?? const <String>["."];
-      gitGrepPatterns = gitGrep["patterns"];
+      gitGrepPathspecs = gitGrep["pathspecs"] == null
+          ? const <String>["."]
+          : new List<String>.from(gitGrep["pathspecs"]);
+      if (gitGrep["patterns"] != null)
+        gitGrepPatterns = new List<String>.from(gitGrep["patterns"]);
     }
 
     return new Analyze(
diff --git a/pkg/testing/lib/src/chain.dart b/pkg/testing/lib/src/chain.dart
index f93a31b..2a82f99 100644
--- a/pkg/testing/lib/src/chain.dart
+++ b/pkg/testing/lib/src/chain.dart
@@ -63,9 +63,9 @@
     Uri uri = base.resolve(path);
     Uri statusFile = base.resolve(json["status"]);
     List<RegExp> pattern =
-        new List<RegExp>.from(json["pattern"].map((String p) => new RegExp(p)));
+        json["pattern"].map<RegExp>((p) => new RegExp(p)).toList();
     List<RegExp> exclude =
-        new List<RegExp>.from(json["exclude"].map((String p) => new RegExp(p)));
+        json["exclude"].map<RegExp>((p) => new RegExp(p)).toList();
     bool processMultitests = json["process-multitests"] ?? false;
     return new Chain(name, kind, source, uri, statusFile, pattern, exclude,
         processMultitests);
diff --git a/pkg/testing/lib/src/error_handling.dart b/pkg/testing/lib/src/error_handling.dart
index b0f2bac..bf13cb0 100644
--- a/pkg/testing/lib/src/error_handling.dart
+++ b/pkg/testing/lib/src/error_handling.dart
@@ -10,7 +10,7 @@
 
 import 'dart:isolate' show ReceivePort;
 
-Future withErrorHandling(Future f()) async {
+Future<T> withErrorHandling<T>(Future<T> f()) async {
   final ReceivePort port = new ReceivePort();
   try {
     return await f();
@@ -20,6 +20,7 @@
     if (trace != null) {
       stderr.writeln(trace);
     }
+    return null;
   } finally {
     port.close();
   }
diff --git a/pkg/testing/lib/src/expectation.dart b/pkg/testing/lib/src/expectation.dart
index 3ba1af80..8c8e7e9 100644
--- a/pkg/testing/lib/src/expectation.dart
+++ b/pkg/testing/lib/src/expectation.dart
@@ -78,7 +78,7 @@
 
   const ExpectationSet(this.internalMap);
 
-  operator [](String name) {
+  Expectation operator [](String name) {
     return internalMap[name.toLowerCase()] ??
         (throw "No expectation named: '$name'.");
   }
diff --git a/pkg/testing/lib/src/run.dart b/pkg/testing/lib/src/run.dart
index c628a7a..a06d328 100644
--- a/pkg/testing/lib/src/run.dart
+++ b/pkg/testing/lib/src/run.dart
@@ -206,8 +206,10 @@
 
 Future<Null> main() async {
   if ($isVerbose) enableVerboseOutput();
-  Map<String, String> environment = json.decode('${json.encode(environment)}');
-  Set<String> selectors = json.decode('${json.encode(selectors)}').toSet();
+  Map<String, String> environment =
+      new Map<String, String>.from(json.decode('${json.encode(environment)}'));
+  Set<String> selectors =
+      new Set<String>.from(json.decode('${json.encode(selectors)}'));
   await runTests(<String, Function> {
       ${splitLines(dart.toString().trim()).join('      ')}
   });
diff --git a/pkg/testing/lib/src/run_tests.dart b/pkg/testing/lib/src/run_tests.dart
index d1860a1..ce0849d 100644
--- a/pkg/testing/lib/src/run_tests.dart
+++ b/pkg/testing/lib/src/run_tests.dart
@@ -39,11 +39,11 @@
   Set<String> get skip => commaSeparated("--skip=");
 
   Set<String> commaSeparated(String prefix) {
-    return options.expand((String s) {
+    return new Set<String>.from(options.expand((String s) {
       if (!s.startsWith(prefix)) return const [];
       s = s.substring(prefix.length);
       return s.split(",");
-    }).toSet();
+    }));
   }
 
   Map<String, String> get environment {
@@ -167,8 +167,8 @@
       print("Running tests took: ${sw.elapsed}.");
     });
 
-Future<Null> runTests(Map<String, Function> tests) =>
-    withErrorHandling(() async {
+Future<void> runTests(Map<String, Function> tests) =>
+    withErrorHandling<void>(() async {
       int completed = 0;
       for (String name in tests.keys) {
         StringBuffer sb = new StringBuffer();
diff --git a/pkg/testing/lib/src/test_dart.dart b/pkg/testing/lib/src/test_dart.dart
index 98e2b82..8ac8457 100644
--- a/pkg/testing/lib/src/test_dart.dart
+++ b/pkg/testing/lib/src/test_dart.dart
@@ -29,7 +29,9 @@
   factory TestDart.fromJsonMap(Uri base, Map json, String name, String kind) {
     String common = json["common"] ?? "";
     String processes = json["processes"] ?? "-j${Platform.numberOfProcessors}";
-    List<String> commandLines = json["command-lines"] ?? <String>[];
+    List<String> commandLines = json["command-lines"] == null
+        ? new List<String>.from(json["command-lines"])
+        : <String>[];
     return new TestDart(name, common, processes, commandLines);
   }
 
diff --git a/pkg/testing/lib/src/test_dart/status_file_parser.dart b/pkg/testing/lib/src/test_dart/status_file_parser.dart
index 30b32c8..c756341 100644
--- a/pkg/testing/lib/src/test_dart/status_file_parser.dart
+++ b/pkg/testing/lib/src/test_dart/status_file_parser.dart
@@ -39,7 +39,7 @@
   Section(this.statusFile, this.condition, this.lineNumber)
       : testRules = new List<TestRule>();
 
-  bool isEnabled(environment) =>
+  bool isEnabled(Map<String, String> environment) =>
       condition == null || condition.evaluate(environment);
 
   String toString() {
@@ -48,15 +48,15 @@
 }
 
 Future<TestExpectations> ReadTestExpectations(List<String> statusFilePaths,
-    Map environment, ExpectationSet expectationSet) {
+    Map<String, String> environment, ExpectationSet expectationSet) {
   var testExpectations = new TestExpectations(expectationSet);
   return Future.wait(statusFilePaths.map((String statusFile) {
     return ReadTestExpectationsInto(testExpectations, statusFile, environment);
   })).then((_) => testExpectations);
 }
 
-Future ReadTestExpectationsInto(
-    TestExpectations expectations, String statusFilePath, environment) {
+Future<void> ReadTestExpectationsInto(TestExpectations expectations,
+    String statusFilePath, Map<String, String> environment) {
   var completer = new Completer();
   List<Section> sections = new List<Section>();
 
@@ -75,7 +75,7 @@
   return completer.future;
 }
 
-void ReadConfigurationInto(Path path, sections, onDone) {
+void ReadConfigurationInto(Path path, List<Section> sections, void onDone()) {
   StatusFile statusFile = new StatusFile(path);
   File file = new File(path.toNativePath());
   if (!file.existsSync()) {
@@ -152,25 +152,25 @@
   // Only create one copy of each Set<Expectation>.
   // We just use .toString as a key, so we may make a few
   // sets that only differ in their toString element order.
-  static Map _cachedSets = new Map();
+  static Map<String, Set<Expectation>> _cachedSets = {};
 
   final ExpectationSet expectationSet;
 
-  Map _map;
+  Map<String, Set<Expectation>> _map;
   bool _preprocessed = false;
-  Map _regExpCache;
-  Map _keyToRegExps;
+  Map<String, RegExp> _regExpCache;
+  Map<String, List<RegExp>> _keyToRegExps;
 
   /**
    * Create a TestExpectations object. See the [expectations] method
    * for an explanation of matching.
    */
-  TestExpectations(this.expectationSet) : _map = new Map();
+  TestExpectations(this.expectationSet) : _map = {};
 
   /**
    * Add a rule to the expectations.
    */
-  void addRule(testRule, environment) {
+  void addRule(TestRule testRule, Map<String, String> environment) {
     // Once we have started using the expectations we cannot add more
     // rules.
     if (_preprocessed) {
@@ -193,7 +193,7 @@
    * "^$keyComponent\$" matches the corresponding filename component.
    */
   Set<Expectation> expectations(String filename) {
-    var result = new Set();
+    var result = new Set<Expectation>();
     var splitFilename = filename.split('/');
 
     // Create mapping from keys to list of RegExps once and for all.
@@ -224,13 +224,13 @@
   void _preprocessForMatching() {
     if (_preprocessed) return;
 
-    _keyToRegExps = new Map();
-    _regExpCache = new Map();
+    _keyToRegExps = {};
+    _regExpCache = {};
 
     _map.forEach((key, expectations) {
       if (_keyToRegExps[key] != null) return;
       var splitKey = key.split('/');
-      var regExps = new List(splitKey.length);
+      var regExps = new List<RegExp>(splitKey.length);
       for (var i = 0; i < splitKey.length; i++) {
         var component = splitKey[i];
         var regExp = _regExpCache[component];
diff --git a/pkg/testing/lib/src/test_root.dart b/pkg/testing/lib/src/test_root.dart
index 16aa0c4..9e3b65e 100644
--- a/pkg/testing/lib/src/test_root.dart
+++ b/pkg/testing/lib/src/test_root.dart
@@ -75,8 +75,9 @@
 
     Uri packages = uri.resolve(data["packages"]);
 
-    List<Suite> suites = new List<Suite>.from(
-        data["suites"].map((Map json) => new Suite.fromJsonMap(uri, json)));
+    List<Suite> suites = data["suites"]
+        .map<Suite>((json) => new Suite.fromJsonMap(uri, json))
+        .toList();
 
     Analyze analyze = await Analyze.fromJsonMap(uri, data["analyze"], suites);
 
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index ba848ff..8bd4fe4 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -178,7 +178,7 @@
   Future<Component> compileInternal(Uri script) async {
     return requireMain
         ? kernelForProgram(script, options)
-        : kernelForComponent([script], options..chaseDependencies = true);
+        : kernelForComponent([script], options);
   }
 }
 
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index 1c7c2f8..0bf5ffb 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -441,7 +441,8 @@
       final IOSink sink = new File(_kernelBinaryFilename).openWrite();
       sink.add(serializeProcedure(procedure));
       await sink.close();
-      _outputStream.writeln('$boundaryKey $_kernelBinaryFilename');
+      _outputStream
+          .writeln('$boundaryKey $_kernelBinaryFilename ${errors.length}');
       _kernelBinaryFilename = _kernelBinaryFilenameIncremental;
     } else {
       _outputStream.writeln(boundaryKey);
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 7e7762f..332017e 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -117,12 +117,6 @@
     // when building a platform dill file for VM/JIT case.
     mixin_deduplication.transformComponent(component);
 
-    if (useGlobalTypeFlowAnalysis) {
-      globalTypeFlow.transformComponent(coreTypes, component, entryPoints);
-    } else {
-      devirtualization.transformComponent(coreTypes, component);
-    }
-
     if (enableConstantEvaluation) {
       await _performConstantEvaluation(source, compilerOptions, component,
           coreTypes, environmentDefines, strongMode, enableAsserts);
@@ -130,6 +124,12 @@
       if (errorDetector.hasCompilationErrors) return;
     }
 
+    if (useGlobalTypeFlowAnalysis) {
+      globalTypeFlow.transformComponent(coreTypes, component, entryPoints);
+    } else {
+      devirtualization.transformComponent(coreTypes, component);
+    }
+
     no_dynamic_invocations_annotator.transformComponent(component);
   }
 }
@@ -145,8 +145,7 @@
   final vmConstants =
       new vm_constants.VmConstantsBackend(environmentDefines, coreTypes);
 
-  final processedOptions =
-      new ProcessedOptions(compilerOptions, false, [source]);
+  final processedOptions = new ProcessedOptions(compilerOptions, [source]);
 
   // Run within the context, so we have uri source tokens...
   await CompilerContext.runWithOptions(processedOptions,
@@ -159,8 +158,8 @@
     final typeEnvironment =
         new TypeEnvironment(coreTypes, hierarchy, strongMode: strongMode);
 
-    // TODO(kustermann): We should use the entrypoints manifest to find out
-    // which fields need to be preserved and remove the rest.
+    // TFA will remove constants fields which are unused (and respects the
+    // vm/embedder entrypoints).
     constants.transformComponent(component, vmConstants,
         keepFields: true,
         strongMode: true,
diff --git a/pkg/vm/lib/transformations/mixin_deduplication.dart b/pkg/vm/lib/transformations/mixin_deduplication.dart
index 2daf9a0..68ade75 100644
--- a/pkg/vm/lib/transformations/mixin_deduplication.dart
+++ b/pkg/vm/lib/transformations/mixin_deduplication.dart
@@ -79,7 +79,7 @@
       _transformSupertype(c);
     }
 
-    if (!c.isSyntheticMixinImplementation) {
+    if (!c.isAnonymousMixin) {
       return c;
     }
 
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 71ee83e..40a3e79 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -611,20 +611,65 @@
   }
 }
 
+/// Keeps track of number of cached [_Invocation] objects with
+/// a particular selector and provides approximation if needed.
+class _SelectorApproximation {
+  /// Approximation [_Invocation] with raw arguments is created and used
+  /// after number of [_Invocation] objects with same selector but
+  /// different arguments reaches this limit.
+  static const int maxInvocationsPerSelector = 5000;
+
+  int count = 0;
+  _Invocation approximation;
+}
+
+/// Maintains ([Selector], [Args]) => [_Invocation] cache.
+/// Invocations are cached in order to reuse previously calculated result.
 class _InvocationsCache {
+  final TypeFlowAnalysis _typeFlowAnalysis;
   final Set<_Invocation> _invocations = new Set<_Invocation>();
+  final Map<Selector, _SelectorApproximation> _approximations =
+      <Selector, _SelectorApproximation>{};
+
+  _InvocationsCache(this._typeFlowAnalysis);
 
   _Invocation getInvocation(Selector selector, Args<Type> args) {
+    ++Statistics.invocationsQueriedInCache;
     _Invocation invocation = (selector is DirectSelector)
         ? new _DirectInvocation(selector, args)
         : new _DispatchableInvocation(selector, args);
     _Invocation result = _invocations.lookup(invocation);
-    if (result == null) {
-      bool added = _invocations.add(invocation);
-      assertx(added);
-      result = invocation;
+    if (result != null) {
+      return result;
     }
-    return result;
+
+    if (selector is InterfaceSelector) {
+      // Detect if there are too many invocations per selector. In such case,
+      // approximate extra invocations with a single invocation with raw
+      // arguments.
+
+      final sa = (_approximations[selector] ??= new _SelectorApproximation());
+
+      if (sa.count >= _SelectorApproximation.maxInvocationsPerSelector) {
+        if (sa.approximation == null) {
+          final rawArgs =
+              _typeFlowAnalysis.summaryCollector.rawArguments(selector);
+          sa.approximation = new _DispatchableInvocation(selector, rawArgs);
+          Statistics.approximateInvocationsCreated++;
+        }
+        Statistics.approximateInvocationsUsed++;
+        return sa.approximation;
+      }
+
+      ++sa.count;
+      Statistics.maxInvocationsCachedPerSelector =
+          max(Statistics.maxInvocationsCachedPerSelector, sa.count);
+    }
+
+    bool added = _invocations.add(invocation);
+    assertx(added);
+    ++Statistics.invocationsAddedToCache;
+    return invocation;
   }
 }
 
@@ -1010,6 +1055,7 @@
   void process() {
     while (pending.isNotEmpty) {
       assertx(callStack.isEmpty && processing.isEmpty);
+      Statistics.iterationsOverInvocationsWorkList++;
       processInvocation(pending.first);
     }
   }
@@ -1060,6 +1106,7 @@
       // Invocation is still pending - it was invalidated while being processed.
       // Move result to invalidatedResult.
       if (_isPending(invocation)) {
+        Statistics.invocationsInvalidatedDuringProcessing++;
         invocation.invalidatedResult = result;
         invocation.result = null;
       }
@@ -1095,7 +1142,7 @@
   final NativeCodeOracle nativeCodeOracle;
   _ClassHierarchyCache hierarchyCache;
   SummaryCollector summaryCollector;
-  _InvocationsCache _invocationsCache = new _InvocationsCache();
+  _InvocationsCache _invocationsCache;
   _WorkList workList;
 
   final Map<Member, Summary> _summaries = <Member, Summary>{};
@@ -1108,6 +1155,7 @@
     hierarchyCache = new _ClassHierarchyCache(this, hierarchy);
     summaryCollector =
         new SummaryCollector(environment, this, nativeCodeOracle);
+    _invocationsCache = new _InvocationsCache(this);
     workList = new _WorkList(this);
 
     if (entryPointsJSONFiles != null) {
@@ -1186,6 +1234,11 @@
   /// ---- Implementation of [EntryPointsListener] interface. ----
 
   @override
+  void addDirectFieldAccess(Field field, Type value) {
+    getFieldValue(field).setValue(value, this);
+  }
+
+  @override
   void addRawCall(Selector selector) {
     if (kPrintDebug) {
       debugPrint("ADD RAW CALL: $selector");
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index e01aed4..d3f72d6 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -24,6 +24,9 @@
   /// Add call by the given selector with arbitrary ('raw') arguments.
   void addRawCall(Selector selector);
 
+  /// Sets the type of the given field.
+  void addDirectFieldAccess(Field field, Type value);
+
   /// Add instantiation of the given class.
   ConcreteType addAllocatedClass(Class c);
 }
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 01e6738..4e260da 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -253,9 +253,12 @@
   Map<VariableDeclaration, Join> _variables;
   Join _returnValue;
   Parameter _receiver;
+  ConstantAllocationCollector constantAllocationCollector;
 
   SummaryCollector(
-      this._environment, this._entryPointsListener, this._nativeCodeOracle);
+      this._environment, this._entryPointsListener, this._nativeCodeOracle) {
+    constantAllocationCollector = new ConstantAllocationCollector(this);
+  }
 
   Summary createSummary(Member member) {
     debugPrint("===== ${member} =====");
@@ -444,10 +447,17 @@
     _summary.add(param);
     assertx(param.index < _summary.parameterCount);
     if (param.index >= _summary.requiredParameterCount) {
-      // TODO(alexmarkov): get actual type of constant initializer
-      param.defaultValue = (initializer != null)
-          ? new Type.fromStatic(initializer.getStaticType(_environment))
-          : _nullType;
+      if (initializer != null) {
+        if (initializer is ConstantExpression) {
+          param.defaultValue =
+              constantAllocationCollector.typeFor(initializer.constant);
+        } else {
+          param.defaultValue =
+              new Type.fromStatic(initializer.getStaticType(_environment));
+        }
+      } else {
+        param.defaultValue = _nullType;
+      }
     } else {
       assertx(initializer == null);
     }
@@ -1182,6 +1192,11 @@
 
   @override
   visitInvalidInitializer(InvalidInitializer node) {}
+
+  @override
+  TypeExpr visitConstantExpression(ConstantExpression node) {
+    return constantAllocationCollector.typeFor(node.constant);
+  }
 }
 
 class EmptyEntryPointsListener implements EntryPointsListener {
@@ -1192,6 +1207,9 @@
   void addRawCall(Selector selector) {}
 
   @override
+  void addDirectFieldAccess(Field field, Type value) {}
+
+  @override
   ConcreteType addAllocatedClass(Class c) {
     final classId = (_classIds[c] ??= new IntClassId(++_classIdCounter));
     return new ConcreteType(classId, c.rawType);
@@ -1213,3 +1231,91 @@
     }
   }
 }
+
+class ConstantAllocationCollector extends ConstantVisitor<Type> {
+  final SummaryCollector summaryCollector;
+
+  final Map<Constant, Type> constants = <Constant, Type>{};
+
+  ConstantAllocationCollector(this.summaryCollector);
+
+  // Ensures the transtive graph of [constant] got scanned for potential
+  // allocations and field types.  Returns the [Type] of this constant.
+  Type typeFor(Constant constant) {
+    return constants.putIfAbsent(constant, () => constant.accept(this));
+  }
+
+  @override
+  defaultConstant(Constant constant) {
+    throw 'There is no support for constant "$constant" in TFA yet!';
+  }
+
+  @override
+  Type visitNullConstant(NullConstant constant) {
+    return summaryCollector._nullType;
+  }
+
+  @override
+  Type visitBoolConstant(BoolConstant constant) {
+    return summaryCollector._boolType;
+  }
+
+  @override
+  Type visitIntConstant(IntConstant constant) {
+    return summaryCollector._intType;
+  }
+
+  @override
+  Type visitDoubleConstant(DoubleConstant constant) {
+    return summaryCollector._doubleType;
+  }
+
+  @override
+  Type visitStringConstant(StringConstant constant) {
+    return summaryCollector._stringType;
+  }
+
+  @override
+  Type visitMapConstant(MapConstant node) {
+    throw 'The kernel2kernel constants transformation desugars const maps!';
+  }
+
+  @override
+  Type visitListConstant(ListConstant constant) {
+    for (final Constant entry in constant.entries) {
+      typeFor(entry);
+    }
+    return new Type.cone(constant.getType(summaryCollector._environment));
+  }
+
+  @override
+  Type visitInstanceConstant(InstanceConstant constant) {
+    final resultType =
+        summaryCollector._entryPointsListener.addAllocatedClass(constant.klass);
+    constant.fieldValues.forEach((Reference fieldReference, Constant value) {
+      summaryCollector._entryPointsListener
+          .addDirectFieldAccess(fieldReference.asField, typeFor(value));
+    });
+    return resultType;
+  }
+
+  @override
+  Type visitTearOffConstant(TearOffConstant constant) {
+    final Procedure procedure = constant.procedure;
+    summaryCollector._entryPointsListener
+        .addRawCall(new DirectSelector(procedure));
+    return new Type.cone(constant.getType(summaryCollector._environment));
+  }
+
+  @override
+  Type visitPartialInstantiationConstant(
+      PartialInstantiationConstant constant) {
+    constant.tearOffConstant.accept(this);
+    return new Type.cone(constant.getType(summaryCollector._environment));
+  }
+
+  @override
+  Type visitTypeLiteralConstant(TypeLiteralConstant constant) {
+    return new Type.cone(constant.getType(summaryCollector._environment));
+  }
+}
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index ce9998f..b3a037a 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -297,11 +297,13 @@
   final Set<Member> _usedMembers = new Set<Member>();
   final Set<Typedef> _usedTypedefs = new Set<Typedef>();
   _TreeShakerTypeVisitor typeVisitor;
+  _TreeShakerConstantVisitor constantVisitor;
   _TreeShakerPass1 _pass1;
   _TreeShakerPass2 _pass2;
 
   TreeShaker(Component component, this.typeFlowAnalysis) {
     typeVisitor = new _TreeShakerTypeVisitor(this);
+    constantVisitor = new _TreeShakerConstantVisitor(this, typeVisitor);
     _pass1 = new _TreeShakerPass1(this);
     _pass2 = new _TreeShakerPass2(this);
   }
@@ -652,6 +654,12 @@
   }
 
   @override
+  TreeNode visitConstantExpression(ConstantExpression node) {
+    shaker.constantVisitor.analyzeConstant(node.constant);
+    return node;
+  }
+
+  @override
   TreeNode visitStaticSet(StaticSet node) {
     node.transformChildren(this);
     if (_isUnreachable(node)) {
@@ -889,3 +897,75 @@
     return node; // Do not traverse into other nodes.
   }
 }
+
+class _TreeShakerConstantVisitor extends ConstantVisitor<Null> {
+  final TreeShaker shaker;
+  final _TreeShakerTypeVisitor typeVisitor;
+  final Set<Constant> constants = new Set<Constant>();
+  final Set<InstanceConstant> instanceConstants = new Set<InstanceConstant>();
+
+  _TreeShakerConstantVisitor(this.shaker, this.typeVisitor);
+
+  analyzeConstant(Constant constant) {
+    if (constants.add(constant)) {
+      constant.accept(this);
+    }
+  }
+
+  @override
+  defaultConstant(Constant constant) {
+    throw 'There is no support for constant "$constant" in TFA yet!';
+  }
+
+  @override
+  visitNullConstant(NullConstant constant) {}
+
+  @override
+  visitBoolConstant(BoolConstant constant) {}
+
+  @override
+  visitIntConstant(IntConstant constant) {}
+
+  @override
+  visitDoubleConstant(DoubleConstant constant) {}
+
+  @override
+  visitStringConstant(StringConstant constant) {}
+
+  @override
+  visitMapConstant(MapConstant node) {
+    throw 'The kernel2kernel constants transformation desugars const maps!';
+  }
+
+  @override
+  visitListConstant(ListConstant constant) {
+    for (final Constant entry in constant.entries) {
+      analyzeConstant(entry);
+    }
+  }
+
+  @override
+  visitInstanceConstant(InstanceConstant constant) {
+    instanceConstants.add(constant);
+    shaker.addClassUsedInType(constant.klass);
+    constant.fieldValues.forEach((Reference fieldRef, Constant value) {
+      shaker.addUsedMember(fieldRef.asField);
+      analyzeConstant(value);
+    });
+  }
+
+  @override
+  visitTearOffConstant(TearOffConstant constant) {
+    shaker.addUsedMember(constant.procedure);
+  }
+
+  @override
+  visitPartialInstantiationConstant(PartialInstantiationConstant constant) {
+    analyzeConstant(constant.tearOffConstant);
+  }
+
+  @override
+  visitTypeLiteralConstant(TypeLiteralConstant constant) {
+    constant.type.accept(typeVisitor);
+  }
+}
diff --git a/pkg/vm/lib/transformations/type_flow/utils.dart b/pkg/vm/lib/transformations/type_flow/utils.dart
index de0d7a0..3ce56e8 100644
--- a/pkg/vm/lib/transformations/type_flow/utils.dart
+++ b/pkg/vm/lib/transformations/type_flow/utils.dart
@@ -78,6 +78,13 @@
   static int maxInvalidationsPerInvocation = 0;
   static int recursiveInvocationsApproximated = 0;
   static int typeConeSpecializations = 0;
+  static int iterationsOverInvocationsWorkList = 0;
+  static int invocationsInvalidatedDuringProcessing = 0;
+  static int invocationsQueriedInCache = 0;
+  static int invocationsAddedToCache = 0;
+  static int maxInvocationsCachedPerSelector = 0;
+  static int approximateInvocationsCreated = 0;
+  static int approximateInvocationsUsed = 0;
   static int classesDropped = 0;
   static int membersDropped = 0;
   static int methodBodiesDropped = 0;
@@ -97,6 +104,13 @@
     maxInvalidationsPerInvocation = 0;
     recursiveInvocationsApproximated = 0;
     typeConeSpecializations = 0;
+    iterationsOverInvocationsWorkList = 0;
+    invocationsInvalidatedDuringProcessing = 0;
+    invocationsQueriedInCache = 0;
+    invocationsAddedToCache = 0;
+    maxInvocationsCachedPerSelector = 0;
+    approximateInvocationsCreated = 0;
+    approximateInvocationsUsed = 0;
     classesDropped = 0;
     membersDropped = 0;
     methodBodiesDropped = 0;
@@ -117,6 +131,13 @@
     ${maxInvalidationsPerInvocation} maximum invalidations per invocation
     ${recursiveInvocationsApproximated} recursive invocations approximated
     ${typeConeSpecializations} type cones specialized
+    ${iterationsOverInvocationsWorkList} iterations over invocations work list
+    ${invocationsInvalidatedDuringProcessing} invocations invalidated during processing
+    ${invocationsQueriedInCache} invocations queried in cache
+    ${invocationsAddedToCache} invocations added to cache
+    ${maxInvocationsCachedPerSelector} maximum invocations cached per selector
+    ${approximateInvocationsCreated} approximate invocations created
+    ${approximateInvocationsUsed} times approximate invocation is used
     ${classesDropped} classes dropped
     ${membersDropped} members dropped
     ${methodBodiesDropped} method bodies dropped
diff --git a/pkg/vm/test/frontend_server_test.dart b/pkg/vm/test/frontend_server_test.dart
index ba2cf03..2a35304 100644
--- a/pkg/vm/test/frontend_server_test.dart
+++ b/pkg/vm/test/frontend_server_test.dart
@@ -519,16 +519,12 @@
       receivedResults.stream.listen((String outputFilenameAndErrorCount) {
         if (count == 0) {
           // First request is to 'compile', which results in full kernel file.
-          int delim = outputFilenameAndErrorCount.lastIndexOf(' ');
-          expect(delim > 0, equals(true));
-          String outputFilename =
-              outputFilenameAndErrorCount.substring(0, delim);
-          int errorsCount = int
-              .parse(outputFilenameAndErrorCount.substring(delim + 1).trim());
+          CompilationResult result =
+              new CompilationResult.parse(outputFilenameAndErrorCount);
 
           expect(dillFile.existsSync(), equals(true));
-          expect(outputFilename, dillFile.path);
-          expect(errorsCount, equals(0));
+          expect(result.filename, dillFile.path);
+          expect(result.errorsCount, equals(0));
           streamController.add('accept\n'.codeUnits);
 
           // 'compile-expression <boundarykey>
@@ -558,7 +554,11 @@
           // Second request is to 'compile-expression', which results in
           // kernel file with a function that wraps compiled expression.
           expect(outputFilenameAndErrorCount, isNotNull);
-          File outputFile = new File(outputFilenameAndErrorCount);
+          CompilationResult result =
+              new CompilationResult.parse(outputFilenameAndErrorCount);
+
+          expect(result.errorsCount, equals(0));
+          File outputFile = new File(result.filename);
           expect(outputFile.existsSync(), equals(true));
           expect(outputFile.lengthSync(), isPositive);
 
@@ -567,11 +567,10 @@
         } else {
           expect(count, 3);
           // Third request is to 'compile' non-existent file, that should fail.
-          int delim = outputFilenameAndErrorCount.lastIndexOf(' ');
-          expect(delim > 0, equals(true));
-          int errorsCount = int
-              .parse(outputFilenameAndErrorCount.substring(delim + 1).trim());
-          expect(errorsCount, greaterThan(0));
+          expect(outputFilenameAndErrorCount, isNotNull);
+          CompilationResult result =
+              new CompilationResult.parse(outputFilenameAndErrorCount);
+          expect(result.errorsCount, greaterThan(0));
           allDone.complete(true);
         }
       });
@@ -623,16 +622,13 @@
       int count = 0;
       Completer<bool> allDone = new Completer<bool>();
       receivedResults.stream.listen((String outputFilenameAndErrorCount) {
-        int delim = outputFilenameAndErrorCount.lastIndexOf(' ');
-        expect(delim > 0, equals(true));
-        String outputFilename = outputFilenameAndErrorCount.substring(0, delim);
-        int errorsCount =
-            int.parse(outputFilenameAndErrorCount.substring(delim + 1).trim());
+        CompilationResult result =
+            new CompilationResult.parse(outputFilenameAndErrorCount);
         if (count == 0) {
           // First request is to 'compile', which results in full kernel file.
           expect(dillFile.existsSync(), equals(true));
-          expect(outputFilename, dillFile.path);
-          expect(errorsCount, 0);
+          expect(result.filename, dillFile.path);
+          expect(result.errorsCount, 0);
           count += 1;
           streamController.add('accept\n'.codeUnits);
           var file2 = new File('${tempDir.path}/bar.dart')..createSync();
@@ -646,8 +642,8 @@
           // Second request is to 'recompile', which results in incremental
           // kernel file.
           var dillIncFile = new File('${dillFile.path}.incremental.dill');
-          expect(outputFilename, dillIncFile.path);
-          expect(errorsCount, 0);
+          expect(result.filename, dillIncFile.path);
+          expect(result.errorsCount, 0);
           expect(dillIncFile.existsSync(), equals(true));
           allDone.complete(true);
         }
@@ -699,16 +695,13 @@
       int count = 0;
       Completer<bool> allDone = new Completer<bool>();
       receivedResults.stream.listen((String outputFilenameAndErrorCount) {
-        int delim = outputFilenameAndErrorCount.lastIndexOf(' ');
-        expect(delim > 0, equals(true));
-        String outputFilename = outputFilenameAndErrorCount.substring(0, delim);
-        int errorsCount =
-            int.parse(outputFilenameAndErrorCount.substring(delim + 1).trim());
+        CompilationResult result =
+            new CompilationResult.parse(outputFilenameAndErrorCount);
         switch (count) {
           case 0:
             expect(dillFile.existsSync(), equals(true));
-            expect(outputFilename, dillFile.path);
-            expect(errorsCount, 2);
+            expect(result.filename, dillFile.path);
+            expect(result.errorsCount, 2);
             count += 1;
             streamController.add('accept\n'.codeUnits);
             var file2 = new File('${tempDir.path}/bar.dart')..createSync();
@@ -720,8 +713,8 @@
             break;
           case 1:
             var dillIncFile = new File('${dillFile.path}.incremental.dill');
-            expect(outputFilename, dillIncFile.path);
-            expect(errorsCount, 1);
+            expect(result.filename, dillIncFile.path);
+            expect(result.errorsCount, 1);
             count += 1;
             streamController.add('accept\n'.codeUnits);
             var file2 = new File('${tempDir.path}/bar.dart')..createSync();
@@ -733,8 +726,8 @@
             break;
           case 2:
             var dillIncFile = new File('${dillFile.path}.incremental.dill');
-            expect(outputFilename, dillIncFile.path);
-            expect(errorsCount, 0);
+            expect(result.filename, dillIncFile.path);
+            expect(result.errorsCount, 0);
             expect(dillIncFile.existsSync(), equals(true));
             allDone.complete(true);
         }
@@ -811,3 +804,15 @@
     return vmDirectory;
   }
 }
+
+class CompilationResult {
+  String filename;
+  int errorsCount;
+
+  CompilationResult.parse(String filenameAndErrorCount) {
+    int delim = filenameAndErrorCount.lastIndexOf(' ');
+    expect(delim > 0, equals(true));
+    filename = filenameAndErrorCount.substring(0, delim);
+    errorsCount = int.parse(filenameAndErrorCount.substring(delim + 1).trim());
+  }
+}
diff --git a/pkg/vm/tool/precompiler2 b/pkg/vm/tool/precompiler2
index 64908b5..d707213 100755
--- a/pkg/vm/tool/precompiler2
+++ b/pkg/vm/tool/precompiler2
@@ -17,6 +17,7 @@
 OPTIONS=()
 GEN_KERNEL_OPTIONS=()
 PACKAGES=
+BUILD_ELF=0
 
 ARGV=()
 for arg in "$@"; do
@@ -35,6 +36,9 @@
     -D* )
     GEN_KERNEL_OPTIONS+=("$arg")
     ;;
+    --build-elf)
+    BUILD_ELF=1
+    ;;
     --*)
     OPTIONS+=("$arg")
     ;;
@@ -52,6 +56,13 @@
 SOURCE_FILE="${ARGV[0]}"
 SNAPSHOT_FILE="${ARGV[1]}"
 
+if [ $BUILD_ELF -eq 1 ]; then
+  DART_BOOTSTRAP_OUT="${SNAPSHOT_FILE}.S"
+else
+  OPTIONS=("--use-blobs" "${OPTIONS[@]}")
+  DART_BOOTSTRAP_OUT="${SNAPSHOT_FILE}"
+fi
+
 function follow_links() {
   file="$1"
   while [ -h "$file" ]; do
@@ -95,12 +106,16 @@
      "$SOURCE_FILE"
 
 # Step 2: Generate snapshot from the Kernel binary.
-exec "$BIN_DIR"/dart_bootstrap                                                 \
+"$BIN_DIR"/dart_bootstrap                                                      \
      --strong                                                                  \
      --reify-generic-functions                                                 \
      --limit-ints-to-64-bits                                                   \
      --snapshot-kind=app-aot                                                   \
-     --use-blobs                                                               \
-     --snapshot="$SNAPSHOT_FILE"                                               \
+     --snapshot="$DART_BOOTSTRAP_OUT"                                          \
      "${OPTIONS[@]}"                                                           \
      "$SNAPSHOT_FILE.dill"
+
+# Step 3: Assemble the assembly file into an ELF object.
+if [ $BUILD_ELF -eq 1 ]; then
+    gcc -shared -o "$SNAPSHOT_FILE" "$DART_BOOTSTRAP_OUT"
+fi
\ No newline at end of file
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 2062431..2d4aa56 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -40,7 +40,10 @@
 
 config("dart_precompiled_runtime_config") {
   defines = []
-  defines += [ "DART_PRECOMPILED_RUNTIME" ]
+  defines += [
+    "DART_PRECOMPILED_RUNTIME",
+    "EXCLUDE_CFE_AND_KERNEL_PLATFORM",
+  ]
 }
 
 # Controls DART_PRECOMPILER #define.
@@ -149,9 +152,7 @@
 
   if (is_fuchsia) {
     import("//build/config/scudo/scudo.gni")
-    include_dirs += [
-      "//zircon/system/ulib/zx/include",
-    ]
+    include_dirs += [ "//zircon/system/ulib/zx/include" ]
     if (!use_scudo) {
       defines += [ "DART_USE_JEMALLOC" ]
       include_dirs += [ "//zircon/third_party/ulib/jemalloc/include" ]
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 970dad7..577560e 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -901,6 +901,9 @@
     }
 
     defines = extra_defines
+    if (exclude_kernel_service) {
+      defines += [ "EXCLUDE_CFE_AND_KERNEL_PLATFORM" ]
+    }
 
     if (dart_use_tcmalloc) {
       deps += [ "//third_party/tcmalloc" ]
@@ -955,9 +958,6 @@
   if (dart_runtime_mode != "release") {
     extra_deps += [ "../observatory:standalone_observatory_archive" ]
   }
-  if (dart_runtime_mode != "release") {
-    extra_deps += [ ":dart_kernel_platform_cc" ]
-  }
   extra_sources = [
     "builtin_nolib.cc",
     "dfe.cc",
@@ -971,6 +971,9 @@
   if (dart_runtime_mode == "release") {
     extra_sources += [ "observatory_assets_empty.cc" ]
   }
+  if (!exclude_kernel_service) {
+    extra_deps += [ ":dart_kernel_platform_cc" ]
+  }
 }
 
 dart_executable("dart_precompiled_runtime") {
@@ -1038,9 +1041,6 @@
     ":generate_web_sql_cc_file",
     "..:libdart_nosnapshot_with_precompiler",
   ]
-  if (dart_runtime_mode != "release") {
-    extra_deps += [ ":dart_kernel_platform_cc" ]
-  }
   extra_defines = [ "NO_OBSERVATORY" ]
   extra_sources = [
     "builtin.cc",
@@ -1073,6 +1073,9 @@
     "$target_gen_dir/web_gl_gen.cc",
     "$target_gen_dir/web_sql_gen.cc",
   ]
+  if (!exclude_kernel_service) {
+    extra_deps += [ ":dart_kernel_platform_cc" ]
+  }
 }
 
 executable("process_test") {
diff --git a/runtime/bin/common_patch.dart b/runtime/bin/common_patch.dart
index 0e46769..d5db154 100644
--- a/runtime/bin/common_patch.dart
+++ b/runtime/bin/common_patch.dart
@@ -23,7 +23,7 @@
 
 import "dart:collection" show HashMap;
 
-import "dart:convert" show Encoding;
+import "dart:convert" show Encoding, utf8;
 
 import "dart:developer" show registerExtension;
 
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index a5d1d83..df3d515 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -85,7 +85,9 @@
 int64_t DartUtils::GetIntegerValue(Dart_Handle value_obj) {
   int64_t value = 0;
   Dart_Handle result = Dart_IntegerToInt64(value_obj, &value);
-  if (Dart_IsError(result)) Dart_PropagateError(result);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
   return value;
 }
 
@@ -102,7 +104,9 @@
 intptr_t DartUtils::GetIntptrValue(Dart_Handle value_obj) {
   int64_t value = 0;
   Dart_Handle result = Dart_IntegerToInt64(value_obj, &value);
-  if (Dart_IsError(result)) Dart_PropagateError(result);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
   if (value < kIntptrMin || kIntptrMax < value) {
     Dart_PropagateError(Dart_NewApiError("Value outside intptr_t range"));
   }
@@ -113,28 +117,85 @@
   bool valid = Dart_IsInteger(value_obj);
   if (valid) {
     Dart_Handle result = Dart_IntegerFitsIntoInt64(value_obj, &valid);
-    if (Dart_IsError(result)) Dart_PropagateError(result);
+    if (Dart_IsError(result)) {
+      Dart_PropagateError(result);
+    }
   }
   if (!valid) return false;
   Dart_Handle result = Dart_IntegerToInt64(value_obj, value);
-  if (Dart_IsError(result)) Dart_PropagateError(result);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
   return true;
 }
 
 const char* DartUtils::GetStringValue(Dart_Handle str_obj) {
   const char* cstring = NULL;
   Dart_Handle result = Dart_StringToCString(str_obj, &cstring);
-  if (Dart_IsError(result)) Dart_PropagateError(result);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
   return cstring;
 }
 
 bool DartUtils::GetBooleanValue(Dart_Handle bool_obj) {
   bool value = false;
   Dart_Handle result = Dart_BooleanValue(bool_obj, &value);
-  if (Dart_IsError(result)) Dart_PropagateError(result);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
   return value;
 }
 
+bool DartUtils::GetNativeBooleanArgument(Dart_NativeArguments args,
+                                         intptr_t index) {
+  bool value = false;
+  Dart_Handle result = Dart_GetNativeBooleanArgument(args, index, &value);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+  return value;
+}
+
+int64_t DartUtils::GetNativeIntegerArgument(Dart_NativeArguments args,
+                                            intptr_t index) {
+  int64_t value = 0;
+  Dart_Handle result = Dart_GetNativeIntegerArgument(args, index, &value);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+  return value;
+}
+
+intptr_t DartUtils::GetNativeIntptrArgument(Dart_NativeArguments args,
+                                            intptr_t index) {
+  int64_t value = GetNativeIntegerArgument(args, index);
+  if (value < kIntptrMin || kIntptrMax < value) {
+    Dart_PropagateError(Dart_NewApiError("Value outside intptr_t range"));
+  }
+  return static_cast<intptr_t>(value);
+}
+
+const char* DartUtils::GetNativeStringArgument(Dart_NativeArguments args,
+                                               intptr_t index) {
+  char* tmp = NULL;
+  Dart_Handle result =
+      Dart_GetNativeStringArgument(args, index, reinterpret_cast<void**>(&tmp));
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+  if (tmp != NULL) {
+    return tmp;
+  }
+  const char* cstring = NULL;
+  result = Dart_StringToCString(result, &cstring);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+  ASSERT(cstring != NULL);
+  return cstring;
+}
+
 Dart_Handle DartUtils::SetIntegerField(Dart_Handle handle,
                                        const char* name,
                                        int64_t val) {
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 2ae7ca6..7c4a735 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -103,7 +103,23 @@
   // Returns the boolean value of a Dart object. If the object is not
   // a boolean value an API error is propagated.
   static bool GetBooleanValue(Dart_Handle bool_obj);
-
+  // Returns the boolean value of the argument at index. If the argument
+  // is not a boolean value an API error is propagated.
+  static bool GetNativeBooleanArgument(Dart_NativeArguments args,
+                                       intptr_t index);
+  // Returns the integer value of the argument at index. If the argument
+  // is not an integer value an API error is propagated.
+  static int64_t GetNativeIntegerArgument(Dart_NativeArguments args,
+                                          intptr_t index);
+  // Returns the intptr_t value of the argument at index. If the argument
+  // is not an integer value or the value is outside the intptr_t range an
+  // API error is propagated.
+  static intptr_t GetNativeIntptrArgument(Dart_NativeArguments args,
+                                          intptr_t index);
+  // Returns the string value of the argument at index. If the argument
+  // is not a string value an API error is propagated.
+  static const char* GetNativeStringArgument(Dart_NativeArguments args,
+                                             intptr_t index);
   static Dart_Handle SetIntegerField(Dart_Handle handle,
                                      const char* name,
                                      int64_t val);
diff --git a/runtime/bin/directory.cc b/runtime/bin/directory.cc
index 2f55937..de20ad9 100644
--- a/runtime/bin/directory.cc
+++ b/runtime/bin/directory.cc
@@ -2,11 +2,17 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+#include <cstdlib>
+#include <memory>
+
 #include "bin/directory.h"
 
 #include "bin/dartutils.h"
+#include "bin/io_buffer.h"
 #include "bin/log.h"
 #include "bin/namespace.h"
+#include "bin/typed_data_utils.h"
+#include "bin/utils.h"
 #include "include/dart_api.h"
 #include "platform/assert.h"
 
@@ -28,14 +34,23 @@
 void FUNCTION_NAME(Directory_SetCurrent)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
   Dart_Handle path = Dart_GetNativeArgument(args, 1);
-  if (Dart_IsError(path) || !Dart_IsString(path)) {
-    Dart_SetReturnValue(args, DartUtils::NewDartArgumentError(NULL));
-    return;
+  OSError os_error;
+  ASSERT(!Dart_IsError(path));
+  bool result;
+  {
+    TypedDataScope data(path);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* name = data.GetCString();
+    result = Directory::SetCurrent(namespc, name);
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
   }
-  if (Directory::SetCurrent(namespc, DartUtils::GetStringValue(path))) {
+  if (result) {
     Dart_SetBooleanReturnValue(args, true);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
@@ -44,24 +59,47 @@
   static const int kDoesNotExist = 0;
   Namespace* namespc = Namespace::GetNamespace(args, 0);
   Dart_Handle path = Dart_GetNativeArgument(args, 1);
-  Directory::ExistsResult result =
-      Directory::Exists(namespc, DartUtils::GetStringValue(path));
+  OSError os_error;
+  Directory::ExistsResult result;
+  {
+    TypedDataScope data(path);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* name = data.GetCString();
+    result = Directory::Exists(namespc, name);
+    if ((result != Directory::DOES_NOT_EXIST) &&
+        (result != Directory::EXISTS)) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (result == Directory::EXISTS) {
     Dart_SetIntegerReturnValue(args, kExists);
   } else if (result == Directory::DOES_NOT_EXIST) {
     Dart_SetIntegerReturnValue(args, kDoesNotExist);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(Directory_Create)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
   Dart_Handle path = Dart_GetNativeArgument(args, 1);
-  if (Directory::Create(namespc, DartUtils::GetStringValue(path))) {
+  OSError os_error;
+  bool result;
+  {
+    TypedDataScope data(path);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* name = data.GetCString();
+    result = Directory::Create(namespc, name);
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
+  if (result) {
     Dart_SetBooleanReturnValue(args, true);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
@@ -74,42 +112,68 @@
 void FUNCTION_NAME(Directory_CreateTemp)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
   Dart_Handle path = Dart_GetNativeArgument(args, 1);
-  if (!Dart_IsString(path)) {
-    Dart_SetReturnValue(
-        args, DartUtils::NewDartArgumentError(
-                  "Prefix argument of CreateSystemTempSync is not a String"));
-    return;
+  OSError os_error;
+  const char* result = NULL;
+  {
+    TypedDataScope data(path);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* name = data.GetCString();
+    result = Directory::CreateTemp(namespc, name);
+    if (result == NULL) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
   }
-  const char* result =
-      Directory::CreateTemp(namespc, DartUtils::GetStringValue(path));
   if (result != NULL) {
     Dart_SetReturnValue(args, DartUtils::NewString(result));
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(Directory_Delete)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
   Dart_Handle path = Dart_GetNativeArgument(args, 1);
-  Dart_Handle recursive = Dart_GetNativeArgument(args, 2);
-  if (Directory::Delete(namespc, DartUtils::GetStringValue(path),
-                        DartUtils::GetBooleanValue(recursive))) {
+  OSError os_error;
+  bool result;
+  {
+    TypedDataScope data(path);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* name = data.GetCString();
+    result = Directory::Delete(namespc, name,
+                               DartUtils::GetNativeBooleanArgument(args, 2));
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
+  if (result) {
     Dart_SetBooleanReturnValue(args, true);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(Directory_Rename)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
   Dart_Handle path = Dart_GetNativeArgument(args, 1);
-  Dart_Handle newPath = Dart_GetNativeArgument(args, 2);
-  if (Directory::Rename(namespc, DartUtils::GetStringValue(path),
-                        DartUtils::GetStringValue(newPath))) {
+  OSError os_error;
+  bool result;
+  {
+    TypedDataScope data(path);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* name = data.GetCString();
+    result = Directory::Rename(namespc, name,
+                               DartUtils::GetNativeStringArgument(args, 2));
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
+  if (result) {
     Dart_SetBooleanReturnValue(args, true);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
@@ -119,17 +183,22 @@
   // The list that we should fill.
   Dart_Handle results = Dart_GetNativeArgument(args, 1);
   Dart_Handle path = Dart_GetNativeArgument(args, 2);
-  Dart_Handle recursive = Dart_GetNativeArgument(args, 3);
-  Dart_Handle follow_links = Dart_GetNativeArgument(args, 4);
-
   Dart_Handle dart_error;
+  const char* name;
+  {
+    TypedDataScope data(path);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    // We need to release our typed data before creating SyncDirectoryListing
+    // since it allocates objects which require us to not be holding typed data
+    // that has been acquired.
+    name = data.GetScopedCString();
+  }
   {
     // Pass the list that should hold the directory listing to the
     // SyncDirectoryListing object, which adds elements to it.
-    SyncDirectoryListing sync_listing(results, namespc,
-                                      DartUtils::GetStringValue(path),
-                                      DartUtils::GetBooleanValue(recursive),
-                                      DartUtils::GetBooleanValue(follow_links));
+    SyncDirectoryListing sync_listing(
+        results, namespc, name, DartUtils::GetNativeBooleanArgument(args, 3),
+        DartUtils::GetNativeBooleanArgument(args, 4));
     Directory::List(&sync_listing);
     dart_error = sync_listing.dart_error();
   }
@@ -206,12 +275,14 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 2) || !request[1]->IsString()) {
+  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString path(request[1]);
-  return Directory::Create(namespc, path.CString()) ? CObject::True()
-                                                    : CObject::NewOSError();
+  CObjectUint8Array path(request[1]);
+  return Directory::Create(namespc,
+                           reinterpret_cast<const char*>(path.Buffer()))
+             ? CObject::True()
+             : CObject::NewOSError();
 }
 
 CObject* Directory::DeleteRequest(const CObjectArray& request) {
@@ -220,13 +291,15 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 3) || !request[1]->IsString() ||
+  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
       !request[2]->IsBool()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString path(request[1]);
+  CObjectUint8Array path(request[1]);
   CObjectBool recursive(request[2]);
-  return Directory::Delete(namespc, path.CString(), recursive.Value())
+  return Directory::Delete(namespc,
+                           reinterpret_cast<const char*>(path.Buffer()),
+                           recursive.Value())
              ? CObject::True()
              : CObject::NewOSError();
 }
@@ -239,11 +312,12 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 2) || !request[1]->IsString()) {
+  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString path(request[1]);
-  Directory::ExistsResult result = Directory::Exists(namespc, path.CString());
+  CObjectUint8Array path(request[1]);
+  Directory::ExistsResult result =
+      Directory::Exists(namespc, reinterpret_cast<const char*>(path.Buffer()));
   if (result == Directory::EXISTS) {
     return new CObjectInt32(CObject::NewInt32(kExists));
   } else if (result == Directory::DOES_NOT_EXIST) {
@@ -259,11 +333,12 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 2) || !request[1]->IsString()) {
+  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString path(request[1]);
-  const char* result = Directory::CreateTemp(namespc, path.CString());
+  CObjectUint8Array path(request[1]);
+  const char* result = Directory::CreateTemp(
+      namespc, reinterpret_cast<const char*>(path.Buffer()));
   if (result == NULL) {
     return CObject::NewOSError();
   }
@@ -286,15 +361,16 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 4) || !request[1]->IsString() ||
+  if ((request.Length() != 4) || !request[1]->IsUint8Array() ||
       !request[2]->IsBool() || !request[3]->IsBool()) {
     return CreateIllegalArgumentError();
   }
-  CObjectString path(request[1]);
+  CObjectUint8Array path(request[1]);
   CObjectBool recursive(request[2]);
   CObjectBool follow_links(request[3]);
   AsyncDirectoryListing* dir_listing = new AsyncDirectoryListing(
-      namespc, path.CString(), recursive.Value(), follow_links.Value());
+      namespc, reinterpret_cast<const char*>(path.Buffer()), recursive.Value(),
+      follow_links.Value());
   if (dir_listing->error()) {
     // Report error now, so we capture the correct OSError.
     CObject* err = CObject::NewOSError();
@@ -357,13 +433,15 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 3) || !request[1]->IsString() ||
+  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
       !request[2]->IsString()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString path(request[1]);
+  CObjectUint8Array path(request[1]);
   CObjectString new_path(request[2]);
-  return Directory::Rename(namespc, path.CString(), new_path.CString())
+  return Directory::Rename(namespc,
+                           reinterpret_cast<const char*>(path.Buffer()),
+                           new_path.CString())
              ? CObject::True()
              : CObject::NewOSError();
 }
@@ -372,7 +450,14 @@
                                                           const char* arg) {
   array_->SetAt(index_++, new CObjectInt32(CObject::NewInt32(type)));
   if (arg != NULL) {
-    array_->SetAt(index_++, new CObjectString(CObject::NewString(arg)));
+    size_t len = strlen(arg);
+    Dart_CObject* io_buffer = CObject::NewIOBuffer(len);
+    uint8_t* data = io_buffer->value.as_external_typed_data.data;
+    strncpy(reinterpret_cast<char*>(data), arg, len);
+
+    CObjectExternalUint8Array* external_array =
+        new CObjectExternalUint8Array(io_buffer);
+    array_->SetAt(index_++, external_array);
   } else {
     array_->SetAt(index_++, CObject::Null());
   }
@@ -410,8 +495,23 @@
 }
 
 bool SyncDirectoryListing::HandleDirectory(const char* dir_name) {
-  Dart_Handle dir_name_dart = DartUtils::NewString(dir_name);
-  Dart_Handle dir = Dart_New(directory_type_, Dart_Null(), 1, &dir_name_dart);
+  // Allocates a Uint8List for dir_name, and invokes the Directory.fromRawPath
+  // constructor. This avoids/delays interpreting the UTF-8 bytes in dir_name.
+  // Later, client code may either choose to access FileSystemEntity.path.
+  // FileSystemEntity.path will trigger UTF-8 decoding and return a path with
+  // non-UTF-8 characters replaced with U+FFFD.
+
+  size_t dir_name_length = strlen(dir_name);
+  uint8_t* buffer = NULL;
+  Dart_Handle dir_name_dart = IOBuffer::Allocate(dir_name_length, &buffer);
+  if (Dart_IsNull(dir_name_dart)) {
+    dart_error_ = DartUtils::NewDartOSError();
+    return false;
+  }
+  memmove(buffer, dir_name, dir_name_length);
+  Dart_Handle constructor_name = from_raw_path_string_;
+  Dart_Handle dir =
+      Dart_New(directory_type_, constructor_name, 1, &dir_name_dart);
   Dart_Handle result = Dart_Invoke(results_, add_string_, 1, &dir);
   if (Dart_IsError(result)) {
     dart_error_ = result;
@@ -421,8 +521,22 @@
 }
 
 bool SyncDirectoryListing::HandleLink(const char* link_name) {
-  Dart_Handle link_name_dart = DartUtils::NewString(link_name);
-  Dart_Handle link = Dart_New(link_type_, Dart_Null(), 1, &link_name_dart);
+  // Allocates a Uint8List for dir_name, and invokes the Directory.fromRawPath
+  // constructor. This avoids/delays interpreting the UTF-8 bytes in dir_name.
+  // Later, client code may either choose to access FileSystemEntity.path.
+  // FileSystemEntity.path will trigger UTF-8 decoding and return a path with
+  // non-UTF-8 characters replaced with U+FFFD.
+
+  size_t link_name_length = strlen(link_name);
+  uint8_t* buffer = NULL;
+  Dart_Handle link_name_dart = IOBuffer::Allocate(link_name_length, &buffer);
+  if (Dart_IsNull(link_name_dart)) {
+    dart_error_ = DartUtils::NewDartOSError();
+    return false;
+  }
+  memmove(buffer, link_name, link_name_length);
+  Dart_Handle constructor_name = from_raw_path_string_;
+  Dart_Handle link = Dart_New(link_type_, constructor_name, 1, &link_name_dart);
   Dart_Handle result = Dart_Invoke(results_, add_string_, 1, &link);
   if (Dart_IsError(result)) {
     dart_error_ = result;
@@ -432,8 +546,22 @@
 }
 
 bool SyncDirectoryListing::HandleFile(const char* file_name) {
-  Dart_Handle file_name_dart = DartUtils::NewString(file_name);
-  Dart_Handle file = Dart_New(file_type_, Dart_Null(), 1, &file_name_dart);
+  // Allocates a Uint8List for dir_name, and invokes the Directory.fromRawPath
+  // constructor. This avoids/delays interpreting the UTF-8 bytes in dir_name.
+  // Later, client code may either choose to access FileSystemEntity.path.
+  // FileSystemEntity.path will trigger UTF-8 decoding and return a path with
+  // non-UTF-8 characters replaced with U+FFFD.
+
+  size_t file_name_length = strlen(file_name);
+  uint8_t* buffer = NULL;
+  Dart_Handle file_name_dart = IOBuffer::Allocate(file_name_length, &buffer);
+  if (Dart_IsNull(file_name_dart)) {
+    dart_error_ = DartUtils::NewDartOSError();
+    return false;
+  }
+  memmove(buffer, file_name, file_name_length);
+  Dart_Handle constructor_name = from_raw_path_string_;
+  Dart_Handle file = Dart_New(file_type_, constructor_name, 1, &file_name_dart);
   Dart_Handle result = Dart_Invoke(results_, add_string_, 1, &file);
   if (Dart_IsError(result)) {
     dart_error_ = result;
diff --git a/runtime/bin/directory.h b/runtime/bin/directory.h
index 0ab2606..4216e84 100644
--- a/runtime/bin/directory.h
+++ b/runtime/bin/directory.h
@@ -211,6 +211,7 @@
         results_(results),
         dart_error_(Dart_Null()) {
     add_string_ = DartUtils::NewString("add");
+    from_raw_path_string_ = DartUtils::NewString("fromRawPath");
     directory_type_ = DartUtils::GetDartType(DartUtils::kIOLibURL, "Directory");
     file_type_ = DartUtils::GetDartType(DartUtils::kIOLibURL, "File");
     link_type_ = DartUtils::GetDartType(DartUtils::kIOLibURL, "Link");
@@ -226,6 +227,7 @@
  private:
   Dart_Handle results_;
   Dart_Handle add_string_;
+  Dart_Handle from_raw_path_string_;
   Dart_Handle directory_type_;
   Dart_Handle file_type_;
   Dart_Handle link_type_;
diff --git a/runtime/bin/directory_patch.dart b/runtime/bin/directory_patch.dart
index 55a33fa..ca15f32 100644
--- a/runtime/bin/directory_patch.dart
+++ b/runtime/bin/directory_patch.dart
@@ -9,27 +9,30 @@
   @patch
   static _current(_Namespace namespace) native "Directory_Current";
   @patch
-  static _setCurrent(_Namespace namespace, path) native "Directory_SetCurrent";
+  static _setCurrent(_Namespace namespace, Uint8List rawPath)
+      native "Directory_SetCurrent";
   @patch
-  static _createTemp(_Namespace namespace, String path)
+  static _createTemp(_Namespace namespace, Uint8List rawPath)
       native "Directory_CreateTemp";
   @patch
   static String _systemTemp(_Namespace namespace) native "Directory_SystemTemp";
   @patch
-  static _exists(_Namespace namespace, String path) native "Directory_Exists";
+  static _exists(_Namespace namespace, Uint8List rawPath)
+      native "Directory_Exists";
   @patch
-  static _create(_Namespace namespace, String path) native "Directory_Create";
+  static _create(_Namespace namespace, Uint8List rawPath)
+      native "Directory_Create";
   @patch
-  static _deleteNative(_Namespace namespace, String path, bool recursive)
+  static _deleteNative(_Namespace namespace, Uint8List rawPath, bool recursive)
       native "Directory_Delete";
   @patch
-  static _rename(_Namespace namespace, String path, String newPath)
+  static _rename(_Namespace namespace, Uint8List rawPath, String newPath)
       native "Directory_Rename";
   @patch
   static void _fillWithDirectoryListing(
       _Namespace namespace,
       List<FileSystemEntity> list,
-      String path,
+      Uint8List rawPath,
       bool recursive,
       bool followLinks) native "Directory_FillWithDirectoryListing";
 }
diff --git a/runtime/bin/eventhandler_fuchsia.cc b/runtime/bin/eventhandler_fuchsia.cc
index 4d0804b..16eee9d 100644
--- a/runtime/bin/eventhandler_fuchsia.cc
+++ b/runtime/bin/eventhandler_fuchsia.cc
@@ -340,7 +340,7 @@
   msg->id = id;
   msg->dart_port = dart_port;
   msg->data = data;
-  zx_status_t status = zx_port_queue(port_handle_, &pkt, 1);
+  zx_status_t status = zx_port_queue(port_handle_, &pkt);
   if (status != ZX_OK) {
     // This is a FATAL because the VM won't work at all if we can't send any
     // messages to the EventHandler thread.
@@ -511,7 +511,7 @@
                                       millis == kInfinityTimeout
                                           ? ZX_TIME_INFINITE
                                           : zx_deadline_after(ZX_MSEC(millis)),
-                                      &pkt, 1);
+                                      &pkt);
     if (status == ZX_ERR_TIMED_OUT) {
       handler_impl->HandleTimeout();
     } else if (status != ZX_OK) {
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index 978db7a..115bf3f 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -11,6 +11,7 @@
 #include "bin/embedded_dart_io.h"
 #include "bin/io_buffer.h"
 #include "bin/namespace.h"
+#include "bin/typed_data_utils.h"
 #include "bin/utils.h"
 #include "include/dart_api.h"
 #include "include/dart_tools_api.h"
@@ -75,8 +76,7 @@
 
 void FUNCTION_NAME(File_SetPointer)(Dart_NativeArguments args) {
   Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
-  intptr_t file_pointer =
-      DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
+  intptr_t file_pointer = DartUtils::GetNativeIntptrArgument(args, 1);
   File* file = reinterpret_cast<File*>(file_pointer);
   Dart_WeakPersistentHandle handle = Dart_NewWeakPersistentHandle(
       dart_this, reinterpret_cast<void*>(file), sizeof(*file), ReleaseFile);
@@ -86,28 +86,41 @@
 
 void FUNCTION_NAME(File_Open)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* filename =
-      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-  int64_t mode = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 2));
-  File::DartFileOpenMode dart_file_mode =
-      static_cast<File::DartFileOpenMode>(mode);
-  File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode);
-  // Check that the file exists before opening it only for
-  // reading. This is to prevent the opening of directories as
-  // files. Directories can be opened for reading using the posix
-  // 'open' call.
-  File* file = File::Open(namespc, filename, file_mode);
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  File* file = NULL;
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* filename = data.GetCString();
+
+    int64_t mode = DartUtils::GetNativeIntegerArgument(args, 2);
+    File::DartFileOpenMode dart_file_mode =
+        static_cast<File::DartFileOpenMode>(mode);
+    File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode);
+    // Check that the file exists before opening it only for
+    // reading. This is to prevent the opening of directories as
+    // files. Directories can be opened for reading using the posix
+    // 'open' call.
+    file = File::Open(namespc, filename, file_mode);
+    if (file == NULL) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (file != NULL) {
     Dart_SetIntegerReturnValue(args, reinterpret_cast<intptr_t>(file));
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_Exists)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* filename =
-      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  TypedDataScope data(path_handle);
+  ASSERT(data.type() == Dart_TypedData_kUint8);
+  const char* filename = data.GetCString();
   bool exists = File::Exists(namespc, filename);
   Dart_SetBooleanReturnValue(args, exists);
 }
@@ -221,8 +234,8 @@
   // integers and have the property that end <=
   // list.length. Therefore, it is safe to extract their value as
   // intptr_t.
-  intptr_t start = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
-  intptr_t end = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
+  intptr_t start = DartUtils::GetNativeIntptrArgument(args, 2);
+  intptr_t end = DartUtils::GetNativeIntptrArgument(args, 3);
   intptr_t length = end - start;
   intptr_t array_len = 0;
   Dart_Handle result = Dart_ListLength(buffer_obj, &array_len);
@@ -254,8 +267,8 @@
   // integers and have the property that (offset + length) <=
   // list.length. Therefore, it is safe to extract their value as
   // intptr_t.
-  intptr_t start = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
-  intptr_t end = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
+  intptr_t start = DartUtils::GetNativeIntptrArgument(args, 2);
+  intptr_t end = DartUtils::GetNativeIntptrArgument(args, 3);
 
   // The buffer object passed in has to be an Int8List or Uint8List object.
   // Acquire a direct pointer to the data area of the buffer object.
@@ -346,60 +359,117 @@
 
 void FUNCTION_NAME(File_LengthFromPath)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* path = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-  int64_t return_value = File::LengthFromPath(namespc, path);
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  int64_t return_value;
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* path = data.GetCString();
+    return_value = File::LengthFromPath(namespc, path);
+    if (return_value < 0) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (return_value >= 0) {
     Dart_SetIntegerReturnValue(args, return_value);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_LastModified)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* name = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-  int64_t return_value = File::LastModified(namespc, name);
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  int64_t return_value;
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* raw_name = data.GetCString();
+    return_value = File::LastModified(namespc, raw_name);
+    if (return_value < 0) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (return_value >= 0) {
     Dart_SetIntegerReturnValue(args, return_value * kMillisecondsPerSecond);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_SetLastModified)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* name = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
   int64_t millis;
   if (!DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &millis)) {
     Dart_ThrowException(DartUtils::NewDartArgumentError(
         "The second argument must be a 64-bit int."));
   }
-  if (!File::SetLastModified(namespc, name, millis)) {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+  bool result;
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* name = data.GetCString();
+    result = File::SetLastModified(namespc, name, millis);
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
+  if (!result) {
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_LastAccessed)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* name = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-  int64_t return_value = File::LastAccessed(namespc, name);
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  int64_t return_value;
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* name = data.GetCString();
+    return_value = File::LastAccessed(namespc, name);
+    if (return_value < 0) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (return_value >= 0) {
     Dart_SetIntegerReturnValue(args, return_value * kMillisecondsPerSecond);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_SetLastAccessed)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* name = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
   int64_t millis;
   if (!DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &millis)) {
     Dart_ThrowException(DartUtils::NewDartArgumentError(
         "The second argument must be a 64-bit int."));
   }
-  if (!File::SetLastAccessed(namespc, name, millis)) {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+  bool result;
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* name = data.GetCString();
+    result = File::SetLastAccessed(namespc, name, millis);
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
+  if (!result) {
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
@@ -438,135 +508,212 @@
 
 void FUNCTION_NAME(File_Create)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* str = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-  bool result = File::Create(namespc, str);
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  bool result;
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* path = data.GetCString();
+    result = File::Create(namespc, path);
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (result) {
     Dart_SetBooleanReturnValue(args, result);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_CreateLink)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  if (Dart_IsString(Dart_GetNativeArgument(args, 1)) &&
-      Dart_IsString(Dart_GetNativeArgument(args, 2))) {
-    const char* name =
-        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-    const char* target =
-        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 2));
-    if (!File::CreateLink(namespc, name, target)) {
-      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+  bool result;
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* name = data.GetCString();
+    const char* target = DartUtils::GetNativeStringArgument(args, 2);
+    result = File::CreateLink(namespc, name, target);
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
     }
-  } else {
-    Dart_Handle err =
-        DartUtils::NewDartArgumentError("Non-string argument to Link.create");
-    Dart_SetReturnValue(args, err);
+  }
+  if (!result) {
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_LinkTarget)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  if (Dart_IsString(Dart_GetNativeArgument(args, 1))) {
-    const char* name =
-        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-    const char* target = File::LinkTarget(namespc, name);
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  const char* target = NULL;
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* name = data.GetCString();
+    target = File::LinkTarget(namespc, name);
     if (target == NULL) {
-      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
-    } else {
-      Dart_SetReturnValue(args, DartUtils::NewString(target));
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
     }
+  }
+  if (target == NULL) {
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   } else {
-    Dart_Handle err =
-        DartUtils::NewDartArgumentError("Non-string argument to Link.target");
-    Dart_SetReturnValue(args, err);
+    Dart_SetReturnValue(args, DartUtils::NewString(target));
   }
 }
 
 void FUNCTION_NAME(File_Delete)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* str = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-  bool result = File::Delete(namespc, str);
+  bool result;
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* path = data.GetCString();
+    result = File::Delete(namespc, path);
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (result) {
     Dart_SetBooleanReturnValue(args, result);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_DeleteLink)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* str = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-  bool result = File::DeleteLink(namespc, str);
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  bool result;
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* path = data.GetCString();
+    result = File::DeleteLink(namespc, path);
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (result) {
     Dart_SetBooleanReturnValue(args, result);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_Rename)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* old_path =
-      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-  const char* new_path =
-      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 2));
-  bool result = File::Rename(namespc, old_path, new_path);
+  Dart_Handle old_path_handle = Dart_GetNativeArgument(args, 1);
+  bool result;
+  OSError os_error;
+  {
+    TypedDataScope old_path_data(old_path_handle);
+    ASSERT(old_path_data.type() == Dart_TypedData_kUint8);
+    const char* old_path = old_path_data.GetCString();
+    const char* new_path = DartUtils::GetNativeStringArgument(args, 2);
+    result = File::Rename(namespc, old_path, new_path);
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (result) {
     Dart_SetBooleanReturnValue(args, result);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_RenameLink)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* old_path =
-      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-  const char* new_path =
-      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 2));
-  bool result = File::RenameLink(namespc, old_path, new_path);
+  Dart_Handle old_path_handle = Dart_GetNativeArgument(args, 1);
+  bool result;
+  OSError os_error;
+  {
+    TypedDataScope old_path_data(old_path_handle);
+    ASSERT(old_path_data.type() == Dart_TypedData_kUint8);
+    const char* old_path = old_path_data.GetCString();
+    const char* new_path = DartUtils::GetNativeStringArgument(args, 2);
+    result = File::RenameLink(namespc, old_path, new_path);
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (result) {
     Dart_SetBooleanReturnValue(args, result);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_Copy)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* old_path =
-      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-  const char* new_path =
-      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 2));
-  bool result = File::Copy(namespc, old_path, new_path);
+  Dart_Handle old_path_handle = Dart_GetNativeArgument(args, 1);
+  bool result;
+  OSError os_error;
+  {
+    TypedDataScope old_path_data(old_path_handle);
+    ASSERT(old_path_data.type() == Dart_TypedData_kUint8);
+    const char* old_path = old_path_data.GetCString();
+    const char* new_path = DartUtils::GetNativeStringArgument(args, 2);
+    result = File::Copy(namespc, old_path, new_path);
+    if (!result) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (result) {
     Dart_SetBooleanReturnValue(args, result);
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_ResolveSymbolicLinks)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  const char* str = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-  const char* path = File::GetCanonicalPath(namespc, str);
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  const char* path = NULL;
+  OSError os_error;
+  {
+    TypedDataScope data(path_handle);
+    ASSERT(data.type() == Dart_TypedData_kUint8);
+    const char* str = data.GetCString();
+    path = File::GetCanonicalPath(namespc, str);
+    if (path == NULL) {
+      // Errors must be caught before TypedDataScope data is destroyed.
+      os_error.Reload();
+    }
+  }
   if (path != NULL) {
     Dart_SetReturnValue(args, DartUtils::NewString(path));
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
   }
 }
 
 void FUNCTION_NAME(File_OpenStdio)(Dart_NativeArguments args) {
-  const int64_t fd =
-      DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 0));
+  const int64_t fd = DartUtils::GetNativeIntegerArgument(args, 0);
   File* file = File::OpenStdio(static_cast<int>(fd));
   Dart_SetIntegerReturnValue(args, reinterpret_cast<intptr_t>(file));
 }
 
 void FUNCTION_NAME(File_GetStdioHandleType)(Dart_NativeArguments args) {
-  int64_t fd = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 0));
+  int64_t fd = DartUtils::GetNativeIntegerArgument(args, 0);
   ASSERT((fd == STDIN_FILENO) || (fd == STDOUT_FILENO) ||
          (fd == STDERR_FILENO));
   File::StdioHandleType type = File::GetStdioHandleType(static_cast<int>(fd));
@@ -575,78 +722,55 @@
 
 void FUNCTION_NAME(File_GetType)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  if (Dart_IsString(Dart_GetNativeArgument(args, 1)) &&
-      Dart_IsBoolean(Dart_GetNativeArgument(args, 2))) {
-    const char* str =
-        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-    bool follow_links =
-        DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 2));
-    File::Type type = File::GetType(namespc, str, follow_links);
-    Dart_SetIntegerReturnValue(args, static_cast<int>(type));
-  } else {
-    Dart_Handle err = DartUtils::NewDartArgumentError(
-        "Non-string argument to FileSystemEntity.type");
-    Dart_SetReturnValue(args, err);
-  }
+  Dart_Handle path_handle = Dart_GetNativeArgument(args, 1);
+  TypedDataScope data(path_handle);
+  ASSERT(data.type() == Dart_TypedData_kUint8);
+  const char* path = data.GetCString();
+  bool follow_links = DartUtils::GetNativeBooleanArgument(args, 2);
+  File::Type type = File::GetType(namespc, path, follow_links);
+  Dart_SetIntegerReturnValue(args, static_cast<int>(type));
 }
 
 void FUNCTION_NAME(File_Stat)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  if (Dart_IsString(Dart_GetNativeArgument(args, 1))) {
-    const char* path =
-        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
+  const char* path = DartUtils::GetNativeStringArgument(args, 1);
 
-    int64_t stat_data[File::kStatSize];
-    File::Stat(namespc, path, stat_data);
-    if (stat_data[File::kType] == File::kDoesNotExist) {
-      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
-    } else {
-      Dart_Handle returned_data =
-          Dart_NewTypedData(Dart_TypedData_kInt64, File::kStatSize);
-      if (Dart_IsError(returned_data)) {
-        Dart_PropagateError(returned_data);
-      }
-      Dart_TypedData_Type data_type_unused;
-      void* data_location;
-      intptr_t data_length_unused;
-      Dart_Handle status =
-          Dart_TypedDataAcquireData(returned_data, &data_type_unused,
-                                    &data_location, &data_length_unused);
-      if (Dart_IsError(status)) {
-        Dart_PropagateError(status);
-      }
-      memmove(data_location, stat_data, File::kStatSize * sizeof(int64_t));
-      status = Dart_TypedDataReleaseData(returned_data);
-      if (Dart_IsError(status)) {
-        Dart_PropagateError(status);
-      }
-      Dart_SetReturnValue(args, returned_data);
-    }
-  } else {
-    Dart_Handle err = DartUtils::NewDartArgumentError(
-        "Non-string argument to FileSystemEntity.stat");
-    Dart_SetReturnValue(args, err);
+  int64_t stat_data[File::kStatSize];
+  File::Stat(namespc, path, stat_data);
+  if (stat_data[File::kType] == File::kDoesNotExist) {
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    return;
   }
+  Dart_Handle returned_data =
+      Dart_NewTypedData(Dart_TypedData_kInt64, File::kStatSize);
+  if (Dart_IsError(returned_data)) {
+    Dart_PropagateError(returned_data);
+  }
+  Dart_TypedData_Type data_type_unused;
+  void* data_location;
+  intptr_t data_length_unused;
+  Dart_Handle status = Dart_TypedDataAcquireData(
+      returned_data, &data_type_unused, &data_location, &data_length_unused);
+  if (Dart_IsError(status)) {
+    Dart_PropagateError(status);
+  }
+  memmove(data_location, stat_data, File::kStatSize * sizeof(int64_t));
+  status = Dart_TypedDataReleaseData(returned_data);
+  if (Dart_IsError(status)) {
+    Dart_PropagateError(status);
+  }
+  Dart_SetReturnValue(args, returned_data);
 }
 
 void FUNCTION_NAME(File_AreIdentical)(Dart_NativeArguments args) {
   Namespace* namespc = Namespace::GetNamespace(args, 0);
-  if (Dart_IsString(Dart_GetNativeArgument(args, 1)) &&
-      Dart_IsString(Dart_GetNativeArgument(args, 2))) {
-    const char* path_1 =
-        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
-    const char* path_2 =
-        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 2));
-    File::Identical result = File::AreIdentical(namespc, path_1, path_2);
-    if (result == File::kError) {
-      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
-    } else {
-      Dart_SetBooleanReturnValue(args, result == File::kIdentical);
-    }
+  const char* path_1 = DartUtils::GetNativeStringArgument(args, 1);
+  const char* path_2 = DartUtils::GetNativeStringArgument(args, 2);
+  File::Identical result = File::AreIdentical(namespc, path_1, path_2);
+  if (result == File::kError) {
+    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
   } else {
-    Dart_Handle err = DartUtils::NewDartArgumentError(
-        "Non-string argument to FileSystemEntity.identical");
-    Dart_SetReturnValue(args, err);
+    Dart_SetBooleanReturnValue(args, result == File::kIdentical);
   }
 }
 
@@ -761,11 +885,12 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 2) || !request[1]->IsString()) {
+  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString filename(request[1]);
-  return CObject::Bool(File::Exists(namespc, filename.CString()));
+  CObjectUint8Array filename(request[1]);
+  return CObject::Bool(
+      File::Exists(namespc, reinterpret_cast<const char*>(filename.Buffer())));
 }
 
 CObject* File::CreateRequest(const CObjectArray& request) {
@@ -774,12 +899,13 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 2) || !request[1]->IsString()) {
+  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString filename(request[1]);
-  return File::Create(namespc, filename.CString()) ? CObject::True()
-                                                   : CObject::NewOSError();
+  CObjectUint8Array filename(request[1]);
+  return File::Create(namespc, reinterpret_cast<const char*>(filename.Buffer()))
+             ? CObject::True()
+             : CObject::NewOSError();
 }
 
 CObject* File::OpenRequest(const CObjectArray& request) {
@@ -788,16 +914,17 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 3) || !request[1]->IsString() ||
+  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
       !request[2]->IsInt32()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString filename(request[1]);
+  CObjectUint8Array filename(request[1]);
   CObjectInt32 mode(request[2]);
   File::DartFileOpenMode dart_file_mode =
       static_cast<File::DartFileOpenMode>(mode.Value());
   File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode);
-  File* file = File::Open(namespc, filename.CString(), file_mode);
+  File* file = File::Open(
+      namespc, reinterpret_cast<const char*>(filename.Buffer()), file_mode);
   if (file == NULL) {
     return CObject::NewOSError();
   }
@@ -811,12 +938,13 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 2) || !request[1]->IsString()) {
+  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
     return CObject::False();
   }
-  CObjectString filename(request[1]);
-  return File::Delete(namespc, filename.CString()) ? CObject::True()
-                                                   : CObject::NewOSError();
+  CObjectUint8Array filename(request[1]);
+  return File::Delete(namespc, reinterpret_cast<const char*>(filename.Buffer()))
+             ? CObject::True()
+             : CObject::NewOSError();
 }
 
 CObject* File::RenameRequest(const CObjectArray& request) {
@@ -825,13 +953,14 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 3) || !request[1]->IsString() ||
+  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
       !request[2]->IsString()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString old_path(request[1]);
+  CObjectUint8Array old_path(request[1]);
   CObjectString new_path(request[2]);
-  return File::Rename(namespc, old_path.CString(), new_path.CString())
+  return File::Rename(namespc, reinterpret_cast<const char*>(old_path.Buffer()),
+                      new_path.CString())
              ? CObject::True()
              : CObject::NewOSError();
 }
@@ -842,13 +971,14 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 3) || !request[1]->IsString() ||
+  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
       !request[2]->IsString()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString old_path(request[1]);
+  CObjectUint8Array old_path(request[1]);
   CObjectString new_path(request[2]);
-  return File::Copy(namespc, old_path.CString(), new_path.CString())
+  return File::Copy(namespc, reinterpret_cast<const char*>(old_path.Buffer()),
+                    new_path.CString())
              ? CObject::True()
              : CObject::NewOSError();
 }
@@ -859,11 +989,12 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 2) || !request[1]->IsString()) {
+  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString filename(request[1]);
-  const char* result = File::GetCanonicalPath(namespc, filename.CString());
+  CObjectUint8Array filename(request[1]);
+  const char* result = File::GetCanonicalPath(
+      namespc, reinterpret_cast<const char*>(filename.Buffer()));
   if (result == NULL) {
     return CObject::NewOSError();
   }
@@ -960,12 +1091,12 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 2) || !request[1]->IsString()) {
+  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString filepath(request[1]);
-  const int64_t return_value =
-      File::LengthFromPath(namespc, filepath.CString());
+  CObjectUint8Array filepath(request[1]);
+  const int64_t return_value = File::LengthFromPath(
+      namespc, reinterpret_cast<const char*>(filepath.Buffer()));
   if (return_value < 0) {
     return CObject::NewOSError();
   }
@@ -978,11 +1109,12 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 2) || !request[1]->IsString()) {
+  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString filepath(request[1]);
-  const int64_t return_value = File::LastAccessed(namespc, filepath.CString());
+  CObjectUint8Array filepath(request[1]);
+  const int64_t return_value = File::LastAccessed(
+      namespc, reinterpret_cast<const char*>(filepath.Buffer()));
   if (return_value < 0) {
     return CObject::NewOSError();
   }
@@ -996,13 +1128,14 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 3) || !request[1]->IsString() ||
+  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
       !request[2]->IsInt32OrInt64()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString filepath(request[1]);
+  CObjectUint8Array filepath(request[1]);
   const int64_t millis = CObjectInt32OrInt64ToInt64(request[2]);
-  return File::SetLastAccessed(namespc, filepath.CString(), millis)
+  return File::SetLastAccessed(
+             namespc, reinterpret_cast<const char*>(filepath.Buffer()), millis)
              ? CObject::Null()
              : CObject::NewOSError();
 }
@@ -1013,11 +1146,12 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 2) || !request[1]->IsString()) {
+  if ((request.Length() != 2) || !request[1]->IsUint8Array()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString filepath(request[1]);
-  const int64_t return_value = File::LastModified(namespc, filepath.CString());
+  CObjectUint8Array filepath(request[1]);
+  const int64_t return_value = File::LastModified(
+      namespc, reinterpret_cast<const char*>(filepath.Buffer()));
   if (return_value < 0) {
     return CObject::NewOSError();
   }
@@ -1031,13 +1165,14 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if ((request.Length() != 3) || !request[1]->IsString() ||
+  if ((request.Length() != 3) || !request[1]->IsUint8Array() ||
       !request[2]->IsInt32OrInt64()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString filepath(request[1]);
+  CObjectUint8Array filepath(request[1]);
   const int64_t millis = CObjectInt32OrInt64ToInt64(request[2]);
-  return File::SetLastModified(namespc, filepath.CString(), millis)
+  return File::SetLastModified(
+             namespc, reinterpret_cast<const char*>(filepath.Buffer()), millis)
              ? CObject::Null()
              : CObject::NewOSError();
 }
@@ -1230,12 +1365,14 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if (!request[1]->IsString() || !request[2]->IsString()) {
+  if (!request[1]->IsUint8Array() || !request[2]->IsString()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString link_name(request[1]);
+  CObjectUint8Array link_name(request[1]);
   CObjectString target_name(request[2]);
-  return File::CreateLink(namespc, link_name.CString(), target_name.CString())
+  return File::CreateLink(namespc,
+                          reinterpret_cast<const char*>(link_name.Buffer()),
+                          target_name.CString())
              ? CObject::True()
              : CObject::NewOSError();
 }
@@ -1246,12 +1383,14 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if (!request[1]->IsString()) {
+  if (!request[1]->IsUint8Array()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString link_path(request[1]);
-  return File::DeleteLink(namespc, link_path.CString()) ? CObject::True()
-                                                        : CObject::NewOSError();
+  CObjectUint8Array link_path(request[1]);
+  return File::DeleteLink(namespc,
+                          reinterpret_cast<const char*>(link_path.Buffer()))
+             ? CObject::True()
+             : CObject::NewOSError();
 }
 
 CObject* File::RenameLinkRequest(const CObjectArray& request) {
@@ -1260,12 +1399,14 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if (!request[1]->IsString() || !request[2]->IsString()) {
+  if (!request[1]->IsUint8Array() || !request[2]->IsString()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString old_path(request[1]);
+  CObjectUint8Array old_path(request[1]);
   CObjectString new_path(request[2]);
-  return File::RenameLink(namespc, old_path.CString(), new_path.CString())
+  return File::RenameLink(namespc,
+                          reinterpret_cast<const char*>(old_path.Buffer()),
+                          new_path.CString())
              ? CObject::True()
              : CObject::NewOSError();
 }
@@ -1276,11 +1417,12 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if (!request[1]->IsString()) {
+  if (!request[1]->IsUint8Array()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString link_path(request[1]);
-  const char* target = File::LinkTarget(namespc, link_path.CString());
+  CObjectUint8Array link_path(request[1]);
+  const char* target = File::LinkTarget(
+      namespc, reinterpret_cast<const char*>(link_path.Buffer()));
   if (target == NULL) {
     return CObject::NewOSError();
   }
@@ -1293,13 +1435,14 @@
   }
   Namespace* namespc = CObjectToNamespacePointer(request[0]);
   RefCntReleaseScope<Namespace> rs(namespc);
-  if (!request[1]->IsString() || !request[2]->IsBool()) {
+  if (!request[1]->IsUint8Array() || !request[2]->IsBool()) {
     return CObject::IllegalArgumentError();
   }
-  CObjectString path(request[1]);
+  CObjectUint8Array path(request[1]);
   CObjectBool follow_links(request[2]);
   File::Type type =
-      File::GetType(namespc, path.CString(), follow_links.Value());
+      File::GetType(namespc, reinterpret_cast<const char*>(path.Buffer()),
+                    follow_links.Value());
   return new CObjectInt32(CObject::NewInt32(type));
 }
 
diff --git a/runtime/bin/file_patch.dart b/runtime/bin/file_patch.dart
index 247c480..99ee6ac 100644
--- a/runtime/bin/file_patch.dart
+++ b/runtime/bin/file_patch.dart
@@ -7,46 +7,48 @@
 @patch
 class _File {
   @patch
-  static _exists(_Namespace namespace, String path) native "File_Exists";
+  static _exists(_Namespace namespace, Uint8List rawPath) native "File_Exists";
   @patch
-  static _create(_Namespace namespace, String path) native "File_Create";
+  static _create(_Namespace namespace, Uint8List rawPath) native "File_Create";
   @patch
-  static _createLink(_Namespace namespace, String path, String target)
+  static _createLink(_Namespace namespace, Uint8List rawPath, String target)
       native "File_CreateLink";
   @patch
-  static _linkTarget(_Namespace namespace, String path)
+  static _linkTarget(_Namespace namespace, Uint8List rawPath)
       native "File_LinkTarget";
   @patch
-  static _deleteNative(_Namespace namespace, String path) native "File_Delete";
+  static _deleteNative(_Namespace namespace, Uint8List rawPath)
+      native "File_Delete";
   @patch
-  static _deleteLinkNative(_Namespace namespace, String path)
+  static _deleteLinkNative(_Namespace namespace, Uint8List rawPath)
       native "File_DeleteLink";
   @patch
-  static _rename(_Namespace namespace, String oldPath, String newPath)
+  static _rename(_Namespace namespace, Uint8List oldPath, String newPath)
       native "File_Rename";
   @patch
-  static _renameLink(_Namespace namespace, String oldPath, String newPath)
+  static _renameLink(_Namespace namespace, Uint8List oldPath, String newPath)
       native "File_RenameLink";
   @patch
-  static _copy(_Namespace namespace, String oldPath, String newPath)
+  static _copy(_Namespace namespace, Uint8List oldPath, String newPath)
       native "File_Copy";
   @patch
-  static _lengthFromPath(_Namespace namespace, String path)
+  static _lengthFromPath(_Namespace namespace, Uint8List rawPath)
       native "File_LengthFromPath";
   @patch
-  static _lastModified(_Namespace namespace, String path)
+  static _lastModified(_Namespace namespace, Uint8List rawPath)
       native "File_LastModified";
   @patch
-  static _setLastModified(_Namespace namespace, String path, int millis)
+  static _setLastModified(_Namespace namespace, Uint8List rawPath, int millis)
       native "File_SetLastModified";
   @patch
-  static _lastAccessed(_Namespace namespace, String path)
+  static _lastAccessed(_Namespace namespace, Uint8List rawPath)
       native "File_LastAccessed";
   @patch
-  static _setLastAccessed(_Namespace namespace, String path, int millis)
+  static _setLastAccessed(_Namespace namespace, Uint8List rawPath, int millis)
       native "File_SetLastAccessed";
   @patch
-  static _open(_Namespace namespace, String path, int mode) native "File_Open";
+  static _open(_Namespace namespace, Uint8List rawPath, int mode)
+      native "File_Open";
   @patch
   static int _openStdio(int fd) native "File_OpenStdio";
 }
@@ -289,8 +291,9 @@
             rewriteMove(event, getIsDir(event));
           }
         }
-      } else if (event == RawSocketEvent.closed) {} else if (event ==
-          RawSocketEvent.readClosed) {} else {
+      } else if (event == RawSocketEvent.closed) {
+      } else if (event == RawSocketEvent.readClosed) {
+      } else {
         assert(false);
       }
       events.addAll(stops);
diff --git a/runtime/bin/file_system_entity_patch.dart b/runtime/bin/file_system_entity_patch.dart
index 3aecd66..973e6b6 100644
--- a/runtime/bin/file_system_entity_patch.dart
+++ b/runtime/bin/file_system_entity_patch.dart
@@ -13,12 +13,12 @@
 @patch
 class FileSystemEntity {
   @patch
-  static _getTypeNative(_Namespace namespace, String path, bool followLinks)
-      native "File_GetType";
+  static _getTypeNative(_Namespace namespace, Uint8List rawPath,
+      bool followLinks) native "File_GetType";
   @patch
   static _identicalNative(_Namespace namespace, String path1, String path2)
       native "File_AreIdentical";
   @patch
-  static _resolveSymbolicLinks(_Namespace namespace, String path)
+  static _resolveSymbolicLinks(_Namespace namespace, Uint8List path)
       native "File_ResolveSymbolicLinks";
 }
diff --git a/runtime/bin/io_impl_sources.gni b/runtime/bin/io_impl_sources.gni
index 1e46f4d..94477a7 100644
--- a/runtime/bin/io_impl_sources.gni
+++ b/runtime/bin/io_impl_sources.gni
@@ -101,4 +101,6 @@
   "sync_socket_linux.cc",
   "sync_socket_macos.cc",
   "sync_socket_win.cc",
+  "typed_data_utils.h",
+  "typed_data_utils.cc",
 ]
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 5a495e8..d46910b 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -345,7 +345,10 @@
       // relative URIs and perform other related tasks. We need Loader to be
       // initialized for this to work because loading from Kernel binary
       // bypasses normal source code loading paths that initialize it.
-      Loader::InitForSnapshot(script_uri);
+      const char* resolved_script_uri = NULL;
+      result = Dart_StringToCString(uri, &resolved_script_uri);
+      CHECK_RESULT(result);
+      Loader::InitForSnapshot(resolved_script_uri);
     }
 
     Dart_TimelineEvent("LoadScript", Dart_TimelineGetMicros(),
@@ -615,7 +618,13 @@
       platform_kernel_buffer_size = kernel_buffer_size;
     }
     if (platform_kernel_buffer == NULL) {
+#if defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
+      FATAL(
+          "Binary built with --exclude-kernel-service. Cannot run"
+          " from source.");
+#else
       FATAL("platform_program cannot be NULL.");
+#endif  // defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
     }
     // TODO(sivachandra): When the platform program is unavailable, check if
     // application kernel binary is self contained or an incremental binary.
diff --git a/runtime/bin/process_fuchsia.cc b/runtime/bin/process_fuchsia.cc
index 43f01ca..d8ff3d0 100644
--- a/runtime/bin/process_fuchsia.cc
+++ b/runtime/bin/process_fuchsia.cc
@@ -205,7 +205,7 @@
   static void SendShutdownMessage() {
     zx_port_packet_t pkt;
     pkt.key = kShutdownPacketKey;
-    zx_status_t status = zx_port_queue(port_, &pkt, 1);
+    zx_status_t status = zx_port_queue(port_, &pkt);
     if (status != ZX_OK) {
       Log::PrintErr("ExitCodeHandler: zx_port_queue failed: %s\n",
                     zx_status_get_string(status));
@@ -219,7 +219,7 @@
 
     zx_port_packet_t pkt;
     while (true) {
-      zx_status_t status = zx_port_wait(port_, ZX_TIME_INFINITE, &pkt, 1);
+      zx_status_t status = zx_port_wait(port_, ZX_TIME_INFINITE, &pkt);
       if (status != ZX_OK) {
         FATAL1("ExitCodeHandler: zx_port_wait failed: %s\n",
                zx_status_get_string(status));
@@ -397,7 +397,7 @@
   }
   while ((out_tmp != NULL) || (err_tmp != NULL) || (exit_tmp != NULL)) {
     zx_port_packet_t pkt;
-    status = zx_port_wait(port, ZX_TIME_INFINITE, &pkt, 1);
+    status = zx_port_wait(port, ZX_TIME_INFINITE, &pkt);
     if (status != ZX_OK) {
       Log::PrintErr("Process::Wait: zx_port_wait failed: %s\n",
                     zx_status_get_string(status));
diff --git a/runtime/bin/typed_data_utils.cc b/runtime/bin/typed_data_utils.cc
new file mode 100644
index 0000000..6c08ca5
--- /dev/null
+++ b/runtime/bin/typed_data_utils.cc
@@ -0,0 +1,65 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "bin/typed_data_utils.h"
+#include "platform/assert.h"
+
+namespace dart {
+namespace bin {
+
+TypedDataScope::TypedDataScope(Dart_Handle data) : data_handle_(data) {
+  Dart_Handle result;
+  result = Dart_TypedDataAcquireData(data, &type_, &data_, &length_);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+}
+
+void TypedDataScope::Release() {
+  if (data_handle_ == NULL) {
+    return;
+  }
+  Dart_Handle result = Dart_TypedDataReleaseData(data_handle_);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+  data_handle_ = NULL;
+  data_ = NULL;
+  length_ = 0;
+  type_ = Dart_TypedData_kInvalid;
+}
+
+intptr_t TypedDataScope::size_in_bytes() const {
+  switch (type_) {
+    case Dart_TypedData_kByteData:
+    case Dart_TypedData_kInt8:
+    case Dart_TypedData_kUint8:
+    case Dart_TypedData_kUint8Clamped:
+      return length_;
+    case Dart_TypedData_kInt16:
+    case Dart_TypedData_kUint16:
+      return length_ * 2;
+    case Dart_TypedData_kInt32:
+    case Dart_TypedData_kUint32:
+    case Dart_TypedData_kFloat32:
+      return length_ * 4;
+    case Dart_TypedData_kInt64:
+    case Dart_TypedData_kUint64:
+    case Dart_TypedData_kFloat64:
+      return length_ * 8;
+    case Dart_TypedData_kFloat32x4:
+      return length_ * 16;
+    default:
+      UNREACHABLE();
+  }
+}
+
+const char* TypedDataScope::GetScopedCString() const {
+  char* buf = reinterpret_cast<char*>(Dart_ScopeAllocate(size_in_bytes()));
+  strncpy(buf, GetCString(), size_in_bytes());
+  return buf;
+}
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/typed_data_utils.h b/runtime/bin/typed_data_utils.h
new file mode 100644
index 0000000..ff8c57a
--- /dev/null
+++ b/runtime/bin/typed_data_utils.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef RUNTIME_BIN_TYPED_DATA_UTILS_H_
+#define RUNTIME_BIN_TYPED_DATA_UTILS_H_
+
+#include "include/dart_api.h"
+#include "platform/globals.h"
+
+namespace dart {
+namespace bin {
+
+class TypedDataScope {
+ public:
+  explicit TypedDataScope(Dart_Handle data);
+  ~TypedDataScope() { Release(); }
+
+  void Release();
+
+  const char* GetCString() const {
+    return reinterpret_cast<const char*>(data_);
+  }
+
+  const char* GetScopedCString() const;
+
+  void* data() const { return data_; }
+  intptr_t length() const { return length_; }
+  intptr_t size_in_bytes() const;
+  Dart_TypedData_Type type() const { return type_; }
+
+ private:
+  Dart_Handle data_handle_;
+  void* data_;
+  intptr_t length_;
+  Dart_TypedData_Type type_;
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(TypedDataScope);
+};
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // RUNTIME_BIN_TYPED_DATA_UTILS_H_
diff --git a/runtime/bin/utils.h b/runtime/bin/utils.h
index 234a969..a5ec66b 100644
--- a/runtime/bin/utils.h
+++ b/runtime/bin/utils.h
@@ -27,6 +27,9 @@
   }
   virtual ~OSError() { free(message_); }
 
+  // Reload this OSError with the current OS error, discarding the previous.
+  void Reload();
+
   SubSystem sub_system() { return sub_system_; }
   int code() { return code_; }
   char* message() { return message_; }
diff --git a/runtime/bin/utils_android.cc b/runtime/bin/utils_android.cc
index a705997..ed6b5de 100644
--- a/runtime/bin/utils_android.cc
+++ b/runtime/bin/utils_android.cc
@@ -18,12 +18,11 @@
 namespace bin {
 
 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
-  set_sub_system(kSystem);
-  set_code(errno);
-  const int kBufferSize = 1024;
-  char error_message[kBufferSize];
-  Utils::StrError(errno, error_message, kBufferSize);
-  SetMessage(error_message);
+  Reload();
+}
+
+void OSError::Reload() {
+  SetCodeAndMessage(kSystem, errno);
 }
 
 void OSError::SetCodeAndMessage(SubSystem sub_system, int code) {
diff --git a/runtime/bin/utils_fuchsia.cc b/runtime/bin/utils_fuchsia.cc
index e1f3dca..4c8b208 100644
--- a/runtime/bin/utils_fuchsia.cc
+++ b/runtime/bin/utils_fuchsia.cc
@@ -17,11 +17,11 @@
 namespace bin {
 
 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
-  set_sub_system(kSystem);
-  set_code(errno);
-  const int kBufferSize = 1024;
-  char error_buf[kBufferSize];
-  SetMessage(Utils::StrError(errno, error_buf, kBufferSize));
+  Reload();
+}
+
+void OSError::Reload() {
+  SetCodeAndMessage(kSystem, errno);
 }
 
 void OSError::SetCodeAndMessage(SubSystem sub_system, int code) {
diff --git a/runtime/bin/utils_linux.cc b/runtime/bin/utils_linux.cc
index 3e27c0c..b87778a 100644
--- a/runtime/bin/utils_linux.cc
+++ b/runtime/bin/utils_linux.cc
@@ -18,11 +18,11 @@
 namespace bin {
 
 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
-  set_sub_system(kSystem);
-  set_code(errno);
-  const int kBufferSize = 1024;
-  char error_buf[kBufferSize];
-  SetMessage(Utils::StrError(errno, error_buf, kBufferSize));
+  Reload();
+}
+
+void OSError::Reload() {
+  SetCodeAndMessage(kSystem, errno);
 }
 
 void OSError::SetCodeAndMessage(SubSystem sub_system, int code) {
diff --git a/runtime/bin/utils_macos.cc b/runtime/bin/utils_macos.cc
index bec7153..52066bc 100644
--- a/runtime/bin/utils_macos.cc
+++ b/runtime/bin/utils_macos.cc
@@ -21,12 +21,11 @@
 namespace bin {
 
 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
-  set_sub_system(kSystem);
-  set_code(errno);
-  const int kBufferSize = 1024;
-  char error_message[kBufferSize];
-  Utils::StrError(errno, error_message, kBufferSize);
-  SetMessage(error_message);
+  Reload();
+}
+
+void OSError::Reload() {
+  SetCodeAndMessage(kSystem, errno);
 }
 
 void OSError::SetCodeAndMessage(SubSystem sub_system, int code) {
diff --git a/runtime/bin/utils_win.cc b/runtime/bin/utils_win.cc
index 99e9fb8..f4764b4 100644
--- a/runtime/bin/utils_win.cc
+++ b/runtime/bin/utils_win.cc
@@ -32,13 +32,11 @@
 }
 
 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
-  set_code(GetLastError());
+  Reload();
+}
 
-  static const int kMaxMessageLength = 256;
-  wchar_t message[kMaxMessageLength];
-  FormatMessageIntoBuffer(code_, message, kMaxMessageLength);
-  char* utf8 = StringUtilsWin::WideToUtf8(message);
-  SetMessage(utf8);
+void OSError::Reload() {
+  SetCodeAndMessage(kSystem, GetLastError());
 }
 
 void OSError::SetCodeAndMessage(SubSystem sub_system, int code) {
diff --git a/runtime/lib/convert_patch.dart b/runtime/lib/convert_patch.dart
index b2e7ed2..a2c802d 100644
--- a/runtime/lib/convert_patch.dart
+++ b/runtime/lib/convert_patch.dart
@@ -63,6 +63,7 @@
     parser.chunk = input;
     parser.chunkEnd = input.length;
     parser.parse(0);
+    parser.close();
     return parser.result;
   }
 
@@ -398,6 +399,7 @@
   static const int KWD_NULL = 0; // Prefix of "null" seen.
   static const int KWD_TRUE = 4; // Prefix of "true" seen.
   static const int KWD_FALSE = 8; // Prefix of "false" seen.
+  static const int KWD_BOM = 12; // Prefix of BOM seen.
   static const int KWD_COUNT_SHIFT = 4; // Prefix length in bits 4+.
 
   // Mask used to mask off two lower bits.
@@ -439,8 +441,11 @@
    *      ..0ddd0011 : Partial 'null' keyword.
    *      ..0ddd0111 : Partial 'true' keyword.
    *      ..0ddd1011 : Partial 'false' keyword.
-   *                   For all three keywords, the `ddd` bits encode the number
+   *      ..0ddd1111 : Partial UTF-8 BOM byte seqeuence ("\xEF\xBB\xBF").
+   *                   For all keywords, the `ddd` bits encode the number
    *                   of letters seen.
+   *                   The BOM byte sequence is only used by [_JsonUtf8Parser],
+   *                   and only at the very beginning of input.
    */
   int partialState = NO_PARTIAL;
 
@@ -789,7 +794,8 @@
     int keywordType = partialState & KWD_TYPE_MASK;
     int count = partialState >> KWD_COUNT_SHIFT;
     int keywordTypeIndex = keywordType >> KWD_TYPE_SHIFT;
-    String keyword = const ["null", "true", "false"][keywordTypeIndex];
+    String keyword =
+        const ["null", "true", "false", "\xEF\xBB\xBF"][keywordTypeIndex];
     assert(count < keyword.length);
     do {
       if (position == chunkEnd) {
@@ -798,13 +804,19 @@
         return chunkEnd;
       }
       int expectedChar = keyword.codeUnitAt(count);
-      if (getChar(position) != expectedChar) return fail(position);
+      if (getChar(position) != expectedChar) {
+        if (count == 0) {
+          assert(keywordType == KWD_BOM);
+          return position;
+        }
+        return fail(position);
+      }
       position++;
       count++;
     } while (count < keyword.length);
     if (keywordType == KWD_NULL) {
       listener.handleNull();
-    } else {
+    } else if (keywordType != KWD_BOM) {
       listener.handleBool(keywordType == KWD_TRUE);
     }
     return position;
@@ -1255,7 +1267,7 @@
         fail(position, "Missing expected digit");
       } else {
         // If it doesn't even start out as a numeral.
-        fail(position, "Unexpected character");
+        fail(position);
       }
     }
     if (digit == 0) {
@@ -1660,7 +1672,7 @@
           position++;
         } else {
           throw new FormatException(
-              "Unexepected UTF-8 continuation byte", utf8, position);
+              "Unexpected UTF-8 continuation byte", utf8, position);
         }
       } else if (char < 0xE0) {
         // C0-DF
@@ -1726,7 +1738,11 @@
   int chunkEnd;
 
   _JsonUtf8Parser(_JsonListener listener, this.allowMalformed)
-      : super(listener);
+      : super(listener) {
+    // Starts out checking for an optional BOM (KWD_BOM, count = 0).
+    partialState =
+        _ChunkedJsonParser.PARTIAL_KEYWORD | _ChunkedJsonParser.KWD_BOM;
+  }
 
   int getChar(int position) => chunk[position];
 
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 3524eef..1651cfa 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -313,7 +313,7 @@
     return CreateTypedefMirror(cls, type, is_declaration, owner_mirror);
   }
 
-  const Array& args = Array::Handle(Array::New(9));
+  const Array& args = Array::Handle(Array::New(10));
   args.SetAt(0, MirrorReference::Handle(MirrorReference::New(cls)));
   args.SetAt(1, type);
   // Note that the VM does not consider mixin application aliases to be mixin
@@ -328,8 +328,9 @@
   args.SetAt(4, Bool::Get(cls.is_abstract()));
   args.SetAt(5, Bool::Get(cls.IsGeneric()));
   args.SetAt(6, Bool::Get(cls.is_mixin_app_alias()));
-  args.SetAt(7, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration);
-  args.SetAt(8, Bool::Get(cls.is_enum_class()));
+  args.SetAt(7, Bool::Get(cls.is_transformed_mixin_application()));
+  args.SetAt(8, cls.NumTypeParameters() == 0 ? Bool::False() : is_declaration);
+  args.SetAt(9, Bool::Get(cls.is_enum_class()));
   return CreateMirror(Symbols::_LocalClassMirror(), args);
 }
 
@@ -993,7 +994,13 @@
   PROPAGATE_IF_MALFORMED(type);
   ASSERT(type.IsFinalized());
   const Class& cls = Class::Handle(type.type_class());
-  const AbstractType& mixin_type = AbstractType::Handle(cls.mixin());
+  AbstractType& mixin_type = AbstractType::Handle();
+  if (cls.is_transformed_mixin_application()) {
+    const Array& interfaces = Array::Handle(cls.interfaces());
+    mixin_type ^= interfaces.At(interfaces.Length() - 1);
+  } else {
+    mixin_type = cls.mixin();
+  }
   ASSERT(mixin_type.IsNull() || mixin_type.IsFinalized());
   return mixin_type.raw();
 }
@@ -1005,7 +1012,13 @@
   PROPAGATE_IF_MALFORMED(type);
   ASSERT(type.IsFinalized());
   const Class& cls = Class::Handle(type.type_class());
-  const AbstractType& mixin_type = AbstractType::Handle(cls.mixin());
+  AbstractType& mixin_type = AbstractType::Handle();
+  if (cls.is_transformed_mixin_application()) {
+    const Array& interfaces = Array::Handle(cls.interfaces());
+    mixin_type ^= interfaces.At(interfaces.Length() - 1);
+  } else {
+    mixin_type = cls.mixin();
+  }
   if (mixin_type.IsNull()) {
     return mixin_type.raw();
   }
diff --git a/runtime/lib/mirrors_impl.dart b/runtime/lib/mirrors_impl.dart
index 5c42dc4..eb0becb 100644
--- a/runtime/lib/mirrors_impl.dart
+++ b/runtime/lib/mirrors_impl.dart
@@ -356,7 +356,16 @@
   DeclarationMirror _owner;
   final bool isAbstract;
   final bool _isGeneric;
+
+  // Only used for Dart 1 named mixin applications.
+  // TODO(alexmarkov): Clean up after Dart 1 is gone.
   final bool _isMixinAlias;
+
+  // Since Dart 2, mixins are erased by kernel transformation.
+  // Resulting classes have this flag set, and mixed-in type is pulled into
+  // the end of interfaces list.
+  final bool _isTransformedMixinApplication;
+
   final bool _isGenericDeclaration;
   final bool isEnum;
   Type _instantiator;
@@ -369,6 +378,7 @@
       this.isAbstract,
       this._isGeneric,
       this._isMixinAlias,
+      this._isTransformedMixinApplication,
       this._isGenericDeclaration,
       this.isEnum)
       : this._simpleName = _s(simpleName),
@@ -443,6 +453,9 @@
       var interfaceTypes = isOriginalDeclaration
           ? _nativeInterfaces(_reflectedType)
           : _nativeInterfacesInstantiated(_reflectedType);
+      if (_isTransformedMixinApplication) {
+        interfaceTypes = interfaceTypes.sublist(0, interfaceTypes.length - 1);
+      }
       var interfaceMirrors = new List<ClassMirror>();
       for (var interfaceType in interfaceTypes) {
         interfaceMirrors.add(reflectType(interfaceType));
@@ -570,6 +583,7 @@
         new UnmodifiableMapView<Symbol, DeclarationMirror>(decls);
   }
 
+  // Note: returns correct result only for Dart 1 anonymous mixin applications.
   bool get _isAnonymousMixinApplication {
     if (_isMixinAlias) return false; // Named mixin application.
     if (mixin == this) return false; // Not a mixin application.
@@ -579,7 +593,7 @@
   List<TypeVariableMirror> _typeVariables;
   List<TypeVariableMirror> get typeVariables {
     if (_typeVariables == null) {
-      if (_isAnonymousMixinApplication) {
+      if (!_isTransformedMixinApplication && _isAnonymousMixinApplication) {
         return _typeVariables = const <TypeVariableMirror>[];
       }
       _typeVariables = new List<TypeVariableMirror>();
@@ -600,7 +614,8 @@
   List<TypeMirror> _typeArguments;
   List<TypeMirror> get typeArguments {
     if (_typeArguments == null) {
-      if (_isGenericDeclaration || _isAnonymousMixinApplication) {
+      if (_isGenericDeclaration ||
+          (!_isTransformedMixinApplication && _isAnonymousMixinApplication)) {
         _typeArguments = const <TypeMirror>[];
       } else {
         _typeArguments = new UnmodifiableListView<TypeMirror>(
@@ -734,7 +749,7 @@
   final _functionReflectee;
   _LocalFunctionTypeMirror(reflectee, this._functionReflectee, reflectedType)
       : super(reflectee, reflectedType, null, null, false, false, false, false,
-            false);
+            false, false);
 
   bool get _isAnonymousMixinApplication => false;
 
diff --git a/runtime/observatory/BUILD.gn b/runtime/observatory/BUILD.gn
index badb8cb..61ddc8f 100644
--- a/runtime/observatory/BUILD.gn
+++ b/runtime/observatory/BUILD.gn
@@ -43,12 +43,12 @@
            "--command",
            "build",
            rebase_path("web/main.dart"),
-           rebase_path("$root_gen_dir/observatory/web/main.dart.js"),
+           rebase_path("$target_gen_dir/observatory/web/main.dart.js"),
            rebase_path("dart2js.packages"),
          ]
 
   outputs = [
-    "$root_gen_dir/observatory/web/main.dart.js",
+    "$target_gen_dir/observatory/web/main.dart.js",
   ]
 }
 
@@ -59,32 +59,28 @@
 
   inputs = [
     script,
-    "$root_gen_dir/observatory/web/main.dart.js",
+    "$target_gen_dir/observatory/web/main.dart.js",
   ]
 
   args = build_args + [
            "--silent=True",
            "--directory",
-           rebase_path("$root_out_dir/observatory"),
+           rebase_path("$target_out_dir/observatory"),
            "--command",
            "deploy",
-           rebase_path("$root_out_dir/observatory/deployed"),
+           rebase_path("$target_out_dir/observatory/deployed"),
            rebase_path("web"),
            rebase_path("lib"),
-           rebase_path("$root_gen_dir/observatory/web/main.dart.js"),
+           rebase_path("$target_gen_dir/observatory/web/main.dart.js"),
            rebase_path("../../third_party/observatory_pub_packages/packages"),
          ]
 
   outputs = [
-    "$root_out_dir/observatory/deployed/web/main.dart.js",
+    "$target_out_dir/observatory/deployed/web/main.dart.js",
   ]
 }
 
 template("observatory_archive") {
-  assert(defined(invoker.inner_namespace),
-         "Need inner_namespace in $target_name")
-  assert(defined(invoker.outer_namespace),
-         "Need outer_namespace in $target_name")
   enable_compression = false
   if (defined(invoker.compress) && invoker.compress) {
     enable_compression = true
@@ -95,42 +91,97 @@
     ]
 
     inputs = [
-      "$root_out_dir/observatory/deployed/web/main.dart.js",
+      "$target_out_dir/observatory/deployed/web/main.dart.js",
     ]
 
-    inner_namespace = invoker.inner_namespace
-    outer_namespace = invoker.outer_namespace
     output_name = target_name
 
+    output = "$target_gen_dir/${output_name}.tar"
+    outputs = [
+      output,
+    ]
+
     script = "../tools/create_archive.py"
     args = [
-      "--output",
-      rebase_path("$root_gen_dir/observatory/${output_name}.cc"),
       "--tar_output",
-      rebase_path("$root_gen_dir/observatory/${output_name}.tar"),
-      "--outer_namespace",
-      outer_namespace,
-      "--inner_namespace",
-      inner_namespace,
-      "--name",
-      "observatory_assets_archive",
+      rebase_path(output),
       "--client_root",
-      rebase_path("$root_out_dir/observatory/deployed/web/"),
+      rebase_path("$target_out_dir/observatory/deployed/web/"),
     ]
     if (enable_compression) {
       args += [ "--compress" ]
     }
+  }
+}
 
+observatory_archive("compressed_observatory_archive") {
+  compress = true
+}
+
+observatory_archive("observatory_archive") {
+  compress = false
+}
+
+# Generates a .cc file containing the bytes of the observatory archive in a C
+# array.
+#
+# Parameters:
+#  inner_namespace (required):
+#    The inner C++ namespace that the C array lives in.
+#
+#  outer_namespace (required):
+#    The outer C++ namespace that the C array lives in.
+#
+#  archive_file (required):
+#    The path to the observatory archive.
+#
+template("observatory_archive_source") {
+  assert(defined(invoker.inner_namespace),
+         "Need inner_namespace in $target_name")
+  assert(defined(invoker.outer_namespace),
+         "Need outer_namespace in $target_name")
+  assert(defined(invoker.archive_file), "Need archive_file in $target_name")
+
+  action(target_name) {
+    forward_variables_from(invoker, [ "deps" ])
+
+    inputs = [
+      invoker.archive_file,
+    ]
+
+    output = "$target_gen_dir/${target_name}.cc"
     outputs = [
-      "$root_gen_dir/observatory/${output_name}.cc",
-      "$root_gen_dir/observatory/${output_name}.tar",
+      output,
+    ]
+
+    script = "../tools/create_archive.py"
+    args = [
+      "--tar_input",
+      rebase_path(invoker.archive_file),
+      "--output",
+      rebase_path(output),
+      "--outer_namespace",
+      invoker.outer_namespace,
+      "--inner_namespace",
+      invoker.inner_namespace,
+      "--name",
+      "observatory_assets_archive",
     ]
   }
 }
 
-observatory_archive("embedded_archive_observatory") {
+observatory_archive_source("embedded_archive_observatory") {
   outer_namespace = "dart"
   inner_namespace = "observatory"
+
+  # TODO(zra): In a Fuchsia build, use a prebuilt Observatory archive.
+  archive_target = ":observatory_archive"
+  deps = [
+    archive_target,
+  ]
+  archive_dir = get_label_info(archive_target, "target_gen_dir")
+  archive_name = get_label_info(archive_target, "name")
+  archive_file = "${archive_dir}/${archive_name}.tar"
 }
 
 source_set("embedded_observatory_archive") {
@@ -139,14 +190,22 @@
   ]
 
   sources = [
-    rebase_path("$root_gen_dir/observatory/embedded_archive_observatory.cc"),
+    rebase_path("$target_gen_dir/embedded_archive_observatory.cc"),
   ]
 }
 
-observatory_archive("standalone_archive_observatory") {
-  compress = true
+observatory_archive_source("standalone_archive_observatory") {
   outer_namespace = "dart"
   inner_namespace = "bin"
+
+  # TODO(zra): In a Fuchsia build, use a prebuilt Observatory archive.
+  archive_target = ":compressed_observatory_archive"
+  deps = [
+    archive_target,
+  ]
+  archive_dir = get_label_info(archive_target, "target_gen_dir")
+  archive_name = get_label_info(archive_target, "name")
+  archive_file = "${archive_dir}/${archive_name}.tar"
 }
 
 source_set("standalone_observatory_archive") {
@@ -155,6 +214,6 @@
   ]
 
   sources = [
-    rebase_path("$root_gen_dir/observatory/standalone_archive_observatory.cc"),
+    rebase_path("$target_gen_dir/standalone_archive_observatory.cc"),
   ]
 }
diff --git a/runtime/observatory/bin/shell.dart b/runtime/observatory/bin/shell.dart
index ae4e7ff..a0cb274 100644
--- a/runtime/observatory/bin/shell.dart
+++ b/runtime/observatory/bin/shell.dart
@@ -29,7 +29,8 @@
 
 void main() {
   String addr = 'ws://localhost:8181/ws';
-  new WebSocketVM(new WebSocketVMTarget(addr)).load().then((VM vm) {
+  new WebSocketVM(new WebSocketVMTarget(addr)).load().then((serviceObject) {
+    VM vm = serviceObject;
     Isolate isolate = vm.isolates.first;
     repl(vm, isolate, 'isolate ${isolate.id}');
   });
diff --git a/runtime/observatory/lib/service.dart b/runtime/observatory/lib/service.dart
index 10028cb..9af0604 100644
--- a/runtime/observatory/lib/service.dart
+++ b/runtime/observatory/lib/service.dart
@@ -14,5 +14,6 @@
 import 'package:observatory/event.dart' show createEventFromServiceEvent;
 import 'package:observatory/models.dart' as M;
 import 'package:observatory/tracer.dart';
+import 'package:observatory/service_common.dart';
 
 part 'src/service/object.dart';
diff --git a/runtime/observatory/lib/src/allocation_profile/allocation_profile.dart b/runtime/observatory/lib/src/allocation_profile/allocation_profile.dart
index b8f9f03..d84be6c 100644
--- a/runtime/observatory/lib/src/allocation_profile/allocation_profile.dart
+++ b/runtime/observatory/lib/src/allocation_profile/allocation_profile.dart
@@ -47,7 +47,7 @@
       accumulators.addAll(new Map.fromIterable(values, value: (_) => classes));
     });
     final List<M.ClassHeapStats> result = <M.ClassHeapStats>[];
-    members.forEach((ClassHeapStats member) {
+    members.forEach((M.ClassHeapStats member) {
       if (accumulators.containsKey(member.clazz.id)) {
         accumulators[member.clazz.id].add(member);
       } else {
diff --git a/runtime/observatory/lib/src/app/application.dart b/runtime/observatory/lib/src/app/application.dart
index 8ea5b0a..79e85ef 100644
--- a/runtime/observatory/lib/src/app/application.dart
+++ b/runtime/observatory/lib/src/app/application.dart
@@ -20,7 +20,7 @@
   VM _vm;
   VM get vm => _vm;
 
-  static bool isConnectedVMTarget(WebSocketVMTarget target) {
+  static bool isConnectedVMTarget(M.Target target) {
     if (app._vm is CommonWebSocketVM) {
       if ((app._vm as CommonWebSocketVM).target == target) {
         return app._vm.isConnected;
diff --git a/runtime/observatory/lib/src/app/location_manager.dart b/runtime/observatory/lib/src/app/location_manager.dart
index 38dd94c..cf77504 100644
--- a/runtime/observatory/lib/src/app/location_manager.dart
+++ b/runtime/observatory/lib/src/app/location_manager.dart
@@ -161,7 +161,7 @@
     event.preventDefault();
     // 'currentTarget' is the dom element that would process the event.
     // If we use 'target' we might get an <em> element or somesuch.
-    var target = event.currentTarget;
+    Element target = event.currentTarget;
     go(target.attributes['href']);
   }
 }
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index 67fcc89..248cacc 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -170,7 +170,8 @@
       app.locationManager.go(Uris.vmConnect());
       return;
     }
-    app.vm.reload().then((VM vm) {
+    app.vm.reload().then((serviceObject) {
+      VM vm = serviceObject;
       container.children = [
         new VMViewElement(vm, _vmrepository, app.events, app.notifications,
             new IsolateRepository(app.vm), _scriptRepository,
@@ -706,7 +707,8 @@
       return;
     }
     final editor = getEditor(uri);
-    app.vm.reload().then((VM vm) async {
+    app.vm.reload().then((serviceObject) async {
+      VM vm = serviceObject;
       // Preload all isolates to avoid sorting problems.
       await Future.wait(vm.isolates.map((i) => i.load()));
       container.children = [
diff --git a/runtime/observatory/lib/src/elements/allocation_profile.dart b/runtime/observatory/lib/src/elements/allocation_profile.dart
index 5fb89b4..f11e63a 100644
--- a/runtime/observatory/lib/src/elements/allocation_profile.dart
+++ b/runtime/observatory/lib/src/elements/allocation_profile.dart
@@ -455,7 +455,8 @@
     _r.dirty();
   }
 
-  void _updateCollectionLine(Element e, M.ClassHeapStats item, index) {
+  void _updateCollectionLine(Element e, itemDynamic, index) {
+    M.ClassHeapStats item = itemDynamic;
     e.children[0].text = Utils.formatSize(_getAccumulatedSize(item));
     e.children[1].text = '${_getAccumulatedInstances(item)}';
     e.children[2].text = Utils.formatSize(_getCurrentSize(item));
diff --git a/runtime/observatory/lib/src/elements/class_allocation_profile.dart b/runtime/observatory/lib/src/elements/class_allocation_profile.dart
index 2b7979d..36df884 100644
--- a/runtime/observatory/lib/src/elements/class_allocation_profile.dart
+++ b/runtime/observatory/lib/src/elements/class_allocation_profile.dart
@@ -75,7 +75,7 @@
       children = const [];
       return;
     }
-    final content = [
+    final content = <HtmlElement>[
       new SampleBufferControlElement(_vm, _progress, _progressStream,
           selectedTag: _tag, queue: _r.queue)
         ..onTagChange.listen((e) {
diff --git a/runtime/observatory/lib/src/elements/class_tree.dart b/runtime/observatory/lib/src/elements/class_tree.dart
index 2a74a06..904014c 100644
--- a/runtime/observatory/lib/src/elements/class_tree.dart
+++ b/runtime/observatory/lib/src/elements/class_tree.dart
@@ -188,7 +188,8 @@
     return children;
   }
 
-  Iterable<M.Class> _children(M.Class cls) {
+  Iterable<M.Class> _children(classDynamic) {
+    M.Class cls = classDynamic;
     return _subclasses[cls.id];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/class_view.dart b/runtime/observatory/lib/src/elements/class_view.dart
index b9f612f..95c5279 100644
--- a/runtime/observatory/lib/src/elements/class_view.dart
+++ b/runtime/observatory/lib/src/elements/class_view.dart
@@ -252,7 +252,7 @@
                         new ButtonElement()
                           ..text = 'disable'
                           ..onClick.listen((e) async {
-                            e.target.disabled = true;
+                            (e.target as ButtonElement).disabled = true;
                             await _profiles.disable(_isolate, _cls);
                             _loadProfile = true;
                             _refresh();
@@ -263,7 +263,7 @@
                         new ButtonElement()
                           ..text = 'enable'
                           ..onClick.listen((e) async {
-                            e.target.disabled = true;
+                            (e.target as ButtonElement).disabled = true;
                             await _profiles.enable(_isolate, _cls);
                             _refresh();
                           })
diff --git a/runtime/observatory/lib/src/elements/containers/virtual_collection.dart b/runtime/observatory/lib/src/elements/containers/virtual_collection.dart
index b9bea3e..810de3a 100644
--- a/runtime/observatory/lib/src/elements/containers/virtual_collection.dart
+++ b/runtime/observatory/lib/src/elements/containers/virtual_collection.dart
@@ -246,7 +246,7 @@
     }
   }
 
-  Iterable<dynamic> _doSearch(String search) {
+  Iterable<dynamic> _doSearch(Pattern search) {
     return _items.where((item) => _search(search, item));
   }
 }
diff --git a/runtime/observatory/lib/src/elements/context_ref.dart b/runtime/observatory/lib/src/elements/context_ref.dart
index 5b6bcb0..25b1fa5 100644
--- a/runtime/observatory/lib/src/elements/context_ref.dart
+++ b/runtime/observatory/lib/src/elements/context_ref.dart
@@ -65,7 +65,7 @@
   }
 
   void render() {
-    var children = [
+    var children = <HtmlElement>[
       new AnchorElement(href: Uris.inspect(_isolate, object: _context))
         ..children = [
           new SpanElement()
diff --git a/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart b/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart
index 559a8988..c4caa7c 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile/virtual_tree.dart
@@ -188,7 +188,10 @@
       ];
   }
 
-  static _getChildren(M.CallTreeNode node) => node.children;
+  static Iterable<M.CallTreeNode> _getChildren(nodeDynamic) {
+    M.CallTreeNode node = nodeDynamic;
+    return node.children;
+  }
 
   static const String _expandedIcon = '▼';
   static const String _collapsedIcon = '►';
diff --git a/runtime/observatory/lib/src/elements/cpu_profile_table.dart b/runtime/observatory/lib/src/elements/cpu_profile_table.dart
index d140e3c..3e141a1 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile_table.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile_table.dart
@@ -222,7 +222,8 @@
     return element;
   }
 
-  void _updateFunction(Element e, M.ProfileFunction item, int index) {
+  void _updateFunction(Element e, itemDynamic, int index) {
+    M.ProfileFunction item = itemDynamic;
     if (item == _selected) {
       e.classes = ['function-item', 'selected'];
     } else {
diff --git a/runtime/observatory/lib/src/elements/debugger.dart b/runtime/observatory/lib/src/elements/debugger.dart
index 5cda2a5..119e352 100644
--- a/runtime/observatory/lib/src/elements/debugger.dart
+++ b/runtime/observatory/lib/src/elements/debugger.dart
@@ -65,7 +65,7 @@
       var commands = debugger.cmd.matchCommand([], false);
       commands.sort((a, b) => a.name.compareTo(b.name));
       con.print('List of commands:\n');
-      for (var command in commands) {
+      for (DebuggerCommand command in commands) {
         con.print('${_nameAndAlias(command).padRight(12)} '
             '- ${command.helpShort}');
       }
@@ -88,7 +88,7 @@
         return new Future.value(null);
       }
       con.print('');
-      for (var command in commands) {
+      for (DebuggerCommand command in commands) {
         con.printBold(_nameAndAlias(command));
         con.print(command.helpLong);
 
@@ -101,7 +101,7 @@
         if (subCommands.isNotEmpty) {
           subCommands.sort((a, b) => a.name.compareTo(b.name));
           con.print('Subcommands:\n');
-          for (var subCommand in subCommands) {
+          for (DebuggerCommand subCommand in subCommands) {
             con.print('    ${subCommand.fullName.padRight(16)} '
                 '- ${subCommand.helpShort}');
           }
@@ -657,7 +657,7 @@
   Future run(List<String> args) async {
     if (args.length == 0) {
       for (var name in _options.keys) {
-        var getHandler = _options[name][2];
+        dynamic getHandler = _options[name][2];
         var value = await getHandler(debugger, name);
         debugger.console.print("${name} = ${value}");
       }
@@ -668,7 +668,7 @@
         debugger.console.print("unrecognized option: $name");
         return;
       } else {
-        var getHandler = optionInfo[2];
+        dynamic getHandler = optionInfo[2];
         var value = await getHandler(debugger, name);
         debugger.console.print("${name} = ${value}");
       }
@@ -680,12 +680,12 @@
         debugger.console.print("unrecognized option: $name");
         return;
       }
-      var validValues = optionInfo[0];
+      dynamic validValues = optionInfo[0];
       if (!validValues.contains(value)) {
         debugger.console.print("'${value}' is not in ${validValues}");
         return;
       }
-      var setHandler = optionInfo[1];
+      dynamic setHandler = optionInfo[1];
       await setHandler(debugger, name, value);
     } else {
       debugger.console.print("set expects 0, 1, or 2 arguments");
@@ -696,7 +696,7 @@
     if (args.length < 1 || args.length > 2) {
       return new Future.value([args.join('')]);
     }
-    var result = [];
+    var result = <String>[];
     if (args.length == 1) {
       var prefix = args[0];
       for (var option in _options.keys) {
@@ -931,7 +931,7 @@
       }
       toRemove.add(bptToRemove);
     }
-    List pending = [];
+    List<Future> pending = [];
     for (var bpt in toRemove) {
       pending.add(debugger.isolate.removeBreakpoint(bpt));
     }
@@ -1041,7 +1041,7 @@
     if (args.length != 1) {
       return new Future.value([args.join('')]);
     }
-    var result = [];
+    var result = <String>[];
     for (var isolate in debugger.vm.isolates) {
       var str = isolate.number.toString();
       if (str.startsWith(args[0])) {
@@ -1086,7 +1086,7 @@
     }
 
     // Refresh all isolates first.
-    var pending = [];
+    var pending = <Future>[];
     for (var isolate in debugger.vm.isolates) {
       pending.add(isolate.reload());
     }
@@ -1508,7 +1508,8 @@
       breakOnException = isolate.exceptionsPauseInfo;
     }
 
-    isolate.reload().then((response) {
+    isolate.reload().then((serviceObject) {
+      S.Isolate response = serviceObject;
       if (response.isSentinel) {
         // The isolate has gone away.  The IsolateExit event will
         // clear the isolate for the debugger page.
@@ -1516,7 +1517,7 @@
       }
       // TODO(turnidge): Currently the debugger relies on all libs
       // being loaded.  Fix this.
-      var pending = [];
+      var pending = <Future>[];
       for (var lib in response.libraries) {
         if (!lib.loaded) {
           pending.add(lib.load());
@@ -1697,20 +1698,20 @@
   void onEvent(S.ServiceEvent event) {
     switch (event.kind) {
       case S.ServiceEvent.kVMUpdate:
-        var vm = event.owner;
+        S.VM vm = event.owner;
         console.print("VM ${vm.displayName} renamed to '${vm.name}'");
         break;
 
       case S.ServiceEvent.kIsolateStart:
         {
-          var iso = event.owner;
+          S.Isolate iso = event.owner;
           console.print("Isolate ${iso.number} '${iso.name}' has been created");
         }
         break;
 
       case S.ServiceEvent.kIsolateExit:
         {
-          var iso = event.owner;
+          S.Isolate iso = event.owner;
           if (iso == isolate) {
             console.print("The current isolate ${iso.number} '${iso.name}' "
                 "has exited");
@@ -1735,7 +1736,7 @@
         break;
 
       case S.ServiceEvent.kIsolateUpdate:
-        var iso = event.owner;
+        S.Isolate iso = event.owner;
         console.print("Isolate ${iso.number} renamed to '${iso.name}'");
         break;
 
@@ -1914,7 +1915,7 @@
         await isolate.addBreakpoint(script, line);
       } else {
         // TODO(turnidge): Clear this breakpoint at current column.
-        var pending = [];
+        var pending = <Future>[];
         for (var bpt in bpts) {
           pending.add(isolate.removeBreakpoint(bpt));
         }
@@ -2019,7 +2020,7 @@
     assert(objects != null);
     assert(scripts != null);
     assert(events != null);
-    final e = document.createElement(tag.name);
+    final DebuggerPageElement e = document.createElement(tag.name);
     final debugger = new ObservatoryDebugger(isolate);
     debugger.page = e;
     debugger.objects = objects;
@@ -2210,7 +2211,7 @@
     assert(objects != null);
     assert(scripts != null);
     assert(events != null);
-    final e = document.createElement(tag.name);
+    final DebuggerStackElement e = document.createElement(tag.name);
     e._isolate = isolate;
     e._debugger = debugger;
     e._scroller = scroller;
diff --git a/runtime/observatory/lib/src/elements/eval_box.dart b/runtime/observatory/lib/src/elements/eval_box.dart
index 6f6191a..ca167b5 100644
--- a/runtime/observatory/lib/src/elements/eval_box.dart
+++ b/runtime/observatory/lib/src/elements/eval_box.dart
@@ -133,7 +133,7 @@
     ];
   }
 
-  TextInputElement _createEvalTextArea() {
+  TextAreaElement _createEvalTextArea() {
     var area = new TextAreaElement()
       ..classes = ['textbox']
       ..placeholder = 'evaluate an expression'
diff --git a/runtime/observatory/lib/src/elements/heap_map.dart b/runtime/observatory/lib/src/elements/heap_map.dart
index 6e313e8..f11f825 100644
--- a/runtime/observatory/lib/src/elements/heap_map.dart
+++ b/runtime/observatory/lib/src/elements/heap_map.dart
@@ -181,7 +181,7 @@
     var pagePixels = _pageHeight * _fragmentationData.width;
     var index = new PixelReference(_fragmentationData, point).index;
     var pageIndex = index ~/ pagePixels;
-    var pageOffset = index % pagePixels;
+    num pageOffset = index % pagePixels;
     var pages = _fragmentation['pages'];
     if (pageIndex < 0 || pageIndex >= pages.length) {
       return null;
@@ -289,9 +289,8 @@
     if (gc != null) {
       params['gc'] = gc;
     }
-    return isolate
-        .invokeRpc('_getHeapMap', params)
-        .then((S.ServiceMap response) {
+    return isolate.invokeRpc('_getHeapMap', params).then((serviceObject) {
+      S.ServiceMap response = serviceObject;
       assert(response['type'] == 'HeapMap');
       _fragmentation = response;
       _updateFragmentationData();
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart
index 59296ec..a6b0953 100644
--- a/runtime/observatory/lib/src/elements/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart
@@ -188,7 +188,7 @@
   VirtualTreeElement _tree;
 
   List<Element> _createReport() {
-    var report = [
+    var report = <HtmlElement>[
       new DivElement()
         ..classes = ['content-centered-big']
         ..children = [
@@ -397,7 +397,8 @@
   static const int kMaxChildren = 100;
   static const int kMinRetainedSize = 4096;
 
-  static Iterable _getChildrenDominator(M.HeapSnapshotDominatorNode node) {
+  static Iterable _getChildrenDominator(nodeDynamic) {
+    M.HeapSnapshotDominatorNode node = nodeDynamic;
     final list = node.children.toList();
     list.sort((a, b) => b.retainedSize - a.retainedSize);
     return list
@@ -405,8 +406,8 @@
         .take(kMaxChildren);
   }
 
-  static Iterable _getChildrenMergedDominator(
-      M.HeapSnapshotMergedDominatorNode node) {
+  static Iterable _getChildrenMergedDominator(nodeDynamic) {
+    M.HeapSnapshotMergedDominatorNode node = nodeDynamic;
     final list = node.children.toList();
     list.sort((a, b) => b.retainedSize - a.retainedSize);
     return list
diff --git a/runtime/observatory/lib/src/elements/memory/allocations.dart b/runtime/observatory/lib/src/elements/memory/allocations.dart
index 329e6ba..64f9595 100644
--- a/runtime/observatory/lib/src/elements/memory/allocations.dart
+++ b/runtime/observatory/lib/src/elements/memory/allocations.dart
@@ -221,7 +221,8 @@
     _r.dirty();
   }
 
-  void _updateCollectionLine(Element e, M.ClassHeapStats item, index) {
+  void _updateCollectionLine(Element e, itemDynamic, index) {
+    M.ClassHeapStats item = itemDynamic;
     e.children[0].text = Utils.formatSize(_getAccumulatedSize(item));
     e.children[1].text = '${_getAccumulatedInstances(item)}';
     e.children[2].text = Utils.formatSize(_getCurrentSize(item));
diff --git a/runtime/observatory/lib/src/elements/memory/snapshot.dart b/runtime/observatory/lib/src/elements/memory/snapshot.dart
index fd91ebc..d6adcf3e 100644
--- a/runtime/observatory/lib/src/elements/memory/snapshot.dart
+++ b/runtime/observatory/lib/src/elements/memory/snapshot.dart
@@ -186,7 +186,8 @@
   static const int kMaxChildren = 100;
   static const int kMinRetainedSize = 4096;
 
-  static Iterable _getChildrenDominator(M.HeapSnapshotDominatorNode node) {
+  static Iterable _getChildrenDominator(nodeDynamic) {
+    M.HeapSnapshotDominatorNode node = nodeDynamic;
     final list = node.children.toList();
     list.sort((a, b) => b.retainedSize - a.retainedSize);
     return list
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index f6ded1c..6937c9e 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -94,10 +94,10 @@
         if (loc.tokenPos != null) {
           line = _loadedScript.tokenToLine(loc.tokenPos);
         } else {
-          line = loc.line;
+          line = (loc as dynamic).line;
         }
       } else {
-        line = loc.line;
+        line = (loc as dynamic).line;
       }
       if ((line == null) || ((line >= _startLine) && (line <= _endLine))) {
         _r.dirty();
@@ -170,7 +170,7 @@
   void _scrollToCurrentPos() {
     var lines = getElementsByClassName(makeLineClass(_currentLine));
     if (lines.length > 0) {
-      lines[0].scrollIntoView();
+      (lines[0] as dynamic).scrollIntoView();
     }
   }
 
@@ -227,7 +227,7 @@
       reports.add(S.Isolate.kProfileReport);
     }
     S.Isolate isolate = _isolate as S.Isolate;
-    var sourceReport =
+    dynamic sourceReport =
         await isolate.getSourceReport(reports, script, _startPos, _endPos);
     _possibleBreakpointLines =
         S.getPossibleBreakpointLines(sourceReport, script);
@@ -355,8 +355,9 @@
   }
 
   Future loadDeclarationsOfLibrary(S.Library lib) {
-    return lib.load().then((lib) {
-      var loads = [];
+    return lib.load().then((serviceObject) {
+      S.Library lib = serviceObject;
+      var loads = <Future>[];
       for (var func in lib.functions) {
         loads.add(func.load());
       }
@@ -371,8 +372,9 @@
   }
 
   Future loadDeclarationsOfClass(S.Class cls) {
-    return cls.load().then((cls) {
-      var loads = [];
+    return cls.load().then((serviceObject) {
+      S.Class cls = serviceObject;
+      var loads = <Future>[];
       for (var func in cls.functions) {
         loads.add(func.load());
       }
@@ -431,9 +433,9 @@
       }
     }
     if (targetUri.scheme == 'package') {
-      targetUri = "packages/${targetUri.path}";
+      var targetUriString = "packages/${targetUri.path}";
       for (M.Library l in script.isolate.libraries) {
-        if (targetUri.toString() == l.uri) {
+        if (targetUriString == l.uri) {
           return l;
         }
       }
@@ -814,7 +816,7 @@
         });
       } else {
         // Existing breakpoint.  Remove it.
-        List pending = [];
+        List<Future> pending = [];
         for (var bpt in line.breakpoints) {
           pending.add(line.script.isolate.removeBreakpoint(bpt));
         }
@@ -928,7 +930,7 @@
   /// children have been added, and only supports one node at a time.
   static void _makeCssClassUncopyable(Element root, String className) {
     var noCopyNodes = root.getElementsByClassName(className);
-    for (var node in noCopyNodes) {
+    for (HtmlElement node in noCopyNodes) {
       node.style.setProperty('-moz-user-select', 'none');
       node.style.setProperty('-khtml-user-select', 'none');
       node.style.setProperty('-webkit-user-select', 'none');
@@ -938,11 +940,11 @@
     root.onCopy.listen((event) {
       // Mark the nodes as hidden before the copy happens, then mark them as
       // visible on the next event loop turn.
-      for (var node in noCopyNodes) {
+      for (HtmlElement node in noCopyNodes) {
         node.style.visibility = 'hidden';
       }
       Timer.run(() {
-        for (var node in noCopyNodes) {
+        for (HtmlElement node in noCopyNodes) {
           node.style.visibility = 'visible';
         }
       });
@@ -1065,7 +1067,7 @@
   BreakpointAnnotation(M.IsolateRef isolate, M.ObjectRepository objects,
       RenderingQueue queue, this.bpt)
       : super(isolate, objects, queue) {
-    var script = bpt.location.script;
+    S.Script script = bpt.location.script;
     var location = bpt.location;
     if (location.tokenPos != null) {
       var pos = location.tokenPos;
@@ -1089,7 +1091,7 @@
     if (element == null) {
       return; // TODO(rmacnak): Handling overlapping annotations.
     }
-    var script = bpt.location.script;
+    S.Script script = bpt.location.script;
     var pos = bpt.location.tokenPos;
     int line = script.tokenToLine(pos);
     int column = script.tokenToCol(pos);
diff --git a/runtime/observatory/lib/src/models/objects/instance.dart b/runtime/observatory/lib/src/models/objects/instance.dart
index 982d6d8..1a1b8d4 100644
--- a/runtime/observatory/lib/src/models/objects/instance.dart
+++ b/runtime/observatory/lib/src/models/objects/instance.dart
@@ -420,37 +420,37 @@
   ///
   /// Provided for instance kinds:
   ///   RegExp
-  Function get oneByteFunction;
+  FunctionRef get oneByteFunction;
 
   /// [optional]
   ///
   /// Provided for instance kinds:
   ///   RegExp
-  Function get twoByteFunction;
+  FunctionRef get twoByteFunction;
 
   /// [optional]
   ///
   /// Provided for instance kinds:
   ///   RegExp
-  Function get externalOneByteFunction;
+  FunctionRef get externalOneByteFunction;
 
   /// [optional]
   ///
   /// Provided for instance kinds:
   ///   RegExp
-  Function get externalTwoByteFunction;
+  FunctionRef get externalTwoByteFunction;
 
   /// [optional]
   ///
   /// Provided for instance kinds:
   ///   RegExp
-  Instance get oneByteBytecode;
+  InstanceRef get oneByteBytecode;
 
   /// [optional]
   ///
   /// Provided for instance kinds:
   ///   RegExp
-  Instance get twoByteBytecode;
+  InstanceRef get twoByteBytecode;
 }
 
 abstract class BoundField {
diff --git a/runtime/observatory/lib/src/repositories/allocation_profile.dart b/runtime/observatory/lib/src/repositories/allocation_profile.dart
index 8698428..a1f364f 100644
--- a/runtime/observatory/lib/src/repositories/allocation_profile.dart
+++ b/runtime/observatory/lib/src/repositories/allocation_profile.dart
@@ -21,7 +21,7 @@
     if (reset) {
       params['reset'] = true;
     }
-    final response = await isolate.invokeRpc(_api, params);
+    final dynamic response = await isolate.invokeRpc(_api, params);
     Map defaults;
     if (combine) {
       defaults = await isolate.vm.invokeRpcNoUpgrade(_defaultsApi, {});
diff --git a/runtime/observatory/lib/src/repositories/sample_profile.dart b/runtime/observatory/lib/src/repositories/sample_profile.dart
index 6778262..3dace5a 100644
--- a/runtime/observatory/lib/src/repositories/sample_profile.dart
+++ b/runtime/observatory/lib/src/repositories/sample_profile.dart
@@ -146,7 +146,7 @@
 
 class ClassSampleProfileRepository implements M.ClassSampleProfileRepository {
   Stream<SampleProfileLoadingProgressEvent> get(
-      M.Isolate i, M.ClassRef c, M.SampleProfileTag t,
+      covariant M.Isolate i, M.ClassRef c, M.SampleProfileTag t,
       {bool clear: false, bool forceFetch: false}) {
     S.Isolate isolate = i as S.Isolate;
     S.Class cls = c as S.Class;
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 26ff6ab..6c52677 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -654,6 +654,7 @@
 abstract class VM extends ServiceObjectOwner implements M.VM {
   VM get vm => this;
   Isolate get isolate => null;
+  WebSocketVMTarget get target;
 
   // TODO(turnidge): The connection should not be stored in the VM object.
   bool get isDisconnected;
@@ -813,7 +814,7 @@
 
   // Note that this function does not reload the isolate if it found
   // in the cache.
-  Future<ServiceObject> getIsolate(String isolateId) {
+  Future<Isolate> getIsolate(String isolateId) {
     if (!loaded) {
       // Trigger a VM load, then get the isolate.
       return load().then((_) => getIsolate(isolateId)).catchError(_ignoreError);
@@ -1077,6 +1078,9 @@
     }
     return new Future.value(response);
   }
+
+  @override
+  WebSocketVMTarget get target => throw new UnimplementedError();
 }
 
 /// Snapshot in time of tag counters.
diff --git a/runtime/observatory/lib/utils.dart b/runtime/observatory/lib/utils.dart
index 4957014..4167fb5 100644
--- a/runtime/observatory/lib/utils.dart
+++ b/runtime/observatory/lib/utils.dart
@@ -96,7 +96,8 @@
     }
   }
 
-  static String formatSize(int bytes) {
+  static String formatSize(bytesDynamic) {
+    int bytes = bytesDynamic;
     const int digits = 1;
     const int bytesPerKB = 1024;
     const int bytesPerMB = 1024 * bytesPerKB;
diff --git a/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.dart b/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.dart
index 472bc70..5fe996a 100644
--- a/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.dart
+++ b/runtime/observatory/tests/observatory_ui/allocation_profile/element_test.dart
@@ -89,7 +89,7 @@
       e
           .querySelectorAll(rTag)
           .sublist(1, 4)
-          .forEach((NavRefreshElement e) => e.refresh());
+          .forEach((e) => (e as NavRefreshElement).refresh());
       e.remove();
       await e.onRendered.first;
       expect(e.children.length, isZero, reason: 'is empty');
diff --git a/runtime/observatory/tests/observatory_ui/flag_list/element_test.dart b/runtime/observatory/tests/observatory_ui/flag_list/element_test.dart
index 727eb0b..e2c74f5 100644
--- a/runtime/observatory/tests/observatory_ui/flag_list/element_test.dart
+++ b/runtime/observatory/tests/observatory_ui/flag_list/element_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:html';
+import 'package:observatory/models.dart' as M;
 import 'package:unittest/unittest.dart';
 import 'package:observatory/src/elements/flag_list.dart';
 import 'package:observatory/src/elements/nav/notify.dart';
@@ -32,7 +33,7 @@
         const FlagMock(name: 'f2', comment: 'c2', modified: false),
         const FlagMock(name: 'f3', comment: 'c3', modified: false),
       ];
-      final flags = []..addAll(modified)..addAll(unmodifed);
+      final flags = <M.Flag>[]..addAll(modified)..addAll(unmodifed);
       final repository = new FlagsRepositoryMock(list: flags);
       final e = new FlagListElement(vm, events, repository, notifications);
       document.body.append(e);
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/instance.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/instance.dart
index aa72df2..df07d2c 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/instance.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/instance.dart
@@ -50,7 +50,7 @@
   final M.ContextRef closureContext;
   final int offset;
   final int count;
-  final Iterable<dynamic> typedElements;
+  final List<dynamic> typedElements;
   final Iterable<M.BoundField> fields;
   final Iterable<M.NativeField> nativeFields;
   final Iterable<M.Guarded<M.ObjectRef>> elements;
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/sample_profile.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/sample_profile.dart
index 13c521f..0beeaea 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/sample_profile.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/sample_profile.dart
@@ -44,7 +44,7 @@
   final ClassSampleProfileRepositoryMockToggleCallback _disable;
 
   Stream<M.SampleProfileLoadingProgressEvent> get(
-      M.Isolate isolate, M.ClassRef cls, M.SampleProfileTag tag,
+      covariant M.Isolate isolate, M.ClassRef cls, M.SampleProfileTag tag,
       {bool clear: false, bool forceFetch: false}) {
     if (_get != null) {
       return _get(isolate, cls, tag, clear, forceFetch);
@@ -52,14 +52,14 @@
     return null;
   }
 
-  Future enable(M.Isolate isolate, M.ClassRef cls) {
+  Future enable(covariant M.Isolate isolate, M.ClassRef cls) {
     if (_enable != null) {
       return _enable(isolate, cls);
     }
     return new Future.value();
   }
 
-  Future disable(M.Isolate isolate, M.ClassRef cls) {
+  Future disable(covariant M.Isolate isolate, M.ClassRef cls) {
     if (_disable != null) {
       return _disable(isolate, cls);
     }
diff --git a/runtime/observatory/tests/service/add_breakpoint_rpc_test.dart b/runtime/observatory/tests/service/add_breakpoint_rpc_test.dart
index 4d917e1..6a982a0 100644
--- a/runtime/observatory/tests/service/add_breakpoint_rpc_test.dart
+++ b/runtime/observatory/tests/service/add_breakpoint_rpc_test.dart
@@ -78,7 +78,8 @@
     expect(await futureBpt2.location.getColumn(), equals(3));
 
     // The first breakpoint hits before value is modified.
-    expect((await rootLib.evaluate('value')).valueAsString, equals('0'));
+    expect(((await rootLib.evaluate('value')) as Instance).valueAsString,
+        equals('0'));
 
     stream = await isolate.vm.getEventStream(VM.kDebugStream);
     completer = new Completer();
@@ -92,7 +93,8 @@
     await completer.future;
 
     // The second breakpoint hits after value has been modified once.
-    expect((await rootLib.evaluate('value')).valueAsString, equals('1'));
+    expect(((await rootLib.evaluate('value')) as Instance).valueAsString,
+        equals('1'));
 
     // Remove the breakpoints.
     expect(
@@ -148,7 +150,9 @@
     expect(await latentBpt2.location.getColumn(), equals(3));
 
     // The first breakpoint hits before value is modified.
-    expect((await rootLib.evaluate('deferredLib.value')).valueAsString,
+    expect(
+        ((await rootLib.evaluate('deferredLib.value')) as Instance)
+            .valueAsString,
         equals('0'));
 
     stream = await isolate.vm.getEventStream(VM.kDebugStream);
@@ -163,7 +167,9 @@
     await completer.future;
 
     // The second breakpoint hits after value has been modified once.
-    expect((await rootLib.evaluate('deferredLib.value')).valueAsString,
+    expect(
+        ((await rootLib.evaluate('deferredLib.value')) as Instance)
+            .valueAsString,
         equals('-1'));
 
     // Remove the breakpoints.
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index d93a63c..afebf2f 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -2,6 +2,116 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+[ $compiler == app_jitk ]
+add_breakpoint_rpc_test: RuntimeError
+async_generator_breakpoint_test: RuntimeError
+async_next_test: RuntimeError
+async_scope_test: RuntimeError
+async_single_step_exception_test: RuntimeError
+async_single_step_into_test: RuntimeError
+async_single_step_out_test: RuntimeError
+async_star_single_step_into_test: RuntimeError
+async_star_step_out_test: RuntimeError
+async_step_out_test: RuntimeError
+awaiter_async_stack_contents_test: RuntimeError
+bad_reload_test: RuntimeError
+break_on_activation_test: RuntimeError
+break_on_function_test: RuntimeError
+breakpoint_in_parts_class_test: RuntimeError
+breakpoint_two_args_checked_test: RuntimeError
+causal_async_stack_contents_test: RuntimeError
+causal_async_stack_presence_test: RuntimeError
+causal_async_star_stack_contents_test: RuntimeError
+causal_async_star_stack_presence_test: RuntimeError
+complex_reload_test: RuntimeError
+coverage_leaf_function_test: RuntimeError
+coverage_optimized_function_test: RuntimeError
+debugger_inspect_test: Skip # Timeout
+debugger_location_second_test: RuntimeError
+debugger_location_test: RuntimeError
+debugging_inlined_finally_test: RuntimeError
+debugging_test: RuntimeError
+developer_service_get_isolate_id_test: RuntimeError
+eval_internal_class_test: RuntimeError
+eval_test: RuntimeError
+evaluate_activation_in_method_class_test: RuntimeError
+evaluate_activation_test/instance: RuntimeError
+evaluate_activation_test/none: RuntimeError
+evaluate_activation_test/scope: RuntimeError
+evaluate_async_closure_test: RuntimeError
+evaluate_class_type_parameters_test: RuntimeError
+evaluate_in_async_activation_test: RuntimeError
+evaluate_in_async_star_activation_test: RuntimeError
+evaluate_in_frame_rpc_test: RuntimeError
+evaluate_in_frame_with_scope_test: RuntimeError
+evaluate_in_sync_star_activation_test: RuntimeError
+evaluate_with_scope_test: RuntimeError
+get_instances_rpc_test: RuntimeError
+get_object_rpc_test: RuntimeError
+get_retaining_path_rpc_test: RuntimeError
+get_source_report_test: RuntimeError
+get_stack_rpc_test: RuntimeError
+get_user_level_retaining_path_rpc_test: RuntimeError
+get_vm_rpc_test: RuntimeError
+get_vm_timeline_rpc_test: RuntimeError
+instance_field_order_rpc_test: RuntimeError
+issue_25465_test: RuntimeError
+issue_27238_test: RuntimeError
+issue_27287_test: RuntimeError
+local_variable_declaration_test: RuntimeError
+mixin_break_test: RuntimeError
+next_through_assign_call_test: RuntimeError
+next_through_assign_int_test: RuntimeError
+next_through_call_on_field_in_class_test: RuntimeError
+next_through_call_on_field_test: RuntimeError
+next_through_call_on_static_field_in_class_test: RuntimeError
+next_through_catch_test: RuntimeError
+next_through_closure_test: RuntimeError
+next_through_create_list_and_map_test: RuntimeError
+next_through_for_each_loop_test: RuntimeError
+next_through_for_loop_with_break_and_continue_test: RuntimeError
+next_through_function_expression_test: RuntimeError
+next_through_implicit_call_test: RuntimeError
+next_through_is_and_as_test: RuntimeError
+next_through_multi_catch_test: RuntimeError
+next_through_new_test: RuntimeError
+next_through_operator_bracket_on_super_test: RuntimeError
+next_through_operator_bracket_on_this_test: RuntimeError
+next_through_operator_bracket_test: RuntimeError
+next_through_simple_async_test: RuntimeError
+next_through_simple_async_with_returns_test: RuntimeError
+next_through_simple_linear_2_test: RuntimeError
+next_through_simple_linear_test: RuntimeError
+parameters_in_scope_at_entry_test: RuntimeError
+pause_on_exceptions_test: Skip # Timeout
+pause_on_unhandled_async_exceptions2_test: RuntimeError
+pause_on_unhandled_async_exceptions_test: RuntimeError
+positive_token_pos_test: RuntimeError
+process_service_test: RuntimeError
+regress_28443_test: RuntimeError
+regress_28980_test: RuntimeError
+rewind_optimized_out_test: RuntimeError
+rewind_test: RuntimeError
+set_library_debuggable_test: RuntimeError
+set_name_rpc_test: RuntimeError
+set_vm_name_rpc_test: RuntimeError
+steal_breakpoint_test: RuntimeError
+step_into_async_no_await_test: RuntimeError
+step_over_await_test: RuntimeError
+step_through_arithmetic_test: RuntimeError
+step_through_constructor_calls_test: RuntimeError
+step_through_constructor_test: RuntimeError
+step_through_function_2_test: RuntimeError
+step_through_function_test: RuntimeError
+step_through_getter_test: RuntimeError
+step_through_property_get_test: RuntimeError
+step_through_property_set_test: RuntimeError
+step_through_setter_test: RuntimeError
+step_through_switch_test: RuntimeError
+step_through_switch_with_continue_test: RuntimeError
+unused_changes_in_last_reload_test: RuntimeError
+valid_source_locations_test: RuntimeError
+
 # Kernel works slightly different. There are kernel specific versions.
 # These are the non-kernel specific versions so skip tests and allow errors.
 [ $compiler == dartk ]
@@ -34,6 +144,10 @@
 [ $arch == simdbc64 && $compiler == dartk && $mode == debug ]
 eval_test: Pass, Slow
 
+[ $compiler == app_jitk && $mode == debug ]
+code_test: RuntimeError
+step_test: RuntimeError
+
 [ $compiler == dartk && $mode == debug ]
 isolate_lifecycle_test: Skip # Flaky.
 pause_idle_isolate_test: Skip # Flaky
@@ -139,6 +253,3 @@
 set_name_rpc_test: RuntimeError # Please triage.
 unused_changes_in_last_reload_test: Skip # Times out on sim architectures.
 valid_source_locations_test: Pass, Slow, Timeout # Issue 33087
-
-[ $compiler == fasta && $strong ]
-add_breakpoint_rpc_test: CompileTimeError
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 517d182..8c09582 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -151,10 +151,6 @@
 #define NOT_IN_PRECOMPILED(code) code
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 
-#if defined(DART_PRECOMPILED_RUNTIME) || defined(PRODUCT)
-#define EXCLUDE_CFE_AND_KERNEL_PLATFORM 1
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
 namespace dart {
 
 struct simd128_value_t {
diff --git a/runtime/runtime_args.gni b/runtime/runtime_args.gni
index f6586e2..cfff1af 100644
--- a/runtime/runtime_args.gni
+++ b/runtime/runtime_args.gni
@@ -81,4 +81,8 @@
   # Whether the runtime should interpret called functions for which bytecode
   # is provided by kernel, rather than compile them before execution.
   dart_use_interpreter = false
+
+  # Whether the VM includes the kernel service in all modes (debug, release,
+  # product).
+  exclude_kernel_service = false
 }
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 2cf1c6e..92c4f22 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -26,6 +26,12 @@
 [ $compiler == app_jit ]
 dart/snapshot_version_test: Fail, OK # Expects to find script snapshot relative to Dart source.
 
+[ $compiler == app_jitk ]
+dart/data_uri_import_test/utf16: MissingRuntimeError
+dart/redirection_type_shuffling_test/00: RuntimeError
+dart/redirection_type_shuffling_test/none: RuntimeError
+dart/snapshot_version_test: RuntimeError
+
 [ $compiler == dart2analyzer ]
 dart/byte_array_optimized_test: CompileTimeError # int64
 dart/byte_array_test: CompileTimeError # int64
@@ -117,6 +123,9 @@
 cc/Profiler_TrivialRecordAllocation: Skip
 cc/Profiler_TypedArrayAllocation: Skip
 
+[ $arch == x64 && $compiler == dartk && $system == windows && $strong ]
+cc/Profiler_BasicSourcePosition: Fail # http://dartbug.com/33224
+
 [ $arch == x64 && $system == windows ]
 cc/Profiler_BinaryOperatorSourcePositionOptimized: Pass, Fail # Issue 31137
 cc/Profiler_ClosureAllocation: Pass, Fail # Issue 31137
diff --git a/runtime/tools/create_archive.py b/runtime/tools/create_archive.py
index c1fc70d..2857db4 100755
--- a/runtime/tools/create_archive.py
+++ b/runtime/tools/create_archive.py
@@ -16,7 +16,7 @@
 import tempfile
 import gzip
 
-def makeArchive(tar_path, client_root, compress, files):
+def CreateTarArchive(tar_path, client_root, compress, files):
   mode_string = 'w'
   tar = tarfile.open(tar_path, mode=mode_string)
   for input_file_name in files:
@@ -42,7 +42,35 @@
       gz.write(uncompressed)
       gz.close()
 
-def writeCCFile(output_file,
+
+def MakeArchive(options):
+  if not options.client_root:
+    sys.stderr.write('--client_root not specified')
+    return -1
+
+  files = [ ]
+  for dirname, dirnames, filenames in os.walk(options.client_root):
+    # strip out all dot files.
+    filenames = [f for f in filenames if not f[0] == '.']
+    dirnames[:] = [d for d in dirnames if not d[0] == '.']
+    for f in filenames:
+      src_path = os.path.join(dirname, f)
+      if (os.path.isdir(src_path)):
+          continue
+      files.append(src_path)
+
+  # Ensure consistent file ordering for reproducible builds.
+  files.sort()
+
+  # Write out archive.
+  CreateTarArchive(options.tar_output,
+                   options.client_root,
+                   options.compress,
+                   files)
+  return 0
+
+
+def WriteCCFile(output_file,
                 outer_namespace,
                 inner_namespace,
                 name,
@@ -89,13 +117,41 @@
 
   open(output_file, 'w').write(cc_text)
 
-def main(args):
+
+def MakeCCFile(options):
+  if not options.output:
+    sys.stderr.write('--output not specified\n')
+    return -1
+  if not options.name:
+    sys.stderr.write('--name not specified\n')
+    return -1
+  if not options.tar_input:
+    sys.stderr.write('--tar_input not specified\n')
+    return -1
+
+  # Read it back in.
+  with open(options.tar_input, 'rb') as tar_file:
+    tar_archive = tar_file.read()
+
+  # Write CC file.
+  WriteCCFile(options.output,
+              options.outer_namespace,
+              options.inner_namespace,
+              options.name,
+              tar_archive)
+  return 0
+
+
+def Main(args):
   try:
     # Parse input.
     parser = OptionParser()
     parser.add_option("--output",
                       action="store", type="string",
                       help="output file name")
+    parser.add_option("--tar_input",\
+                      action="store", type="string",
+                      help="input tar archive")
     parser.add_option("--tar_output",
                       action="store", type="string",
                       help="tar output file name")
@@ -116,51 +172,11 @@
                       help="root directory client resources")
 
     (options, args) = parser.parse_args()
-    if not options.output:
-      sys.stderr.write('--output not specified\n')
-      return -1
-    if not options.tar_output:
-      sys.stderr.write('--tar_output not specified\n')
-      return -1
-    if not options.name:
-      sys.stderr.write('--name not specified\n')
-      return -1
-    if not options.client_root:
-      sys.stderr.write('--client_root not specified')
-      return -1
 
-    files = [ ]
-
-    for dirname, dirnames, filenames in os.walk(options.client_root):
-      # strip out all dot files.
-      filenames = [f for f in filenames if not f[0] == '.']
-      dirnames[:] = [d for d in dirnames if not d[0] == '.']
-      for f in filenames:
-        src_path = os.path.join(dirname, f)
-        if (os.path.isdir(src_path)):
-            continue
-        files.append(src_path)
-
-    # Ensure consistent file ordering for reproducible builds.
-    files.sort()
-
-    # Write out archive.
-    makeArchive(options.tar_output,
-                options.client_root,
-                options.compress,
-                files)
-
-    # Read it back in.
-    with open(options.tar_output, 'rb') as tar_file:
-      tar_archive = tar_file.read()
-
-    # Write CC file.
-    writeCCFile(options.output,
-                options.outer_namespace,
-                options.inner_namespace,
-                options.name,
-                tar_archive)
-    return 0
+    if options.tar_output:
+      return MakeArchive(options)
+    else:
+      return MakeCCFile(options)
 
   except Exception, inst:
     sys.stderr.write('create_resources.py exception\n')
@@ -168,5 +184,6 @@
     sys.stderr.write('\n')
     return -1
 
+
 if __name__ == '__main__':
-  sys.exit(main(sys.argv))
+  sys.exit(Main(sys.argv))
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 2d94185..3d4eea8 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -3150,6 +3150,31 @@
   return Type::New(mixin_app_class, mixin_app_args, mixin_app_type.token_pos());
 }
 
+// For a class used as an interface marks this class and all its superclasses
+// implemented.
+//
+// Does not mark its interfaces implemented because those would already be
+// marked as such.
+static void MarkImplemented(Zone* zone, const Class& iface) {
+  if (iface.is_implemented()) {
+    return;
+  }
+
+  Class& cls = Class::Handle(zone, iface.raw());
+  AbstractType& type = AbstractType::Handle(zone);
+
+  while (!cls.is_implemented()) {
+    cls.set_is_implemented();
+
+    type = cls.super_type();
+    if (type.IsNull() || type.IsObjectType()) {
+      break;
+    }
+    ASSERT(type.IsResolved());
+    cls = type.type_class();
+  }
+}
+
 // Recursively walks the graph of explicitly declared super type and
 // interfaces, resolving unresolved super types and interfaces.
 // Reports an error if there is an interface reference that cannot be
@@ -3328,9 +3353,10 @@
         }
       }
     }
-    interface_class.set_is_implemented();
+
     // Now resolve the super interfaces.
     ResolveSuperTypeAndInterfaces(interface_class, visited);
+    MarkImplemented(zone, interface_class);
   }
   visited->RemoveLast();
   cls.set_is_cycle_free();
diff --git a/runtime/vm/compiler/assembler/disassembler_arm64.cc b/runtime/vm/compiler/assembler/disassembler_arm64.cc
index 2fb2b93..f5b49f7 100644
--- a/runtime/vm/compiler/assembler/disassembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/disassembler_arm64.cc
@@ -614,9 +614,7 @@
       } else if (format[1] == 'f') {
         ASSERT(STRING_STARTS_WITH(format, "sf"));
         if (instr->SFField() == 1) {
-          // TODO(zra): If we don't use the w form much, we can omit printing
-          // this x.
-          Print("x");
+          // 64-bit width is most commonly used, no need to print "x".
         } else {
           Print("w");
         }
@@ -1142,13 +1140,13 @@
   int32_t mask = B31 | B30 | B29 | B23 | B22 | B21 | B15 | MiscDP3SourceMask;
   int32_t bits = instr->InstructionBits() & mask;
 
-  if (bits == MADD) {
+  if (bits == MADD || bits == MADDW) {
     if (zero_operand) {
       Format(instr, "mul'sf 'rd, 'rn, 'rm");
     } else {
       Format(instr, "madd'sf 'rd, 'rn, 'rm, 'ra");
     }
-  } else if (bits == MSUB) {
+  } else if (bits == MSUB || bits == MSUBW) {
     if (zero_operand) {
       Format(instr, "mneg'sf 'rd, 'rn, 'rm");
     } else {
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index ddea9fe..93d70f3 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -3362,8 +3362,9 @@
   return GetCachedConstant(offset, &result_);
 }
 
-Instance& StreamingConstantEvaluator::EvaluateExpression(intptr_t offset,
-                                                         bool reset_position) {
+RawInstance* StreamingConstantEvaluator::EvaluateExpression(
+    intptr_t offset,
+    bool reset_position) {
   ASSERT(Error::Handle(Z, H.thread()->sticky_error()).IsNull());
   if (!GetCachedConstant(offset, &result_)) {
     ASSERT(IsAllowedToEvaluate());
@@ -3481,9 +3482,7 @@
       builder_->SkipExpression();
     }
   }
-  // We return a new `ZoneHandle` here on purpose: The intermediate language
-  // instructions do not make a copy of the handle, so we do it.
-  return Instance::ZoneHandle(Z, result_.raw());
+  return result_.raw();
 }
 
 Instance& StreamingConstantEvaluator::EvaluateListLiteral(intptr_t offset,
@@ -3538,7 +3537,7 @@
   return Instance::ZoneHandle(Z, result_.raw());
 }
 
-Object& StreamingConstantEvaluator::EvaluateExpressionSafe(intptr_t offset) {
+RawObject* StreamingConstantEvaluator::EvaluateExpressionSafe(intptr_t offset) {
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     return EvaluateExpression(offset);
@@ -3547,7 +3546,7 @@
     Error& error = Error::Handle(Z);
     error = thread->sticky_error();
     thread->clear_sticky_error();
-    return error;
+    return error.raw();
   }
 }
 
@@ -3695,8 +3694,9 @@
 void StreamingConstantEvaluator::EvaluateMethodInvocation() {
   builder_->ReadPosition();  // read position.
   // This method call wasn't cached, so receiver et al. isn't cached either.
-  const Instance& receiver =
-      EvaluateExpression(builder_->ReaderOffset(), false);  // read receiver.
+  const Instance& receiver = Instance::Handle(
+      Z,
+      EvaluateExpression(builder_->ReaderOffset(), false));  // read receiver.
   Class& klass =
       Class::Handle(Z, isolate_->class_table()->At(receiver.GetClassId()));
   ASSERT(!klass.IsNull());
@@ -3721,8 +3721,9 @@
 void StreamingConstantEvaluator::EvaluateDirectMethodInvocation() {
   builder_->ReadPosition();  // read position.
 
-  const Instance& receiver =
-      EvaluateExpression(builder_->ReaderOffset(), false);  // read receiver.
+  const Instance& receiver = Instance::Handle(
+      Z,
+      EvaluateExpression(builder_->ReaderOffset(), false));  // read receiver.
 
   NameIndex kernel_name =
       builder_->ReadCanonicalNameReference();  // read target_reference.
@@ -3828,7 +3829,7 @@
   Instance* receiver = NULL;
   const TypeArguments* type_arguments_argument = NULL;
   if (!constructor.IsFactory()) {
-    receiver = &Instance::ZoneHandle(Z, Instance::New(klass, Heap::kOld));
+    receiver = &Instance::Handle(Z, Instance::New(klass, Heap::kOld));
     if (type_arguments != NULL) {
       receiver->SetTypeArguments(*type_arguments);
     }
@@ -3991,9 +3992,10 @@
   const Array& const_list =
       Array::ZoneHandle(Z, Array::New(length, Heap::kOld));
   const_list.SetTypeArguments(type_arguments);
+  Instance& expression = Instance::Handle(Z);
   for (intptr_t i = 0; i < length; ++i) {
-    const Instance& expression = EvaluateExpression(
-        builder_->ReaderOffset(), false);  // read ith expression.
+    expression = EvaluateExpression(builder_->ReaderOffset(),
+                                    false);  // read ith expression.
     const_list.SetAt(i, expression);
   }
   const_list.MakeImmutable();
@@ -4008,13 +4010,13 @@
   intptr_t length = builder_->ReadListLength();  // read length of entries.
 
   // This MapLiteral wasn't cached, so content isn't cached either.
-  Array& const_kv_array =
-      Array::ZoneHandle(Z, Array::New(2 * length, Heap::kOld));
+  Array& const_kv_array = Array::Handle(Z, Array::New(2 * length, Heap::kOld));
+  Instance& temp = Instance::Handle(Z);
   for (intptr_t i = 0; i < length; ++i) {
-    const_kv_array.SetAt(2 * i + 0, EvaluateExpression(builder_->ReaderOffset(),
-                                                       false));  // read key.
-    const_kv_array.SetAt(2 * i + 1, EvaluateExpression(builder_->ReaderOffset(),
-                                                       false));  // read value.
+    temp = EvaluateExpression(builder_->ReaderOffset(), false);  // read key.
+    const_kv_array.SetAt(2 * i + 0, temp);
+    temp = EvaluateExpression(builder_->ReaderOffset(), false);  // read value.
+    const_kv_array.SetAt(2 * i + 1, temp);
   }
 
   const_kv_array.MakeImmutable();
@@ -4050,8 +4052,9 @@
   if (tag == kNothing) {
     local->SetConstValue(Instance::ZoneHandle(Z, Instance::null()));
   } else {
-    local->SetConstValue(EvaluateExpression(
-        builder_->ReaderOffset(), false));  // read rest of initializer.
+    local->SetConstValue(Instance::ZoneHandle(
+        Z, EvaluateExpression(builder_->ReaderOffset(),
+                              false)));  // read rest of initializer.
   }
 
   EvaluateExpression(builder_->ReaderOffset(), false);  // read body
@@ -4059,8 +4062,9 @@
 
 void StreamingConstantEvaluator::EvaluatePartialTearoffInstantiation() {
   // This method call wasn't cached, so receiver et al. isn't cached either.
-  const Instance& receiver =
-      EvaluateExpression(builder_->ReaderOffset(), false);  // read receiver.
+  const Instance& receiver = Instance::Handle(
+      Z,
+      EvaluateExpression(builder_->ReaderOffset(), false));  // read receiver.
   if (!receiver.IsClosure()) {
     H.ReportError(script_, TokenPosition::kNoSource, "Expected closure.");
   }
@@ -4069,26 +4073,16 @@
   // read type arguments.
   intptr_t num_type_args = builder_->ReadListLength();
   const TypeArguments* type_args = &T.BuildTypeArguments(num_type_args);
-  // Even if all dynamic types are passed in, we need to put a vector in here to
-  // distinguish this partially applied tearoff from a normal tearoff. This is
-  // necessary because the tearoff wrapper (BuildGraphOfImplicitClosureFunction)
-  // needs to throw NSM if type arguments are passed to a partially applied
-  // tearoff.
-  if (type_args->IsNull()) {
-    type_args =
-        &TypeArguments::ZoneHandle(Z, TypeArguments::New(num_type_args));
-    for (intptr_t i = 0; i < num_type_args; ++i) {
-      type_args->SetTypeAt(i, Type::ZoneHandle(Z, Type::DynamicType()));
-    }
-  }
 
   // Create new closure with the type arguments inserted, and other things
   // copied over.
   Closure& new_closure = Closure::Handle(
-      Z, Closure::New(TypeArguments::Handle(
-                          Z, old_closure.instantiator_type_arguments()),
-                      *type_args, Function::Handle(Z, old_closure.function()),
-                      Context::Handle(Z, old_closure.context()), Heap::kOld));
+      Z,
+      Closure::New(
+          TypeArguments::Handle(Z, old_closure.instantiator_type_arguments()),
+          TypeArguments::Handle(old_closure.function_type_arguments()),
+          *type_args, Function::Handle(Z, old_closure.function()),
+          Context::Handle(Z, old_closure.context()), Heap::kOld));
   result_ = H.Canonicalize(new_closure);
 }
 
@@ -4159,7 +4153,7 @@
       (receiver != NULL ? 1 : 0) + (type_args != NULL ? 1 : 0);
 
   // Build up arguments.
-  const Array& arguments = Array::ZoneHandle(
+  const Array& arguments = Array::Handle(
       Z, Array::New(extra_arguments + argument_count, H.allocation_space()));
   intptr_t pos = 0;
   if (receiver != NULL) {
@@ -4180,7 +4174,7 @@
   // List of named.
   list_length = builder_->ReadListLength();  // read list length.
   const Array& names =
-      Array::ZoneHandle(Z, Array::New(list_length, H.allocation_space()));
+      Array::Handle(Z, Array::New(list_length, H.allocation_space()));
   for (intptr_t i = 0; i < list_length; ++i) {
     String& name = H.DartSymbolObfuscate(
         builder_->ReadStringReference());  // read ith name index.
@@ -5105,7 +5099,8 @@
       flow_graph_builder_->CheckStackOverflowInPrologue(field_helper.position_);
   if (field_helper.IsConst()) {
     // this will (potentially) read the initializer, but reset the position.
-    body += Constant(constant_evaluator_.EvaluateExpression(ReaderOffset()));
+    body += Constant(Instance::ZoneHandle(
+        Z, constant_evaluator_.EvaluateExpression(ReaderOffset())));
     SkipExpression();  // read the initializer.
   } else {
     body += BuildExpression();  // read initializer.
@@ -5163,7 +5158,8 @@
     // contain because it would detect spurious circular initialization when it
     // checks for the transition sentinel.
     ASSERT(initializer_tag == kSomething);
-    body += Constant(constant_evaluator_.EvaluateExpression(ReaderOffset()));
+    body += Constant(Instance::ZoneHandle(
+        Z, constant_evaluator_.EvaluateExpression(ReaderOffset())));
   } else {
     // The field always has an initializer because static fields without
     // initializers are initialized eagerly and do not have implicit getters.
@@ -5214,8 +5210,8 @@
         if (tag == kSomething) {
           // this will (potentially) read the initializer,
           // but reset the position.
-          default_value =
-              &constant_evaluator_.EvaluateExpression(ReaderOffset());
+          default_value = &Instance::ZoneHandle(
+              Z, constant_evaluator_.EvaluateExpression(ReaderOffset()));
           SkipExpression();  // read (actual) initializer.
         } else {
           default_value = &Instance::ZoneHandle(Z, Instance::null());
@@ -5242,8 +5238,8 @@
         if (tag == kSomething) {
           // this will (potentially) read the initializer,
           // but reset the position.
-          default_value =
-              &constant_evaluator_.EvaluateExpression(ReaderOffset());
+          default_value = &Instance::ZoneHandle(
+              Z, constant_evaluator_.EvaluateExpression(ReaderOffset()));
           SkipExpression();  // read (actual) initializer.
         } else {
           default_value = &Instance::ZoneHandle(Z, Instance::null());
@@ -8452,7 +8448,8 @@
     const Field& field =
         Field::ZoneHandle(Z, H.LookupFieldByKernelField(target));
     if (field.is_const()) {
-      return Constant(constant_evaluator_.EvaluateExpression(offset));
+      return Constant(Instance::ZoneHandle(
+          Z, constant_evaluator_.EvaluateExpression(offset)));
     } else {
       const Class& owner = Class::Handle(Z, field.Owner());
       const String& getter_name = H.DartGetterName(target);
@@ -8474,7 +8471,8 @@
       return StaticCall(position, function, 0, Array::null_array(),
                         ICData::kStatic, &result_type);
     } else if (H.IsMethod(target)) {
-      return Constant(constant_evaluator_.EvaluateExpression(offset));
+      return Constant(Instance::ZoneHandle(
+          Z, constant_evaluator_.EvaluateExpression(offset)));
     } else {
       UNIMPLEMENTED();
     }
@@ -8551,7 +8549,8 @@
     intptr_t argument_count = PeekArgumentsCount() + 1;
 
     if ((argument_count == 1) && (token_kind == Token::kNEGATE)) {
-      const Object& result = constant_evaluator_.EvaluateExpressionSafe(offset);
+      const Object& result = Object::ZoneHandle(
+          Z, constant_evaluator_.EvaluateExpressionSafe(offset));
       if (!result.IsError()) {
         SkipArguments();               // read arguments.
         SkipCanonicalNameReference();  // read interface_target_reference.
@@ -8560,7 +8559,8 @@
     } else if ((argument_count == 2) &&
                Token::IsBinaryArithmeticOperator(token_kind) &&
                IsNumberLiteral(PeekArgumentsFirstPositionalTag())) {
-      const Object& result = constant_evaluator_.EvaluateExpressionSafe(offset);
+      const Object& result = Object::ZoneHandle(
+          Z, constant_evaluator_.EvaluateExpressionSafe(offset));
       if (!result.IsError()) {
         SkipArguments();               // read arguments.
         SkipCanonicalNameReference();  // read interface_target_reference.
@@ -9355,7 +9355,8 @@
 
   intptr_t offset = ReaderOffset() - 1;  // EvaluateExpression needs the tag.
   SkipStringReference();                 // read index into string table.
-  return Constant(constant_evaluator_.EvaluateExpression(offset));
+  return Constant(
+      Instance::ZoneHandle(Z, constant_evaluator_.EvaluateExpression(offset)));
 }
 
 Fragment StreamingFlowGraphBuilder::BuildTypeLiteral(TokenPosition* position) {
@@ -10208,8 +10209,8 @@
         TargetEntryInstr* otherwise;
 
         TokenPosition position = ReadPosition();  // read jth position.
-        current_instructions +=
-            Constant(constant_evaluator_.EvaluateExpression(ReaderOffset()));
+        current_instructions += Constant(Instance::ZoneHandle(
+            Z, constant_evaluator_.EvaluateExpression(ReaderOffset())));
         SkipExpression();  // read jth expression.
         current_instructions += PushArgument();
         current_instructions += LoadLocal(scopes()->switch_variable);
@@ -10666,8 +10667,9 @@
     instructions += NullConstant();
   } else {
     if (helper.IsConst()) {
-      const Instance& constant_value = constant_evaluator_.EvaluateExpression(
-          ReaderOffset());  // read initializer form current position.
+      const Instance& constant_value = Instance::ZoneHandle(
+          Z, constant_evaluator_.EvaluateExpression(
+                 ReaderOffset()));  // read initializer form current position.
       variable->SetConstValue(constant_value);
       instructions += Constant(constant_value);
       SkipExpression();  // skip initializer.
@@ -11048,8 +11050,8 @@
     Tag tag = ReadTag();  // read (first part of) initializer.
     if (tag == kSomething) {
       // this will (potentially) read the initializer, but reset the position.
-      Instance& constant =
-          constant_evaluator_.EvaluateExpression(ReaderOffset());
+      Instance& constant = Instance::ZoneHandle(
+          Z, constant_evaluator_.EvaluateExpression(ReaderOffset()));
       SkipExpression();  // read (actual) initializer.
       param_descriptor.SetAt(entry_start + Parser::kParameterDefaultValueOffset,
                              constant);
@@ -11097,7 +11099,8 @@
       Array::Handle(Z, Array::New(list_length, H.allocation_space()));
   for (intptr_t i = 0; i < list_length; ++i) {
     // this will (potentially) read the expression, but reset the position.
-    Instance& value = constant_evaluator_.EvaluateExpression(ReaderOffset());
+    Instance& value = Instance::ZoneHandle(
+        Z, constant_evaluator_.EvaluateExpression(ReaderOffset()));
     SkipExpression();  // read (actual) initializer.
     metadata_values.SetAt(i, value);
   }
@@ -11341,10 +11344,8 @@
                                                   : Object::bool_false().raw();
         break;
       case kIntConstant: {
-        temp_instance_ = const_evaluator_
-                             .EvaluateExpression(builder_.ReaderOffset(),
-                                                 false /* reset position */)
-                             .raw();
+        temp_instance_ = const_evaluator_.EvaluateExpression(
+            builder_.ReaderOffset(), false /* reset position */);
         break;
       }
       case kDoubleConstant: {
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index ce7dc4d..859d443 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -431,8 +431,10 @@
   };
 
   enum Flag {
-    kIsAbstract = 1,
-    kIsEnumClass = 2,
+    kIsAbstract = 1 << 2,
+    kIsEnumClass = 1 << 3,
+    kIsAnonymousMixin = 1 << 4,
+    kIsEliminatedMixin = 1 << 5,
   };
 
   explicit ClassHelper(KernelReaderHelper* helper)
@@ -447,9 +449,13 @@
   void SetNext(Field field) { next_read_ = field; }
   void SetJustRead(Field field) { next_read_ = field + 1; }
 
-  bool is_abstract() { return flags_ & Flag::kIsAbstract; }
+  bool is_abstract() const { return flags_ & Flag::kIsAbstract; }
 
-  bool is_enum_class() { return flags_ & Flag::kIsEnumClass; }
+  bool is_enum_class() const { return flags_ & Flag::kIsEnumClass; }
+
+  bool is_transformed_mixin_application() const {
+    return flags_ & Flag::kIsEliminatedMixin;
+  }
 
   NameIndex canonical_name_;
   TokenPosition position_;
@@ -923,12 +929,12 @@
 
   bool IsCached(intptr_t offset);
 
-  Instance& EvaluateExpression(intptr_t offset, bool reset_position = true);
+  RawInstance* EvaluateExpression(intptr_t offset, bool reset_position = true);
   Instance& EvaluateListLiteral(intptr_t offset, bool reset_position = true);
   Instance& EvaluateMapLiteral(intptr_t offset, bool reset_position = true);
   Instance& EvaluateConstructorInvocation(intptr_t offset,
                                           bool reset_position = true);
-  Object& EvaluateExpressionSafe(intptr_t offset);
+  RawObject* EvaluateExpressionSafe(intptr_t offset);
 
  private:
   bool IsAllowedToEvaluate();
diff --git a/runtime/vm/compiler/intrinsifier_arm64.cc b/runtime/vm/compiler/intrinsifier_arm64.cc
index d14b824..ef7fb20 100644
--- a/runtime/vm/compiler/intrinsifier_arm64.cc
+++ b/runtime/vm/compiler/intrinsifier_arm64.cc
@@ -1175,6 +1175,9 @@
   // --qh
   __ sub(R6, R6, Operand(1));
 
+  // Continue while loop.
+  __ b(&qh_adj_loop);
+
   __ Bind(&qh_ok);
   // R0 = qd = qh << 32
   __ orr(R0, ZR, Operand(R6, LSL, 32));
@@ -1227,6 +1230,9 @@
   // --ql
   __ sub(R6, R6, Operand(1));
 
+  // Continue while loop.
+  __ b(&ql_adj_loop);
+
   __ Bind(&ql_ok);
   // qd |= ql;
   __ orr(R0, R0, Operand(R6));
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 95b3f87..9294a1b 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -522,8 +522,10 @@
 enum MiscDP3SourceOp {
   MiscDP3SourceMask = 0x1f000000,
   MiscDP3SourceFixed = DPRegisterFixed | B28 | B24,
-  MADD = MiscDP3SourceFixed,
-  MSUB = MiscDP3SourceFixed | B15,
+  MADDW = MiscDP3SourceFixed,
+  MADD = MiscDP3SourceFixed | B31,
+  MSUBW = MiscDP3SourceFixed | B15,
+  MSUB = MiscDP3SourceFixed | B31 | B15,
   SMULH = MiscDP3SourceFixed | B31 | B22,
   UMULH = MiscDP3SourceFixed | B31 | B23 | B22,
   SMADDL = MiscDP3SourceFixed | B31 | B21,
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 09ce27c..e845697 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -700,15 +700,21 @@
 #elif defined(TARGET_ARCH_IA32)
     buffer.AddString(" ia32");
 #elif defined(TARGET_ARCH_X64)
-#if defined(_WIN64)
+#if defined(TARGET_OS_WINDOWS)
     buffer.AddString(" x64-win");
 #else
     buffer.AddString(" x64-sysv");
 #endif
 #elif defined(TARGET_ARCH_DBC)
-    buffer.AddString(" dbc");
-#elif defined(TARGET_ARCH_DBC64)
+#if defined(ARCH_IS_32_BIT)
+    buffer.AddString(" dbc32");
+#elif defined(ARCH_IS_64_BIT)
     buffer.AddString(" dbc64");
+#else
+#error What word size?
+#endif
+#else
+#error What architecture?
 #endif
   }
 
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 61af137..d927ba9 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -801,6 +801,8 @@
 #define FLAG_FOR_NONPRODUCT(action)
 #endif
 
+#define FLAG_FOR_PRODUCT(action) action
+
 #define SET_FROM_FLAG(when, name, bitname, isolate_flag, flag)                 \
   FLAG_FOR_##when(isolate_flags_ = bitname##Bit::update(                       \
                       api_flags.isolate_flag, isolate_flags_));
@@ -809,6 +811,7 @@
 
 #undef FLAG_FOR_NONPRODUCT
 #undef FLAG_FOR_PRECOMPILER
+#undef FLAG_FOR_PRODUCT
 #undef SET_FROM_FLAG
 
   set_use_dart_frontend(api_flags.use_dart_frontend);
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 28c0795..6584382 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -138,10 +138,10 @@
   V(NONPRODUCT, type_checks, EnableTypeChecks, enable_type_checks,             \
     FLAG_enable_type_checks)                                                   \
   V(NONPRODUCT, asserts, EnableAsserts, enable_asserts, FLAG_enable_asserts)   \
-  V(NONPRODUCT, reify_generic_functions, ReifyGenericFunctions,                \
+  V(PRODUCT, reify_generic_functions, ReifyGenericFunctions,                   \
     reify_generic_functions, FLAG_reify_generic_functions)                     \
-  V(NONPRODUCT, sync_async, SyncAsync, sync_async, FLAG_sync_async)            \
-  V(NONPRODUCT, strong, Strong, strong, FLAG_strong)                           \
+  V(PRODUCT, sync_async, SyncAsync, sync_async, FLAG_sync_async)               \
+  V(PRODUCT, strong, Strong, strong, FLAG_strong)                              \
   V(NONPRODUCT, error_on_bad_type, ErrorOnBadType, enable_error_on_bad_type,   \
     FLAG_error_on_bad_type)                                                    \
   V(NONPRODUCT, error_on_bad_override, ErrorOnBadOverride,                     \
@@ -718,6 +718,8 @@
 #define FLAG_FOR_NONPRODUCT(from_field, from_flag) (from_flag)
 #endif
 
+#define FLAG_FOR_PRODUCT(from_field, from_flag) (from_field)
+
 #define DECLARE_GETTER(when, name, bitname, isolate_flag_name, flag_name)      \
   bool name() const {                                                          \
     const bool false_by_default = false;                                       \
@@ -727,6 +729,7 @@
   ISOLATE_FLAG_LIST(DECLARE_GETTER)
 #undef FLAG_FOR_NONPRODUCT
 #undef FLAG_FOR_PRECOMPILER
+#undef FLAG_FOR_PRODUCT
 #undef DECLARE_GETTER
 
 #if defined(PRODUCT)
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index ba05ff0..70a967b 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,7 +20,7 @@
 // package:kernel/binary.md.
 
 static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
-static const uint32_t kBinaryFormatVersion = 6;
+static const uint32_t kBinaryFormatVersion = 7;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 607c1e9..e7f45d2 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -967,6 +967,10 @@
   klass->set_interfaces(interfaces);
 
   if (class_helper->is_abstract()) klass->set_is_abstract();
+
+  if (class_helper->is_transformed_mixin_application()) {
+    klass->set_is_transformed_mixin_application();
+  }
 }
 
 // Workaround for http://dartbug.com/32087: currently Kernel front-end
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index de61db2..d379d22 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3792,6 +3792,11 @@
   set_state_bits(MixinTypeAppliedBit::update(true, raw_ptr()->state_bits_));
 }
 
+void Class::set_is_transformed_mixin_application() const {
+  set_state_bits(
+      TransformedMixinApplicationBit::update(true, raw_ptr()->state_bits_));
+}
+
 void Class::set_is_fields_marked_nullable() const {
   set_state_bits(FieldsMarkedNullableBit::update(true, raw_ptr()->state_bits_));
 }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 1d8dc12..ee04799 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1311,6 +1311,17 @@
   }
   void set_is_mixin_type_applied() const;
 
+  // Tests if this is a mixin application class which was desugared
+  // to a normal class by kernel mixin transformation
+  // (pkg/kernel/lib/transformations/mixin_full_resolution.dart).
+  //
+  // In such case, its mixed-in type was pulled into the end of
+  // interfaces list.
+  bool is_transformed_mixin_application() const {
+    return TransformedMixinApplicationBit::decode(raw_ptr()->state_bits_);
+  }
+  void set_is_transformed_mixin_application() const;
+
   bool is_fields_marked_nullable() const {
     return FieldsMarkedNullableBit::decode(raw_ptr()->state_bits_);
   }
@@ -1470,6 +1481,7 @@
     kFieldsMarkedNullableBit = 11,
     kCycleFreeBit = 12,
     kEnumBit = 13,
+    kTransformedMixinApplicationBit = 14,
     kIsAllocatedBit = 15,
   };
   class ConstBit : public BitField<uint16_t, bool, kConstBit, 1> {};
@@ -1494,6 +1506,8 @@
       : public BitField<uint16_t, bool, kFieldsMarkedNullableBit, 1> {};
   class CycleFreeBit : public BitField<uint16_t, bool, kCycleFreeBit, 1> {};
   class EnumBit : public BitField<uint16_t, bool, kEnumBit, 1> {};
+  class TransformedMixinApplicationBit
+      : public BitField<uint16_t, bool, kTransformedMixinApplicationBit, 1> {};
   class IsAllocatedBit : public BitField<uint16_t, bool, kIsAllocatedBit, 1> {};
 
   void set_name(const String& value) const;
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 3db2d65..5493d43 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -2552,7 +2552,7 @@
       const int32_t alu_out = ra_val - (rn_val * rm_val);
       set_wregister(rd, alu_out, R31IsZR);
     }
-  } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 2) &&
+  } else if ((instr->Bits(29, 3) == 4) && (instr->Bits(21, 3) == 2) &&
              (instr->Bit(15) == 0)) {
     ASSERT(ra == R31);  // Should-Be-One
     // Format(instr, "smulh 'rd, 'rn, 'rm");
@@ -2568,7 +2568,7 @@
     const int64_t alu_out = static_cast<int64_t>(res >> 64);
 #endif  // HOST_OS_WINDOWS
     set_register(instr, rd, alu_out, R31IsZR);
-  } else if ((instr->Bits(29, 2) == 0) && (instr->Bits(21, 3) == 6) &&
+  } else if ((instr->Bits(29, 3) == 4) && (instr->Bits(21, 3) == 6) &&
              (instr->Bit(15) == 0)) {
     ASSERT(ra == R31);  // Should-Be-One
     // Format(instr, "umulh 'rd, 'rn, 'rm");
diff --git a/sdk/bin/dartdevk b/sdk/bin/dartdevk
index f6111dc..6d75105 100755
--- a/sdk/bin/dartdevk
+++ b/sdk/bin/dartdevk
@@ -43,4 +43,4 @@
 
 DEV_COMPILER="$DART_ROOT/pkg/dev_compiler/bin/dartdevk.dart"
 
-exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$@"
+exec "$DART" "--preview-dart-2" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$@"
diff --git a/sdk/bin/dartdevk.bat b/sdk/bin/dartdevk.bat
index 154162a..79c09c5 100644
--- a/sdk/bin/dartdevk.bat
+++ b/sdk/bin/dartdevk.bat
@@ -34,7 +34,7 @@
 
 set DEV_COMPILER=%DART_ROOT%\pkg\dev_compiler\bin\dartdevk.dart
 
-"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "%DEV_COMPILER%" %*
+"%DART%" "--preview-dart-2" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "%DEV_COMPILER%" %*
 
 endlocal
 
diff --git a/sdk/bin/dartdevk_sdk b/sdk/bin/dartdevk_sdk
index 098775a..dc790e4 100755
--- a/sdk/bin/dartdevk_sdk
+++ b/sdk/bin/dartdevk_sdk
@@ -26,4 +26,4 @@
 
 # We are running the snapshot in the built SDK.
 DART="$BIN_DIR/dart"
-exec "$DART" "$SNAPSHOT" "--packages=$SDK_DIR/../../../.packages" "$@"
+exec "$DART" "--preview-dart-2" "$SNAPSHOT" "--packages=$SDK_DIR/../../../.packages" "$@"
diff --git a/sdk/bin/dartdevk_sdk.bat b/sdk/bin/dartdevk_sdk.bat
index 8e490ef..3879afb 100644
--- a/sdk/bin/dartdevk_sdk.bat
+++ b/sdk/bin/dartdevk_sdk.bat
@@ -20,7 +20,7 @@
 rem Remove trailing backslash if there is one
 if %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1%
 
-"%DART%" "%SNAPSHOT%" "--packages=%SDK_DIR%\..\..\..\.packages" %*
+"%DART%" "--preview-dart-2" "%SNAPSHOT%" "--packages=%SDK_DIR%\..\..\..\.packages" %*
 
 endlocal
 
diff --git a/sdk/bin/dartfmt b/sdk/bin/dartfmt
index ad54140..fb58a1e 100755
--- a/sdk/bin/dartfmt
+++ b/sdk/bin/dartfmt
@@ -28,4 +28,4 @@
 
 DARTFMT="$DART_ROOT/third_party/pkg_tested/dart_style/bin/format.dart"
 
-exec "$DART" "--packages=$DART_ROOT/.packages" "$DARTFMT" "$@"
+exec "$DART" "--preview-dart-2" "--packages=$DART_ROOT/.packages" "$DARTFMT" "$@"
diff --git a/sdk/bin/dartfmt.bat b/sdk/bin/dartfmt.bat
index 7a7412b..f668f56 100644
--- a/sdk/bin/dartfmt.bat
+++ b/sdk/bin/dartfmt.bat
@@ -27,7 +27,7 @@
 
 set DARTFMT=%DART_ROOT%\third_party\pkg_tested\dart_style\bin\format.dart
 
-"%DART%" "--packages=%DART_ROOT%\.packages" "%DARTFMT%" %*
+"%DART%" "--preview-dart-2" "--packages=%DART_ROOT%\.packages" "%DARTFMT%" %*
 
 endlocal
 
diff --git a/sdk/bin/dartfmt_sdk b/sdk/bin/dartfmt_sdk
index 273733c..b6b98c4 100755
--- a/sdk/bin/dartfmt_sdk
+++ b/sdk/bin/dartfmt_sdk
@@ -26,4 +26,4 @@
 
 # We are running the snapshot in the built SDK.
 DART="$BIN_DIR/dart"
-exec "$DART" "$SNAPSHOT" "$@"
+exec "$DART" "--preview-dart-2" "$SNAPSHOT" "$@"
diff --git a/sdk/bin/dartfmt_sdk.bat b/sdk/bin/dartfmt_sdk.bat
index 295b977..f746a72 100644
--- a/sdk/bin/dartfmt_sdk.bat
+++ b/sdk/bin/dartfmt_sdk.bat
@@ -14,7 +14,7 @@
 set DART=%BIN_DIR%\dart
 set SNAPSHOT=%BIN_DIR%\snapshots\dartfmt.dart.snapshot
 
-"%DART%" "%SNAPSHOT%" %*
+"%DART%" "--preview-dart-2" "%SNAPSHOT%" %*
 
 endlocal
 
diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
index 7c88473..9cfb7ef 100644
--- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
@@ -17,12 +17,12 @@
   }
 
   @patch
-  static _setCurrent(_Namespace namespace, path) {
+  static _setCurrent(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("Directory_SetCurrent");
   }
 
   @patch
-  static _createTemp(_Namespace namespace, String path) {
+  static _createTemp(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("Directory._createTemp");
   }
 
@@ -32,22 +32,22 @@
   }
 
   @patch
-  static _exists(_Namespace namespace, String path) {
+  static _exists(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("Directory._exists");
   }
 
   @patch
-  static _create(_Namespace namespace, String path) {
+  static _create(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("Directory._create");
   }
 
   @patch
-  static _deleteNative(_Namespace namespace, String path, bool recursive) {
+  static _deleteNative(_Namespace namespace, Uint8List path, bool recursive) {
     throw new UnsupportedError("Directory._deleteNative");
   }
 
   @patch
-  static _rename(_Namespace namespace, String path, String newPath) {
+  static _rename(_Namespace namespace, Uint8List path, String newPath) {
     throw new UnsupportedError("Directory._rename");
   }
 
@@ -55,7 +55,7 @@
   static void _fillWithDirectoryListing(
       _Namespace namespace,
       List<FileSystemEntity> list,
-      String path,
+      Uint8List path,
       bool recursive,
       bool followLinks) {
     throw new UnsupportedError("Directory._fillWithDirectoryListing");
@@ -89,7 +89,8 @@
 @patch
 class FileSystemEntity {
   @patch
-  static _getTypeNative(_Namespace namespace, String path, bool followLinks) {
+  static _getTypeNative(
+      _Namespace namespace, Uint8List path, bool followLinks) {
     throw new UnsupportedError("FileSystemEntity._getType");
   }
 
@@ -99,7 +100,7 @@
   }
 
   @patch
-  static _resolveSymbolicLinks(_Namespace namespace, String path) {
+  static _resolveSymbolicLinks(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("FileSystemEntity._resolveSymbolicLinks");
   }
 }
@@ -107,77 +108,77 @@
 @patch
 class _File {
   @patch
-  static _exists(_Namespace namespace, String path) {
+  static _exists(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("File._exists");
   }
 
   @patch
-  static _create(_Namespace namespace, String path) {
+  static _create(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("File._create");
   }
 
   @patch
-  static _createLink(_Namespace namespace, String path, String target) {
+  static _createLink(_Namespace namespace, Uint8List path, String target) {
     throw new UnsupportedError("File._createLink");
   }
 
   @patch
-  static _linkTarget(_Namespace namespace, String path) {
+  static _linkTarget(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("File._linkTarget");
   }
 
   @patch
-  static _deleteNative(_Namespace namespace, String path) {
+  static _deleteNative(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("File._deleteNative");
   }
 
   @patch
-  static _deleteLinkNative(_Namespace namespace, String path) {
+  static _deleteLinkNative(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("File._deleteLinkNative");
   }
 
   @patch
-  static _rename(_Namespace namespace, String oldPath, String newPath) {
+  static _rename(_Namespace namespace, Uint8List oldPath, String newPath) {
     throw new UnsupportedError("File._rename");
   }
 
   @patch
-  static _renameLink(_Namespace namespace, String oldPath, String newPath) {
+  static _renameLink(_Namespace namespace, Uint8List oldPath, String newPath) {
     throw new UnsupportedError("File._renameLink");
   }
 
   @patch
-  static _copy(_Namespace namespace, String oldPath, String newPath) {
+  static _copy(_Namespace namespace, Uint8List oldPath, String newPath) {
     throw new UnsupportedError("File._copy");
   }
 
   @patch
-  static _lengthFromPath(_Namespace namespace, String path) {
+  static _lengthFromPath(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("File._lengthFromPath");
   }
 
   @patch
-  static _lastModified(_Namespace namespace, String path) {
+  static _lastModified(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("File._lastModified");
   }
 
   @patch
-  static _lastAccessed(_Namespace namespace, String path) {
+  static _lastAccessed(_Namespace namespace, Uint8List path) {
     throw new UnsupportedError("File._lastAccessed");
   }
 
   @patch
-  static _setLastModified(_Namespace namespace, String path, int millis) {
+  static _setLastModified(_Namespace namespace, Uint8List path, int millis) {
     throw new UnsupportedError("File._setLastModified");
   }
 
   @patch
-  static _setLastAccessed(_Namespace namespace, String path, int millis) {
+  static _setLastAccessed(_Namespace namespace, Uint8List path, int millis) {
     throw new UnsupportedError("File._setLastAccessed");
   }
 
   @patch
-  static _open(_Namespace namespace, String path, int mode) {
+  static _open(_Namespace namespace, Uint8List path, int mode) {
     throw new UnsupportedError("File._open");
   }
 
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index af67c0e..4896e9d 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -3447,10 +3447,20 @@
 
 extractFunctionTypeObjectFrom(o) {
   var interceptor = getInterceptor(o);
+  return extractFunctionTypeObjectFromInternal(interceptor);
+}
+
+extractFunctionTypeObjectFromInternal(o) {
   var signatureName = JS_GET_NAME(JsGetName.SIGNATURE_NAME);
-  return JS('bool', '# in #', signatureName, interceptor)
-      ? JS('', '#[#]()', interceptor, signatureName)
-      : null;
+  if (JS('bool', '# in #', signatureName, o)) {
+    var signature = JS('', '#[#]', o, signatureName);
+    if (JS('bool', 'typeof # == "number"', signature)) {
+      return getType(signature);
+    } else {
+      return JS('', '#[#]()', o, signatureName);
+    }
+  }
+  return null;
 }
 
 functionTypeTest(value, functionTypeRti) {
diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
index d6be639..09f2df3 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
@@ -859,10 +859,8 @@
   if (isDartFunctionType(t)) {
     // Functions are treated specially and have their type information stored
     // directly in the instance.
-    var targetSignatureFunction =
-        getField(o, '${JS_GET_NAME(JsGetName.SIGNATURE_NAME)}');
-    if (targetSignatureFunction == null) return false;
-    type = invokeOn(targetSignatureFunction, o, null);
+    type = extractFunctionTypeObjectFromInternal(o);
+    if (type == null) return false;
     return isFunctionSubtype(type, t);
   }
   return isSubtype(type, t);
diff --git a/sdk/lib/io/directory.dart b/sdk/lib/io/directory.dart
index 3e4ee6b..683e22a 100644
--- a/sdk/lib/io/directory.dart
+++ b/sdk/lib/io/directory.dart
@@ -115,7 +115,7 @@
   /**
    * Gets the path of this directory.
    */
-  final String path;
+  String get path;
 
   /**
    * Creates a [Directory] object.
@@ -134,6 +134,11 @@
     return overrides.createDirectory(path);
   }
 
+  factory Directory.fromRawPath(Uint8List path) {
+    // TODO(bkonyi): Handle overrides.
+    return new _Directory.fromRawPath(path);
+  }
+
   /**
    * Create a Directory object from a URI.
    *
diff --git a/sdk/lib/io/directory_impl.dart b/sdk/lib/io/directory_impl.dart
index 8be9257..ea1aa74 100644
--- a/sdk/lib/io/directory_impl.dart
+++ b/sdk/lib/io/directory_impl.dart
@@ -5,28 +5,41 @@
 part of dart.io;
 
 class _Directory extends FileSystemEntity implements Directory {
-  final String path;
+  String _path;
+  Uint8List _rawPath;
 
-  _Directory(this.path) {
+  _Directory(String path) {
     if (path is! String) {
-      throw new ArgumentError('${Error.safeToString(path)} '
-          'is not a String');
+      throw new ArgumentError('${Error.safeToString(path)} is not a String');
     }
+    _path = path;
+    _rawPath = FileSystemEntity._toUtf8Array(_path);
   }
 
+  _Directory.fromRawPath(Uint8List rawPath) {
+    if (rawPath == null) {
+      throw new ArgumentError('rawPath cannot be null');
+    }
+    _rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawPath);
+    _path = FileSystemEntity._toStringFromUtf8Array(rawPath);
+  }
+
+  String get path => _path;
+
   external static _current(_Namespace namespace);
-  external static _setCurrent(_Namespace namespace, path);
-  external static _createTemp(_Namespace namespace, String path);
+  external static _setCurrent(_Namespace namespace, Uint8List rawPath);
+  external static _createTemp(_Namespace namespace, Uint8List rawPath);
   external static String _systemTemp(_Namespace namespace);
-  external static _exists(_Namespace namespace, String path);
-  external static _create(_Namespace namespace, String path);
+  external static _exists(_Namespace namespace, Uint8List rawPath);
+  external static _create(_Namespace namespace, Uint8List rawPath);
   external static _deleteNative(
-      _Namespace namespace, String path, bool recursive);
-  external static _rename(_Namespace namespace, String path, String newPath);
+      _Namespace namespace, Uint8List rawPath, bool recursive);
+  external static _rename(
+      _Namespace namespace, Uint8List rawPath, String newPath);
   external static void _fillWithDirectoryListing(
       _Namespace namespace,
       List<FileSystemEntity> list,
-      String path,
+      Uint8List rawPath,
       bool recursive,
       bool followLinks);
 
@@ -40,12 +53,27 @@
   }
 
   static void set current(path) {
-    if (path is Directory) path = path.path;
+    Uint8List _rawPath;
+    if (path is _Directory) {
+      // For our internal Directory implementation, go ahead and use the raw
+      // path.
+      _rawPath = path._rawPath;
+    } else if (path is Directory) {
+      // FIXME(bkonyi): package:file passes in instances of classes which do
+      // not have _path defined, so we will fallback to using the existing
+      // path String for now.
+      _rawPath = FileSystemEntity._toUtf8Array(path.path);
+    } else if (path is String) {
+      _rawPath = FileSystemEntity._toUtf8Array(path);
+    } else {
+      throw new ArgumentError('${Error.safeToString(path)} is not a String or'
+          ' Directory');
+    }
     if (!_EmbedderConfig._mayChdir) {
       throw new UnsupportedError(
           "This embedder disallows setting Directory.current");
     }
-    var result = _setCurrent(_Namespace._namespace, path);
+    var result = _setCurrent(_Namespace._namespace, _rawPath);
     if (result is ArgumentError) throw result;
     if (result is OSError) {
       throw new FileSystemException(
@@ -59,7 +87,7 @@
 
   Future<bool> exists() {
     return _File._dispatchWithNamespace(
-        _IOService.directoryExists, [null, path]).then((response) {
+        _IOService.directoryExists, [null, _rawPath]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionOrErrorFromResponse(response, "Exists failed");
       }
@@ -68,7 +96,7 @@
   }
 
   bool existsSync() {
-    var result = _exists(_Namespace._namespace, path);
+    var result = _exists(_Namespace._namespace, _rawPath);
     if (result is OSError) {
       throw new FileSystemException("Exists failed", path, result);
     }
@@ -91,7 +119,7 @@
       });
     } else {
       return _File._dispatchWithNamespace(
-          _IOService.directoryCreate, [null, path]).then((response) {
+          _IOService.directoryCreate, [null, _rawPath]).then((response) {
         if (_isErrorResponse(response)) {
           throw _exceptionOrErrorFromResponse(response, "Creation failed");
         }
@@ -107,7 +135,7 @@
         parent.createSync(recursive: true);
       }
     }
-    var result = _create(_Namespace._namespace, path);
+    var result = _create(_Namespace._namespace, _rawPath);
     if (result is OSError) {
       throw new FileSystemException("Creation failed", path, result);
     }
@@ -123,13 +151,15 @@
           "To use the system temp directory, use Directory.systemTemp");
     }
     String fullPrefix;
+    // FIXME(bkonyi): here we're using `path` directly, which might cause
+    // issues if it is not UTF-8 encoded.
     if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) {
       fullPrefix = "$path$prefix";
     } else {
       fullPrefix = "$path${Platform.pathSeparator}$prefix";
     }
-    return _File._dispatchWithNamespace(
-        _IOService.directoryCreateTemp, [null, fullPrefix]).then((response) {
+    return _File._dispatchWithNamespace(_IOService.directoryCreateTemp,
+        [null, FileSystemEntity._toUtf8Array(fullPrefix)]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionOrErrorFromResponse(
             response, "Creation of temporary directory failed");
@@ -145,12 +175,15 @@
           "To use the system temp directory, use Directory.systemTemp");
     }
     String fullPrefix;
+    // FIXME(bkonyi): here we're using `path` directly, which might cause
+    // issues if it is not UTF-8 encoded.
     if (path.endsWith('/') || (Platform.isWindows && path.endsWith('\\'))) {
       fullPrefix = "$path$prefix";
     } else {
       fullPrefix = "$path${Platform.pathSeparator}$prefix";
     }
-    var result = _createTemp(_Namespace._namespace, fullPrefix);
+    var result = _createTemp(
+        _Namespace._namespace, FileSystemEntity._toUtf8Array(fullPrefix));
     if (result is OSError) {
       throw new FileSystemException(
           "Creation of temporary directory failed", fullPrefix, result);
@@ -159,8 +192,8 @@
   }
 
   Future<Directory> _delete({bool recursive: false}) {
-    return _File._dispatchWithNamespace(
-        _IOService.directoryDelete, [null, path, recursive]).then((response) {
+    return _File._dispatchWithNamespace(_IOService.directoryDelete,
+        [null, _rawPath, recursive]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionOrErrorFromResponse(response, "Deletion failed");
       }
@@ -169,7 +202,7 @@
   }
 
   void _deleteSync({bool recursive: false}) {
-    var result = _deleteNative(_Namespace._namespace, path, recursive);
+    var result = _deleteNative(_Namespace._namespace, _rawPath, recursive);
     if (result is OSError) {
       throw new FileSystemException("Deletion failed", path, result);
     }
@@ -177,7 +210,7 @@
 
   Future<Directory> rename(String newPath) {
     return _File._dispatchWithNamespace(
-        _IOService.directoryRename, [null, path, newPath]).then((response) {
+        _IOService.directoryRename, [null, _rawPath, newPath]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionOrErrorFromResponse(response, "Rename failed");
       }
@@ -189,7 +222,7 @@
     if (newPath is! String) {
       throw new ArgumentError();
     }
-    var result = _rename(_Namespace._namespace, path, newPath);
+    var result = _rename(_Namespace._namespace, _rawPath, newPath);
     if (result is OSError) {
       throw new FileSystemException("Rename failed", path, result);
     }
@@ -199,7 +232,10 @@
   Stream<FileSystemEntity> list(
       {bool recursive: false, bool followLinks: true}) {
     return new _AsyncDirectoryLister(
-            FileSystemEntity._ensureTrailingPathSeparators(path),
+            // FIXME(bkonyi): here we're using `path` directly, which might cause issues
+            // if it is not UTF-8 encoded.
+            FileSystemEntity._toUtf8Array(
+                FileSystemEntity._ensureTrailingPathSeparators(path)),
             recursive,
             followLinks)
         .stream;
@@ -214,7 +250,10 @@
     _fillWithDirectoryListing(
         _Namespace._namespace,
         result,
-        FileSystemEntity._ensureTrailingPathSeparators(path),
+        // FIXME(bkonyi): here we're using `path` directly, which might cause issues
+        // if it is not UTF-8 encoded.
+        FileSystemEntity
+            ._toUtf8Array(FileSystemEntity._ensureTrailingPathSeparators(path)),
         recursive,
         followLinks);
     return result;
@@ -258,7 +297,7 @@
   static const int responseComplete = 1;
   static const int responseError = 2;
 
-  final String path;
+  final Uint8List rawPath;
   final bool recursive;
   final bool followLinks;
 
@@ -269,7 +308,7 @@
   _AsyncDirectoryListerOps _ops;
   Completer closeCompleter = new Completer();
 
-  _AsyncDirectoryLister(this.path, this.recursive, this.followLinks) {
+  _AsyncDirectoryLister(this.rawPath, this.recursive, this.followLinks) {
     controller = new StreamController<FileSystemEntity>(
         onListen: onListen, onResume: onResume, onCancel: onCancel, sync: true);
   }
@@ -287,7 +326,7 @@
 
   void onListen() {
     _File._dispatchWithNamespace(_IOService.directoryListStart,
-        [null, path, recursive, followLinks]).then((response) {
+        [null, rawPath, recursive, followLinks]).then((response) {
       if (response is int) {
         _ops = new _AsyncDirectoryListerOps(response);
         next();
@@ -340,13 +379,13 @@
           assert(i % 2 == 0);
           switch (result[i++]) {
             case listFile:
-              controller.add(new File(result[i]));
+              controller.add(new File.fromRawPath(result[i]));
               break;
             case listDirectory:
-              controller.add(new Directory(result[i]));
+              controller.add(new Directory.fromRawPath(result[i]));
               break;
             case listLink:
-              controller.add(new Link(result[i]));
+              controller.add(new Link.fromRawPath(result[i]));
               break;
             case listError:
               error(result[i]);
@@ -395,7 +434,11 @@
       var err = new OSError(responseErrorInfo[_osErrorResponseMessage],
           responseErrorInfo[_osErrorResponseErrorCode]);
       var errorPath = message[responsePath];
-      if (errorPath == null) errorPath = path;
+      if (errorPath == null) {
+        errorPath = utf8.decode(rawPath, allowMalformed: true);
+      } else if (errorPath is Uint8List) {
+        errorPath = utf8.decode(message[responsePath], allowMalformed: true);
+      }
       controller.addError(
           new FileSystemException("Directory listing failed", errorPath, err));
     } else {
diff --git a/sdk/lib/io/file.dart b/sdk/lib/io/file.dart
index 33ce01f..236aa2b 100644
--- a/sdk/lib/io/file.dart
+++ b/sdk/lib/io/file.dart
@@ -263,6 +263,15 @@
   factory File.fromUri(Uri uri) => new File(uri.toFilePath());
 
   /**
+   * Creates a File object from a raw path, that is, a sequence of bytes
+   * as represented by the OS.
+   */
+  factory File.fromRawPath(Uint8List rawPath) {
+    // TODO(bkonyi): Handle overrides.
+    return new _File.fromRawPath(rawPath);
+  }
+
+  /**
    * Create the file. Returns a `Future<File>` that completes with
    * the file when it has been created.
    *
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 67a49b7..e8221bc 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -203,16 +203,27 @@
 
 // Class for encapsulating the native implementation of files.
 class _File extends FileSystemEntity implements File {
-  final String path;
+  String _path;
+  Uint8List _rawPath;
 
-  // Constructor for file.
-  _File(this.path) {
+  _File(String path) {
     if (path is! String) {
-      throw new ArgumentError('${Error.safeToString(path)} '
-          'is not a String');
+      throw new ArgumentError('${Error.safeToString(path)} is not a String');
     }
+    _path = path;
+    _rawPath = FileSystemEntity._toUtf8Array(path);
   }
 
+  _File.fromRawPath(Uint8List rawPath) {
+    if (rawPath == null) {
+      throw new ArgumentError('rawPath cannot be null');
+    }
+    _rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawPath);
+    _path = FileSystemEntity._toStringFromUtf8Array(rawPath);
+  }
+
+  String get path => _path;
+
   // WARNING:
   // Calling this function will increase the reference count on the native
   // namespace object. It should only be called to pass the pointer to the
@@ -226,7 +237,7 @@
   }
 
   Future<bool> exists() {
-    return _dispatchWithNamespace(_IOService.fileExists, [null, path])
+    return _dispatchWithNamespace(_IOService.fileExists, [null, _rawPath])
         .then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "Cannot check existence", path);
@@ -235,10 +246,10 @@
     });
   }
 
-  external static _exists(_Namespace namespace, String path);
+  external static _exists(_Namespace namespace, Uint8List rawPath);
 
   bool existsSync() {
-    var result = _exists(_Namespace._namespace, path);
+    var result = _exists(_Namespace._namespace, _rawPath);
     throwIfError(result, "Cannot check existence of file", path);
     return result;
   }
@@ -249,8 +260,8 @@
     var result =
         recursive ? parent.create(recursive: true) : new Future.value(null);
     return result
-        .then(
-            (_) => _dispatchWithNamespace(_IOService.fileCreate, [null, path]))
+        .then((_) =>
+            _dispatchWithNamespace(_IOService.fileCreate, [null, _rawPath]))
         .then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "Cannot create file", path);
@@ -259,17 +270,18 @@
     });
   }
 
-  external static _create(_Namespace namespace, String path);
+  external static _create(_Namespace namespace, Uint8List rawPath);
 
-  external static _createLink(_Namespace namespace, String path, String target);
+  external static _createLink(
+      _Namespace namespace, Uint8List rawPath, String target);
 
-  external static _linkTarget(_Namespace namespace, String path);
+  external static _linkTarget(_Namespace namespace, Uint8List rawPath);
 
   void createSync({bool recursive: false}) {
     if (recursive) {
       parent.createSync(recursive: true);
     }
-    var result = _create(_Namespace._namespace, path);
+    var result = _create(_Namespace._namespace, _rawPath);
     throwIfError(result, "Cannot create file", path);
   }
 
@@ -277,7 +289,7 @@
     if (recursive) {
       return new Directory(path).delete(recursive: true).then((_) => this);
     }
-    return _dispatchWithNamespace(_IOService.fileDelete, [null, path])
+    return _dispatchWithNamespace(_IOService.fileDelete, [null, _rawPath])
         .then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "Cannot delete file", path);
@@ -286,21 +298,21 @@
     });
   }
 
-  external static _deleteNative(_Namespace namespace, String path);
+  external static _deleteNative(_Namespace namespace, Uint8List rawPath);
 
-  external static _deleteLinkNative(_Namespace namespace, String path);
+  external static _deleteLinkNative(_Namespace namespace, Uint8List rawPath);
 
   void _deleteSync({bool recursive: false}) {
     if (recursive) {
-      return new Directory(path).deleteSync(recursive: true);
+      return new Directory.fromRawPath(_rawPath).deleteSync(recursive: true);
     }
-    var result = _deleteNative(_Namespace._namespace, path);
+    var result = _deleteNative(_Namespace._namespace, _rawPath);
     throwIfError(result, "Cannot delete file", path);
   }
 
   Future<File> rename(String newPath) {
-    return _dispatchWithNamespace(_IOService.fileRename, [null, path, newPath])
-        .then((response) {
+    return _dispatchWithNamespace(
+        _IOService.fileRename, [null, _rawPath, newPath]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(
             response, "Cannot rename file to '$newPath'", path);
@@ -309,20 +321,21 @@
     });
   }
 
-  external static _rename(_Namespace namespace, String oldPath, String newPath);
+  external static _rename(
+      _Namespace namespace, Uint8List oldPath, String newPath);
 
   external static _renameLink(
-      _Namespace namespace, String oldPath, String newPath);
+      _Namespace namespace, Uint8List oldPath, String newPath);
 
   File renameSync(String newPath) {
-    var result = _rename(_Namespace._namespace, path, newPath);
+    var result = _rename(_Namespace._namespace, _rawPath, newPath);
     throwIfError(result, "Cannot rename file to '$newPath'", path);
     return new File(newPath);
   }
 
   Future<File> copy(String newPath) {
-    return _dispatchWithNamespace(_IOService.fileCopy, [null, path, newPath])
-        .then((response) {
+    return _dispatchWithNamespace(
+        _IOService.fileCopy, [null, _rawPath, newPath]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(
             response, "Cannot copy file to '$newPath'", path);
@@ -331,10 +344,11 @@
     });
   }
 
-  external static _copy(_Namespace namespace, String oldPath, String newPath);
+  external static _copy(
+      _Namespace namespace, Uint8List oldPath, String newPath);
 
   File copySync(String newPath) {
-    var result = _copy(_Namespace._namespace, path, newPath);
+    var result = _copy(_Namespace._namespace, _rawPath, newPath);
     throwIfError(result, "Cannot copy file to '$newPath'", path);
     return new File(newPath);
   }
@@ -348,8 +362,8 @@
       return new Future.error(
           new ArgumentError('Invalid file mode for this operation'));
     }
-    return _dispatchWithNamespace(_IOService.fileOpen, [null, path, mode._mode])
-        .then((response) {
+    return _dispatchWithNamespace(
+        _IOService.fileOpen, [null, _rawPath, mode._mode]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "Cannot open file", path);
       }
@@ -358,8 +372,8 @@
   }
 
   Future<int> length() {
-    return _dispatchWithNamespace(_IOService.fileLengthFromPath, [null, path])
-        .then((response) {
+    return _dispatchWithNamespace(
+        _IOService.fileLengthFromPath, [null, _rawPath]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(
             response, "Cannot retrieve length of file", path);
@@ -368,16 +382,16 @@
     });
   }
 
-  external static _lengthFromPath(_Namespace namespace, String path);
+  external static _lengthFromPath(_Namespace namespace, Uint8List rawPath);
 
   int lengthSync() {
-    var result = _lengthFromPath(_Namespace._namespace, path);
+    var result = _lengthFromPath(_Namespace._namespace, _rawPath);
     throwIfError(result, "Cannot retrieve length of file", path);
     return result;
   }
 
   Future<DateTime> lastAccessed() {
-    return _dispatchWithNamespace(_IOService.fileLastAccessed, [null, path])
+    return _dispatchWithNamespace(_IOService.fileLastAccessed, [null, _rawPath])
         .then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(
@@ -387,10 +401,10 @@
     });
   }
 
-  external static _lastAccessed(_Namespace namespace, String path);
+  external static _lastAccessed(_Namespace namespace, Uint8List rawPath);
 
   DateTime lastAccessedSync() {
-    var ms = _lastAccessed(_Namespace._namespace, path);
+    var ms = _lastAccessed(_Namespace._namespace, _rawPath);
     throwIfError(ms, "Cannot retrieve access time", path);
     return new DateTime.fromMillisecondsSinceEpoch(ms);
   }
@@ -398,7 +412,8 @@
   Future setLastAccessed(DateTime time) {
     int millis = time.millisecondsSinceEpoch;
     return _dispatchWithNamespace(
-        _IOService.fileSetLastAccessed, [null, path, millis]).then((response) {
+            _IOService.fileSetLastAccessed, [null, _rawPath, millis])
+        .then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "Cannot set access time", path);
       }
@@ -407,11 +422,11 @@
   }
 
   external static _setLastAccessed(
-      _Namespace namespace, String path, int millis);
+      _Namespace namespace, Uint8List rawPath, int millis);
 
   void setLastAccessedSync(DateTime time) {
     int millis = time.millisecondsSinceEpoch;
-    var result = _setLastAccessed(_Namespace._namespace, path, millis);
+    var result = _setLastAccessed(_Namespace._namespace, _rawPath, millis);
     if (result is OSError) {
       throw new FileSystemException(
           "Failed to set file access time", path, result);
@@ -419,7 +434,7 @@
   }
 
   Future<DateTime> lastModified() {
-    return _dispatchWithNamespace(_IOService.fileLastModified, [null, path])
+    return _dispatchWithNamespace(_IOService.fileLastModified, [null, _rawPath])
         .then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(
@@ -429,10 +444,10 @@
     });
   }
 
-  external static _lastModified(_Namespace namespace, String path);
+  external static _lastModified(_Namespace namespace, Uint8List rawPath);
 
   DateTime lastModifiedSync() {
-    var ms = _lastModified(_Namespace._namespace, path);
+    var ms = _lastModified(_Namespace._namespace, _rawPath);
     throwIfError(ms, "Cannot retrieve modification time", path);
     return new DateTime.fromMillisecondsSinceEpoch(ms);
   }
@@ -440,7 +455,8 @@
   Future setLastModified(DateTime time) {
     int millis = time.millisecondsSinceEpoch;
     return _dispatchWithNamespace(
-        _IOService.fileSetLastModified, [null, path, millis]).then((response) {
+            _IOService.fileSetLastModified, [null, _rawPath, millis])
+        .then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(
             response, "Cannot set modification time", path);
@@ -450,18 +466,18 @@
   }
 
   external static _setLastModified(
-      _Namespace namespace, String path, int millis);
+      _Namespace namespace, Uint8List rawPath, int millis);
 
   void setLastModifiedSync(DateTime time) {
     int millis = time.millisecondsSinceEpoch;
-    var result = _setLastModified(_Namespace._namespace, path, millis);
+    var result = _setLastModified(_Namespace._namespace, _rawPath, millis);
     if (result is OSError) {
       throw new FileSystemException(
           "Failed to set file modification time", path, result);
     }
   }
 
-  external static _open(_Namespace namespace, String path, int mode);
+  external static _open(_Namespace namespace, Uint8List rawPath, int mode);
 
   RandomAccessFile openSync({FileMode mode: FileMode.read}) {
     if (mode != FileMode.read &&
@@ -471,9 +487,9 @@
         mode != FileMode.writeOnlyAppend) {
       throw new ArgumentError('Invalid file mode for this operation');
     }
-    var id = _open(_Namespace._namespace, path, mode._mode);
+    var id = _open(_Namespace._namespace, _rawPath, mode._mode);
     throwIfError(id, "Cannot open file", path);
-    return new _RandomAccessFile(id, path);
+    return new _RandomAccessFile(id, _path);
   }
 
   external static int _openStdio(int fd);
diff --git a/sdk/lib/io/file_system_entity.dart b/sdk/lib/io/file_system_entity.dart
index a78e03f..2c995d0 100644
--- a/sdk/lib/io/file_system_entity.dart
+++ b/sdk/lib/io/file_system_entity.dart
@@ -255,6 +255,9 @@
  *   files and directories.
  */
 abstract class FileSystemEntity {
+  String _path;
+  Uint8List _rawPath;
+
   String get path;
 
   /**
@@ -351,7 +354,7 @@
    */
   Future<String> resolveSymbolicLinks() {
     return _File._dispatchWithNamespace(
-        _IOService.fileResolveSymbolicLinks, [null, path]).then((response) {
+        _IOService.fileResolveSymbolicLinks, [null, _rawPath]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(
             response, "Cannot resolve symbolic links", path);
@@ -390,7 +393,7 @@
    * behavior.
    */
   String resolveSymbolicLinksSync() {
-    var result = _resolveSymbolicLinks(_Namespace._namespace, path);
+    var result = _resolveSymbolicLinks(_Namespace._namespace, _rawPath);
     _throwIfError(result, "Cannot resolve symbolic links", path);
     return result;
   }
@@ -495,6 +498,7 @@
    */
   Stream<FileSystemEvent> watch(
       {int events: FileSystemEvent.all, bool recursive: false}) {
+    // FIXME(bkonyi): find a way to do this using the raw path.
     final String trimmedPath = _trimTrailingPathSeparators(path);
     final IOOverrides overrides = IOOverrides.current;
     if (overrides == null) {
@@ -579,6 +583,22 @@
     }
   }
 
+  Uint8List get _rawAbsolutePath {
+    if (isAbsolute) return _rawPath;
+    var current = Directory.current._rawPath.toList();
+    assert(current.last == 0);
+    current.removeLast(); // Remove null terminator.
+    if ((current.last == '/'.codeUnitAt(0)) ||
+        (Platform.isWindows && (current.last == '\\'.codeUnitAt(0)))) {
+      current.addAll(_rawPath);
+      return new Uint8List.fromList(current);
+    } else {
+      current.addAll(utf8.encode(Platform.pathSeparator));
+      current.addAll(_rawPath);
+      return new Uint8List.fromList(current);
+    }
+  }
+
   static bool _identicalSync(String path1, String path2) {
     var result = _identicalNative(_Namespace._namespace, path1, path2);
     _throwIfError(result, 'Error in FileSystemEntity.identicalSync');
@@ -618,6 +638,35 @@
     return overrides.fsWatchIsSupported();
   }
 
+  // The native methods which determine type of the FileSystemEntity require
+  // that the buffer provided is null terminated.
+  static Uint8List _toUtf8Array(String s) =>
+      _toNullTerminatedUtf8Array(utf8.encode(s));
+
+  static Uint8List _toNullTerminatedUtf8Array(Uint8List l) {
+    if (l == null) {
+      return null;
+    }
+    if (l.isNotEmpty && l.last != 0) {
+      final tmp = new Uint8List(l.length + 1);
+      tmp.setRange(0, l.length, l);
+      return tmp;
+    } else {
+      return l;
+    }
+  }
+
+  static String _toStringFromUtf8Array(Uint8List l) {
+    if (l == null) {
+      return '';
+    }
+    Uint8List nonNullTerminated = l;
+    if (l.last == 0) {
+      nonNullTerminated = new Uint8List.view(l.buffer, 0, l.length - 1);
+    }
+    return utf8.decode(nonNullTerminated, allowMalformed: true);
+  }
+
   /**
    * Finds the type of file system object that a path points to.
    *
@@ -633,7 +682,7 @@
    */
   static Future<FileSystemEntityType> type(String path,
       {bool followLinks: true}) {
-    return _getType(path, followLinks);
+    return _getType(_toUtf8Array(path), followLinks);
   }
 
   /**
@@ -650,53 +699,59 @@
    * caused by passing the wrong type of arguments to the function.
    */
   static FileSystemEntityType typeSync(String path, {bool followLinks: true}) {
-    return _getTypeSync(path, followLinks);
+    return _getTypeSync(_toUtf8Array(path), followLinks);
   }
 
   /**
    * Checks if type(path, followLinks: false) returns FileSystemEntityType.link.
    */
-  static Future<bool> isLink(String path) =>
-      _getType(path, false).then((type) => (type == FileSystemEntityType.link));
+  static Future<bool> isLink(String path) => _isLinkRaw(_toUtf8Array(path));
+
+  static Future<bool> _isLinkRaw(Uint8List rawPath) => _getType(rawPath, false)
+      .then((type) => (type == FileSystemEntityType.link));
 
   /**
    * Checks if type(path) returns FileSystemEntityType.file.
    */
-  static Future<bool> isFile(String path) =>
-      _getType(path, true).then((type) => (type == FileSystemEntityType.file));
+  static Future<bool> isFile(String path) => _getType(_toUtf8Array(path), true)
+      .then((type) => (type == FileSystemEntityType.file));
 
   /**
    * Checks if type(path) returns FileSystemEntityType.directory.
    */
-  static Future<bool> isDirectory(String path) => _getType(path, true)
-      .then((type) => (type == FileSystemEntityType.directory));
+  static Future<bool> isDirectory(String path) =>
+      _getType(_toUtf8Array(path), true)
+          .then((type) => (type == FileSystemEntityType.directory));
 
   /**
    * Synchronously checks if typeSync(path, followLinks: false) returns
    * FileSystemEntityType.link.
    */
-  static bool isLinkSync(String path) =>
-      (_getTypeSync(path, false) == FileSystemEntityType.link);
+  static bool isLinkSync(String path) => _isLinkRawSync(_toUtf8Array(path));
+
+  static bool _isLinkRawSync(rawPath) =>
+      (_getTypeSync(rawPath, false) == FileSystemEntityType.link);
 
   /**
    * Synchronously checks if typeSync(path) returns
    * FileSystemEntityType.file.
    */
   static bool isFileSync(String path) =>
-      (_getTypeSync(path, true) == FileSystemEntityType.file);
+      (_getTypeSync(_toUtf8Array(path), true) == FileSystemEntityType.file);
 
   /**
    * Synchronously checks if typeSync(path) returns
    * FileSystemEntityType.directory.
    */
   static bool isDirectorySync(String path) =>
-      (_getTypeSync(path, true) == FileSystemEntityType.directory);
+      (_getTypeSync(_toUtf8Array(path), true) ==
+          FileSystemEntityType.directory);
 
   external static _getTypeNative(
-      _Namespace namespace, String path, bool followLinks);
+      _Namespace namespace, Uint8List rawPath, bool followLinks);
   external static _identicalNative(
       _Namespace namespace, String path1, String path2);
-  external static _resolveSymbolicLinks(_Namespace namespace, String path);
+  external static _resolveSymbolicLinks(_Namespace namespace, Uint8List path);
 
   // Finds the next-to-last component when dividing at path separators.
   static final RegExp _parentRegExp = Platform.isWindows
@@ -742,37 +797,42 @@
   Directory get parent => new Directory(parentOf(path));
 
   static FileSystemEntityType _getTypeSyncHelper(
-      String path, bool followLinks) {
-    var result = _getTypeNative(_Namespace._namespace, path, followLinks);
+      Uint8List rawPath, bool followLinks) {
+    var result = _getTypeNative(_Namespace._namespace, rawPath, followLinks);
     _throwIfError(result, 'Error getting type of FileSystemEntity');
     return FileSystemEntityType._lookup(result);
   }
 
-  static FileSystemEntityType _getTypeSync(String path, bool followLinks) {
+  static FileSystemEntityType _getTypeSync(
+      Uint8List rawPath, bool followLinks) {
     IOOverrides overrides = IOOverrides.current;
     if (overrides == null) {
-      return _getTypeSyncHelper(path, followLinks);
+      return _getTypeSyncHelper(rawPath, followLinks);
     }
-    return overrides.fseGetTypeSync(path, followLinks);
+    return overrides.fseGetTypeSync(
+        utf8.decode(rawPath, allowMalformed: true), followLinks);
   }
 
   static Future<FileSystemEntityType> _getTypeRequest(
-      String path, bool followLinks) {
+      Uint8List rawPath, bool followLinks) {
     return _File._dispatchWithNamespace(
-        _IOService.fileType, [null, path, followLinks]).then((response) {
+        _IOService.fileType, [null, rawPath, followLinks]).then((response) {
       if (_isErrorResponse(response)) {
-        throw _exceptionFromResponse(response, "Error getting type", path);
+        throw _exceptionFromResponse(response, "Error getting type",
+            utf8.decode(rawPath, allowMalformed: true));
       }
       return FileSystemEntityType._lookup(response);
     });
   }
 
-  static Future<FileSystemEntityType> _getType(String path, bool followLinks) {
+  static Future<FileSystemEntityType> _getType(
+      Uint8List rawPath, bool followLinks) {
     IOOverrides overrides = IOOverrides.current;
     if (overrides == null) {
-      return _getTypeRequest(path, followLinks);
+      return _getTypeRequest(rawPath, followLinks);
     }
-    return overrides.fseGetType(path, followLinks);
+    return overrides.fseGetType(
+        utf8.decode(rawPath, allowMalformed: true), followLinks);
   }
 
   static _throwIfError(Object result, String msg, [String path]) {
@@ -783,6 +843,7 @@
     }
   }
 
+  // TODO(bkonyi): find a way to do this with raw paths.
   static String _trimTrailingPathSeparators(String path) {
     // Don't handle argument errors here.
     if (path is! String) return path;
@@ -799,6 +860,7 @@
     return path;
   }
 
+  // TODO(bkonyi): find a way to do this with raw paths.
   static String _ensureTrailingPathSeparators(String path) {
     // Don't handle argument errors here.
     if (path is! String) return path;
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index 697694f..9029dcb 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -20,6 +20,11 @@
     return overrides.createLink(path);
   }
 
+  factory Link.fromRawPath(Uint8List rawPath) {
+    // TODO(bkonyi): handle overrides
+    return new _Link.fromRawPath(rawPath);
+  }
+
   /**
    * Creates a [Link] object.
    *
@@ -150,22 +155,32 @@
 }
 
 class _Link extends FileSystemEntity implements Link {
-  final String path;
+  String _path;
+  Uint8List _rawPath;
 
-  _Link(this.path) {
+  _Link(String path) {
     if (path is! String) {
       throw new ArgumentError('${Error.safeToString(path)} '
           'is not a String');
     }
+    _path = path;
+    _rawPath = FileSystemEntity._toUtf8Array(path);
   }
 
+  _Link.fromRawPath(Uint8List rawPath) {
+    _rawPath = FileSystemEntity._toNullTerminatedUtf8Array(rawPath);
+    _path = FileSystemEntity._toStringFromUtf8Array(rawPath);
+  }
+
+  String get path => _path;
+
   String toString() => "Link: '$path'";
 
-  Future<bool> exists() => FileSystemEntity.isLink(path);
+  Future<bool> exists() => FileSystemEntity._isLinkRaw(_rawPath);
 
-  bool existsSync() => FileSystemEntity.isLinkSync(path);
+  bool existsSync() => FileSystemEntity._isLinkRawSync(_rawPath);
 
-  Link get absolute => new Link(_absolutePath);
+  Link get absolute => new Link.fromRawPath(_rawAbsolutePath);
 
   Future<Link> create(String target, {bool recursive: false}) {
     if (Platform.isWindows) {
@@ -175,7 +190,7 @@
         recursive ? parent.create(recursive: true) : new Future.value(null);
     return result
         .then((_) => _File._dispatchWithNamespace(
-            _IOService.fileCreateLink, [null, path, target]))
+            _IOService.fileCreateLink, [null, _rawPath, target]))
         .then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(
@@ -192,7 +207,7 @@
     if (Platform.isWindows) {
       target = _makeWindowsLinkTarget(target);
     }
-    var result = _File._createLink(_Namespace._namespace, path, target);
+    var result = _File._createLink(_Namespace._namespace, _rawPath, target);
     throwIfError(result, "Cannot create link", path);
   }
 
@@ -230,10 +245,12 @@
 
   Future<Link> _delete({bool recursive: false}) {
     if (recursive) {
-      return new Directory(path).delete(recursive: true).then((_) => this);
+      return new Directory.fromRawPath(_rawPath)
+          .delete(recursive: true)
+          .then((_) => this);
     }
     return _File._dispatchWithNamespace(
-        _IOService.fileDeleteLink, [null, path]).then((response) {
+        _IOService.fileDeleteLink, [null, _rawPath]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(response, "Cannot delete link", path);
       }
@@ -243,15 +260,15 @@
 
   void _deleteSync({bool recursive: false}) {
     if (recursive) {
-      return new Directory(path).deleteSync(recursive: true);
+      return new Directory.fromRawPath(_rawPath).deleteSync(recursive: true);
     }
-    var result = _File._deleteLinkNative(_Namespace._namespace, path);
+    var result = _File._deleteLinkNative(_Namespace._namespace, _rawPath);
     throwIfError(result, "Cannot delete link", path);
   }
 
   Future<Link> rename(String newPath) {
     return _File._dispatchWithNamespace(
-        _IOService.fileRenameLink, [null, path, newPath]).then((response) {
+        _IOService.fileRenameLink, [null, _rawPath, newPath]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(
             response, "Cannot rename link to '$newPath'", path);
@@ -261,14 +278,14 @@
   }
 
   Link renameSync(String newPath) {
-    var result = _File._renameLink(_Namespace._namespace, path, newPath);
+    var result = _File._renameLink(_Namespace._namespace, _rawPath, newPath);
     throwIfError(result, "Cannot rename link '$path' to '$newPath'");
     return new Link(newPath);
   }
 
   Future<String> target() {
     return _File._dispatchWithNamespace(
-        _IOService.fileLinkTarget, [null, path]).then((response) {
+        _IOService.fileLinkTarget, [null, _rawPath]).then((response) {
       if (_isErrorResponse(response)) {
         throw _exceptionFromResponse(
             response, "Cannot get target of link", path);
@@ -278,7 +295,7 @@
   }
 
   String targetSync() {
-    var result = _File._linkTarget(_Namespace._namespace, path);
+    var result = _File._linkTarget(_Namespace._namespace, _rawPath);
     throwIfError(result, "Cannot read link", path);
     return result;
   }
diff --git a/sdk/lib/io/overrides.dart b/sdk/lib/io/overrides.dart
index 4eed013..f68d417 100644
--- a/sdk/lib/io/overrides.dart
+++ b/sdk/lib/io/overrides.dart
@@ -214,7 +214,7 @@
   /// When this override is installed, this function overrides the behavior of
   /// `FileSystemEntity.type`.
   Future<FileSystemEntityType> fseGetType(String path, bool followLinks) {
-    return FileSystemEntity._getTypeRequest(path, followLinks);
+    return FileSystemEntity._getTypeRequest(utf8.encode(path), followLinks);
   }
 
   /// Returns the [FileSystemEntityType] for [path].
@@ -222,7 +222,7 @@
   /// When this override is installed, this function overrides the behavior of
   /// `FileSystemEntity.typeSync`.
   FileSystemEntityType fseGetTypeSync(String path, bool followLinks) {
-    return FileSystemEntity._getTypeSyncHelper(path, followLinks);
+    return FileSystemEntity._getTypeSyncHelper(utf8.encode(path), followLinks);
   }
 
   // _FileSystemWatcher
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 5efb0e9..7f22c73 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -7089,24 +7089,7 @@
 Language/Classes/Constructors/Generative_Constructors/redirection_t03: Crash
 Language/Classes/Constructors/Generative_Constructors/redirection_t07: Crash
 Language/Classes/Constructors/Generative_Constructors/redirection_t08: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t02: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t05: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t07: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t08: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t09: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t10: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t11: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t12: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t13: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t14: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t15: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t16: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t17: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t18: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t19: Crash
 Language/Classes/Instance_Methods/Operators/allowed_names_t20: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t21: Crash
-Language/Classes/Instance_Methods/Operators/allowed_names_t22: Crash
 Language/Classes/member_definition_t04: Crash
 Language/Classes/member_definition_t06: Crash
 Language/Classes/member_definition_t07: Crash
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index d72657b..dfd4e39 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -1777,5 +1777,5 @@
 LibTest/typed_data/Uint64List/Uint64List.view_A01_t01: CompileTimeError
 LibTest/typed_data/Uint64List/Uint64List.view_A01_t02: CompileTimeError
 
-[ $compiler == dartk || $compiler == dartkp ]
+[ $compiler == app_jitk || $compiler == dartk || $compiler == dartkp ]
 *: SkipByDesign
diff --git a/tests/compiler/dart2js/closure/closure_test.dart b/tests/compiler/dart2js/closure/closure_test.dart
index 96f99de..dfc8631 100644
--- a/tests/compiler/dart2js/closure/closure_test.dart
+++ b/tests/compiler/dart2js/closure/closure_test.dart
@@ -13,10 +13,10 @@
 import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
 import 'package:compiler/src/js_model/locals.dart';
 import 'package:compiler/src/universe/world_builder.dart';
-import 'package:compiler/src/util/util.dart';
 import 'package:expect/expect.dart';
 import '../equivalence/id_equivalence.dart';
 import '../equivalence/id_equivalence_helper.dart';
+import 'package:front_end/src/fasta/util/link.dart' show Link;
 import 'package:kernel/ast.dart' as ir;
 
 const List<String> skipForKernel = const <String>[];
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index 50d9225..619871d 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -20,14 +20,14 @@
 export 'package:compiler/src/diagnostics/messages.dart';
 export 'package:compiler/src/diagnostics/source_span.dart';
 export 'package:compiler/src/diagnostics/spannable.dart';
-
-import 'package:compiler/src/util/util.dart';
 export 'package:compiler/src/util/util.dart';
 
 import 'package:compiler/src/world.dart';
 
 import 'package:compiler/src/compiler.dart' show Compiler;
 
+import 'package:front_end/src/fasta/util/link.dart' show Link;
+
 import 'memory_compiler.dart';
 
 import 'output_collector.dart';
diff --git a/tests/compiler/dart2js/deferred/custom_element_test.dart b/tests/compiler/dart2js/deferred/custom_element_test.dart
index 01fb615..d2e6236 100644
--- a/tests/compiler/dart2js/deferred/custom_element_test.dart
+++ b/tests/compiler/dart2js/deferred/custom_element_test.dart
@@ -23,15 +23,16 @@
       await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
   Compiler compiler = result.compiler;
   var closedWorld = compiler.backendClosedWorldForTesting;
-  var outputUnitForEntity = compiler.backend.outputUnitData.outputUnitForEntity;
+  var outputUnitForMember = compiler.backend.outputUnitData.outputUnitForMember;
+  var outputUnitForClass = compiler.backend.outputUnitData.outputUnitForClass;
   var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
   var elementEnvironment = closedWorld.elementEnvironment;
   dynamic lib = elementEnvironment.lookupLibrary(Uri.parse("memory:lib.dart"));
   var customType = elementEnvironment.lookupClass(lib, "CustomType");
   var foo = elementEnvironment.lookupLibraryMember(lib, "foo");
-  Expect.notEquals(mainOutputUnit, outputUnitForEntity(foo));
+  Expect.notEquals(mainOutputUnit, outputUnitForMember(foo));
   // Native elements are not deferred
-  Expect.equals(mainOutputUnit, outputUnitForEntity(customType));
+  Expect.equals(mainOutputUnit, outputUnitForClass(customType));
 }
 
 // The main library imports a file defining a custom element.
diff --git a/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
index 33da0d2..e65d0c2 100644
--- a/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
+++ b/tests/compiler/dart2js/deferred/dont_inline_deferred_constants_test.dart
@@ -25,20 +25,20 @@
       return elementEnvironment.lookupLibrary(Uri.parse(name));
     }
 
-    var outputUnitForEntity =
-        compiler.backend.outputUnitData.outputUnitForEntity;
+    var outputUnitForMember =
+        compiler.backend.outputUnitData.outputUnitForMember;
 
     dynamic lib1 = lookupLibrary("memory:lib1.dart");
     var foo1 = elementEnvironment.lookupLibraryMember(lib1, "foo");
-    var ou_lib1 = outputUnitForEntity(foo1);
+    var ou_lib1 = outputUnitForMember(foo1);
 
     dynamic lib2 = lookupLibrary("memory:lib2.dart");
     var foo2 = elementEnvironment.lookupLibraryMember(lib2, "foo");
-    var ou_lib2 = outputUnitForEntity(foo2);
+    var ou_lib2 = outputUnitForMember(foo2);
 
     dynamic mainApp = elementEnvironment.mainLibrary;
     var fooMain = elementEnvironment.lookupLibraryMember(mainApp, "foo");
-    var ou_lib1_lib2 = outputUnitForEntity(fooMain);
+    var ou_lib1_lib2 = outputUnitForMember(fooMain);
 
     String mainOutput = collector.getOutput("", OutputType.js);
     String lib1Output =
diff --git a/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart b/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
index 7b6db2d..25c48e3 100644
--- a/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
+++ b/tests/compiler/dart2js/deferred/dont_inline_deferred_globals_test.dart
@@ -25,12 +25,12 @@
       return elementEnvironment.lookupLibrary(Uri.parse(name));
     }
 
-    var outputUnitForEntity =
-        compiler.backend.outputUnitData.outputUnitForEntity;
+    var outputUnitForMember =
+        compiler.backend.outputUnitData.outputUnitForMember;
 
     dynamic lib1 = lookupLibrary("memory:lib1.dart");
     var foo1 = elementEnvironment.lookupLibraryMember(lib1, "finalVar");
-    var ou_lib1 = outputUnitForEntity(foo1);
+    var ou_lib1 = outputUnitForMember(foo1);
 
     String mainOutput = collector.getOutput("", OutputType.js);
     String lib1Output =
diff --git a/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart b/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart
index f5e7858..f3aecaa 100644
--- a/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart
+++ b/tests/compiler/dart2js/deferred/follow_implicit_super_regression_test.dart
@@ -20,17 +20,17 @@
       return elementEnvironment.lookupLibrary(Uri.parse(name));
     }
 
-    var outputUnitForEntity =
-        compiler.backend.outputUnitData.outputUnitForEntity;
+    var outputUnitForMember =
+        compiler.backend.outputUnitData.outputUnitForMember;
 
     dynamic lib = lookupLibrary("memory:lib.dart");
     var a = elementEnvironment.lookupLibraryMember(lib, "a");
     var b = elementEnvironment.lookupLibraryMember(lib, "b");
     var c = elementEnvironment.lookupLibraryMember(lib, "c");
     var d = elementEnvironment.lookupLibraryMember(lib, "d");
-    Expect.equals(outputUnitForEntity(a), outputUnitForEntity(b));
-    Expect.equals(outputUnitForEntity(a), outputUnitForEntity(c));
-    Expect.equals(outputUnitForEntity(a), outputUnitForEntity(d));
+    Expect.equals(outputUnitForMember(a), outputUnitForMember(b));
+    Expect.equals(outputUnitForMember(a), outputUnitForMember(c));
+    Expect.equals(outputUnitForMember(a), outputUnitForMember(d));
   }
 
   asyncTest(() async {
diff --git a/tests/compiler/dart2js/deferred/inline_restrictions_test.dart b/tests/compiler/dart2js/deferred/inline_restrictions_test.dart
index a296c65e..6c53fcf 100644
--- a/tests/compiler/dart2js/deferred/inline_restrictions_test.dart
+++ b/tests/compiler/dart2js/deferred/inline_restrictions_test.dart
@@ -18,16 +18,16 @@
         memorySourceFiles: MEMORY_SOURCE_FILES, outputProvider: collector);
     Compiler compiler = result.compiler;
     var env = compiler.backendClosedWorldForTesting.elementEnvironment;
-    var outputUnitForEntity =
-        compiler.backend.outputUnitData.outputUnitForEntity;
+    var outputUnitForMember =
+        compiler.backend.outputUnitData.outputUnitForMember;
     lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
     dynamic lib1 = lookupLibrary("memory:lib1.dart");
     var inlineMeAway = env.lookupLibraryMember(lib1, "inlineMeAway");
-    var ou_lib1 = outputUnitForEntity(inlineMeAway);
+    var ou_lib1 = outputUnitForMember(inlineMeAway);
 
     dynamic lib3 = lookupLibrary("memory:lib3.dart");
     var sameContextInline = env.lookupLibraryMember(lib3, "sameContextInline");
-    var ou_lib3 = outputUnitForEntity(sameContextInline);
+    var ou_lib3 = outputUnitForMember(sameContextInline);
 
     // Test that we actually got different output units.
     Expect.notEquals(ou_lib1.name, ou_lib3.name);
diff --git a/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart b/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart
index c73eb2e..985ad2a 100644
--- a/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart
+++ b/tests/compiler/dart2js/deferred/load_graph_segmentation2_test.dart
@@ -16,15 +16,15 @@
     CompilationResult result =
         await runCompiler(memorySourceFiles: MEMORY_SOURCE_FILES);
     Compiler compiler = result.compiler;
-    var outputUnitForEntity =
-        compiler.backend.outputUnitData.outputUnitForEntity;
+    var outputUnitForMember =
+        compiler.backend.outputUnitData.outputUnitForMember;
     var env = compiler.backendClosedWorldForTesting.elementEnvironment;
     var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
     dynamic lib = env.lookupLibrary(Uri.parse("memory:lib.dart"));
     var f1 = env.lookupLibraryMember(lib, "f1");
     var f2 = env.lookupLibraryMember(lib, "f2");
-    Expect.notEquals(mainOutputUnit, outputUnitForEntity(f1));
-    Expect.equals(mainOutputUnit, outputUnitForEntity(f2));
+    Expect.notEquals(mainOutputUnit, outputUnitForMember(f1));
+    Expect.equals(mainOutputUnit, outputUnitForMember(f2));
   });
 }
 
diff --git a/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart b/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart
index 8135ce0..f20cef3 100644
--- a/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart
+++ b/tests/compiler/dart2js/deferred/load_graph_segmentation_test.dart
@@ -23,8 +23,9 @@
     var main = env.mainFunction;
     Expect.isNotNull(main, "Could not find 'main'");
 
-    var outputUnitForEntity =
-        compiler.backend.outputUnitData.outputUnitForEntity;
+    var outputUnitForMember =
+        compiler.backend.outputUnitData.outputUnitForMember;
+    var outputUnitForClass = compiler.backend.outputUnitData.outputUnitForClass;
 
     var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
     var backend = compiler.backend;
@@ -40,21 +41,21 @@
     var bar1 = env.lookupLibraryMember(lib4, "bar1");
     var bar2 = env.lookupLibraryMember(lib4, "bar2");
 
-    OutputUnit ou_lib1 = outputUnitForEntity(foo1);
-    OutputUnit ou_lib2 = outputUnitForEntity(foo2);
-    OutputUnit ou_lib1_lib2 = outputUnitForEntity(foo3);
-    OutputUnit ou_lib4_1 = outputUnitForEntity(bar1);
-    OutputUnit ou_lib4_2 = outputUnitForEntity(bar2);
+    OutputUnit ou_lib1 = outputUnitForMember(foo1);
+    OutputUnit ou_lib2 = outputUnitForMember(foo2);
+    OutputUnit ou_lib1_lib2 = outputUnitForMember(foo3);
+    OutputUnit ou_lib4_1 = outputUnitForMember(bar1);
+    OutputUnit ou_lib4_2 = outputUnitForMember(bar2);
 
-    Expect.equals(mainOutputUnit, outputUnitForEntity(main));
-    Expect.notEquals(mainOutputUnit, outputUnitForEntity(foo1));
+    Expect.equals(mainOutputUnit, outputUnitForMember(main));
+    Expect.notEquals(mainOutputUnit, outputUnitForMember(foo1));
     Expect.notEquals(ou_lib1, ou_lib1_lib2);
     Expect.notEquals(ou_lib2, ou_lib1_lib2);
     Expect.notEquals(ou_lib1, ou_lib2);
     Expect.notEquals(ou_lib4_1, ou_lib4_2);
     Expect.notEquals(ou_lib1, ou_lib4_2);
     // InputElement is native, so it should be in the mainOutputUnit.
-    Expect.equals(mainOutputUnit, outputUnitForEntity(inputElement));
+    Expect.equals(mainOutputUnit, outputUnitForClass(inputElement));
 
     var hunksToLoad = compiler.deferredLoadTask.hunksToLoad;
 
diff --git a/tests/compiler/dart2js/deferred/not_in_main_test.dart b/tests/compiler/dart2js/deferred/not_in_main_test.dart
index 4a13b29..a259716 100644
--- a/tests/compiler/dart2js/deferred/not_in_main_test.dart
+++ b/tests/compiler/dart2js/deferred/not_in_main_test.dart
@@ -20,8 +20,8 @@
   asyncTest(() async {
     CompilationResult result = await runCompiler(memorySourceFiles: TEST1);
     Compiler compiler = result.compiler;
-    var outputUnitForEntity =
-        compiler.backend.outputUnitData.outputUnitForEntity;
+    var outputUnitForMember =
+        compiler.backend.outputUnitData.outputUnitForMember;
     var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
     var env = compiler.backendClosedWorldForTesting.elementEnvironment;
     lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
@@ -30,7 +30,7 @@
     env.lookupLibraryMember(lib1, "foo1");
     var foo2 = env.lookupLibraryMember(lib2, "foo2");
 
-    Expect.notEquals(mainOutputUnit, outputUnitForEntity(foo2));
+    Expect.notEquals(mainOutputUnit, outputUnitForMember(foo2));
   });
 }
 
@@ -38,16 +38,15 @@
   asyncTest(() async {
     CompilationResult result = await runCompiler(memorySourceFiles: TEST2);
     Compiler compiler = result.compiler;
-    var outputUnitForEntity =
-        compiler.backend.outputUnitData.outputUnitForEntity;
+    var outputUnitForClass = compiler.backend.outputUnitData.outputUnitForClass;
 
     var mainOutputUnit = compiler.backend.outputUnitData.mainOutputUnit;
     var env = compiler.backendClosedWorldForTesting.elementEnvironment;
     lookupLibrary(name) => env.lookupLibrary(Uri.parse(name));
     dynamic shared = lookupLibrary("memory:shared.dart");
-    var a = env.lookupLibraryMember(shared, "A");
+    var a = env.lookupClass(shared, "A");
 
-    Expect.equals(mainOutputUnit, outputUnitForEntity(a));
+    Expect.equals(mainOutputUnit, outputUnitForClass(a));
   });
 }
 
diff --git a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
index cef5d1b..ca8c88f 100644
--- a/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
+++ b/tests/compiler/dart2js/deferred_loading/deferred_loading_test.dart
@@ -117,7 +117,7 @@
       : super(reporter, actualMap);
 
   String getMemberValue(MemberEntity member) {
-    return outputUnitString(_data.outputUnitForEntity(member));
+    return outputUnitString(_data.outputUnitForMember(member));
   }
 
   @override
@@ -162,7 +162,7 @@
     Compiler compiler, ClassEntity cls, Map<Id, ActualData> actualMap,
     {bool verbose: false}) {
   OutputUnitData data = compiler.backend.outputUnitData;
-  String value = outputUnitString(data.outputUnitForEntity(cls));
+  String value = outputUnitString(data.outputUnitForClass(cls));
 
   KernelBackendStrategy backendStrategy = compiler.backendStrategy;
   KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
diff --git a/tests/compiler/dart2js/inference/data/field_type.dart b/tests/compiler/dart2js/inference/data/field_type.dart
index 51b672d..44168f3 100644
--- a/tests/compiler/dart2js/inference/data/field_type.dart
+++ b/tests/compiler/dart2js/inference/data/field_type.dart
@@ -202,7 +202,8 @@
 
   /*element: A9.:[exact=A9]*/
   A9(/*[exact=JSBool]*/ x) {
-    if (x) {} else {
+    if (x) {
+    } else {
       /*update: [exact=A9]*/ f9 = "1";
     }
   }
@@ -727,7 +728,8 @@
   /*element: A29.:[exact=A29]*/
   A29(/*[exact=JSUInt31]*/ x) {
     this. /*update: [exact=A29]*/ f29a = x;
-    if (x /*invoke: [exact=JSUInt31]*/ == 0) {} else {
+    if (x /*invoke: [exact=JSUInt31]*/ == 0) {
+    } else {
       return;
     }
     this. /*update: [exact=A29]*/ f29b = x;
diff --git a/tests/compiler/dart2js/inference/data/general.dart b/tests/compiler/dart2js/inference/data/general.dart
index ea317d5..1b2d806 100644
--- a/tests/compiler/dart2js/inference/data/general.dart
+++ b/tests/compiler/dart2js/inference/data/general.dart
@@ -306,7 +306,8 @@
 
 /*element: testIsCheck26:[subclass=JSInt]*/
 testIsCheck26(/*[null|subclass=Object]*/ a) {
-  if (a is int) {} else {
+  if (a is int) {
+  } else {
     throw 42;
   }
   return a;
@@ -314,7 +315,8 @@
 
 /*element: testIsCheck27:[subclass=JSInt]*/
 testIsCheck27(/*[null|subclass=Object]*/ a) {
-  if (a is int) {} else {
+  if (a is int) {
+  } else {
     return 42;
   }
   return a;
@@ -322,7 +324,8 @@
 
 /*element: testIsCheck28:[null|subclass=Object]*/
 testIsCheck28(/*[null|subclass=Object]*/ a) {
-  if (a is int) {} else {}
+  if (a is int) {
+  } else {}
   return a;
 }
 
@@ -344,7 +347,8 @@
 /*element: testIf2:[null|exact=JSUInt31]*/
 testIf2(/*[null|subclass=Object]*/ a) {
   var c = null;
-  if (a) {} else {
+  if (a) {
+  } else {
     c = 10;
   }
   return c;
diff --git a/tests/compiler/dart2js/link_test.dart b/tests/compiler/dart2js/link_test.dart
index 841c89f..5033eea 100644
--- a/tests/compiler/dart2js/link_test.dart
+++ b/tests/compiler/dart2js/link_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
-import 'package:compiler/src/util/util.dart';
+import 'package:front_end/src/fasta/util/link.dart' show Link;
 import 'link_helper.dart';
 
 main() {
@@ -21,8 +21,6 @@
   testFromList([0, 1, 2, 3, 4]);
   testFromList([0, 1, 2, 3, 4, 5]);
   testSkip();
-
-  testCopyWithout();
 }
 
 testFromList(List list) {
@@ -63,14 +61,3 @@
   Expect.isTrue(emptyLink.skip(0).isEmpty);
   Expect.throws(() => emptyLink.skip(1), (e) => e is RangeError);
 }
-
-testCopyWithout() {
-  test(const Link().copyWithout(0), []);
-
-  test(LinkFromList([0]).copyWithout(0), []);
-  test(LinkFromList([0, 1]).copyWithout(0), [1]);
-  test(LinkFromList([0, 1, 2]).copyWithout(0), [1, 2]);
-  test(LinkFromList([0, 1, 2]).copyWithout(1), [0, 2]);
-  test(LinkFromList([0, 1, 2]).copyWithout(2), [0, 1]);
-  test(LinkFromList([0, 1, 2]).copyWithout(3), [0, 1, 2]);
-}
diff --git a/tests/compiler/dart2js/memory_source_file_helper.dart b/tests/compiler/dart2js/memory_source_file_helper.dart
index 24a93e7..b1e0be0 100644
--- a/tests/compiler/dart2js/memory_source_file_helper.dart
+++ b/tests/compiler/dart2js/memory_source_file_helper.dart
@@ -29,7 +29,8 @@
   MemorySourceFileProvider(Map<String, dynamic> this.memorySourceFiles);
 
   @override
-  Future<Input> readBytesFromUri(Uri resourceUri, InputKind inputKind) {
+  Future<Input<List<int>>> readBytesFromUri(
+      Uri resourceUri, InputKind inputKind) {
     if (resourceUri.scheme != 'memory') {
       return super.readBytesFromUri(resourceUri, inputKind);
     }
@@ -41,7 +42,7 @@
       return new Future.error(new Exception(
           'No such memory file $resourceUri in ${memorySourceFiles.keys}'));
     }
-    Input input;
+    Input<List<int>> input;
     switch (inputKind) {
       case InputKind.UTF8:
         if (source is String) {
diff --git a/tests/compiler/dart2js/model/class_set_test.dart b/tests/compiler/dart2js/model/class_set_test.dart
index a8216b1..401c441 100644
--- a/tests/compiler/dart2js/model/class_set_test.dart
+++ b/tests/compiler/dart2js/model/class_set_test.dart
@@ -12,8 +12,8 @@
 import 'package:compiler/src/elements/entities.dart' show ClassEntity;
 import 'package:compiler/src/universe/class_set.dart';
 import 'package:compiler/src/util/enumset.dart';
-import 'package:compiler/src/util/util.dart';
 import 'package:compiler/src/world.dart';
+import 'package:front_end/src/fasta/util/link.dart' show Link;
 import '../type_test_helper.dart';
 
 void main() {
diff --git a/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart b/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart
index fa652b4..16a33bd 100644
--- a/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart
+++ b/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart
@@ -179,16 +179,18 @@
       (ClassEntity cls) {
     List<String> expectedLiveMembers =
         expectedLiveMembersMap[cls.name] ?? const <String>[];
-    elementEnvironment.forEachLocalClassMember(cls, (MemberEntity member) {
+    List<String> actualLiveMembers = <String>[];
+    closedWorld.processedMembers.forEach((MemberEntity member) {
       if (member.enclosingClass != cls) return;
-      bool expected = expectedLiveMembers.contains(member.name);
-      bool live = closedWorld.processedMembers.contains(member);
-      Expect.equals(
-          expected,
-          live,
-          "Member $member ${expected ? '' : 'not '}expected to be live "
-          "in ${strongMode ? 'Dart 2' : 'Dart 1'}. "
-          "Expected members for ${cls.name}: $expectedLiveMembers");
+      if (member.isConstructor) return;
+      actualLiveMembers.add(member.name);
     });
+    Expect.setEquals(
+        expectedLiveMembers,
+        actualLiveMembers,
+        "Unexpected live members for $cls "
+        "in ${strongMode ? 'Dart 2' : 'Dart 1'}. \n"
+        "Expected members for ${cls.name}: $expectedLiveMembers\n"
+        "Actual members for ${cls.name}  : $actualLiveMembers");
   });
 }
diff --git a/tests/compiler/dart2js_extra/deferred_function_types1_test.dart b/tests/compiler/dart2js_extra/deferred_function_types1_test.dart
new file mode 100644
index 0000000..91c9075
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types1_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method1() is int Function(int));
+  Expect.isFalse(lib1.method1() is String Function(String));
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method2() is int Function(int));
+  Expect.isTrue(lib2.method2() is String Function(String));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types2_test.dart b/tests/compiler/dart2js_extra/deferred_function_types2_test.dart
new file mode 100644
index 0000000..4336421
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types2_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method2() is int Function(int));
+  Expect.isTrue(lib2.method2() is String Function(String));
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method1() is int Function(int));
+  Expect.isFalse(lib1.method1() is String Function(String));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types3_test.dart b/tests/compiler/dart2js_extra/deferred_function_types3_test.dart
new file mode 100644
index 0000000..98a6de8
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types3_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method3() is Object Function(Null));
+  Expect.isFalse(lib1.method3() is Object Function(Null, Null));
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method4() is Object Function(Null));
+  Expect.isTrue(lib2.method4() is Object Function(Null, Null));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types4_test.dart b/tests/compiler/dart2js_extra/deferred_function_types4_test.dart
new file mode 100644
index 0000000..fc78d96
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types4_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method4() is Object Function(Null));
+  Expect.isTrue(lib2.method4() is Object Function(Null, Null));
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method3() is Object Function(Null));
+  Expect.isFalse(lib1.method3() is Object Function(Null, Null));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types5_test.dart b/tests/compiler/dart2js_extra/deferred_function_types5_test.dart
new file mode 100644
index 0000000..998d678
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types5_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.test3(lib1.method3()));
+  Expect.isFalse(lib1.method3() is Object Function(String));
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method4() is Object Function(String, String));
+  Expect.isTrue(lib2.test4(lib2.method4()));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types6_test.dart b/tests/compiler/dart2js_extra/deferred_function_types6_test.dart
new file mode 100644
index 0000000..2423b52
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types6_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2018, 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method4() is Object Function(String, String));
+  Expect.isTrue(lib2.test4(lib2.method4()));
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.test3(lib1.method3()));
+  Expect.isFalse(lib1.method3() is Object Function(String));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types7_test.dart b/tests/compiler/dart2js_extra/deferred_function_types7_test.dart
new file mode 100644
index 0000000..c3e8de0
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types7_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method1() is int Function(int));
+  Expect.isFalse(lib1.method1() is String Function(String));
+  Expect.isTrue(lib1.method5 is Object Function(Null, String, int));
+  Expect.isFalse(lib1.method5 is Object Function(Null, int, String));
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method2() is int Function(int));
+  Expect.isTrue(lib2.method2() is String Function(String));
+  Expect.isFalse(lib2.method6 is Object Function(Null, String, int));
+  Expect.isTrue(lib2.method6 is Object Function(Null, int, String));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types8_test.dart b/tests/compiler/dart2js_extra/deferred_function_types8_test.dart
new file mode 100644
index 0000000..eaa89ca
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types8_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2018, 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method2() is int Function(int));
+  Expect.isTrue(lib2.method2() is String Function(String));
+  Expect.isFalse(lib2.method6 is Object Function(Null, String, int));
+  Expect.isTrue(lib2.method6 is Object Function(Null, int, String));
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method1() is int Function(int));
+  Expect.isFalse(lib1.method1() is String Function(String));
+  Expect.isTrue(lib1.method5 is Object Function(Null, String, int));
+  Expect.isFalse(lib1.method5 is Object Function(Null, int, String));
+}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types_lib1.dart b/tests/compiler/dart2js_extra/deferred_function_types_lib1.dart
new file mode 100644
index 0000000..4bacb61
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types_lib1.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2018, 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.
+
+method1() {
+  return (int i) => i;
+}
+
+class Class1 {}
+
+method3() {
+  return (Class1 c) => c;
+}
+
+test3(o) => o is Class1 Function(Class1);
+
+method5(Class1 c, String s, int i) {}
diff --git a/tests/compiler/dart2js_extra/deferred_function_types_lib2.dart b/tests/compiler/dart2js_extra/deferred_function_types_lib2.dart
new file mode 100644
index 0000000..a8abb54
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_function_types_lib2.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2018, 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.
+
+method2() {
+  return (String s) => s;
+}
+
+class Class2 {}
+
+method4() {
+  return (Class2 c1, Class2 c2) => c1;
+}
+
+test4(o) => o is Class2 Function(Class2, Class2);
+
+method6(Class2 c, int i, String s) {}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index e327d40..327e76e 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -299,8 +299,8 @@
 
 # We skip all the Dart 1.0 tests in dartk and dartkp mode as these
 # modes are intended only for Dart 2.0 with strong mode enabled.
-[ $compiler == dartk || $compiler == dartkp ]
-*: Skip
+[ $compiler == app_jitk || $compiler == dartk || $compiler == dartkp ]
+*: SkipByDesign
 
 [ $runtime == dart_precompiled || $runtime == flutter || $runtime == vm ]
 big_integer_arith_vm_test: CompileTimeError # Large integer literal
diff --git a/tests/corelib_2/bigint_test.dart b/tests/corelib_2/bigint_test.dart
index 290e477..030e59f 100644
--- a/tests/corelib_2/bigint_test.dart
+++ b/tests/corelib_2/bigint_test.dart
@@ -363,6 +363,9 @@
   a = BigInt.parse("12345678901234567890");
   b = BigInt.parse("10000000000000000");
   Expect.equals(new BigInt.from(1234), a ~/ b);
+  a = BigInt.parse("9173112362840293939050000000000000000");
+  b = BigInt.parse("50000000000000000");
+  Expect.equals(BigInt.parse("183462247256805878781"), a ~/ b);
 }
 
 testBigintDiv() {
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index 740c6c6..d996c09 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -4,6 +4,14 @@
 iterable_where_type_test: RuntimeError # Disabled.  Issue 32463
 maps_test: Skip # Maps class no longer exists
 
+[ $compiler == app_jitk ]
+symbol_operator_test/03: RuntimeError
+symbol_reserved_word_test/06: RuntimeError
+symbol_reserved_word_test/09: RuntimeError
+symbol_reserved_word_test/12: RuntimeError
+symbol_test/none: RuntimeError
+unicode_test: RuntimeError
+
 [ $compiler == dart2analyzer ]
 bigint_from_test: CompileTimeError # Issue 32585
 compare_to2_test: CompileTimeError # invalid test
@@ -12,11 +20,11 @@
 num_sign_test: Crash, Pass # Issue 31768
 
 [ $compiler == dart2js ]
+apply_generic_function_test: RuntimeError # Issue 32691
 bigint_from_test: RuntimeError # Issue 32589
 date_time11_test: RuntimeError, Pass # Fails when US is on winter time, issue 31285.
 iterable_where_type_test: RuntimeError # issue 31718
 list_unmodifiable_test: Pass, RuntimeError # Issue 28712
-apply_generic_function_test: RuntimeError # Issue 32691
 
 [ $compiler != dartdevc ]
 error_stack_trace_test/static: MissingCompileTimeError
@@ -93,9 +101,23 @@
 [ $arch == x64 && $system == windows ]
 stopwatch_test: Skip # Flaky test due to expected performance behaviour.
 
-[ $arch == simarm || $arch == simarm64 || $arch == simdbc64 ]
-bigint_parse_radix_test: Pass, Slow # Bigint computations are slow on simulated architectures.
-bigint_test: Pass, Slow # Bigint computations are slow on simulated architectures.
+# All static_tests have expected compile-time errors.
+[ $compiler != app_jitk && $compiler != dart2analyzer && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkp && $compiler != fasta && $strong ]
+core_runtime_types_static_test: MissingCompileTimeError
+splay_tree_test/01: MissingCompileTimeError
+splay_tree_test/02: MissingCompileTimeError
+string_base_vm_static_test: MissingCompileTimeError
+string_replace_static_test: MissingCompileTimeError
+string_static_test: MissingCompileTimeError
+
+[ $compiler != app_jitk && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkp && $compiler != fasta ]
+iterable_element_at_test/static: MissingCompileTimeError
+
+[ $compiler != app_jitk && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkp && $compiler != fasta && ($compiler != dart2analyzer || !$strong) ]
+iterable_mapping_test/01: MissingCompileTimeError
+
+[ $compiler != app_jitk && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkp && $runtime != none ]
+map_keys2_test: RuntimeError # needs Dart 2 is checks
 
 [ $compiler == dart2analyzer && !$checked && !$strong ]
 from_environment_const_type_test/02: MissingCompileTimeError
@@ -133,15 +155,6 @@
 [ $compiler != dart2analyzer && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk ]
 bigint_js_test: SkipByDesign # JavaScript-specific test
 
-# All static_tests have expected compile-time errors.
-[ $compiler != dart2analyzer && $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkp && $compiler != fasta && $strong ]
-core_runtime_types_static_test: MissingCompileTimeError
-splay_tree_test/01: MissingCompileTimeError
-splay_tree_test/02: MissingCompileTimeError
-string_base_vm_static_test: MissingCompileTimeError
-string_replace_static_test: MissingCompileTimeError
-string_static_test: MissingCompileTimeError
-
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 list_as_map_test: Pass, Slow # TODO(kasperl): Please triage.
 string_trimlr_test/unicode63: RuntimeError # Uses Unicode 6.2.0 or earlier.
@@ -196,10 +209,6 @@
 map_test: Crash # tests/corelib_2/map_test.dart:903:7: Internal problem: Unhandled Null in installDefaultConstructor.
 symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
 
-[ $compiler == dart2js && $fast_startup ]
-apply3_test: RuntimeError
-dynamic_nosuchmethod_test: RuntimeError
-
 [ $compiler == dart2js && $fast_startup && $fasta && $strong ]
 cast_test: RuntimeError
 error_stack_trace1_test: RuntimeError
@@ -279,15 +288,6 @@
 [ $compiler == dart2js && !$fasta ]
 *: SkipByDesign
 
-[ $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkp && $compiler != fasta ]
-iterable_element_at_test/static: MissingCompileTimeError
-
-[ $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkp && $compiler != fasta && ($compiler != dart2analyzer || !$strong) ]
-iterable_mapping_test/01: MissingCompileTimeError
-
-[ $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkp && $runtime != none ]
-map_keys2_test: RuntimeError # needs Dart 2 is checks
-
 [ $compiler != dart2js && $fasta ]
 bool_from_environment2_test/03: MissingCompileTimeError
 string_from_environment3_test/03: MissingCompileTimeError
@@ -539,6 +539,10 @@
 [ !$strong && ($runtime == dart_precompiled || $runtime == vm) ]
 list_test/*: RuntimeError # VM doesn't implement strong mode covariance checks
 
+[ $arch == simarm || $arch == simarm64 || $arch == simdbc64 ]
+bigint_parse_radix_test: Pass, Slow # Bigint computations are slow on simulated architectures.
+bigint_test: Pass, Slow # Bigint computations are slow on simulated architectures.
+
 [ $arch == simdbc || $arch == simdbc64 ]
 regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter
 
diff --git a/tests/kernel/kernel.status b/tests/kernel/kernel.status
index 37322af..7d79601 100644
--- a/tests/kernel/kernel.status
+++ b/tests/kernel/kernel.status
@@ -11,6 +11,9 @@
 [ !$fasta ]
 unsorted/loop_test: Skip # This test uses optional new/const.
 
+[ $compiler != app_jitk && $compiler != dartk && $compiler != dartkp && $runtime != none ]
+unsorted/types_test: RuntimeError
+
 [ $compiler == dart2analyzer && $runtime == none ]
 unsorted/super_mixin_test: CompileTimeError
 
@@ -27,9 +30,6 @@
 [ $compiler == dart2js && !$fasta ]
 unsorted/super_mixin_test: CompileTimeError
 
-[ $compiler != dartk && $compiler != dartkp && $runtime != none ]
-unsorted/types_test: RuntimeError
-
 [ $compiler != dartk && $compiler != dartkp && !$strong ]
 unsorted/invocation_errors_test/00: MissingCompileTimeError # This test has been tuned for dart 2.
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index e634a35..76720a4 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -559,31 +559,10 @@
 generic_methods_type_expression_test/03: Crash # 'file:*/pkg/compiler/lib/src/ssa/builder_kernel.dart': Failed assertion: line 1728 pos 16: 'type is MethodTypeVariableType': is not true.
 generic_methods_type_expression_test/none: Crash # 'file:*/pkg/compiler/lib/src/ssa/builder_kernel.dart': Failed assertion: line 1728 pos 16: 'type is MethodTypeVariableType': is not true.
 invocation_mirror_test: Crash # 'file:*/pkg/compiler/lib/src/ssa/builder_kernel.dart': Failed assertion: line 3014 pos 14: 'arguments.named.isEmpty': is not true.
-operator2_negative_test: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
 sync_generator2_test/41: Crash # 'file:*/pkg/compiler/lib/src/kernel/element_map_impl.dart': Failed assertion: line 939 pos 18: 'asyncMarker == AsyncMarker.SYNC': is not true.
 sync_generator2_test/52: Crash # 'file:*/pkg/compiler/lib/src/kernel/element_map_impl.dart': Failed assertion: line 939 pos 18: 'asyncMarker == AsyncMarker.SYNC': is not true.
-syntax_test/04: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/05: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/06: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/07: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/08: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/09: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/10: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/11: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/13: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/14: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/15: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/16: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/17: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/18: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/19: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/20: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
 syntax_test/21: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
 syntax_test/22: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/23: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/24: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/25: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/26: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
 
 [ $compiler == dart2js && $fasta && $minified ]
 deferred_load_library_wrong_args_test/01: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
diff --git a/tests/language/language_kernel.status b/tests/language/language_kernel.status
index c9903f0..7b7cd78 100644
--- a/tests/language/language_kernel.status
+++ b/tests/language/language_kernel.status
@@ -195,5 +195,5 @@
 
 # We skip all the Dart 1.0 tests in dartk and dartkp mode as these
 # modes are intended only for Dart 2.0 with strong mode enabled.
-[ $compiler == dartk || $compiler == dartkp ]
-*: Skip
+[ $compiler == app_jitk || $compiler == dartk || $compiler == dartkp ]
+*: SkipByDesign
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index 23cf368..ba20d61 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -46,6 +46,9 @@
 initializer_super_last_test/cc31: MissingCompileTimeError
 initializer_super_last_test/cc32: MissingCompileTimeError
 
+[ $compiler != app_jitk && $compiler != dartk && $compiler != dartkp && $mode == debug && $runtime == vm ]
+built_in_identifier_type_annotation_test/set: Crash # Not supported by legacy VM front-end.
+
 [ $compiler != dart2js && $compiler != dartdevc && !$fasta && $strong ]
 type_promotion_functions_test: CompileTimeError # Issue 30895: This test requires a complete rewrite for 2.0.
 
@@ -117,9 +120,6 @@
 [ $compiler != dartdevc && !$checked ]
 function_type/*: Skip # Needs checked mode.
 
-[ $compiler != dartk && $compiler != dartkp && $mode == debug && $runtime == vm ]
-built_in_identifier_type_annotation_test/set: Crash # Not supported by legacy VM front-end.
-
 [ $compiler == none && $runtime == drt && !$checked ]
 assertion_initializer_const_error_test/01: Fail
 
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index 74be6be..fdfc105 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -399,7 +399,6 @@
 generic_methods_bounds_test/01: MissingCompileTimeError
 generic_methods_dynamic_test/01: MissingCompileTimeError
 generic_methods_dynamic_test/03: MissingCompileTimeError
-generic_methods_overriding_test/01: MissingCompileTimeError
 generic_methods_overriding_test/03: MissingCompileTimeError
 generic_methods_overriding_test/06: StaticWarning
 generic_methods_recursive_bound_test/02: MissingCompileTimeError
@@ -1107,8 +1106,6 @@
 field3a_negative_test: StaticWarning # Issue 28823
 forwarding_stub_tearoff_test: CompileTimeError
 generic_methods_generic_function_result_test/none: CompileTimeError # Issue #30207
-generic_methods_overriding_test/01: MissingCompileTimeError # Issue 29070
-generic_methods_overriding_test/03: MissingCompileTimeError # Issue 29070
 generic_no_such_method_dispatcher_test: CompileTimeError
 generic_tearoff_test: CompileTimeError
 import_core_prefix_test: CompileTimeError # "dynamic" should be defined in core.
@@ -1353,6 +1350,7 @@
 generic_field_mixin6_test/01: MissingCompileTimeError
 generic_function_typedef2_test/04: MissingCompileTimeError
 generic_methods_generic_function_result_test/01: MissingCompileTimeError # Issue #30207
+generic_methods_overriding_test/01: MissingCompileTimeError
 generic_test/01: MissingCompileTimeError
 identical_const_test/01: MissingCompileTimeError
 identical_const_test/02: MissingCompileTimeError
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 953e7a2..830d006 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -486,7 +486,6 @@
 stacktrace_rethrow_error_test/withtraceparameter: RuntimeError # Issue 12698
 stacktrace_rethrow_nonerror_test: RuntimeError # Issue 12698
 stacktrace_test: RuntimeError # Issue 12698
-super_call4_test: Crash # NoSuchMethodError: The getter 'thisLocal' was called on null.
 switch_bad_case_test/01: MissingCompileTimeError
 switch_bad_case_test/02: MissingCompileTimeError
 switch_case_test/00: MissingCompileTimeError
@@ -808,7 +807,6 @@
 string_split_test: CompileTimeError
 string_supertype_checked_test: CompileTimeError
 super_bound_closure_test/none: CompileTimeError
-super_call4_test: Crash # NoSuchMethodError: The getter 'thisLocal' was called on null.
 super_no_such_method1_test: CompileTimeError
 super_no_such_method2_test: CompileTimeError
 super_no_such_method3_test: CompileTimeError
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 2bfb404..11456f2 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -63,7 +63,6 @@
 generic_local_functions_test: CompileTimeError
 generic_methods_generic_function_parameter_test: CompileTimeError
 generic_methods_generic_function_result_test/none: CompileTimeError # Issue #30208
-generic_methods_overriding_test/03: MissingCompileTimeError # Issue 29920
 generic_no_such_method_dispatcher_simple_test: Skip # This test is just for kernel.
 generic_no_such_method_dispatcher_test: CompileTimeError
 getter_closure_execution_order_test: RuntimeError # Issue 29920
@@ -391,6 +390,7 @@
 function_type_parameter_negative_test: Fail
 generic_function_bounds_test: RuntimeError
 generic_methods_generic_function_result_test/01: MissingCompileTimeError
+generic_methods_overriding_test/01: MissingCompileTimeError # Issue 29920
 generic_methods_recursive_bound_test/02: MissingCompileTimeError
 generic_no_such_method_dispatcher_simple_test: CompileTimeError # Warning: Superclass has no method named 'foo'.
 generic_no_such_method_dispatcher_test: CompileTimeError # Issue 31533
@@ -685,7 +685,6 @@
 generic_function_type_as_type_argument_test/02: MissingCompileTimeError # Issue 29920
 generic_instanceof2_test: RuntimeError # Issue 29920; ReferenceError: FooOfK$String is not defined
 generic_is_check_test: RuntimeError # Issue 29920; Expect.isTrue(false) fails.
-generic_methods_overriding_test/01: MissingCompileTimeError # Issue 29920
 generic_tearoff_test: CompileTimeError
 identical_closure2_test: RuntimeError # Issue 29920; Expect.isFalse(true) fails.
 infinite_switch_label_test: RuntimeError # Issue 29920; NoSuchMethodError: method not found: '<Unexpected Null Value>'
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 4a738cc..e923ac4 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -10,6 +10,175 @@
 # missing a section you need, please reach out to sigmund@ to see the best way
 # to add them.
 
+[ $compiler == app_jitk ]
+assertion_initializer_const_error2_test/cc01: MissingCompileTimeError
+assertion_initializer_const_error2_test/cc02: MissingCompileTimeError
+assertion_initializer_const_error2_test/cc03: MissingCompileTimeError
+assertion_initializer_const_error2_test/cc04: MissingCompileTimeError
+assertion_initializer_const_error2_test/cc05: MissingCompileTimeError
+assertion_initializer_const_error2_test/cc06: MissingCompileTimeError
+assertion_initializer_const_error2_test/cc07: MissingCompileTimeError
+assertion_initializer_const_error2_test/cc08: MissingCompileTimeError
+assertion_initializer_const_error2_test/cc09: MissingCompileTimeError
+assertion_initializer_const_error2_test/cc10: MissingCompileTimeError
+async_star_cancel_while_paused_test: RuntimeError
+async_star_pause_test: RuntimeError
+async_star_test/02: RuntimeError
+call_method_implicit_tear_off_implements_function_test/05: RuntimeError
+call_method_implicit_tear_off_implements_function_test/06: RuntimeError
+call_method_must_not_be_field_test/03: RuntimeError
+call_method_must_not_be_getter_test/03: RuntimeError
+compile_time_constant_static5_test/11: CompileTimeError
+compile_time_constant_static5_test/16: CompileTimeError
+compile_time_constant_static5_test/21: CompileTimeError
+compile_time_constant_static5_test/23: CompileTimeError
+conditional_import_string_test: CompileTimeError
+conditional_import_test: CompileTimeError
+conditional_rewrite_test: RuntimeError
+config_import_corelib_test: CompileTimeError
+config_import_test: RuntimeError
+const_list_test: RuntimeError
+const_locals_test: RuntimeError
+const_map4_test: RuntimeError
+const_nested_test: RuntimeError
+const_string_test: RuntimeError
+constructor12_test: RuntimeError
+covariant_subtyping_test: RuntimeError
+ct_const_test: RuntimeError
+cyclic_type2_test: CompileTimeError
+cyclic_type_test/02: CompileTimeError
+cyclic_type_test/04: CompileTimeError
+cyclic_typedef_test/10: DartkCrash
+cyclic_typedef_test/11: DartkCrash
+deferred_call_empty_before_load_test: RuntimeError
+deferred_load_constants_test/none: RuntimeError
+deferred_not_loaded_check_test: RuntimeError
+deferred_redirecting_factory_test: RuntimeError
+deferred_static_seperate_test: RuntimeError
+dynamic_prefix_core_test/none: CompileTimeError
+emit_const_fields_test: CompileTimeError
+example_constructor_test: RuntimeError
+export_ambiguous_main_test: Crash
+external_test/10: MissingRuntimeError
+external_test/13: MissingRuntimeError
+external_test/20: MissingRuntimeError
+field_initialization_order_test/01: MissingCompileTimeError
+field_initialization_order_test/none: RuntimeError
+flatten_test/05: MissingRuntimeError
+flatten_test/08: MissingRuntimeError
+flatten_test/09: MissingRuntimeError
+flatten_test/12: MissingRuntimeError
+function_propagation_test: RuntimeError
+function_subtype_inline2_test: RuntimeError
+generic_function_bounds_test: RuntimeError
+generic_function_dcall_test: RuntimeError
+generic_instanceof2_test: RuntimeError
+generic_is_check_test: RuntimeError
+generic_no_such_method_dispatcher_simple_test: CompileTimeError
+generic_no_such_method_dispatcher_test: CompileTimeError
+generic_tearoff_test: CompileTimeError
+generic_test/01: MissingCompileTimeError
+instantiate_tearoff_of_call_test: CompileTimeError
+issue31596_super_test/01: CompileTimeError
+issue31596_super_test/03: CompileTimeError
+issue31596_super_test/05: RuntimeError
+least_upper_bound_expansive_test/none: CompileTimeError
+library_env_test/has_html_support: RuntimeError
+library_env_test/has_no_io_support: RuntimeError
+library_env_test/has_no_mirror_support: RuntimeError
+local_function2_test/none: RuntimeError
+local_function3_test/none: RuntimeError
+local_function_test/none: RuntimeError
+main_test/03: RuntimeError
+method_override_test: CompileTimeError
+mixin_illegal_super_use_test/01: MissingCompileTimeError
+mixin_illegal_super_use_test/04: MissingCompileTimeError
+mixin_illegal_super_use_test/07: MissingCompileTimeError
+mixin_illegal_super_use_test/10: MissingCompileTimeError
+mixin_illegal_super_use_test/11: MissingCompileTimeError
+mixin_illegal_superclass_test/01: MissingCompileTimeError
+mixin_illegal_superclass_test/02: MissingCompileTimeError
+mixin_illegal_superclass_test/03: MissingCompileTimeError
+mixin_illegal_superclass_test/04: MissingCompileTimeError
+mixin_illegal_superclass_test/05: MissingCompileTimeError
+mixin_illegal_superclass_test/06: MissingCompileTimeError
+mixin_illegal_superclass_test/07: MissingCompileTimeError
+mixin_illegal_superclass_test/08: MissingCompileTimeError
+mixin_illegal_superclass_test/09: MissingCompileTimeError
+mixin_illegal_superclass_test/10: MissingCompileTimeError
+mixin_illegal_superclass_test/11: MissingCompileTimeError
+mixin_illegal_superclass_test/12: MissingCompileTimeError
+mixin_illegal_superclass_test/13: MissingCompileTimeError
+mixin_illegal_superclass_test/14: MissingCompileTimeError
+mixin_illegal_superclass_test/15: MissingCompileTimeError
+mixin_illegal_superclass_test/16: MissingCompileTimeError
+mixin_illegal_superclass_test/17: MissingCompileTimeError
+mixin_illegal_superclass_test/18: MissingCompileTimeError
+mixin_illegal_superclass_test/19: MissingCompileTimeError
+mixin_illegal_superclass_test/20: MissingCompileTimeError
+mixin_illegal_superclass_test/21: MissingCompileTimeError
+mixin_illegal_superclass_test/22: MissingCompileTimeError
+mixin_illegal_superclass_test/23: MissingCompileTimeError
+mixin_illegal_superclass_test/24: MissingCompileTimeError
+mixin_illegal_superclass_test/25: MissingCompileTimeError
+mixin_illegal_superclass_test/26: MissingCompileTimeError
+mixin_illegal_superclass_test/27: MissingCompileTimeError
+mixin_illegal_superclass_test/28: MissingCompileTimeError
+mixin_illegal_superclass_test/29: MissingCompileTimeError
+mixin_illegal_superclass_test/30: MissingCompileTimeError
+mock_writable_final_private_field_test: RuntimeError
+named_parameters_default_eq_test/none: RuntimeError
+nested_generic_closure_test: RuntimeError
+no_main_test/01: Crash
+no_such_method_mock_test: RuntimeError
+null_no_such_method_test: CompileTimeError
+override_inheritance_field_test/04: CompileTimeError
+override_inheritance_field_test/06: CompileTimeError
+override_inheritance_field_test/26: CompileTimeError
+override_inheritance_field_test/29: CompileTimeError
+override_inheritance_generic_test/02: CompileTimeError
+override_inheritance_method_test/28: CompileTimeError
+override_inheritance_method_test/29: CompileTimeError
+parser_quirks_test: CompileTimeError
+regress_22443_test: RuntimeError
+regress_23089_test: DartkCrash
+regress_23408_test: CompileTimeError
+regress_29025_test: CompileTimeError
+regress_29405_test: CompileTimeError
+regress_30339_test: CompileTimeError
+string_interpolate_test: CompileTimeError
+string_interpolation_and_buffer_test: RuntimeError
+string_split_test: CompileTimeError
+string_supertype_checked_test: CompileTimeError
+super_bound_closure_test/none: CompileTimeError
+super_no_such_method1_test: CompileTimeError
+super_no_such_method2_test: CompileTimeError
+super_no_such_method3_test: CompileTimeError
+super_no_such_method4_test: CompileTimeError
+super_no_such_method5_test: CompileTimeError
+super_operator_index5_test: CompileTimeError
+super_operator_index6_test: CompileTimeError
+super_operator_index7_test: CompileTimeError
+super_operator_index8_test: CompileTimeError
+super_test: RuntimeError
+type_alias_equality_test/02: RuntimeError
+type_alias_equality_test/03: RuntimeError
+type_alias_equality_test/04: RuntimeError
+type_error_test: RuntimeError
+type_literal_test: RuntimeError
+type_promotion_functions_test/02: CompileTimeError
+type_promotion_functions_test/03: CompileTimeError
+type_promotion_functions_test/04: CompileTimeError
+type_promotion_functions_test/09: CompileTimeError
+type_promotion_functions_test/11: CompileTimeError
+type_promotion_functions_test/12: CompileTimeError
+type_promotion_functions_test/13: CompileTimeError
+type_promotion_functions_test/14: CompileTimeError
+type_promotion_functions_test/none: CompileTimeError
+type_promotion_more_specific_test/04: CompileTimeError
+vm/optimized_guarded_field_isolates_test: RuntimeError
+vm/type_cast_vm_test: RuntimeError
+
 [ $compiler == dartkp ]
 class_cycle_test/02: MissingCompileTimeError
 class_cycle_test/03: MissingCompileTimeError
@@ -437,7 +606,15 @@
 [ $arch != simarm && $arch != simarm64 && $arch != simdbc64 && $compiler == dartk && $runtime == vm && $strong ]
 export_ambiguous_main_test: Crash # Issue 32618
 
-[ $compiler != dart2js && $compiler != dartk && $compiler != dartkp && $fasta ]
+[ $compiler == app_jitk && $mode == product ]
+type_variable_promotion_test: RuntimeError
+vm/causal_async_exception_stack2_test: RuntimeError
+vm/causal_async_exception_stack_test: RuntimeError
+
+[ $compiler == app_jitk && ($mode == debug || $mode == release) ]
+assertion_test: RuntimeError
+
+[ $compiler != app_jitk && $compiler != dart2js && $compiler != dartk && $compiler != dartkp && $fasta ]
 const_optional_args_test/01: MissingCompileTimeError
 
 # The precomilation configuration uses a kernel2kernel constants evaluator
@@ -454,10 +631,6 @@
 mixin_supertype_subclass_test/02: MissingCompileTimeError
 mixin_supertype_subclass_test/05: MissingCompileTimeError
 
-[ $compiler == dartk && $mode == debug && $runtime == vm && $strong ]
-const_instance_field_test/01: Crash # Issue 32326.
-deopt_inlined_function_lazy_test: Skip
-
 [ $compiler == dartk && $mode == product && $runtime == vm ]
 deferred_load_constants_test/02: Fail
 deferred_load_constants_test/03: Fail
@@ -1305,6 +1478,10 @@
 setter_override2_test/02: MissingCompileTimeError
 variable_shadow_class_test/01: MissingCompileTimeError
 
+[ $mode == debug && $runtime == vm && $strong && ($compiler == app_jitk || $compiler == dartk) ]
+const_instance_field_test/01: Crash # Issue 32326.
+deopt_inlined_function_lazy_test: Skip
+
 [ $fasta && $strong ]
 compile_time_constant_static2_test/04: MissingCompileTimeError
 compile_time_constant_static3_test/04: MissingCompileTimeError
diff --git a/tests/language_2/partial_tearoff_instantiation_test.dart b/tests/language_2/partial_tearoff_instantiation_test.dart
index 72bd744..b534a96 100644
--- a/tests/language_2/partial_tearoff_instantiation_test.dart
+++ b/tests/language_2/partial_tearoff_instantiation_test.dart
@@ -112,5 +112,10 @@
 
     // Not OK with a type argument.
     y.f<String>("hello6"); //# 08: compile-time error
+
+    // Correct runtime type of x.f.
+    void instantiatedFType(dynamic _) {}
+    Expect.equals(x.f.runtimeType.toString(),
+        instantiatedFType.runtimeType.toString()); // #09: ok
   }
 }
diff --git a/tests/language_2/vm/regress_b80154489_test.dart b/tests/language_2/vm/regress_b80154489_test.dart
new file mode 100644
index 0000000..a93b384
--- /dev/null
+++ b/tests/language_2/vm/regress_b80154489_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2018, 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.
+
+// Check that class finalizer correctly marks supertypes of superinterfaces
+// as implemented.
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  String method();
+}
+
+abstract class B extends A {}
+
+class D extends A {
+  String method() => "D";
+}
+
+class C implements B {
+  String method() => "C";
+}
+
+String invoke(A a) {
+  return a.method();
+}
+
+void main(List<String> args) {
+  Expect.equals("C", invoke(args.contains('--use-d') ? new D() : new C()));
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index a376ae2..d316685 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -374,7 +374,7 @@
 
 # All these tests have been migrated as strong mode compatible tests to
 # lib_2, so skipping these tests for dartk and dartkp
-[ $compiler == dartk || $compiler == dartkp ]
+[ $compiler == app_jitk || $compiler == dartk || $compiler == dartkp ]
 *: SkipByDesign
 
 [ $runtime == chrome || $runtime == ff ]
diff --git a/tests/lib_2/convert/json_test.dart b/tests/lib_2/convert/json_test.dart
index d7be8a0..22e5f24 100644
--- a/tests/lib_2/convert/json_test.dart
+++ b/tests/lib_2/convert/json_test.dart
@@ -104,10 +104,16 @@
 }
 
 void testThrows(jsonText) {
+  var message = "json = '${escape(jsonText)}'";
   Expect.throwsFormatException(() => json.decode(jsonText),
-      "json = '${escape(jsonText)}'");
+      "json.decode, $message");
   Expect.throwsFormatException(() => jsonDecode(jsonText),
-      "json = '${escape(jsonText)}'");
+      "jsonDecode, $message");
+  Expect.throwsFormatException(() => json.decoder.convert(jsonText),
+      "json.decoder.convert, $message");
+  Expect.throwsFormatException(() =>
+      utf8.decoder.fuse(json.decoder).convert(utf8.encode(jsonText)),
+      "utf8.decoder.fuse(json.decoder) o utf.encode, $message");
 }
 
 testNumbers() {
@@ -187,6 +193,10 @@
   testThrows("-2.2 e+2");
   testThrows("-2.2e +2");
   testThrows("-2.2e+ 2");
+  testThrows("01");
+  testThrows("0.");
+  testThrows(".0");
+  testThrows("0.e1");
 
   testThrows("[2.,2]");
   testThrows("{2.:2}");
diff --git a/tests/lib_2/convert/json_utf8_test.dart b/tests/lib_2/convert/json_utf8_test.dart
new file mode 100644
index 0000000..6afae4d
--- /dev/null
+++ b/tests/lib_2/convert/json_utf8_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that the fused UTF-8/JSON decoder accepts a leading BOM.
+library test;
+
+import "package:expect/expect.dart";
+import "dart:convert";
+
+void main() {
+  for (var parse in [parseFuse, parseSequence, parseChunked]) {
+    // Sanity checks.
+    Expect.isTrue(parse('true'.codeUnits.toList()));
+    Expect.isFalse(parse('false'.codeUnits.toList()));
+    Expect.equals(123, parse('123'.codeUnits.toList()));
+    Expect.listEquals([42], parse('[42]'.codeUnits.toList()));
+    Expect.mapEquals({"x": 42}, parse('{"x":42}'.codeUnits.toList()));
+
+    // String (0x22 = ") with UTF-8 encoded Unicode characters.
+    Expect.equals(
+        "A\xff\u1234\u{65555}",
+        parse([
+          0x22,
+          0x41,
+          0xc3,
+          0xbf,
+          0xe1,
+          0x88,
+          0xb4,
+          0xf1,
+          0xa5,
+          0x95,
+          0x95,
+          0x22
+        ]));
+
+    // BOM followed by true.
+    Expect.isTrue(parse([0xEF, 0xBB, 0xBF, 0x74, 0x72, 0x75, 0x65]));
+  }
+
+  // Do not accept BOM in non-UTF-8 decoder.
+  Expect.throws<FormatException>(
+      () => new JsonDecoder().convert("\xEF\xBB\xBFtrue"));
+  Expect.throws<FormatException>(() => new JsonDecoder().convert("\uFEFFtrue"));
+
+  // Only accept BOM first.
+  Expect.throws<FormatException>(
+      () => parseFuse(" \xEF\xBB\xBFtrue".codeUnits.toList()));
+  // Only accept BOM first.
+  Expect.throws<FormatException>(
+      () => parseFuse(" true\xEF\xBB\xBF".codeUnits.toList()));
+
+  Expect.throws<FormatException>(
+      () => parseFuse(" [\xEF\xBB\xBF]".codeUnits.toList()));
+}
+
+Object parseFuse(List<int> text) {
+  return new Utf8Decoder().fuse(new JsonDecoder()).convert(text);
+}
+
+Object parseSequence(List<int> text) {
+  return new JsonDecoder().convert(new Utf8Decoder().convert(text));
+}
+
+Object parseChunked(List<int> text) {
+  var result;
+  var sink = new Utf8Decoder().fuse(new JsonDecoder()).startChunkedConversion(
+      new ChunkedConversionSink.withCallback((List<Object> values) {
+    result = values[0];
+  }));
+  for (var i = 0; i < text.length; i++) {
+    sink.add([text[i]]);
+  }
+  sink.close();
+  return result;
+}
diff --git a/tests/lib_2/html/interactive_media_test.dart b/tests/lib_2/html/interactive_media_test.dart
index d7060ac..4fbc597 100644
--- a/tests/lib_2/html/interactive_media_test.dart
+++ b/tests/lib_2/html/interactive_media_test.dart
@@ -32,72 +32,68 @@
         }
       } catch (e) {
         // Could fail if bot machine doesn't support audio or video.
-        expect(e.name, DomException.NOT_FOUND);
+        expect(e.name == DomException.NOT_FOUND, true);
       }
     });
 
     test('getUserMedia', () {
-      try {
-        return window.navigator.getUserMedia(video: true).then((stream) {
-          expect(stream, isNotNull);
+      return window.navigator.getUserMedia(video: true).then((stream) {
+        expect(stream, isNotNull);
 
-          var url = Url.createObjectUrlFromStream(stream);
-          expect(url, isNotNull);
+        var url = Url.createObjectUrlFromStream(stream);
+        expect(url, isNotNull);
 
-          var video = new VideoElement()..autoplay = true;
+        var video = new VideoElement()..autoplay = true;
 
-          var completer = new Completer();
-          video.onError.listen((e) {
-            completer.completeError(e);
-          });
-          video.onPlaying.first.then((e) {
-            completer.complete(video);
-          });
-
-          document.body.append(video);
-          video.src = url;
-
-          return completer.future;
+        var completer = new Completer();
+        video.onError.listen((e) {
+          completer.completeError(e);
         });
-      } catch (e) {
+        video.onPlaying.first.then((e) {
+          completer.complete(video);
+        });
+
+        document.body.append(video);
+        video.src = url;
+
+        return completer.future;
+      }).catchError((e) {
         // Could fail if bot machine doesn't support audio or video.
-        expect(e.name, DomException.NOT_FOUND);
-      }
+        expect(e.name == DomException.NOT_FOUND, true);
+      });
     });
 
     test('getUserMediaComplexConstructor', () {
-      try {
-        return window.navigator.getUserMedia(video: {
-          'mandatory': {'minAspectRatio': 1.333, 'maxAspectRatio': 1.334},
-          'optional': [
-            {'minFrameRate': 60},
-            {'maxWidth': 640}
-          ]
-        }).then((stream) {
-          expect(stream, isNotNull);
+      return window.navigator.getUserMedia(video: {
+        'mandatory': {'minAspectRatio': 1.333, 'maxAspectRatio': 1.334},
+        'optional': [
+          {'minFrameRate': 60},
+          {'maxWidth': 640}
+        ]
+      }).then((stream) {
+        expect(stream, isNotNull);
 
-          var url = Url.createObjectUrlFromStream(stream);
-          expect(url, isNotNull);
+        var url = Url.createObjectUrlFromStream(stream);
+        expect(url, isNotNull);
 
-          var video = new VideoElement()..autoplay = true;
+        var video = new VideoElement()..autoplay = true;
 
-          var completer = new Completer();
-          video.onError.listen((e) {
-            completer.completeError(e);
-          });
-          video.onPlaying.first.then((e) {
-            completer.complete(video);
-          });
-
-          document.body.append(video);
-          video.src = url;
-
-          return completer.future;
+        var completer = new Completer();
+        video.onError.listen((e) {
+          completer.completeError(e);
         });
-      } catch (e) {
+        video.onPlaying.first.then((e) {
+          completer.complete(video);
+        });
+
+        document.body.append(video);
+        video.src = url;
+
+        return completer.future;
+      }).catchError((e) {
         // Could fail if bot machine doesn't support audio or video.
-        expect(e.name, DomException.NOT_FOUND);
-      }
+        expect(e.name == DomException.NOT_FOUND, true);
+      });
     });
   }
 }
diff --git a/tests/lib_2/lib_2_app_jit.status b/tests/lib_2/lib_2_app_jit.status
index a2a86f3..d219200 100644
--- a/tests/lib_2/lib_2_app_jit.status
+++ b/tests/lib_2/lib_2_app_jit.status
@@ -2,5 +2,5 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $compiler == app_jit ]
+[ $compiler == app_jit || $compiler == app_jitk ]
 mirrors/*: Skip # Issue 27929: Triage
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 72d9070..785d1a3 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -371,6 +371,7 @@
 html/input_element_datetime_test: Fail
 html/input_element_month_test: Fail
 html/input_element_week_test: Fail
+html/interactive_media_test: RuntimeError # Not supported in FF
 html/media_stream_test: Fail
 html/messageevent_test: Pass, RuntimeError # Issue 28983
 html/request_animation_frame_test: Skip # Async test hangs.
@@ -468,9 +469,6 @@
 [ $compiler == dart2js && $system == linux ]
 html/interactive_geolocation_test: Skip # Requires allowing geo location.
 
-[ $compiler == dart2js && $system != macos && ($runtime != chrome || $runtime != safari) ]
-html/interactive_media_test: RuntimeError # # See NOTE in test on how to run.
-
 [ $compiler == dart2js && $system == windows ]
 html/xhr_test: RuntimeError
 
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index e2910bb..d1abdeb 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -26,7 +26,6 @@
 
 [ $system == linux && ($compiler == dartdevc || $compiler == dartdevk) ]
 html/interactive_geolocation_test: Skip # Requires allowing geo location.
-html/interactive_media_test: RuntimeError # # See NOTE in test on how to run.
 
 [ $system == macos && ($compiler == dartdevc || $compiler == dartdevk) ]
 html/client_rect_test: Pass, RuntimeError # Issue 31019
@@ -85,7 +84,6 @@
 html/element_classes_svg_test: RuntimeError # Issue 29922
 html/element_classes_test: RuntimeError # Issue 29922
 html/fontface_loaded_test: RuntimeError
-html/interactive_media_test: RuntimeError # See NOTE in test on how to run and interactive permissions (camera, geolocation)
 html/isolates_test: RuntimeError # Issue 29922
 html/js_typed_interop_default_arg_test/default_value: MissingCompileTimeError # Issue 29922
 html/js_typed_interop_side_cast_exp_test/01: RuntimeError # Requires --experimental-trust-js-interop-type-annotations flag.
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index 14b7bf9..da72614 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -10,6 +10,24 @@
 # missing a section you need, please reach out to sigmund@ to see the best way
 # to add them.
 
+[ $compiler == app_jitk ]
+async/async_await_sync_completer_test: RuntimeError
+async/future_test/01: RuntimeError
+async/future_test/none: RuntimeError
+async/slow_consumer2_test: RuntimeError
+async/stream_controller_async_test: RuntimeError
+async/stream_distinct_test: RuntimeError
+async/stream_join_test: RuntimeError
+async/stream_subscription_as_future_test: RuntimeError
+async/timer_not_available_test: RuntimeError
+isolate/issue_21398_parent_isolate1_test: RuntimeError
+isolate/issue_22778_test: Crash
+isolate/kill_self_synchronously_test: RuntimeError
+isolate/message_test: RuntimeError
+isolate/mint_maker_test: RuntimeError
+isolate/ping_pause_test: Skip # Timeout
+isolate/static_function_test: RuntimeError
+
 [ $compiler == fasta ]
 html/*: Skip # TODO(ahe): Make dart:html available.
 isolate/browser/*: Skip # TODO(ahe): Make dart:html available.
@@ -45,6 +63,10 @@
 mirrors/invocation_fuzz_test/smi: Crash, RuntimeError, Fail, Pass # Crashes on opt counter builder (#31838)
 mirrors/invocation_fuzz_test/string: Pass, Crash, RuntimeError # Flaky on vm-kernel-optcounter-threshold-linux-release-x64, bug #31838
 
+[ $compiler == app_jitk && $mode == product ]
+isolate/spawn_function_custom_class_test: Skip # Timeout
+isolate/spawn_uri_nested_vm_test: Skip # Timeout
+
 [ $compiler != dart2js && $fasta && !$strong ]
 isolate/browser/compute_this_script_browser_test: CompileTimeError
 isolate/browser/package_resolve_browser_hook2_test: CompileTimeError
@@ -111,12 +133,9 @@
 mirrors/generic_f_bounded_mixin_application_test: RuntimeError
 mirrors/generic_function_typedef_test: RuntimeError
 mirrors/generic_interface_test/01: RuntimeError
-mirrors/generic_interface_test/none: RuntimeError
 mirrors/generic_mixin_applications_test: RuntimeError
-mirrors/generic_mixin_test: RuntimeError
 mirrors/hot_get_field_test: RuntimeError
 mirrors/hot_set_field_test: RuntimeError
-mirrors/intercepted_object_test: RuntimeError # Issue 31402 (Invocation arguments)
 mirrors/invocation_fuzz_test: RuntimeError, Crash
 mirrors/invoke_private_test: RuntimeError
 mirrors/invoke_private_wrong_library_test: RuntimeError
@@ -149,8 +168,6 @@
 mirrors/mirrors_used_typedef_declaration_test/none: RuntimeError
 mirrors/mixin_application_test: RuntimeError # Issue 31402 (Invocation arguments)
 mirrors/mixin_members_test: CompileTimeError # Issue 31402 (Invocation arguments)
-mirrors/mixin_simple_test: RuntimeError
-mirrors/mixin_test: RuntimeError
 mirrors/native_class_test: SkipByDesign # Imports dart:html
 mirrors/operator_test: CompileTimeError # Issue 31402 (Invocation arguments)
 mirrors/other_declarations_location_test: RuntimeError
@@ -322,7 +339,7 @@
 typed_data/int32x4_static_test/01: MissingCompileTimeError
 typed_data/int32x4_static_test/02: MissingCompileTimeError
 
-[ $compiler == dartk || $compiler == dartkp ]
+[ $compiler == app_jitk || $compiler == dartk || $compiler == dartkp ]
 html/*: SkipByDesign
 isolate/browser/*: SkipByDesign
 js/*: SkipByDesign
diff --git a/tests/lib_2/lib_2_vm.status b/tests/lib_2/lib_2_vm.status
index cd5c32c..16463be 100644
--- a/tests/lib_2/lib_2_vm.status
+++ b/tests/lib_2/lib_2_vm.status
@@ -14,7 +14,7 @@
 [ $arch == simarm64 && $runtime == vm ]
 convert/utf85_test: Skip # Pass, Slow Issue 20111.
 
-[ $compiler != dartk && $runtime == vm ]
+[ $compiler != app_jitk && $compiler != dartk && $runtime == vm ]
 convert/streamed_conversion_json_utf8_decode_test: Pass, Slow # Infrequent timeouts.
 html/*: SkipByDesign # dart:html not supported on VM.
 js/datetime_roundtrip_test: CompileTimeError
@@ -32,10 +32,10 @@
 mirrors/native_class_test: SkipByDesign # Imports dart:html
 mirrors/redirecting_factory_different_type_test/01: MissingCompileTimeError
 
-[ $compiler != dartk && $runtime == vm && !$checked ]
+[ $compiler != app_jitk && $compiler != dartk && $runtime == vm && !$checked ]
 mirrors/inference_and_no_such_method_test: RuntimeError
 
-[ $compiler != dartk && $runtime == vm && $strong ]
+[ $compiler != app_jitk && $compiler != dartk && $runtime == vm && $strong ]
 async/future_or_only_in_async_test/00: MissingCompileTimeError
 
 [ $compiler != dartk && $runtime == vm && !$strong ]
diff --git a/tests/standalone/io/file_invalid_arguments_test.dart b/tests/standalone/io/file_invalid_arguments_test.dart
deleted file mode 100644
index 94e3a22..0000000
--- a/tests/standalone/io/file_invalid_arguments_test.dart
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// OtherResources=fixed_length_file_invalid_arguments
-
-import "dart:async";
-import "dart:io";
-
-import "package:async_helper/async_helper.dart";
-import "package:expect/expect.dart";
-
-void testReadInvalidArgs(arg) {
-  String filename = getFilename("fixed_length_file_invalid_arguments");
-  var file = (new File(filename)).openSync();
-  Expect.throws(() => file.readSync(arg), (e) => e is ArgumentError);
-
-  Expect.throws(() => file.read(arg), (e) => e is ArgumentError);
-  file.closeSync();
-}
-
-void testReadIntoInvalidArgs(buffer, start, end) {
-  String filename = getFilename("fixed_length_file_invalid_arguments");
-  var file = (new File(filename)).openSync();
-  Expect.throws(
-      () => file.readIntoSync(buffer, start, end), (e) => e is ArgumentError);
-
-  Expect.throws(
-      () => file.readInto(buffer, start, end), (e) => e is ArgumentError);
-  file.closeSync();
-}
-
-void testWriteByteInvalidArgs(value) {
-  String filename = getFilename("fixed_length_file_invalid_arguments");
-  var file = (new File("${filename}_out")).openSync(mode: FileMode.write);
-  Expect.throws(() => file.writeByteSync(value), (e) => e is ArgumentError);
-
-  Expect.throws(() => file.writeByte(value), (e) => e is ArgumentError);
-  file.closeSync();
-}
-
-void testWriteFromInvalidArgs(buffer, start, end) {
-  String filename = getFilename("fixed_length_file_invalid_arguments");
-  var file = (new File("${filename}_out")).openSync(mode: FileMode.write);
-  Expect.throws(
-      () => file.writeFromSync(buffer, start, end), (e) => e is ArgumentError);
-
-  Expect.throws(
-      () => file.writeFrom(buffer, start, end), (e) => e is ArgumentError);
-  file.closeSync();
-}
-
-void testWriteStringInvalidArgs(string, encoding) {
-  String filename = getFilename("fixed_length_file_invalid_arguments");
-  var file = new File("${filename}_out").openSync(mode: FileMode.write);
-  Expect.throws(() => file.writeStringSync(string, encoding: encoding),
-      (e) => e is ArgumentError);
-
-  Expect.throws(() => file.writeString(string, encoding: encoding),
-      (e) => e is ArgumentError);
-  file.closeSync();
-}
-
-Future futureThrows(Future result) {
-  return result.then((value) {
-    throw new ExpectException(
-        "futureThrows received $value instead of an exception");
-  }, onError: (_) => null);
-}
-
-void testFileSystemEntity() {
-  Expect.throws(() => ((x) => FileSystemEntity.typeSync(x))([1, 2, 3]));
-  Expect.throws(() => ((x, y) =>
-      FileSystemEntity.typeSync(x, followLinks: y))(".", "why not?"));
-  Expect.throws(
-      () => ((x, y) => FileSystemEntity.identicalSync(x, y))([1, 2, 3], "."));
-  Expect
-      .throws(() => ((x, y) => FileSystemEntity.identicalSync(x, y))(".", 52));
-  Expect.throws(() => ((x) => FileSystemEntity.isLinkSync(x))(52));
-  Expect.throws(() => ((x) => FileSystemEntity.isFileSync(x))(52));
-  Expect.throws(() => ((x) => FileSystemEntity.isDirectorySync(x))(52));
-
-  asyncStart();
-  futureThrows(((x) => FileSystemEntity.type(x))([1, 2, 3]))
-      .then((_) => futureThrows(((x, y) =>
-          FileSystemEntity.type(x, followLinks: y))(".", "why not?")))
-      .then((_) => futureThrows(
-          ((x, y) => FileSystemEntity.identical(x, y))([1, 2, 3], ".")))
-      .then((_) =>
-          futureThrows(((x, y) => FileSystemEntity.identical(x, y))(".", 52)))
-      .then((_) => futureThrows(((x) => FileSystemEntity.isLink(x))(52)))
-      .then((_) => futureThrows(((x) => FileSystemEntity.isFile(x))(52)))
-      .then((_) => futureThrows(((x) => FileSystemEntity.isDirectory(x))(52)))
-      .then((_) => asyncEnd());
-}
-
-String getFilename(String path) {
-  return Platform.script.resolve(path).toFilePath();
-}
-
-main() {
-  testReadInvalidArgs('asdf');
-  testReadIntoInvalidArgs(12, 0, 1);
-  testReadIntoInvalidArgs(new List(10), '0', 1);
-  testReadIntoInvalidArgs(new List(10), 0, '1');
-  testWriteByteInvalidArgs('asdf');
-  testWriteFromInvalidArgs(12, 0, 1);
-  testWriteFromInvalidArgs(new List(10), '0', 1);
-  testWriteFromInvalidArgs(new List(10), 0, '1');
-  testWriteStringInvalidArgs("Hello, world", 42);
-  testFileSystemEntity();
-}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 22bb3c2..beb2ac3 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -26,9 +26,6 @@
 [ $builder_tag == swarming && $system == macos ]
 io/*: Skip # Issue 30618
 
-[ $compiler == dartk && $strong ]
-*: SkipByDesign
-
 [ $compiler == fasta && $strong ]
 io/directory_invalid_arguments_test: CompileTimeError
 io/io_override_test: CompileTimeError
@@ -63,25 +60,21 @@
 io/directory_fuzz_test: Skip # These test have type errors on purpose and take very long to run in checked mode with no benefit. Skip.
 io/directory_invalid_arguments_test: Fail, OK # These tests have type errors on purpose.
 io/file_fuzz_test: Skip # These test have type errors on purpose and take very long to run in checked mode with no benefit. Skip.
-io/file_invalid_arguments_test: Fail, OK # These tests have type errors on purpose.
 io/internet_address_invalid_arguments_test: Fail, OK # These tests have type errors on purpose.
 io/process_invalid_arguments_test: Fail, OK # These tests have type errors on purpose.
 io/socket_invalid_arguments_test: Fail, OK # These tests have type errors on purpose.
 io/stdout_bad_argument_test: Fail, OK # These tests have type errors on purpose.
 
-[ !$strong && ($compiler == dartk || $compiler == dartkp) ]
-*: Skip
-
 [ $compiler == app_jit || $compiler == precompiler ]
 io/compile_all_test: Skip # Incompatible flag --compile_all
 
-[ $compiler == dart2js || $compiler == dartdevc ]
-*: SkipByDesign
-
 # We skip all the Dart 1.0 tests in dartk and dartkp mode as these
 # modes are intended only for Dart 2.0 with strong mode enabled.
-[ $compiler == dartk || $compiler == dartkp ]
-*: Skip
+[ $compiler == app_jitk || $compiler == dartk || $compiler == dartkp ]
+*: SkipByDesign
+
+[ $compiler == dart2js || $compiler == dartdevc ]
+*: SkipByDesign
 
 [ $compiler != none || $runtime != vm ]
 script_snapshot_depfile_test: SkipByDesign # Only makes sense running from source.
diff --git a/tests/standalone_2/io/non_utf8_directory_test.dart b/tests/standalone_2/io/non_utf8_directory_test.dart
new file mode 100644
index 0000000..1ebe6b9
--- /dev/null
+++ b/tests/standalone_2/io/non_utf8_directory_test.dart
@@ -0,0 +1,88 @@
+// Copyright (c) 2018, 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:io';
+import 'dart:typed_data';
+
+import 'package:test/test.dart';
+
+Future main() async {
+  var asyncDir;
+  var syncDir;
+
+  test('Non-UTF8 Directory Listing', () async {
+    Directory.current = await Directory.systemTemp.createTemp();
+    final rawPath = new Uint8List.fromList([182]);
+    asyncDir = new Directory.fromRawPath(rawPath);
+    if (Platform.isMacOS || Platform.isIOS) {
+      try {
+        await asyncDir.create();
+      } on FileSystemException catch (e) {
+        // Macos doesn't support non-UTF-8 paths.
+        return;
+      }
+    } else {
+      await asyncDir.create();
+    }
+    expect(await asyncDir.exists(), isTrue);
+
+    await for (final e in Directory.current.list()) {
+      // FIXME(bkonyi): reenable when rawPath is exposed.
+      /*
+      if (Platform.isWindows) {
+        // Windows replaces invalid characters with � when creating file system
+        // entities.
+        final raw = e.rawPath;
+        expect(raw.sublist(raw.length - 3), [239, 191, 189]);
+      } else {
+        expect(e.rawPath.last, 182);
+      }
+      */
+    }
+    await asyncDir.delete(recursive: true);
+  });
+
+  test('Non-UTF8 Directory Sync Listing', () {
+    Directory.current = Directory.systemTemp.createTempSync();
+    final rawPath = new Uint8List.fromList([182]);
+    syncDir = new Directory.fromRawPath(rawPath);
+
+    if (Platform.isMacOS || Platform.isIOS) {
+      try {
+        syncDir.createSync();
+      } on FileSystemException catch (e) {
+        // Macos doesn't support non-UTF-8 paths.
+        return;
+      }
+    } else {
+      syncDir.createSync();
+    }
+    expect(syncDir.existsSync(), isTrue);
+
+    for (final e in Directory.current.listSync()) {
+      // FIXME(bkonyi): reenable when rawPath is exposed.
+      /*
+      if (Platform.isWindows) {
+        // Windows replaces invalid characters with � when creating file system
+        // entities.
+        final raw = e.rawPath;
+        expect(raw.sublist(raw.length - 3), [239, 191, 189]);
+      } else {
+        expect(e.rawPath.last, 182);
+      }
+      */
+    }
+    syncDir.deleteSync(recursive: true);
+  });
+
+  tearDown(() {
+    if ((asyncDir != null) && asyncDir.existsSync()) {
+      asyncDir.deleteSync(recursive: true);
+    }
+    if ((syncDir != null) && syncDir.existsSync()) {
+      syncDir.deleteSync(recursive: true);
+    }
+  });
+}
diff --git a/tests/standalone_2/io/non_utf8_file_test.dart b/tests/standalone_2/io/non_utf8_file_test.dart
new file mode 100644
index 0000000..df35c06
--- /dev/null
+++ b/tests/standalone_2/io/non_utf8_file_test.dart
@@ -0,0 +1,96 @@
+// Copyright (c) 2018, 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:io';
+import 'dart:typed_data';
+
+import 'package:test/test.dart';
+
+Future main() async {
+  var asyncFile;
+  var syncFile;
+
+  test('Non-UTF8 Filename', () async {
+    Directory.current = await Directory.systemTemp.createTemp();
+    final rawPath = new Uint8List.fromList([182]);
+    asyncFile = new File.fromRawPath(rawPath);
+    if (Platform.isMacOS || Platform.isIOS) {
+      try {
+        await asyncFile.create();
+      } on FileSystemException catch (e) {
+        // Macos doesn't support non-UTF-8 paths.
+        return;
+      }
+    } else {
+      await asyncFile.create();
+    }
+    expect(await asyncFile.exists(), isTrue);
+
+    for (final file in Directory.current.listSync()) {
+      // FIXME(bkonyi): reenable when rawPath is exposed.
+      /*
+      if (Platform.isWindows) {
+        // Windows replaces invalid characters with � when creating file system
+        // entities.
+        final raw = file.rawPath;
+        expect(raw.sublist(raw.length - 3), [239, 191, 189]);
+      } else {
+        expect(file.rawPath.last, 182);
+      }
+      */
+      // FIXME(bkonyi): this isn't true on some versions of MacOS. Why?
+      if (!Platform.isMacOS && !Platform.isIOS) {
+        expect(file.path.endsWith('�'), isTrue);
+      }
+    }
+    await asyncFile.delete();
+  });
+
+  test('Non-UTF8 Filename Sync', () {
+    Directory.current = Directory.systemTemp.createTempSync();
+    final rawPath = new Uint8List.fromList([182]);
+    syncFile = new File.fromRawPath(rawPath);
+
+    if (Platform.isMacOS || Platform.isIOS) {
+      try {
+        syncFile.createSync();
+      } on FileSystemException catch (e) {
+        // Macos doesn't support non-UTF-8 paths.
+        return;
+      }
+    } else {
+      syncFile.createSync();
+    }
+    expect(syncFile.existsSync(), isTrue);
+
+    for (final file in Directory.current.listSync()) {
+      // FIXME(bkonyi): reenable when rawPath is exposed.
+      /*
+      if (Platform.isWindows) {
+        // Windows replaces invalid characters with � when creating file system
+        // entities.
+        final raw = file.rawPath;
+        expect(raw.sublist(raw.length - 3), [239, 191, 189]);
+      } else {
+        expect(file.rawPath.last, 182);
+      }
+      */
+      // FIXME(bkonyi): this isn't true on some versions of MacOS. Why?
+      if (!Platform.isMacOS && !Platform.isIOS) {
+        expect(file.path.endsWith('�'), isTrue);
+      }
+    }
+    syncFile.deleteSync();
+  });
+
+  tearDown(() {
+    if ((asyncFile != null) && asyncFile.existsSync()) {
+      asyncFile.deleteSync();
+    }
+    if ((syncFile != null) && syncFile.existsSync()) {
+      syncFile.deleteSync();
+    }
+  });
+}
diff --git a/tests/standalone_2/io/non_utf8_link_test.dart b/tests/standalone_2/io/non_utf8_link_test.dart
new file mode 100644
index 0000000..4527412
--- /dev/null
+++ b/tests/standalone_2/io/non_utf8_link_test.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2018, 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 'dart:io';
+import 'dart:typed_data';
+
+import 'package:path/path.dart';
+import 'package:test/test.dart';
+
+Future main() async {
+  var asyncLink;
+  var syncLink;
+  const dirName = 'foobar';
+
+  test('Non-UTF8 Link', () async {
+    Directory tmp = await Directory.systemTemp.createTemp();
+    Directory.current = await tmp.resolveSymbolicLinks();
+    final path = join(Directory.current.path, dirName);
+    final rawPath =
+        utf8.encode(path).sublist(0, path.length - dirName.length).toList();
+    rawPath.add(47);
+    rawPath.add(182);
+
+    final f = new Directory(path);
+    await f.create();
+    expect(await f.exists(), isTrue);
+
+    final rawName = new Uint8List.fromList(rawPath);
+    asyncLink = new Link.fromRawPath(rawName);
+
+    if (Platform.isMacOS || Platform.isIOS) {
+      try {
+        asyncLink = await asyncLink.create(path);
+      } on FileSystemException catch (e) {
+        // Macos doesn't support non-UTF-8 paths.
+        return;
+      }
+    } else {
+      asyncLink = await asyncLink.create(path);
+    }
+    expect(await asyncLink.exists(), isTrue);
+
+    await for (final e in Directory.current.list()) {
+      if (e is Link) {
+        // FIXME(bkonyi): reenable when rawPath is exposed.
+        /*
+        if (Platform.isWindows) {
+          // Windows replaces invalid characters with � when creating file system
+          // entities.
+          final raw = e.rawPath;
+          expect(raw.sublist(raw.length - 3), [239, 191, 189]);
+        } else {
+          expect(e.rawPath.last, 182);
+        }
+        */
+        expect(e.path, path);
+      }
+    }
+
+    // FIXME(bkonyi): reenable when rawPath is exposed.
+    // expect(asyncLink.absolute.rawPath, rawPath);
+    expect(await asyncLink.resolveSymbolicLinks(), path);
+    expect(await asyncLink.target(), path);
+    await asyncLink.delete();
+  });
+
+  test('Non-UTF8 Link Sync', () {
+    Directory tmp = Directory.systemTemp.createTempSync();
+    Directory.current = tmp.resolveSymbolicLinksSync();
+    final path = join(Directory.current.path, dirName);
+    final rawPath =
+        utf8.encode(path).sublist(0, path.length - dirName.length).toList();
+    rawPath.add(47); // '/'
+    rawPath.add(182); // invalid UTF-8 character.
+
+    final f = new Directory(path);
+    f.createSync();
+    expect(f.existsSync(), isTrue);
+
+    final rawName = new Uint8List.fromList(rawPath);
+    syncLink = new Link.fromRawPath(rawName);
+
+    if (Platform.isMacOS || Platform.isIOS) {
+      try {
+        syncLink.createSync(path);
+      } on FileSystemException catch (e) {
+        // Macos doesn't support non-UTF-8 paths.
+        return;
+      }
+    } else {
+      syncLink.createSync(path);
+    }
+    expect(syncLink.existsSync(), isTrue);
+
+    for (final e in Directory.current.listSync()) {
+      if (e is Link) {
+        // FIXME(bkonyi): reenable when rawPath is exposed.
+        /*
+        if (Platform.isWindows) {
+          // Windows replaces invalid characters with � when creating file system
+          // entities.
+          final raw = e.rawPath;
+          expect(raw.sublist(raw.length - 3), [239, 191, 189]);
+        } else {
+          expect(e.rawPath.last, 182);
+        }
+        */
+        expect(e.path, path);
+      }
+    }
+    // FIXME(bkonyi): reenable when rawPath is exposed.
+    // expect(syncLink.absolute.rawPath, rawPath);
+    expect(syncLink.resolveSymbolicLinksSync(), path);
+    expect(syncLink.targetSync(), path);
+    syncLink.deleteSync();
+  });
+
+  tearDown(() {
+    if ((asyncLink != null) && asyncLink.existsSync()) {
+      asyncLink.deleteSync();
+    }
+    if ((syncLink != null) && syncLink.existsSync()) {
+      syncLink.deleteSync();
+    }
+  });
+}
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index eb1b3b2..90a5707 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -69,7 +69,7 @@
 io/*: Skip # Issue 30618
 
 # All static_tests have expected compile-time errors.
-[ $compiler != dart2analyzer && $compiler != dartdevc && $compiler != dartk && $compiler != dartkp && $runtime != none && $strong ]
+[ $compiler != app_jitk && $compiler != dart2analyzer && $compiler != dartdevc && $compiler != dartk && $compiler != dartkp && $runtime != none && $strong ]
 float_array_static_test: MissingCompileTimeError
 
 [ $compiler == none && $runtime == vm && $system == fuchsia ]
diff --git a/tests/standalone_2/standalone_2_kernel.status b/tests/standalone_2/standalone_2_kernel.status
index dcf6699..66193af 100644
--- a/tests/standalone_2/standalone_2_kernel.status
+++ b/tests/standalone_2/standalone_2_kernel.status
@@ -10,6 +10,42 @@
 # missing a section you need, please reach out to sigmund@ to see the best way
 # to add them.
 
+[ $compiler == app_jitk ]
+io/dependency_graph_test: CompileTimeError
+io/directory_test: RuntimeError
+io/file_error_test: RuntimeError
+io/file_test: RuntimeError
+io/http_auth_digest_test: RuntimeError
+io/http_auth_test: RuntimeError
+io/http_compression_test: RuntimeError
+io/http_cookie_date_test: CompileTimeError
+io/http_headers_test: CompileTimeError
+io/http_parser_test: CompileTimeError
+io/http_redirect_test: RuntimeError
+io/http_reuse_server_port_test: RuntimeError
+io/http_server_response_test: RuntimeError
+io/namespace_test: RuntimeError
+io/platform_resolved_executable_test/00: RuntimeError
+io/platform_resolved_executable_test/01: RuntimeError
+io/platform_resolved_executable_test/02: RuntimeError
+io/platform_resolved_executable_test/03: RuntimeError
+io/platform_resolved_executable_test/04: RuntimeError
+io/platform_resolved_executable_test/05: RuntimeError
+io/platform_test: RuntimeError
+io/regress_10026_test: RuntimeError
+io/secure_socket_argument_test: CompileTimeError
+io/skipping_dart2js_compilations_test: CompileTimeError
+io/socket_upgrade_to_secure_test: RuntimeError
+io/test_extension_fail_test: RuntimeError
+io/test_extension_test: RuntimeError
+io/test_harness_analyzer_test: CompileTimeError
+io/test_runner_test: CompileTimeError
+io/web_socket_pipe_test: RuntimeError
+io/web_socket_protocol_processor_test: CompileTimeError
+io/zlib_test: RuntimeError
+oom_error_stacktrace_test: RuntimeError
+out_of_memory_test: RuntimeError
+
 [ $fasta ]
 deferred_transitive_import_error_test: CompileTimeError
 package/package1_test: CompileTimeError
@@ -24,6 +60,10 @@
 [ $builder_tag == optimization_counter_threshold && $compiler == dartk ]
 map_insert_remove_oom_test: Skip # Heap limit too low.
 
+[ $compiler == app_jitk && ($mode == debug || $mode == release) ]
+dart_developer_disabled_env_test: RuntimeError
+io/code_collection_test: RuntimeError
+
 [ $compiler == dartk && $mode == debug && $runtime == vm && $strong ]
 io/file_lock_test: Slow, Pass
 io/raw_socket_test: Crash
diff --git a/tools/VERSION b/tools/VERSION
index 18e0327..1d4965d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 0
 PATCH 0
-PRERELEASE 58
+PRERELEASE 59
 PRERELEASE_PATCH 0
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 0f5f4a7..ce55a8e 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -436,6 +436,29 @@
     },
     {
       "builders": [
+        "app-kernel-linux-debug-x64",
+        "app-kernel-linux-product-x64",
+        "app-kernel-linux-release-x64"
+      ],
+      "meta": {
+        "description": "This configuration is used by the vm kernel app builder group."
+      },
+      "steps": [
+        {
+          "name": "build dart",
+          "script": "tools/build.py",
+          "arguments": [
+            "runtime_kernel"
+          ]
+        },
+        {
+          "name": "vm tests",
+          "arguments": ["--compiler=app_jitk", "--strong"]
+        }
+      ]
+    },
+    {
+      "builders": [
         "ddc-linux-release-chrome",
         "ddc-win-release-chrome"
       ],
diff --git a/tools/build.py b/tools/build.py
index f22d32d..faab699 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -228,6 +228,8 @@
   build_config = utils.GetBuildConf(mode, arch, target_os)
   out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
   using_goma = False
+  # TODO(zra): Remove auto-run of gn, replace with prompt for user to run
+  # gn.py manually.
   if ShouldRunGN(out_dir):
     RunGN(target_os, mode, arch)
   command = ['ninja', '-C', out_dir]
diff --git a/tools/gn.py b/tools/gn.py
index d348a21..1a19afd 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -221,6 +221,8 @@
   else:
     gn_args['dart_runtime_mode'] = 'develop'
 
+  gn_args['exclude_kernel_service'] = args.exclude_kernel_service
+
   dont_use_clang = DontUseClang(args, gn_args['target_os'],
                                       gn_args['host_cpu'],
                                       gn_args['target_cpu'])
@@ -392,6 +394,11 @@
       help='Generate an IDE file.',
       default=os_has_ide(HOST_OS),
       action='store_true')
+  other_group.add_argument('--exclude-kernel-service',
+      help='Exclude the kernel service.',
+      default=False,
+      dest='exclude_kernel_service',
+      action='store_true')
   other_group.add_argument('--msan',
       help='Build with MSAN',
       default=UseMSAN(),
diff --git a/tools/patch_sdk.dart b/tools/patch_sdk.dart
index 53f4002..411442c 100644
--- a/tools/patch_sdk.dart
+++ b/tools/patch_sdk.dart
@@ -200,19 +200,11 @@
     ..compileSdk = true
     ..sdkRoot = patchedSdk
     ..packagesFileUri = packages
-    ..chaseDependencies = true
     ..target = target;
 
   var inputs = [Uri.parse('dart:core')];
-  var result = await generateKernel(
-      new ProcessedOptions(
-          options,
-          // TODO(sigmund): pass all sdk libraries needed here, and make this
-          // hermetic.
-          false,
-          inputs),
-      buildSummary: true,
-      buildComponent: true);
+  var result = await generateKernel(new ProcessedOptions(options, inputs),
+      buildSummary: true, buildComponent: true);
   await writeComponentToFile(result.component, output);
   return result.deps;
 }
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 5f930c6..2206a5c 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -68,6 +68,9 @@
       case Compiler.appJit:
         return new AppJitCompilerConfiguration(configuration);
 
+      case Compiler.appJitk:
+        return new AppJitCompilerConfiguration(configuration, useDfe: true);
+
       case Compiler.precompiler:
         return new PrecompilerCompilerConfiguration(configuration);
 
@@ -910,7 +913,11 @@
 }
 
 class AppJitCompilerConfiguration extends CompilerConfiguration {
-  AppJitCompilerConfiguration(Configuration configuration)
+  // This boolean is used by the [VMTestSuite] for running cc tests via
+  // run_vm_tests.
+  final bool useDfe;
+
+  AppJitCompilerConfiguration(Configuration configuration, {this.useDfe: false})
       : super._subclass(configuration);
 
   int get timeoutMultiplier {
@@ -934,6 +941,9 @@
     var exec = "${_configuration.buildDirectory}/dart";
     var snapshot = "$tempDir/out.jitsnapshot";
     var args = ["--snapshot=$snapshot", "--snapshot-kind=app-jit"];
+    if (useDfe) {
+      args.add("--preview-dart-2");
+    }
     args.addAll(arguments);
 
     return Command.compilation('app_jit', tempDir, bootstrapDependencies(),
@@ -966,6 +976,9 @@
       args.add('--enable_asserts');
       args.add('--enable_type_checks');
     }
+    if (useDfe) {
+      args.add('--preview-dart-2');
+    }
     args
       ..addAll(vmOptions)
       ..addAll(sharedOptions)
diff --git a/tools/testing/dart/configuration.dart b/tools/testing/dart/configuration.dart
index 9071636..a6ad1fd 100644
--- a/tools/testing/dart/configuration.dart
+++ b/tools/testing/dart/configuration.dart
@@ -187,6 +187,7 @@
   /// as the first stage of compilation.
   bool get usesFasta {
     var fastaCompilers = const [
+      Compiler.appJitk,
       Compiler.dartdevk,
       Compiler.dartk,
       Compiler.dartkp,
@@ -546,6 +547,7 @@
   static const dartdevc = const Compiler._('dartdevc');
   static const dartdevk = const Compiler._('dartdevk');
   static const appJit = const Compiler._('app_jit');
+  static const appJitk = const Compiler._('app_jitk');
   static const dartk = const Compiler._('dartk');
   static const dartkp = const Compiler._('dartkp');
   static const specParser = const Compiler._('spec_parser');
@@ -561,6 +563,7 @@
     dartdevc,
     dartdevk,
     appJit,
+    appJitk,
     dartk,
     dartkp,
     specParser,
@@ -614,6 +617,7 @@
       case Compiler.dart2analyzer:
         return const [Runtime.none];
       case Compiler.appJit:
+      case Compiler.appJitk:
       case Compiler.dartk:
         return const [Runtime.vm, Runtime.selfCheck];
       case Compiler.precompiler:
@@ -647,6 +651,7 @@
       case Compiler.dart2analyzer:
         return Runtime.none;
       case Compiler.appJit:
+      case Compiler.appJitk:
       case Compiler.dartk:
         return Runtime.vm;
       case Compiler.precompiler:
@@ -805,6 +810,7 @@
       ].contains(this);
 
   bool get isIE => name.startsWith("ie");
+
   bool get isSafari => name.startsWith("safari");
 
   /// Whether this runtime is a command-line JavaScript environment.
diff --git a/tools/testing/dart/options.dart b/tools/testing/dart/options.dart
index f20dbfd..e52f9cb 100644
--- a/tools/testing/dart/options.dart
+++ b/tools/testing/dart/options.dart
@@ -96,6 +96,7 @@
 dart2js:       Compile to JavaScript using dart2js.
 dart2analyzer: Perform static analysis on Dart code using the analyzer.
 app_jit:       Compile the Dart code into an app snapshot.
+app_jitk:      Compile the Dart code into Kernel and then into an app snapshot.
 dartk:         Compile the Dart code into Kernel before running test.
 dartkp:        Compile the Dart code into Kernel and then Kernel into AOT
                snapshot before running the test.
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index 6165c85..888f89d 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -35,6 +35,8 @@
 }
 
 application_snapshot("dartdevk") {
+  dart_version = 2
+
   main_dart = "../../pkg/dev_compiler/bin/dartdevk.dart"
 
   training_args = [
diff --git a/utils/dartfmt/BUILD.gn b/utils/dartfmt/BUILD.gn
index 566475f..99ae1ed 100644
--- a/utils/dartfmt/BUILD.gn
+++ b/utils/dartfmt/BUILD.gn
@@ -5,6 +5,9 @@
 import("../application_snapshot.gni")
 
 application_snapshot("dartfmt") {
+  dart_version = 2
   main_dart = "../../third_party/pkg_tested/dart_style/bin/format.dart"
-  training_args = [ "--help" ]
+
+  # Train it on formatting its own source.
+  training_args = [ "../../third_party/pkg_tested/dart_style" ]
 }